comparison main/MainWindow.cpp @ 34:8ad306d8a568

* Pull transforms out of Layer menu (again) and into a separate Transforms menu * Add Recent Transforms submenu * Add effects and generators to the transforms menu (not yet implemented) as well as analysis plugins and data-from-effects (control output ports) * Add a nice dictionary-volume-style alphabetic subdivision of plugin names in plugins By Name menus
author Chris Cannam
date Fri, 22 Sep 2006 16:12:23 +0000
parents 544ab25d2372
children da7a3828727f
comparison
equal deleted inserted replaced
33:544ab25d2372 34:8ad306d8a568
98 m_viewManager(0), 98 m_viewManager(0),
99 m_panner(0), 99 m_panner(0),
100 m_timeRulerLayer(0), 100 m_timeRulerLayer(0),
101 m_playSource(0), 101 m_playSource(0),
102 m_playTarget(0), 102 m_playTarget(0),
103 m_recentFiles("RecentFiles"),
104 m_recentTransforms("RecentTransforms"),
103 m_mainMenusCreated(false), 105 m_mainMenusCreated(false),
104 m_paneMenu(0), 106 m_paneMenu(0),
105 m_layerMenu(0), 107 m_layerMenu(0),
108 m_transformsMenu(0),
106 m_existingLayersMenu(0), 109 m_existingLayersMenu(0),
110 m_recentFilesMenu(0),
111 m_recentTransformsMenu(0),
107 m_rightButtonMenu(0), 112 m_rightButtonMenu(0),
108 m_rightButtonLayerMenu(0), 113 m_rightButtonLayerMenu(0),
114 m_rightButtonTransformsMenu(0),
109 m_documentModified(false), 115 m_documentModified(false),
110 m_preferencesDialog(0) 116 m_preferencesDialog(0)
111 { 117 {
112 setWindowTitle(tr("Sonic Visualiser")); 118 setWindowTitle(tr("Sonic Visualiser"));
113 119
248 } else { 254 } else {
249 m_rightButtonLayerMenu = m_rightButtonMenu->addMenu(tr("&Layer")); 255 m_rightButtonLayerMenu = m_rightButtonMenu->addMenu(tr("&Layer"));
250 m_rightButtonMenu->addSeparator(); 256 m_rightButtonMenu->addSeparator();
251 } 257 }
252 258
259 if (m_rightButtonTransformsMenu) {
260 m_rightButtonTransformsMenu->clear();
261 } else {
262 m_rightButtonTransformsMenu = m_rightButtonMenu->addMenu(tr("&Transform"));
263 m_rightButtonMenu->addSeparator();
264 }
265
253 if (!m_mainMenusCreated) { 266 if (!m_mainMenusCreated) {
254 267
255 CommandHistory::getInstance()->registerMenu(m_rightButtonMenu); 268 CommandHistory::getInstance()->registerMenu(m_rightButtonMenu);
256 m_rightButtonMenu->addSeparator(); 269 m_rightButtonMenu->addSeparator();
257 270
335 connect(this, SIGNAL(canExportLayer(bool)), action, SLOT(setEnabled(bool))); 348 connect(this, SIGNAL(canExportLayer(bool)), action, SLOT(setEnabled(bool)));
336 menu->addAction(action); 349 menu->addAction(action);
337 350
338 menu->addSeparator(); 351 menu->addSeparator();
339 m_recentFilesMenu = menu->addMenu(tr("&Recent Files")); 352 m_recentFilesMenu = menu->addMenu(tr("&Recent Files"));
340 menu->addMenu(m_recentFilesMenu);
341 setupRecentFilesMenu(); 353 setupRecentFilesMenu();
342 connect(RecentFiles::getInstance(), SIGNAL(recentFilesChanged()), 354 connect(&m_recentFiles, SIGNAL(recentChanged()),
343 this, SLOT(setupRecentFilesMenu())); 355 this, SLOT(setupRecentFilesMenu()));
344 356
345 menu->addSeparator(); 357 menu->addSeparator();
346 action = new QAction(tr("&Preferences..."), this); 358 action = new QAction(tr("&Preferences..."), this);
347 action->setStatusTip(tr("Adjust the application preferences")); 359 action->setStatusTip(tr("Adjust the application preferences"));
563 } else { 575 } else {
564 m_paneMenu = menuBar()->addMenu(tr("&Pane")); 576 m_paneMenu = menuBar()->addMenu(tr("&Pane"));
565 } 577 }
566 578
567 if (m_layerMenu) { 579 if (m_layerMenu) {
568 m_layerTransformActions.clear();
569 m_layerActions.clear(); 580 m_layerActions.clear();
570 m_layerMenu->clear(); 581 m_layerMenu->clear();
571 } else { 582 } else {
572 m_layerMenu = menuBar()->addMenu(tr("&Layer")); 583 m_layerMenu = menuBar()->addMenu(tr("&Layer"));
573 } 584 }
574 585
586 if (m_transformsMenu) {
587 m_transformActions.clear();
588 m_transformActionsReverse.clear();
589 m_transformsMenu->clear();
590 } else {
591 m_transformsMenu = menuBar()->addMenu(tr("&Transform"));
592 }
593
575 TransformFactory::TransformList transforms = 594 TransformFactory::TransformList transforms =
576 TransformFactory::getInstance()->getAllTransforms(); 595 TransformFactory::getInstance()->getAllTransforms();
577 596
578 vector<QString> types = 597 vector<QString> types =
579 TransformFactory::getInstance()->getAllTransformTypes(); 598 TransformFactory::getInstance()->getAllTransformTypes();
582 map<QString, map<QString, QMenu *> > makerMenus; 601 map<QString, map<QString, QMenu *> > makerMenus;
583 602
584 map<QString, QMenu *> byPluginNameMenus; 603 map<QString, QMenu *> byPluginNameMenus;
585 map<QString, map<QString, QMenu *> > pluginNameMenus; 604 map<QString, map<QString, QMenu *> > pluginNameMenus;
586 605
606 m_recentTransformsMenu = m_transformsMenu->addMenu(tr("&Recent Transforms"));
607 m_rightButtonTransformsMenu->addMenu(m_recentTransformsMenu);
608 connect(&m_recentTransforms, SIGNAL(recentChanged()),
609 this, SLOT(setupRecentTransformsMenu()));
610
611 m_transformsMenu->addSeparator();
612 m_rightButtonTransformsMenu->addSeparator();
613
587 for (vector<QString>::iterator i = types.begin(); i != types.end(); ++i) { 614 for (vector<QString>::iterator i = types.begin(); i != types.end(); ++i) {
588 615
589 if (i != types.begin()) { 616 if (i != types.begin()) {
590 m_layerMenu->addSeparator(); 617 m_transformsMenu->addSeparator();
591 m_rightButtonLayerMenu->addSeparator(); 618 m_rightButtonTransformsMenu->addSeparator();
592 } 619 }
593 620
594 QString byCategoryLabel = tr("%1 by Category").arg(*i); 621 QString byCategoryLabel = tr("%1 by Category").arg(*i);
595 QMenu *byCategoryMenu = m_layerMenu->addMenu(byCategoryLabel); 622 QMenu *byCategoryMenu = m_transformsMenu->addMenu(byCategoryLabel);
596 m_rightButtonLayerMenu->addMenu(byCategoryMenu); 623 m_rightButtonTransformsMenu->addMenu(byCategoryMenu);
597 624
598 vector<QString> categories = 625 vector<QString> categories =
599 TransformFactory::getInstance()->getTransformCategories(*i); 626 TransformFactory::getInstance()->getTransformCategories(*i);
600 627
601 for (vector<QString>::iterator j = categories.begin(); 628 for (vector<QString>::iterator j = categories.begin();
628 } 655 }
629 } 656 }
630 } 657 }
631 } 658 }
632 659
660 QString byPluginNameLabel = tr("%1 by Plugin Name").arg(*i);
661 byPluginNameMenus[*i] = m_transformsMenu->addMenu(byPluginNameLabel);
662 m_rightButtonTransformsMenu->addMenu(byPluginNameMenus[*i]);
663
633 QString byMakerLabel = tr("%1 by Maker").arg(*i); 664 QString byMakerLabel = tr("%1 by Maker").arg(*i);
634 QMenu *byMakerMenu = m_layerMenu->addMenu(byMakerLabel); 665 QMenu *byMakerMenu = m_transformsMenu->addMenu(byMakerLabel);
635 m_rightButtonLayerMenu->addMenu(byMakerMenu); 666 m_rightButtonTransformsMenu->addMenu(byMakerMenu);
636 667
637 vector<QString> makers = 668 vector<QString> makers =
638 TransformFactory::getInstance()->getTransformMakers(*i); 669 TransformFactory::getInstance()->getTransformMakers(*i);
639 670
640 for (vector<QString>::iterator j = makers.begin(); 671 for (vector<QString>::iterator j = makers.begin();
643 QString maker = *j; 674 QString maker = *j;
644 if (maker == "") maker = tr("Unknown"); 675 if (maker == "") maker = tr("Unknown");
645 676
646 makerMenus[*i][maker] = byMakerMenu->addMenu(maker); 677 makerMenus[*i][maker] = byMakerMenu->addMenu(maker);
647 } 678 }
648 679 }
649 QString byPluginNameLabel = tr("%1 by Plugin Name").arg(*i); 680
650 byPluginNameMenus[*i] = m_layerMenu->addMenu(byPluginNameLabel); 681 map<QString, set<QString> > pluginNameLists;
651 m_rightButtonLayerMenu->addMenu(byPluginNameMenus[*i]); 682 map<QString, map<QString, QMenu *> > pluginNameToChunkMenuMap;
652 } 683
653 684 for (unsigned int i = 0; i < transforms.size(); ++i) {
685 QString description = transforms[i].description;
686 if (description == "") description = transforms[i].name;
687 QString type = transforms[i].type;
688 QString pluginName = description.section(": ", 0, 0);
689 pluginNameLists[type].insert(pluginName);
690 }
691
692 for (vector<QString>::iterator i = types.begin(); i != types.end(); ++i) {
693
694 size_t total = pluginNameLists[*i].size();
695 size_t chunk = 14;
696
697 if (total < (chunk * 3) / 2) continue;
698
699 size_t count = 0;
700 QMenu *chunkMenu = new QMenu();
701
702 QString firstNameInChunk;
703 QChar firstInitialInChunk;
704 bool discriminateStartInitial = false;
705
706 for (set<QString>::iterator j = pluginNameLists[*i].begin();
707 j != pluginNameLists[*i].end();
708 ++j) {
709
710 pluginNameToChunkMenuMap[*i][*j] = chunkMenu;
711
712 set<QString>::iterator k = j;
713 ++k;
714
715 QChar initial = (*j)[0];
716
717 if (count == 0) {
718 firstNameInChunk = *j;
719 firstInitialInChunk = initial;
720 }
721
722 bool lastInChunk = (k == pluginNameLists[*i].end() ||
723 (count >= chunk-1 &&
724 (count == (5*chunk) / 2 ||
725 (*k)[0] != initial)));
726
727 ++count;
728
729 if (lastInChunk) {
730
731 bool discriminateEndInitial = (k != pluginNameLists[*i].end() &&
732 (*k)[0] == initial);
733
734 bool initialsEqual = (firstInitialInChunk == initial);
735
736 QString from = QString("%1").arg(firstInitialInChunk);
737 if (discriminateStartInitial ||
738 (discriminateEndInitial && initialsEqual)) {
739 from = firstNameInChunk.left(3);
740 }
741
742 QString to = QString("%1").arg(initial);
743 if (discriminateEndInitial ||
744 (discriminateStartInitial && initialsEqual)) {
745 to = j->left(3);
746 }
747
748 QString menuText;
749
750 if (from == to) menuText = from;
751 else menuText = tr("%1 - %2").arg(from).arg(to);
752
753 discriminateStartInitial = discriminateEndInitial;
754
755 chunkMenu->setTitle(menuText);
756
757 byPluginNameMenus[*i]->addMenu(chunkMenu);
758
759 chunkMenu = new QMenu();
760
761 count = 0;
762 }
763 }
764
765 if (count == 0) delete chunkMenu;
766 }
767
654 for (unsigned int i = 0; i < transforms.size(); ++i) { 768 for (unsigned int i = 0; i < transforms.size(); ++i) {
655 769
656 QString description = transforms[i].description; 770 QString description = transforms[i].description;
657 if (description == "") description = transforms[i].name; 771 if (description == "") description = transforms[i].name;
658 772
667 QString pluginName = description.section(": ", 0, 0); 781 QString pluginName = description.section(": ", 0, 0);
668 QString output = description.section(": ", 1); 782 QString output = description.section(": ", 1);
669 783
670 action = new QAction(tr("%1...").arg(description), this); 784 action = new QAction(tr("%1...").arg(description), this);
671 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 785 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
672 m_layerTransformActions[action] = transforms[i].name; 786 m_transformActions[action] = transforms[i].name;
787 m_transformActionsReverse[transforms[i].name] = action;
673 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 788 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
674 789
675 if (categoryMenus[type].find(category) == categoryMenus[type].end()) { 790 if (categoryMenus[type].find(category) == categoryMenus[type].end()) {
676 std::cerr << "WARNING: MainWindow::setupMenus: Internal error: " 791 std::cerr << "WARNING: MainWindow::setupMenus: Internal error: "
677 << "No category menu for transform \"" 792 << "No category menu for transform \""
690 makerMenus[type][maker]->addAction(action); 805 makerMenus[type][maker]->addAction(action);
691 } 806 }
692 807
693 action = new QAction(tr("%1...").arg(output == "" ? pluginName : output), this); 808 action = new QAction(tr("%1...").arg(output == "" ? pluginName : output), this);
694 connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); 809 connect(action, SIGNAL(triggered()), this, SLOT(addLayer()));
695 m_layerTransformActions[action] = transforms[i].name; 810 m_transformActions[action] = transforms[i].name;
696 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); 811 connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool)));
812
813 // cerr << "Transform: \"" << name.toStdString() << "\": plugin name \"" << pluginName.toStdString() << "\"" << endl;
697 814
698 if (pluginNameMenus[type].find(pluginName) == 815 if (pluginNameMenus[type].find(pluginName) ==
699 pluginNameMenus[type].end()) { 816 pluginNameMenus[type].end()) {
700 817
818 QMenu *parentMenu = pluginNameToChunkMenuMap[type][pluginName];
819 if (!parentMenu) parentMenu = byPluginNameMenus[type];
820
701 if (output == "") { 821 if (output == "") {
702 byPluginNameMenus[type]->addAction(action); 822 parentMenu->addAction(action);
703 } else { 823 } else {
704 pluginNameMenus[type][pluginName] = 824 pluginNameMenus[type][pluginName] =
705 byPluginNameMenus[type]->addMenu(pluginName); 825 parentMenu->addMenu(pluginName);
706 connect(this, SIGNAL(canAddLayer(bool)), 826 connect(this, SIGNAL(canAddLayer(bool)),
707 pluginNameMenus[type][pluginName], 827 pluginNameMenus[type][pluginName],
708 SLOT(setEnabled(bool))); 828 SLOT(setEnabled(bool)));
709 } 829 }
710 } 830 }
713 pluginNameMenus[type].end()) { 833 pluginNameMenus[type].end()) {
714 pluginNameMenus[type][pluginName]->addAction(action); 834 pluginNameMenus[type][pluginName]->addAction(action);
715 } 835 }
716 } 836 }
717 837
718 m_rightButtonLayerMenu->addSeparator(); 838 setupRecentTransformsMenu();
719 839
720 menu = m_paneMenu; 840 menu = m_paneMenu;
721 841
722 action = new QAction(QIcon(":/icons/pane.png"), tr("Add &New Pane"), this); 842 action = new QAction(QIcon(":/icons/pane.png"), tr("Add &New Pane"), this);
723 action->setShortcut(tr("Alt+N")); 843 action->setShortcut(tr("Alt+N"));
729 849
730 menu->addSeparator(); 850 menu->addSeparator();
731 851
732 menu = m_layerMenu; 852 menu = m_layerMenu;
733 853
734 menu->addSeparator(); 854 // menu->addSeparator();
735 855
736 LayerFactory::LayerTypeSet emptyLayerTypes = 856 LayerFactory::LayerTypeSet emptyLayerTypes =
737 LayerFactory::getInstance()->getValidEmptyLayerTypes(); 857 LayerFactory::getInstance()->getValidEmptyLayerTypes();
738 858
739 for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin(); 859 for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin();
986 1106
987 void 1107 void
988 MainWindow::setupRecentFilesMenu() 1108 MainWindow::setupRecentFilesMenu()
989 { 1109 {
990 m_recentFilesMenu->clear(); 1110 m_recentFilesMenu->clear();
991 vector<QString> files = RecentFiles::getInstance()->getRecentFiles(); 1111 vector<QString> files = m_recentFiles.getRecent();
992 for (size_t i = 0; i < files.size(); ++i) { 1112 for (size_t i = 0; i < files.size(); ++i) {
993 QAction *action = new QAction(files[i], this); 1113 QAction *action = new QAction(files[i], this);
994 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile())); 1114 connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile()));
995 m_recentFilesMenu->addAction(action); 1115 m_recentFilesMenu->addAction(action);
1116 }
1117 }
1118
1119 void
1120 MainWindow::setupRecentTransformsMenu()
1121 {
1122 m_recentTransformsMenu->clear();
1123 vector<QString> transforms = m_recentTransforms.getRecent();
1124 for (size_t i = 0; i < transforms.size(); ++i) {
1125 TransformActionReverseMap::iterator ti =
1126 m_transformActionsReverse.find(transforms[i]);
1127 if (ti == m_transformActionsReverse.end()) {
1128 std::cerr << "WARNING: MainWindow::setupRecentTransformsMenu: "
1129 << "Unknown transform \"" << transforms[i].toStdString()
1130 << "\" in recent transforms list" << std::endl;
1131 continue;
1132 }
1133 m_recentTransformsMenu->addAction(ti->second);
996 } 1134 }
997 } 1135 }
998 1136
999 void 1137 void
1000 MainWindow::setupExistingLayersMenu() 1138 MainWindow::setupExistingLayersMenu()
1700 delete writer; 1838 delete writer;
1701 } 1839 }
1702 1840
1703 if (ok) { 1841 if (ok) {
1704 if (!multiple) { 1842 if (!multiple) {
1705 RecentFiles::getInstance()->addFile(path); 1843 m_recentFiles.addFile(path);
1706 } 1844 }
1707 } else { 1845 } else {
1708 QMessageBox::critical(this, tr("Failed to write file"), error); 1846 QMessageBox::critical(this, tr("Failed to write file"), error);
1709 } 1847 }
1710 } 1848 }
1781 << "): Failed to read XML file: " 1919 << "): Failed to read XML file: "
1782 << reader.getErrorString().toStdString() << std::endl; 1920 << reader.getErrorString().toStdString() << std::endl;
1783 return false; 1921 return false;
1784 } 1922 }
1785 1923
1786 RecentFiles::getInstance()->addFile(path); 1924 m_recentFiles.addFile(path);
1787 return true; 1925 return true;
1788 1926
1789 } else { 1927 } else {
1790 1928
1791 Model *model = DataFileReaderFactory::load(path, getMainModel()->getSampleRate()); 1929 Model *model = DataFileReaderFactory::load(path, getMainModel()->getSampleRate());
1792 1930
1793 if (model) { 1931 if (model) {
1794 Layer *newLayer = m_document->createImportedLayer(model); 1932 Layer *newLayer = m_document->createImportedLayer(model);
1795 if (newLayer) { 1933 if (newLayer) {
1796 m_document->addLayerToView(pane, newLayer); 1934 m_document->addLayerToView(pane, newLayer);
1797 RecentFiles::getInstance()->addFile(path); 1935 m_recentFiles.addFile(path);
1798 return true; 1936 return true;
1799 } 1937 }
1800 } 1938 }
1801 } 1939 }
1802 1940
1860 } 1998 }
1861 1999
1862 if (error != "") { 2000 if (error != "") {
1863 QMessageBox::critical(this, tr("Failed to write file"), error); 2001 QMessageBox::critical(this, tr("Failed to write file"), error);
1864 } else { 2002 } else {
1865 RecentFiles::getInstance()->addFile(path); 2003 m_recentFiles.addFile(path);
1866 } 2004 }
1867 } 2005 }
1868 2006
1869 bool 2007 bool
1870 MainWindow::openAudioFile(QString path, AudioFileOpenMode mode) 2008 MainWindow::openAudioFile(QString path, AudioFileOpenMode mode)
1968 2106
1969 CommandHistory::getInstance()->endCompoundOperation(); 2107 CommandHistory::getInstance()->endCompoundOperation();
1970 } 2108 }
1971 2109
1972 updateMenuStates(); 2110 updateMenuStates();
1973 RecentFiles::getInstance()->addFile(path); 2111 m_recentFiles.addFile(path);
1974 2112
1975 return true; 2113 return true;
1976 } 2114 }
1977 2115
1978 void 2116 void
2273 setupMenus(); 2411 setupMenus();
2274 CommandHistory::getInstance()->clear(); 2412 CommandHistory::getInstance()->clear();
2275 CommandHistory::getInstance()->documentSaved(); 2413 CommandHistory::getInstance()->documentSaved();
2276 m_documentModified = false; 2414 m_documentModified = false;
2277 updateMenuStates(); 2415 updateMenuStates();
2278 RecentFiles::getInstance()->addFile(path); 2416 m_recentFiles.addFile(path);
2279 } else { 2417 } else {
2280 setWindowTitle(tr("Sonic Visualiser")); 2418 setWindowTitle(tr("Sonic Visualiser"));
2281 } 2419 }
2282 2420
2283 return ok; 2421 return ok;
2327 QString fname = QString("tmp-%1-%2.sv") 2465 QString fname = QString("tmp-%1-%2.sv")
2328 .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz")) 2466 .arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"))
2329 .arg(QProcess().pid()); 2467 .arg(QProcess().pid());
2330 QString fpath = QDir(svDir).filePath(fname); 2468 QString fpath = QDir(svDir).filePath(fname);
2331 if (saveSessionFile(fpath)) { 2469 if (saveSessionFile(fpath)) {
2332 RecentFiles::getInstance()->addFile(fpath); 2470 m_recentFiles.addFile(fpath);
2333 return true; 2471 return true;
2334 } else { 2472 } else {
2335 return false; 2473 return false;
2336 } 2474 }
2337 } 2475 }
2436 setWindowTitle(tr("Sonic Visualiser: %1") 2574 setWindowTitle(tr("Sonic Visualiser: %1")
2437 .arg(QFileInfo(path).fileName())); 2575 .arg(QFileInfo(path).fileName()));
2438 m_sessionFile = path; 2576 m_sessionFile = path;
2439 CommandHistory::getInstance()->documentSaved(); 2577 CommandHistory::getInstance()->documentSaved();
2440 documentRestored(); 2578 documentRestored();
2441 RecentFiles::getInstance()->addFile(path); 2579 m_recentFiles.addFile(path);
2442 } 2580 }
2443 } 2581 }
2444 2582
2445 bool 2583 bool
2446 MainWindow::saveSessionFile(QString path) 2584 MainWindow::saveSessionFile(QString path)
2853 m_document->addLayerToView(pane, newLayer); 2991 m_document->addLayerToView(pane, newLayer);
2854 m_paneStack->setCurrentLayer(pane, newLayer); 2992 m_paneStack->setCurrentLayer(pane, newLayer);
2855 return; 2993 return;
2856 } 2994 }
2857 2995
2858 TransformActionMap::iterator i = m_layerTransformActions.find(action); 2996 TransformActionMap::iterator i = m_transformActions.find(action);
2859 2997
2860 if (i == m_layerTransformActions.end()) { 2998 if (i == m_transformActions.end()) {
2861 2999
2862 LayerActionMap::iterator i = m_layerActions.find(action); 3000 LayerActionMap::iterator i = m_layerActions.find(action);
2863 3001
2864 if (i == m_layerActions.end()) { 3002 if (i == m_layerActions.end()) {
2865 std::cerr << "WARNING: MainWindow::addLayer: unknown action " 3003 std::cerr << "WARNING: MainWindow::addLayer: unknown action "
2922 configurationXml); 3060 configurationXml);
2923 3061
2924 if (newLayer) { 3062 if (newLayer) {
2925 m_document->addLayerToView(pane, newLayer); 3063 m_document->addLayerToView(pane, newLayer);
2926 m_document->setChannel(newLayer, context.channel); 3064 m_document->setChannel(newLayer, context.channel);
3065 m_recentTransforms.add(transform);
2927 } 3066 }
2928 3067
2929 updateMenuStates(); 3068 updateMenuStates();
2930 } 3069 }
2931 3070
3168 MainWindow::modelGenerationFailed(QString transformName) 3307 MainWindow::modelGenerationFailed(QString transformName)
3169 { 3308 {
3170 QMessageBox::warning 3309 QMessageBox::warning
3171 (this, 3310 (this,
3172 tr("Failed to generate layer"), 3311 tr("Failed to generate layer"),
3173 tr("The layer transform \"%1\" failed to run.\nThis probably means that a plugin failed to initialise.") 3312 tr("Failed to generate a derived layer.\n\nThe layer transform \"%1\" failed.\n\nThis probably means that a plugin failed to initialise, perhaps because it\nrejected the processing block size that was requested.")
3174 .arg(transformName), 3313 .arg(transformName),
3175 QMessageBox::Ok, 0); 3314 QMessageBox::Ok, 0);
3176 } 3315 }
3177 3316
3178 void 3317 void
3179 MainWindow::modelRegenerationFailed(QString layerName, QString transformName) 3318 MainWindow::modelRegenerationFailed(QString layerName, QString transformName)
3180 { 3319 {
3181 QMessageBox::warning 3320 QMessageBox::warning
3182 (this, 3321 (this,
3183 tr("Failed to regenerate layer"), 3322 tr("Failed to regenerate layer"),
3184 tr("Failed to regenerate derived layer \"%1\".\nThe layer transform \"%2\" failed to run.\nThis probably means the layer used a plugin that is not currently available.") 3323 tr("Failed to regenerate derived layer \"%1\".\n\nThe layer transform \"%2\" failed to run.\n\nThis probably means the layer used a plugin that is not currently available.")
3185 .arg(layerName).arg(transformName), 3324 .arg(layerName).arg(transformName),
3186 QMessageBox::Ok, 0); 3325 QMessageBox::Ok, 0);
3187 } 3326 }
3188 3327
3189 void 3328 void