comparison main/MainWindow.cpp @ 33:544ab25d2372

* Add support for plugin classification using category files. Add separate menus listing plugins by category, maker, and plugin name.
author Chris Cannam
date Thu, 21 Sep 2006 16:43:50 +0000
parents 61259228d029
children 8ad306d8a568
comparison
equal deleted inserted replaced
32:e3b32dc5180b 33:544ab25d2372
85 #include <errno.h> 85 #include <errno.h>
86 86
87 using std::cerr; 87 using std::cerr;
88 using std::endl; 88 using std::endl;
89 89
90 using std::vector;
91 using std::map;
92 using std::set;
93
90 94
91 MainWindow::MainWindow() : 95 MainWindow::MainWindow() :
92 m_document(0), 96 m_document(0),
93 m_paneStack(0), 97 m_paneStack(0),
94 m_viewManager(0), 98 m_viewManager(0),
569 } 573 }
570 574
571 TransformFactory::TransformList transforms = 575 TransformFactory::TransformList transforms =
572 TransformFactory::getInstance()->getAllTransforms(); 576 TransformFactory::getInstance()->getAllTransforms();
573 577
574 std::vector<QString> types = 578 vector<QString> types =
575 TransformFactory::getInstance()->getAllTransformTypes(); 579 TransformFactory::getInstance()->getAllTransformTypes();
576 580
577 std::map<QString, QMenu *> transformMenus; 581 map<QString, map<QString, QMenu *> > categoryMenus;
578 582 map<QString, map<QString, QMenu *> > makerMenus;
579 for (std::vector<QString>::iterator i = types.begin(); i != types.end(); ++i) { 583
580 transformMenus[*i] = m_layerMenu->addMenu(*i); 584 map<QString, QMenu *> byPluginNameMenus;
581 m_rightButtonLayerMenu->addMenu(transformMenus[*i]); 585 map<QString, map<QString, QMenu *> > pluginNameMenus;
586
587 for (vector<QString>::iterator i = types.begin(); i != types.end(); ++i) {
588
589 if (i != types.begin()) {
590 m_layerMenu->addSeparator();
591 m_rightButtonLayerMenu->addSeparator();
592 }
593
594 QString byCategoryLabel = tr("%1 by Category").arg(*i);
595 QMenu *byCategoryMenu = m_layerMenu->addMenu(byCategoryLabel);
596 m_rightButtonLayerMenu->addMenu(byCategoryMenu);
597
598 vector<QString> categories =
599 TransformFactory::getInstance()->getTransformCategories(*i);
600
601 for (vector<QString>::iterator j = categories.begin();
602 j != categories.end(); ++j) {
603
604 QString category = *j;
605 if (category == "") category = tr("Unclassified");
606
607 if (categories.size() < 2) {
608 categoryMenus[*i][category] = byCategoryMenu;
609 continue;
610 }
611
612 QStringList components = category.split(" > ");
613 QString key;
614
615 for (QStringList::iterator k = components.begin();
616 k != components.end(); ++k) {
617
618 QString parentKey = key;
619 if (key != "") key += " > ";
620 key += *k;
621
622 if (categoryMenus[*i].find(key) == categoryMenus[*i].end()) {
623 if (parentKey == "") {
624 categoryMenus[*i][key] = byCategoryMenu->addMenu(*k);
625 } else {
626 categoryMenus[*i][key] =
627 categoryMenus[*i][parentKey]->addMenu(*k);
628 }
629 }
630 }
631 }
632
633 QString byMakerLabel = tr("%1 by Maker").arg(*i);
634 QMenu *byMakerMenu = m_layerMenu->addMenu(byMakerLabel);
635 m_rightButtonLayerMenu->addMenu(byMakerMenu);
636
637 vector<QString> makers =
638 TransformFactory::getInstance()->getTransformMakers(*i);
639
640 for (vector<QString>::iterator j = makers.begin();
641 j != makers.end(); ++j) {
642
643 QString maker = *j;
644 if (maker == "") maker = tr("Unknown");
645
646 makerMenus[*i][maker] = byMakerMenu->addMenu(maker);
647 }
648
649 QString byPluginNameLabel = tr("%1 by Plugin Name").arg(*i);
650 byPluginNameMenus[*i] = m_layerMenu->addMenu(byPluginNameLabel);
651 m_rightButtonLayerMenu->addMenu(byPluginNameMenus[*i]);
582 } 652 }
583 653
584 for (unsigned int i = 0; i < transforms.size(); ++i) { 654 for (unsigned int i = 0; i < transforms.size(); ++i) {
585 655
586 QString description = transforms[i].description; 656 QString description = transforms[i].description;
587 if (description == "") description = transforms[i].name; 657 if (description == "") description = transforms[i].name;
588 658
589 QString actionText = description; 659 QString type = transforms[i].type;
590 if (transforms[i].configurable) { 660
591 actionText = QString("%1...").arg(actionText); 661 QString category = transforms[i].category;
592 } 662 if (category == "") category = tr("Unclassified");
593 663
594 action = new QAction(actionText, this); 664 QString maker = transforms[i].maker;
665 if (maker == "") maker = tr("Unknown");
666
667 QString pluginName = description.section(": ", 0, 0);
668 QString output = description.section(": ", 1);
669
670 action = new QAction(tr("%1...").arg(description), this);
595 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 671 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
596 m_layerTransformActions[action] = transforms[i].name; 672 m_layerTransformActions[action] = transforms[i].name;
597 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 673 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
598 transformMenus[transforms[i].type]->addAction(action); 674
675 if (categoryMenus[type].find(category) == categoryMenus[type].end()) {
676 std::cerr << "WARNING: MainWindow::setupMenus: Internal error: "
677 << "No category menu for transform \""
678 << description.toStdString() << "\" (category = \""
679 << category.toStdString() << "\")" << std::endl;
680 } else {
681 categoryMenus[type][category]->addAction(action);
682 }
683
684 if (makerMenus[type].find(maker) == makerMenus[type].end()) {
685 std::cerr << "WARNING: MainWindow::setupMenus: Internal error: "
686 << "No maker menu for transform \""
687 << description.toStdString() << "\" (maker = \""
688 << maker.toStdString() << "\")" << std::endl;
689 } else {
690 makerMenus[type][maker]->addAction(action);
691 }
692
693 action = new QAction(tr("%1...").arg(output == "" ? pluginName : output), this);
694 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
695 m_layerTransformActions[action] = transforms[i].name;
696 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
697
698 if (pluginNameMenus[type].find(pluginName) ==
699 pluginNameMenus[type].end()) {
700
701 if (output == "") {
702 byPluginNameMenus[type]->addAction(action);
703 } else {
704 pluginNameMenus[type][pluginName] =
705 byPluginNameMenus[type]->addMenu(pluginName);
706 connect(this, SIGNAL(canAddLayer(bool)),
707 pluginNameMenus[type][pluginName],
708 SLOT(setEnabled(bool)));
709 }
710 }
711
712 if (pluginNameMenus[type].find(pluginName) !=
713 pluginNameMenus[type].end()) {
714 pluginNameMenus[type][pluginName]->addAction(action);
715 }
599 } 716 }
600 717
601 m_rightButtonLayerMenu->addSeparator(); 718 m_rightButtonLayerMenu->addSeparator();
602 719
603 menu = m_paneMenu; 720 menu = m_paneMenu;
869 986
870 void 987 void
871 MainWindow::setupRecentFilesMenu() 988 MainWindow::setupRecentFilesMenu()
872 { 989 {
873 m_recentFilesMenu->clear(); 990 m_recentFilesMenu->clear();
874 std::vector<QString> files = RecentFiles::getInstance()->getRecentFiles(); 991 vector<QString> files = RecentFiles::getInstance()->getRecentFiles();
875 for (size_t i = 0; i < files.size(); ++i) { 992 for (size_t i = 0; i < files.size(); ++i) {
876 QAction *action = new QAction(files[i], this); 993 QAction *action = new QAction(files[i], this);
877 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile())); 994 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile()));
878 m_recentFilesMenu->addAction(action); 995 m_recentFilesMenu->addAction(action);
879 } 996 }
887 // std::cerr << "MainWindow::setupExistingLayersMenu" << std::endl; 1004 // std::cerr << "MainWindow::setupExistingLayersMenu" << std::endl;
888 1005
889 m_existingLayersMenu->clear(); 1006 m_existingLayersMenu->clear();
890 m_existingLayerActions.clear(); 1007 m_existingLayerActions.clear();
891 1008
892 std::vector<Layer *> orderedLayers; 1009 vector<Layer *> orderedLayers;
893 std::set<Layer *> observedLayers; 1010 set<Layer *> observedLayers;
894 1011
895 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { 1012 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
896 1013
897 Pane *pane = m_paneStack->getPane(i); 1014 Pane *pane = m_paneStack->getPane(i);
898 if (!pane) continue; 1015 if (!pane) continue;
912 orderedLayers.push_back(layer); 1029 orderedLayers.push_back(layer);
913 observedLayers.insert(layer); 1030 observedLayers.insert(layer);
914 } 1031 }
915 } 1032 }
916 1033
917 std::map<QString, int> observedNames; 1034 map<QString, int> observedNames;
918 1035
919 for (int i = 0; i < orderedLayers.size(); ++i) { 1036 for (int i = 0; i < orderedLayers.size(); ++i) {
920 1037
921 QString name = orderedLayers[i]->getLayerPresentationName(); 1038 QString name = orderedLayers[i]->getLayerPresentationName();
922 int n = ++observedNames[name]; 1039 int n = ++observedNames[name];
2786 channel = c; 2903 channel = c;
2787 break; 2904 break;
2788 } 2905 }
2789 } 2906 }
2790 2907
2791 bool needConfiguration = false; 2908 // We always ask for configuration, even if the plugin isn't
2792 2909 // supposed to be configurable, because we need to let the user
2793 //!!! actually we should probably always ask for configuration 2910 // change the execution context (block size etc).
2794 //because we need the execution context
2795
2796 if (factory->isTransformConfigurable(transform)) {
2797 needConfiguration = true;
2798 } else {
2799 int minChannels, maxChannels;
2800 int myChannels = m_document->getMainModel()->getChannelCount();
2801 if (factory->getTransformChannelRange(transform,
2802 minChannels,
2803 maxChannels)) {
2804 // std::cerr << "myChannels: " << myChannels << ", minChannels: " << minChannels << ", maxChannels: " << maxChannels << std::endl;
2805 needConfiguration = (myChannels > maxChannels && maxChannels == 1);
2806 }
2807 }
2808 2911
2809 PluginTransform::ExecutionContext context(channel); 2912 PluginTransform::ExecutionContext context(channel);
2810 2913
2811 if (needConfiguration) { 2914 bool ok =
2812 bool ok = 2915 factory->getConfigurationForTransform
2813 factory->getConfigurationForTransform 2916 (transform, m_document->getMainModel(), context, configurationXml);
2814 (transform, m_document->getMainModel(), context, configurationXml); 2917 if (!ok) return;
2815 if (!ok) return;
2816 }
2817 2918
2818 Layer *newLayer = m_document->createDerivedLayer(transform, 2919 Layer *newLayer = m_document->createDerivedLayer(transform,
2819 m_document->getMainModel(), 2920 m_document->getMainModel(),
2820 context, 2921 context,
2821 configurationXml); 2922 configurationXml);