diff --git a/Modules/US/Testing/mitkUSImageVideoSourceTest.cpp b/Modules/US/Testing/mitkUSImageVideoSourceTest.cpp index cfdb23e5a3..9bb4ae2aa7 100644 --- a/Modules/US/Testing/mitkUSImageVideoSourceTest.cpp +++ b/Modules/US/Testing/mitkUSImageVideoSourceTest.cpp @@ -1,79 +1,77 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkUSImageVideoSource.h" #include "mitkTestingMacros.h" class mitkUSImageVideoSourceTestClass { public: static void TestInstantiation() { // let's create an object of our class mitk::USImageVideoSource::Pointer usSource = mitk::USImageVideoSource::New(); MITK_TEST_CONDITION_REQUIRED(usSource.IsNotNull(), "USImageVideoSource should not be null after instantiation"); } static void TestOpenVideoFile(std::string videoFilePath) { mitk::USImageVideoSource::Pointer usSource = mitk::USImageVideoSource::New(); usSource->SetVideoFileInput(videoFilePath); MITK_TEST_CONDITION_REQUIRED(usSource->GetIsVideoReady(), "USImageVideoSource should have isVideoReady flag set after opening a Video File"); mitk::Image::Pointer frame; frame = usSource->GetNextImage(); MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "First frame should not be null."); frame = usSource->GetNextImage(); MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "Second frame should not be null."); frame = usSource->GetNextImage(); MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "Third frame should not be null."); frame = usSource->GetNextImage(); MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "Fourth frame should not be null."); frame = usSource->GetNextImage(); MITK_TEST_CONDITION_REQUIRED(frame.IsNotNull(), "Fifth frame should not be null."); } /** This Test will fail if no device is attached. Since it basically covers the same non-OpenCV Functionality as TestOpenVideoFile, it is ommited static void TestOpenDevice() { mitk::USImageVideoSource::Pointer usSource = mitk::USImageVideoSource::New(); usSource->SetCameraInput(-1); MITK_TEST_CONDITION_REQUIRED(usSource->GetIsVideoReady(), "USImageVideoSource should have isVideoReady flag set after opening a Camera device"); } */ }; /** * This function is testing methods of the class USImageVideoSource. */ int mitkUSImageVideoSourceTest(int, char* argv[]) { MITK_TEST_BEGIN("mitkUSImageVideoSourceTest"); mitkUSImageVideoSourceTestClass::TestInstantiation(); #ifdef WIN32 // Video file compression is currently only supported under windows. mitkUSImageVideoSourceTestClass::TestOpenVideoFile(argv[1]); -#else - argv; #endif // This test is commented out since no videodevcie ist steadily connected to the dart clients. // Functionality should sufficiently be tested through TestOpenVideoFile anyway //mitkUSImageVideoSourceTestClass::TestOpenDevice(); MITK_TEST_END(); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/resources/welcome/function.js b/Plugins/org.mitk.gui.qt.diffusionimagingapp/resources/welcome/function.js index f5bbf10fc7..3b50d7c9fa 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/resources/welcome/function.js +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/resources/welcome/function.js @@ -1,323 +1,323 @@ // If you want to create a new button you have to add some data (strings) to the following five arrays. // Make sure that you add your data at the same position in each array. // The buttons will be generated in order to the array's index. e.g. data at array's index '0' will generate the first button. // enter the name of your module here var moduleNames = new Array("Dicom Import", - "IVIM", - "Preprocessing", - "Quantification", + "Preprocessing and Reconstruction", "Tractography", "Connectomics", - "Synthetic Data", - "Registration", + "Fiberfox", +// "Registration", + "IVIM", "Image Processing", "Visualization", "Utilities", "MITK Downloads & News"); // add the MITK-link to your module var moduleLinks = new Array("mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", - "mitk://mitk.perspectives/org.mitk.perspectives.diffusiondefault?clear=false", + "mitk://mitk.perspectives/org.mitk.perspectives.reconstruction1?clear=false", + "mitk://mitk.perspectives/org.mitk.perspectives.tractography2?clear=false", + "mitk://mitk.perspectives/org.mitk.perspectives.connectomics?clear=false", + "mitk://mitk.perspectives/org.mitk.perspectives.syntheticdata?clear=false", + "mitk://mitk.perspectives/org.mitk.perspectives.ivim?clear=false", + "", + "", + "", +// "", +// "", "http://www.mitk.org"); // add the filename of your icon for the module. Place the picture in subdirectory "pics". // The picture's width should be 136 pixel; the height 123 pixel. var picFilenames = new Array("01dicomimport.png", - "07ivim.png", "02preprocessingreconstruction.png", - "03quantification.png", +// "03quantification.png", "04tractography.png", "06connectomics.png", "10softwarephantoms.png", - "12registration.png", +// "12registration.png", + "07ivim.png", "11segmentation.png", "08volumevisualization.png", "13utilities.png", "button_mitk.png"); // if you want to create an animated icon, add the name of your animated gif (placed in subdirectory "pics"). Otherwise enter an empty string "". // The animation's width should be 136 pixel; the height 123 pixel. var aniFilenames = new Array("01adicomimport.png", - "07aivim.png", "02apreprocessingreconstruction.png", - "03aquantification.png", +// "03aquantification.png", "04atractography.png", "06aconnectomics.png", "10asoftwarephantoms.png", - "12aregistration.png", +// "12aregistration.png", + "07aivim.png", "11asegmentation.png", "08avolumevisualization.png", "13autilities.png", "button_mitka.png"); // if your module is not stable, you can mark it as experimental. // just set true for experimental or false for stable. var experimental = new Array(false, false, false, false, false, false, false, - true, - false, false, +// false, +// false, false, false); // add the description for your module. The description is displayed in a PopUp-window. var moduleDescriptions = new Array("MITK Diffusion supports direct import of Siemens diffusion weighted DICOM files.", - "You can use Intravoxel Incoherent Motion to estimate tissue perfusion on basis of diffusion measurements. Several models and interactive exploration of the data are supported.", "You can use MITK Diffusion to preprocess diffusion weighted MR Images using techniques like gradient averaging or reduction and baseline image extraction. Then you can estimate diffusion tensors or q-balls using different reconstruction methods and calculates scalar indices (FA, GFA, ...).", - "MITK Diffusion allows partial volume analysis and the evaluation and exploration of Tract Based Spatial Statistic datasets (it does NOT reimplement the TBSS methods available in FSL). The Partial Volume Analysis view provides a very robust method for semi-automatic ROI analysis. It uses EM clustering to probabilistically segment fiber vs. non-fiber vs. partial volume.", - "The tractography components of MITK Diffusion implement several fiber tractography algorithms (global, probabilistic and streamline). The fiber bundle operations view allows for extraction, join, and substraction of bundles. It also generates a variety of images from given fiber tracts and gives detailed information about the fiberbundle itself.", - "Connectomics aims at building graphs (nodes and edges) from a global tractogram and applying graph theory for data analysis.", - "The Fiberfox software phantom tool allows you to create synthetic phantoms easily and with a wide variety of properties and options.", - "Registration views allow for rigid and point based image registration (only non-diffusion!).", +// "MITK Diffusion allows partial volume analysis and the evaluation and exploration of Tract Based Spatial Statistic datasets (it does NOT reimplement the TBSS methods available in FSL). The Partial Volume Analysis view provides a very robust method for semi-automatic ROI analysis. It uses EM clustering to probabilistically segment fiber vs. non-fiber vs. partial volume.", + "The tractography components of MITK Diffusion implement several fiber tractography algorithms (global and streamline; tensor, dODF/fODF/FOD, peak based as well as machine learning based using the raw signal). The fiber bundle operations view enables fiber postprocessing in various ways. The fiber quantification view generates a variety of images from given fiber tracts, extracts the principal fiber directions and gives detailed information about the fiberbundle itself.", + "Connectomics aims at building graphs (nodes and edges) from a tractogram and applying graph theory for data analysis.", + "The Fiberfox software phantom tool allows you to create synthetic diffusion-weighted MR images easily and with a wide variety of properties and options.", +// "Registration views allow for rigid and point based image registration (only non-diffusion!).", + "You can use Intravoxel Incoherent Motion to estimate tissue perfusion on basis of diffusion measurements. Several models and interactive exploration of the data are supported.", "MITK Diffusion provides tools for image segmentation and diffusion unrelated image processing.", "In order to visually present your research MITK Diffusion contains fast volume rendering of images, means to capture high resolution screenshots as well as movies of the 3D sceen.", "Further utilites include the property list view to modify the properties of the selected data node as well as a logging view for debugging purposes.", "Open the MITK website in an external browser."); var bttns = new Array(); var d = document, da = d.all; // holds id of current mouseover-HTML-element var currentTarget; // get the id of current mouseover-HTML-element d.onmouseover = function(o){ var e = da ? event.srcElement : o.target; currentTarget = e.id; } // build-function called by onload-event in HTML-document function createButtons(){ for (i=0; i < moduleNames.length; i++){ bttns[i] = new Button(moduleNames[i],moduleLinks[i], picFilenames[i], aniFilenames[i],moduleDescriptions[i]); bttns[i].createButton(); } for (i=0; i < moduleNames.length; i++){ if(experimental[i]){ setExperimental(i); } } createClearFloat(); } // Class Button function Button(moduleName, moduleLink, picFilename, aniFilename, moduleDescr){ // Properties this.bttnID = "bttn" + moduleName; this.modName = moduleName; this.modLink = moduleLink; this.picPath = "pics/" + picFilename; this.aniPath = "pics/" + aniFilename; this.modDescr = moduleDescr; // Methods this.createButton = function(){ // get DIV-wrapper for Button and append it to HTML-document bttnWrapper = this.createWrapper(); document.getElementById("bttnField").appendChild(bttnWrapper); // get link-element for picture and append it to DIV-wrapper bttnPicLink = this.createPicLink(); bttnWrapper.appendChild(bttnPicLink); // set HTML attributes for button-element bttn = document.createElement("img"); bttn.src = this.picPath; bttn.id = this.bttnID; bttn.className = "modBttn"; bttn.height = 123; bttn.width = 136; bttn.onmouseover = function(){startAni(this.id);}; bttn.onmouseout = function(){stopAni(this.id);}; // append button to link-element bttnPicLink.appendChild(bttn); - // create text-link and add it to DIV-wrapper - bttnTxtLink = document.createElement("a"); - bttnTxtLink.href = this.modLink; - bttnTxtLink.className = "txtLink"; - bttnTxtLink.appendChild(document.createTextNode(this.modName)); - bttnWrapper.appendChild(bttnTxtLink); +// // create text-link and add it to DIV-wrapper +// bttnTxtLink = document.createElement("a"); +//// bttnTxtLink.href = this.modLink; +// bttnTxtLink.className = "txtLink"; +// bttnTxtLink.appendChild(document.createTextNode(this.modName)); +// bttnTxtLink.onclick = function(){showPopUpWindow();}; +// bttnTxtLink.id = "popup" + this.modName; +// bttnWrapper.appendChild(bttnTxtLink); // create pop-up link for module description bttnPopUpLink = document.createElement("a"); modName = this.modName; modDescr = this.modDescr; bttnPopUpLink.onclick = function(){showPopUpWindow();}; bttnPopUpLink.className = "popUpLink"; bttnPopUpLink.id = "popup" + this.modName; - bttnPopUpLink.appendChild(document.createTextNode("more info >>")); - bttnWrapper.appendChild(document.createElement("br")); + bttnPopUpLink.appendChild(document.createTextNode(this.modName)); bttnWrapper.appendChild(bttnPopUpLink); return bttn; } this.createWrapper = function(){ bttnWrapper = document.createElement("div"); bttnWrapper.id = "wrapper" + this.modName; bttnWrapper.className = "bttnWrap"; return bttnWrapper; } this.createPicLink = function(){ picLink = document.createElement("a"); picLink.href = this.modLink; picLink.id = "link" + this.modName; return picLink; } } function showPopUpWindow(){ // modules position in array? modulePos = getPos(currentTarget,"popup"); // get reference to anchor-element in HTML-document popUpAnchor = document.getElementById("popupAnchor"); // check if a popUp is open if(popUpAnchor.hasChildNodes()){ // if a popUp is open, remove it! popUpAnchor.removeChild(document.getElementById("popup")); } // create new container for popUp container = document.createElement("div"); container.id = "popup"; container.align = "right"; // append popUp-container to HTML-document popUpAnchor.appendChild(container); // create close-button and append it to popUp-container bttnClose = document.createElement("img"); bttnClose.src = "pics/popup_bttn_close.png"; bttnClose.id = "bttnClose"; bttnClose.onclick = function(){closeInfoWindow();}; container.appendChild(bttnClose); // create container for content-elements contHeadline = document.createElement("div"); contHeadline.id = "contHeadline"; contDescription = document.createElement("div"); contDescription.id = "contDescription"; contModLink = document.createElement("div"); contModLink.id = "contModLink"; // append content-container to popUp-container container.appendChild(contHeadline); container.appendChild(contDescription); container.appendChild(contModLink); // create text-elements with content headline = document.createTextNode(moduleNames[modulePos] + " "); description = document.createTextNode(moduleDescriptions[modulePos]); moduleLink = document.createElement("a"); moduleLink.href = moduleLinks[modulePos] ; moduleLink.className = 'moduleLink'; moduleLinkTxt = document.createTextNode("Click here to open '" + moduleNames[modulePos].toLowerCase() + "'"); moduleLink.appendChild(moduleLinkTxt); // append text-elements to their container contHeadline.appendChild(headline); contDescription.appendChild(description); - //contModLink.appendChild(moduleLink); +// contModLink.appendChild(moduleLink); } function getPos(id,prefix){ if(prefix == "popup"){ targetID = id.slice(5); }else{ if(prefix == "bttn"){ targetID = id.slice(4); } } for(i=0; i < moduleNames.length; i++ ){ if(moduleNames[i] == targetID){ return i; } } } function setExperimental(modPos){ linkID = "link" + moduleNames[modPos]; expPic = document.createElement("img"); expPic.src = "pics/experimental.png"; expPic.className = "expPic"; //alert(bttns[modPos].bttnID); expPic.onmouseover = function(){startAni(bttns[modPos].bttnID);changeToHover(bttns[modPos].bttnID);}; expPic.onmouseout = function(){stopAni(bttns[modPos].bttnID);changeToNormal(bttns[modPos].bttnID);}; document.getElementById(linkID).appendChild(expPic); } function changeToHover(targetId){ bttn = document.getElementById(targetId); bttn.className = "modBttnHover"; } function changeToNormal(targetId){ bttn = document.getElementById(targetId); bttn.className = "modBttn"; } // function to close PopUp-window function closeInfoWindow(){ popUpAnchor = document.getElementById("popupAnchor"); popUpAnchor.removeChild(document.getElementById("popup")); } function createClearFloat(){ cf = document.createElement("div"); cf.className = "clearfloat"; document.getElementById("bttnField").appendChild(cf); } startAni = function(targetId){ modulePos = getPos(targetId,"bttn"); if(aniFilenames[modulePos] != ''){ bttn = document.getElementById(targetId); bttn.src = "pics/" + aniFilenames[modulePos]; } } stopAni = function(targetId){ modulePos = getPos(targetId,"bttn"); bttn = document.getElementById(targetId); bttn.src = "pics/" + picFilenames[modulePos]; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/resources/welcome/mitkdiffusionimagingappwelcomeview.html b/Plugins/org.mitk.gui.qt.diffusionimagingapp/resources/welcome/mitkdiffusionimagingappwelcomeview.html index db39343fd2..285410692b 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/resources/welcome/mitkdiffusionimagingappwelcomeview.html +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/resources/welcome/mitkdiffusionimagingappwelcomeview.html @@ -1,40 +1,44 @@ MITK Diffusion Imaging App
-

Welcome to MITK Diffusion!

+

Welcome to MITK Diffusion (beta release)!

- This application includes all diffusion imaging modules that were developed at the German Cancer Research Center (DKFZ). The software is developed on the basis of the well established, free open source software toolkit MITK. It is designed to perform tasks like fiber tracking, quantification, group analysis, connectomics, synthetic data generation or other image processing tasks. For more information, please also visit our website www.mitk.org or have a look at the help perspective. + MITK Diffusion is the diffusion-weighted MR image processing application developed at the German Cancer Research Center (DKFZ). The software is developed on the basis of the well established, free open source software toolkit MITK. It is designed to perform tasks like ODF reconstruction, fiber tractography, MR image simulation, quantification and other image processing tasks.
- Work with MITK Diffusion - + This is a beta release based on the current master branch of MITK that features cutting edge developments and has not been tested extensively! The next stable release of this application will be based on the next stable release of MITK. Many but not all modules available in MITK are included in this beta release. If you are missing a feature we recommend to build MITK Diffusion from source. +
+ To get started, select one of the perspectives in the toolbar above. If you hover over an icon the tooltip will tell you what tools and algorithms are provided in the respective perspective. If you want to brows all available views (tabs that provide a certain functionality), click on the "View Navigator" icon in the toolbar. If you need more information about a view, open it, select it with your mouse and press "F1". For even more information, please also visit our website mitk.org or have a look at the help perspective. +
+ If you encounter any bugs, please report them in our bugtracking system or use the MITK-users mailing list. We are grateful for any feedback!
+

Features:

diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/QmitkDiffusionImagingAppWorkbenchAdvisor.cpp b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/QmitkDiffusionImagingAppWorkbenchAdvisor.cpp index 23b8306587..a67109b037 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/QmitkDiffusionImagingAppWorkbenchAdvisor.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/QmitkDiffusionImagingAppWorkbenchAdvisor.cpp @@ -1,98 +1,99 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDiffusionImagingAppWorkbenchAdvisor.h" #include "internal/QmitkDiffusionApplicationPlugin.h" #include #include #include #include #include #include #include #include const QString QmitkDiffusionImagingAppWorkbenchAdvisor::WELCOME_PERSPECTIVE_ID = "org.mitk.diffusionimagingapp.perspectives.welcome"; class QmitkDiffusionImagingAppWorkbenchWindowAdvisor : public QmitkExtWorkbenchWindowAdvisor { public: QmitkDiffusionImagingAppWorkbenchWindowAdvisor(berry::WorkbenchAdvisor* wbAdvisor, berry::IWorkbenchWindowConfigurer::Pointer configurer) : QmitkExtWorkbenchWindowAdvisor(wbAdvisor, configurer) { } void PostWindowOpen() { QmitkExtWorkbenchWindowAdvisor::PostWindowOpen(); berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer(); configurer->GetWindow()->GetWorkbench()->GetIntroManager()->ShowIntro(configurer->GetWindow(), false); } }; void QmitkDiffusionImagingAppWorkbenchAdvisor::Initialize(berry::IWorkbenchConfigurer::Pointer configurer) { berry::QtWorkbenchAdvisor::Initialize(configurer); configurer->SetSaveAndRestore(true); } berry::WorkbenchWindowAdvisor* QmitkDiffusionImagingAppWorkbenchAdvisor::CreateWorkbenchWindowAdvisor( berry::IWorkbenchWindowConfigurer::Pointer configurer) { QList perspExcludeList; perspExcludeList.push_back( "org.blueberry.uitest.util.EmptyPerspective" ); perspExcludeList.push_back( "org.blueberry.uitest.util.EmptyPerspective2" ); perspExcludeList.push_back("org.blueberry.perspectives.help"); QList viewExcludeList; viewExcludeList.push_back( "org.mitk.views.controlvisualizationpropertiesview" ); + viewExcludeList.push_back( "org.mitk.views.modules" ); QRect rec = QApplication::desktop()->screenGeometry(); configurer->SetInitialSize(QPoint(rec.width(),rec.height())); QmitkDiffusionImagingAppWorkbenchWindowAdvisor* advisor = new QmitkDiffusionImagingAppWorkbenchWindowAdvisor(this, configurer); advisor->ShowViewMenuItem(true); advisor->ShowNewWindowMenuItem(true); advisor->ShowClosePerspectiveMenuItem(true); advisor->SetPerspectiveExcludeList(perspExcludeList); advisor->SetViewExcludeList(viewExcludeList); advisor->ShowViewToolbar(false); advisor->ShowPerspectiveToolbar(true); advisor->ShowVersionInfo(true); advisor->ShowMitkVersionInfo(true); advisor->ShowMemoryIndicator(false); advisor->SetProductName("MITK Diffusion"); advisor->SetWindowIcon(":/org.mitk.gui.qt.diffusionimagingapp/app-icon.png"); return advisor; } QString QmitkDiffusionImagingAppWorkbenchAdvisor::GetInitialWindowPerspectiveId() { return WELCOME_PERSPECTIVE_ID; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp index 3c2f4178f7..bd9b51f009 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp @@ -1,85 +1,85 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkDiffusionApplicationPlugin.h" #include "src/QmitkDiffusionImagingAppApplication.h" #include "src/internal/Perspectives/QmitkWelcomePerspective.h" #include "src/internal/QmitkDiffusionImagingAppIntroPart.h" #include #include #include #include #include #include QmitkDiffusionApplicationPlugin* QmitkDiffusionApplicationPlugin::inst = nullptr; QmitkDiffusionApplicationPlugin::QmitkDiffusionApplicationPlugin() { inst = this; } QmitkDiffusionApplicationPlugin::~QmitkDiffusionApplicationPlugin() { } QmitkDiffusionApplicationPlugin* QmitkDiffusionApplicationPlugin::GetDefault() { return inst; } void QmitkDiffusionApplicationPlugin::start(ctkPluginContext* context) { berry::AbstractUICTKPlugin::start(context); this->context = context; + BERRY_REGISTER_EXTENSION_CLASS(QmitkWelcomePerspective, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingAppApplication, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingAppIntroPart, context) - BERRY_REGISTER_EXTENSION_CLASS(QmitkWelcomePerspective, context) ctkServiceReference cmRef = context->getServiceReference(); ctkConfigurationAdmin* configAdmin = nullptr; if (cmRef) { configAdmin = context->getService(cmRef); } // Use the CTK Configuration Admin service to configure the BlueBerry help system if (configAdmin) { ctkConfigurationPtr conf = configAdmin->getConfiguration("org.blueberry.services.help", QString()); ctkDictionary helpProps; helpProps.insert("homePage", "qthelp://org.mitk.gui.qt.diffusionimagingapp/bundle/index.html"); conf->update(helpProps); context->ungetService(cmRef); } else { MITK_WARN << "Configuration Admin service unavailable, cannot set home page url."; } } ctkPluginContext* QmitkDiffusionApplicationPlugin::GetPluginContext() const { return context; } diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp index 18ba09a378..4df8ae6609 100644 --- a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp +++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp @@ -1,698 +1,701 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ //Qmitk headers #include "QmitkViewNavigatorWidget.h" // Blueberry #include #include #include #include #include #include #include #include #include #include // MITK #include // Qt #include #include #include #include #include class KeywordRegistry { public: KeywordRegistry() { berry::IExtensionRegistry* extensionPointService = berry::Platform::GetExtensionRegistry(); auto keywordExts = extensionPointService->GetConfigurationElementsFor("org.blueberry.ui.keywords"); for (auto keywordExtsIt = keywordExts.begin(); keywordExtsIt != keywordExts.end(); ++keywordExtsIt) { QString keywordId = (*keywordExtsIt)->GetAttribute("id"); QString keywordLabels = (*keywordExtsIt)->GetAttribute("label"); m_Keywords[keywordId].push_back(keywordLabels); } } QStringList GetKeywords(const QString& id) { return m_Keywords[id]; } QStringList GetKeywords(const QStringList& ids) { QStringList result; for (int i = 0; i < ids.size(); ++i) { result.append(this->GetKeywords(ids[i])); } return result; } private: QHash m_Keywords; }; class ClassFilterProxyModel : public QSortFilterProxyModel { private : bool hasToBeDisplayed(const QModelIndex index) const; bool displayElement(const QModelIndex index) const; public: ClassFilterProxyModel(QObject *parent = nullptr); bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; }; ClassFilterProxyModel::ClassFilterProxyModel(QObject *parent): QSortFilterProxyModel(parent) { } bool ClassFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); return hasToBeDisplayed(index); } bool ClassFilterProxyModel::displayElement(const QModelIndex index) const { bool result = false; QString type = sourceModel()->data(index, Qt::DisplayRole).toString(); QStandardItem * item = dynamic_cast(sourceModel())->itemFromIndex(index); if (type.contains(filterRegExp())) { return true; } { mitk::QtViewItem* viewItem = dynamic_cast(item); if (viewItem) { for (int i = 0; i < viewItem->m_Tags.size(); ++i) { if (viewItem->m_Tags[i].contains(filterRegExp())) { return true; } } if (viewItem->m_Description.contains(filterRegExp())) { return true; } } } { mitk::QtPerspectiveItem* viewItem = dynamic_cast(item); if (viewItem) { for (int i = 0; i < viewItem->m_Tags.size(); ++i) { if (viewItem->m_Tags[i].contains(filterRegExp())) { return true; } } if (viewItem->m_Description.contains(filterRegExp())) { return true; } } } return result; } bool ClassFilterProxyModel::hasToBeDisplayed(const QModelIndex index) const { bool result = false; if ( sourceModel()->rowCount(index) > 0 ) { for( int ii = 0; ii < sourceModel()->rowCount(index); ii++) { QModelIndex childIndex = sourceModel()->index(ii,0,index); if ( ! childIndex.isValid() ) break; result = hasToBeDisplayed(childIndex); result |= displayElement(index); if (result) { break; } } } else { result = displayElement(index); } return result; } class ViewNavigatorPerspectiveListener: public berry::IPerspectiveListener { public: ViewNavigatorPerspectiveListener(QmitkViewNavigatorWidget* p) : parentWidget(p) { } Events::Types GetPerspectiveEventTypes() const override { return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED // remove the following line when command framework is finished | Events::CLOSED | Events::OPENED | Events::PART_CHANGED; } void PerspectiveActivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& perspective) override { parentWidget->m_ActivePerspective = perspective; parentWidget->UpdateTreeList(); } void PerspectiveSavedAs(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*oldPerspective*/, const berry::IPerspectiveDescriptor::Pointer& newPerspective) override { parentWidget->m_ActivePerspective = newPerspective; parentWidget->UpdateTreeList(); } void PerspectiveDeactivated(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { parentWidget->m_ActivePerspective = nullptr; parentWidget->UpdateTreeList(); } void PerspectiveOpened(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { parentWidget->UpdateTreeList(); } void PerspectiveClosed(const berry::IWorkbenchPage::Pointer& /*page*/, const berry::IPerspectiveDescriptor::Pointer& /*perspective*/) override { parentWidget->m_ActivePerspective = nullptr; parentWidget->UpdateTreeList(); } using IPerspectiveListener::PerspectiveChanged; void PerspectiveChanged(const berry::IWorkbenchPage::Pointer&, const berry::IPerspectiveDescriptor::Pointer&, const berry::IWorkbenchPartReference::Pointer& partRef, const std::string& changeId) { if (changeId=="viewHide" && partRef->GetId()=="org.mitk.views.viewnavigatorview") berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->RemovePerspectiveListener(parentWidget->m_PerspectiveListener.data()); else parentWidget->UpdateTreeList(nullptr, partRef.GetPointer(), changeId); } private: QmitkViewNavigatorWidget* parentWidget; }; bool compareViews(const berry::IViewDescriptor::Pointer& a, const berry::IViewDescriptor::Pointer& b) { if (a.IsNull() || b.IsNull()) return false; return a->GetLabel().compare(b->GetLabel()) < 0; } bool comparePerspectives(const berry::IPerspectiveDescriptor::Pointer& a, const berry::IPerspectiveDescriptor::Pointer& b) { if (a.IsNull() || b.IsNull()) return false; return a->GetLabel().compare(b->GetLabel()) < 0; } bool compareQStandardItems(const QStandardItem* a, const QStandardItem* b) { if (a==nullptr || b==nullptr) return false; return a->text().compare(b->text()) < 0; } QmitkViewNavigatorWidget::QmitkViewNavigatorWidget(berry::IWorkbenchWindow::Pointer window, QWidget * parent, Qt::WindowFlags ) : QWidget(parent) , m_Window(window) { m_Generated = false; this->CreateQtPartControl(this); } QmitkViewNavigatorWidget::~QmitkViewNavigatorWidget() { m_Window->RemovePerspectiveListener(m_PerspectiveListener.data()); } void QmitkViewNavigatorWidget::setFocus() { m_Controls.lineEdit->setFocus(); } void QmitkViewNavigatorWidget::CreateQtPartControl( QWidget *parent ) { // create GUI widgets from the Qt Designer's .ui file m_PerspectiveListener.reset(new ViewNavigatorPerspectiveListener(this)); m_Window->AddPerspectiveListener(m_PerspectiveListener.data()); m_Parent = parent; m_Controls.setupUi( parent ); connect( m_Controls.m_PluginTreeView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(CustomMenuRequested(QPoint))); connect( m_Controls.m_PluginTreeView, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(ItemClicked(const QModelIndex&))); connect( m_Controls.lineEdit, SIGNAL(textChanged(QString)), SLOT(FilterChanged())); m_ContextMenu = new QMenu(m_Controls.m_PluginTreeView); m_Controls.m_PluginTreeView->setContextMenuPolicy(Qt::CustomContextMenu); // Create a new TreeModel for the data m_TreeModel = new QStandardItemModel(); m_FilterProxyModel = new ClassFilterProxyModel(this); m_FilterProxyModel->setSourceModel(m_TreeModel); //proxyModel->setFilterFixedString("Diff"); m_Controls.m_PluginTreeView->setModel(m_FilterProxyModel); this->UpdateTreeList(); } void QmitkViewNavigatorWidget::UpdateTreeList(QStandardItem* root, berry::IWorkbenchPartReference *partRef, const std::string &changeId) { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); if (page.IsNull()) return; if( !m_Generated ) { m_Generated = FillTreeList(); } if (root==nullptr) root = m_TreeModel->invisibleRootItem(); for (int i=0; irowCount(); i++) { QStandardItem* item = root->child(i); QFont font; if (dynamic_cast(item)) { mitk::QtPerspectiveItem* pItem = dynamic_cast(item); berry::IPerspectiveDescriptor::Pointer currentPersp = page->GetPerspective(); if (currentPersp.IsNotNull() && currentPersp->GetId()==pItem->m_Perspective->GetId()) font.setBold(true); pItem->setFont(font); } mitk::QtViewItem* vItem = dynamic_cast(item); if (vItem) { QList viewParts(page->GetViews()); for (int i=0; iGetPartName()==vItem->m_View->GetLabel()) { font.setBold(true); break; } if( partRef!=nullptr && partRef->GetId()==vItem->m_View->GetId() && changeId=="viewHide") font.setBold(false); vItem->setFont(font); } UpdateTreeList(item, partRef, changeId); } } bool QmitkViewNavigatorWidget::FillTreeList() { // active workbench window available? if (m_Window.IsNull()) return false; // active page available? berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); if (page.IsNull()) return false; // everything is fine and we can remove the window listener if (m_WindowListener != nullptr) berry::PlatformUI::GetWorkbench()->RemoveWindowListener(m_WindowListener.data()); // initialize tree model m_TreeModel->clear(); QStandardItem *treeRootItem = m_TreeModel->invisibleRootItem(); // get all available perspectives berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry(); QList perspectiveDescriptors(perspRegistry->GetPerspectives()); qSort(perspectiveDescriptors.begin(), perspectiveDescriptors.end(), comparePerspectives); // get all Keywords KeywordRegistry keywordRegistry; berry::IPerspectiveDescriptor::Pointer currentPersp = page->GetPerspective(); //QStringList perspectiveExcludeList = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetPerspectiveExcludeList(); std::vector< QStandardItem* > categoryItems; - QStandardItem *perspectiveRootItem = new QStandardItem("Workflows"); + QStandardItem *perspectiveRootItem = new QStandardItem("Perspectives"); perspectiveRootItem->setEditable(false); perspectiveRootItem->setFont(QFont("", 12, QFont::Normal)); treeRootItem->appendRow(perspectiveRootItem); for (int i=0; iGetId()) { skipPerspective = true; break; } if (skipPerspective) continue; */ //QIcon* pIcon = static_cast(p->GetImageDescriptor()->CreateImage()); mitk::QtPerspectiveItem* pItem = new mitk::QtPerspectiveItem(p->GetLabel()); pItem->m_Perspective = p; pItem->m_Description = p->GetDescription(); QStringList keylist = p->GetKeywordReferences(); pItem->m_Tags = keywordRegistry.GetKeywords(keylist); pItem->setEditable(false); QFont font; font.setBold(true); if (currentPersp.IsNotNull() && currentPersp->GetId()==p->GetId()) pItem->setFont(font); QStringList catPath = p->GetCategoryPath(); if (catPath.isEmpty()) { perspectiveRootItem->appendRow(pItem); } else { QStandardItem* categoryItem = nullptr; for (unsigned int c=0; ctext() == catPath.front()) { categoryItem = categoryItems.at(c); break; } } if (categoryItem==nullptr) { categoryItem = new QStandardItem(QIcon(),catPath.front()); categoryItems.push_back(categoryItem); } categoryItem->setEditable(false); categoryItem->appendRow(pItem); categoryItem->setFont(QFont("", 12, QFont::Normal)); } } std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems); for (unsigned int i=0; iappendRow(categoryItems.at(i)); // get all available views berry::IViewRegistry* viewRegistry = berry::PlatformUI::GetWorkbench()->GetViewRegistry(); QList viewDescriptors(viewRegistry->GetViews()); QList viewParts(page->GetViews()); qSort(viewDescriptors.begin(), viewDescriptors.end(), compareViews); auto emptyItem = new QStandardItem(); emptyItem->setFlags(Qt::ItemIsEnabled); treeRootItem->appendRow(emptyItem); //QStringList viewExcludeList = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetViewExcludeList(); //There currently is no way to get the list of excluded views at application start QStringList viewExcludeList; // internal view used for the intro screen, will crash when opened directly, see T22352 viewExcludeList.append(QString("org.blueberry.ui.internal.introview")); + viewExcludeList.append(QString("org.mitk.views.controlvisualizationpropertiesview")); + viewExcludeList.append(QString("org.mitk.views.modules")); + viewExcludeList.append(QString("org.mitk.views.viewnavigatorview")); QStandardItem* viewRootItem = new QStandardItem(QIcon(),"Views"); viewRootItem->setFont(QFont("", 12, QFont::Normal)); viewRootItem->setEditable(false); treeRootItem->appendRow(viewRootItem); categoryItems.clear(); QStandardItem* noCategoryItem = new QStandardItem(QIcon(),"Miscellaneous"); noCategoryItem->setEditable(false); noCategoryItem->setFont(QFont("", 12, QFont::Normal)); for (int i = 0; i < viewDescriptors.size(); ++i) { berry::IViewDescriptor::Pointer v = viewDescriptors[i]; bool skipView = false; for(int e=0; eGetId()) { skipView = true; break; } if (skipView) continue; QStringList catPath = v->GetCategoryPath(); QIcon icon = v->GetImageDescriptor(); mitk::QtViewItem* vItem = new mitk::QtViewItem(icon, v->GetLabel()); vItem->m_View = v; vItem->setToolTip(v->GetDescription()); vItem->m_Description = v->GetDescription(); QStringList keylist = v->GetKeywordReferences(); vItem->m_Tags = keywordRegistry.GetKeywords(keylist); vItem->setEditable(false); for (int i=0; iGetPartName()==v->GetLabel()) { QFont font; font.setBold(true); vItem->setFont(font); break; } if (catPath.empty()) noCategoryItem->appendRow(vItem); else { QStandardItem* categoryItem = nullptr; for (unsigned int c=0; ctext() == catPath.front()) { categoryItem = categoryItems.at(c); break; } if (categoryItem==nullptr) { categoryItem = new QStandardItem(QIcon(),catPath.front()); categoryItems.push_back(categoryItem); } categoryItem->setEditable(false); categoryItem->appendRow(vItem); categoryItem->setFont(QFont("", 12, QFont::Normal)); } } std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems); for (unsigned int i=0; iappendRow(categoryItems.at(i)); if (noCategoryItem->hasChildren()) viewRootItem->appendRow(noCategoryItem); m_Controls.m_PluginTreeView->expandAll(); return true; } void QmitkViewNavigatorWidget::FilterChanged() { QString filterString = m_Controls.lineEdit->text(); // if (filterString.size() > 0 ) m_Controls.m_PluginTreeView->expandAll(); // else // m_Controls.m_PluginTreeView->collapseAll(); // QRegExp::PatternSyntax syntax = QRegExp::RegExp; Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive; QString strPattern = "^*" + filterString; QRegExp regExp(strPattern, caseSensitivity); m_FilterProxyModel->setFilterRegExp(regExp); } void QmitkViewNavigatorWidget::ItemClicked(const QModelIndex &index) { QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index)); if ( dynamic_cast< mitk::QtPerspectiveItem* >(item) ) { try { mitk::QtPerspectiveItem* pItem = dynamic_cast< mitk::QtPerspectiveItem* >(item); berry::PlatformUI::GetWorkbench()->ShowPerspective( pItem->m_Perspective->GetId(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() ); } catch (...) { QMessageBox::critical(nullptr, "Opening Perspective Failed", QString("The requested perspective could not be opened.\nSee the log for details.")); } } else if ( dynamic_cast< mitk::QtViewItem* >(item) ) { berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(); if (page.IsNotNull()) { try { mitk::QtViewItem* vItem = dynamic_cast< mitk::QtViewItem* >(item); page->ShowView(vItem->m_View->GetId()); } catch (berry::PartInitException e) { BERRY_ERROR << "Error: " << e.what() << std::endl; } } } } void QmitkViewNavigatorWidget::SaveCurrentPerspectiveAs() { berry::IHandlerService* handlerService = m_Window->GetService(); try { handlerService->ExecuteCommand(berry::IWorkbenchCommandConstants::WINDOW_SAVE_PERSPECTIVE_AS, berry::UIElement::Pointer()); FillTreeList(); } catch(const berry::NotHandledException) {} catch(const berry::CommandException& e) { MITK_ERROR << e.what(); } } void QmitkViewNavigatorWidget::ResetCurrentPerspective() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to reset the current perspective?", QMessageBox::Yes|QMessageBox::No).exec()) berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective(); } void QmitkViewNavigatorWidget::ClosePerspective() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close the current perspective?", QMessageBox::Yes|QMessageBox::No).exec()) { berry::IWorkbenchPage::Pointer page = m_Window->GetActivePage(); page->ClosePerspective(page->GetPerspective(), true, true); // if ( page->GetPerspective().IsNull() ) // { // berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry(); // berry::PlatformUI::GetWorkbench()->ShowPerspective( perspRegistry->GetDefaultPerspective(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() ); // } } } void QmitkViewNavigatorWidget::CloseAllPerspectives() { if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close all perspectives?", QMessageBox::Yes|QMessageBox::No).exec()) { berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(); page->CloseAllPerspectives(true, true); // berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry(); // berry::PlatformUI::GetWorkbench()->ShowPerspective( perspRegistry->GetDefaultPerspective(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() ); } } void QmitkViewNavigatorWidget::ExpandAll() { m_Controls.m_PluginTreeView->expandAll(); } void QmitkViewNavigatorWidget::CollapseAll() { m_Controls.m_PluginTreeView->collapseAll(); } void QmitkViewNavigatorWidget::CustomMenuRequested(QPoint pos) { QModelIndex index = m_Controls.m_PluginTreeView->indexAt(pos); QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index)); if (m_ContextMenu==nullptr) return; m_ContextMenu->clear(); QAction* expandAction = new QAction("Expand tree", this); m_ContextMenu->addAction(expandAction); connect(expandAction, SIGNAL(triggered()), SLOT(ExpandAll())); QAction* collapseAction = new QAction("Collapse tree", this); m_ContextMenu->addAction(collapseAction); connect(collapseAction, SIGNAL(triggered()), SLOT(CollapseAll())); m_ContextMenu->addSeparator(); if ( item!=nullptr && dynamic_cast< mitk::QtPerspectiveItem* >(item) ) { berry::IPerspectiveDescriptor::Pointer persp = dynamic_cast< mitk::QtPerspectiveItem* >(item)->m_Perspective; if (this->m_ActivePerspective.IsNotNull() && this->m_ActivePerspective == persp) { //m_ContextMenu->addSeparator(); QAction* saveAsAction = new QAction("Save As...", this); m_ContextMenu->addAction(saveAsAction); connect(saveAsAction, SIGNAL(triggered()), SLOT(SaveCurrentPerspectiveAs())); m_ContextMenu->addSeparator(); } } QAction* resetAction = new QAction("Reset current perspective", this); m_ContextMenu->addAction(resetAction); connect(resetAction, SIGNAL(triggered()), SLOT(ResetCurrentPerspective())); QAction* closeAction = new QAction("Close perspective", this); m_ContextMenu->addAction(closeAction); connect(closeAction, SIGNAL(triggered()), SLOT(ClosePerspective())); m_ContextMenu->addSeparator(); QAction* closeAllAction = new QAction("Close all perspectives", this); m_ContextMenu->addAction(closeAllAction); connect(closeAllAction, SIGNAL(triggered()), SLOT(CloseAllPerspectives())); m_ContextMenu->popup(m_Controls.m_PluginTreeView->viewport()->mapToGlobal(pos)); }