Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkCmdLineModuleMenuComboBox.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) University College London (UCL).
6 All rights reserved.
7 
8 This software is distributed WITHOUT ANY WARRANTY; without
9 even the implied warranty of MERCHANTABILITY or FITNESS FOR
10 A PARTICULAR PURPOSE.
11 
12 See LICENSE.txt or http://www.mitk.org for details.
13 
14 ===================================================================*/
15 
17 #include <iostream>
18 #include <QString>
19 #include <QStringList>
20 #include <QDebug>
21 #include <QMenu>
22 #include <QAction>
23 #include <QList>
24 #include <cassert>
25 #include <ctkCmdLineModuleDescription.h>
26 #include <ctkCmdLineModuleReference.h>
27 #include <ctkCmdLineModuleManager.h>
28 
29 // -------------------------------------------------------------------------
31 : ctkMenuComboBox(parent)
32 , m_ModuleManager(nullptr)
33 {
34  qRegisterMetaType<ctkCmdLineModuleReference>();
35 }
36 
37 
38 // -------------------------------------------------------------------------
40 {
41 
42 }
43 
44 
45 // -------------------------------------------------------------------------
46 void QmitkCmdLineModuleMenuComboBox::SetManager(ctkCmdLineModuleManager* manager)
47 {
48  if (m_ModuleManager != nullptr)
49  {
50  QObject::disconnect(manager, nullptr, this, nullptr);
51  }
52 
53  m_ModuleManager = manager;
54 
55  connect(m_ModuleManager, SIGNAL(moduleRegistered(const ctkCmdLineModuleReference&)), this, SLOT(OnModuleRegistered(const ctkCmdLineModuleReference&)));
56  connect(m_ModuleManager, SIGNAL(moduleUnregistered(const ctkCmdLineModuleReference&)), this, SLOT(OnModuleUnRegistered(const ctkCmdLineModuleReference&)));
57 }
58 
59 
60 // -------------------------------------------------------------------------
61 ctkCmdLineModuleManager* QmitkCmdLineModuleMenuComboBox::GetManager() const
62 {
63  return m_ModuleManager;
64 }
65 
66 
67 // -------------------------------------------------------------------------
68 void QmitkCmdLineModuleMenuComboBox::OnModuleRegistered(const ctkCmdLineModuleReference&)
69 {
70  this->RebuildMenu();
71 }
72 
73 
74 // -------------------------------------------------------------------------
75 void QmitkCmdLineModuleMenuComboBox::OnModuleUnRegistered(const ctkCmdLineModuleReference&)
76 {
77  this->RebuildMenu();
78 }
79 
80 
81 // -------------------------------------------------------------------------
82 void QmitkCmdLineModuleMenuComboBox::AddName(
83  QList< QHash<QString, QMenu*>* >& listOfHashMaps,
84  const int& depth,
85  const QString& name,
86  QMenu* menu
87  )
88 {
89  if (depth >= listOfHashMaps.size())
90  {
91  int need = depth - listOfHashMaps.size();
92  for (int i = 0; i <= need; i++)
93  {
94  auto newHashMap = new QHash<QString, QMenu*>();
95  listOfHashMaps.push_back(newHashMap);
96  }
97  }
98  listOfHashMaps[depth]->insert(name, menu);
99 }
100 
101 
102 // -------------------------------------------------------------------------
103 void QmitkCmdLineModuleMenuComboBox::RebuildMenu()
104 {
105  if (m_ModuleManager == nullptr)
106  {
107  qDebug() << "QmitkCmdLineModuleMenuComboBox::RebuildMenu(): Module Manager is NULL? Surely a bug?";
108  return;
109  }
110 
111  // Can't see another way to get a nested menu, without rebuilding the whole thing each time.
112  // :-(
113 
114  auto menu = new QMenu();
115  QStringList listOfModules;
116 
117  QList<ctkCmdLineModuleReference> references = m_ModuleManager->moduleReferences();
118 
119  // Get full names
120  for (int i = 0; i < references.size(); i++)
121  {
122  ctkCmdLineModuleReference reference = references[i];
123  ctkCmdLineModuleDescription description = reference.description();
124  QString title = description.title();
125  QString category = description.category();
126  QString fullName = category + "." + title;
127  listOfModules << fullName;
128  }
129 
130  // Sort list, so menu comes out in some sort of nice order.
131  listOfModules.sort();
132 
133  // Temporary data structure to enable connecting menus together.
134  QList< QHash<QString, QMenu*>* > list;
135 
136  // Iterate through all modules.
137  foreach (QString fullName, listOfModules)
138  {
139  // Pointer to keep track of where we are in the menu tree.
140  QMenu *currentMenu = menu;
141 
142  // Get individual parts, as they correspond to menu levels.
143  QStringList nameParts = fullName.split(".", QString::SkipEmptyParts);
144 
145  // Iterate over each part, building up either a QMenu or QAction.
146  for (int i = 0; i < nameParts.size(); i++)
147  {
148  QString part = nameParts[i];
149 
150  if (i != nameParts.size() - 1)
151  {
152  // Need to add a menu/submenu, not an action.
153  if (list.size() <= i || list[i] == nullptr || !list[i]->contains(part))
154  {
155  auto newMenu = new QMenu(part);
156  currentMenu->addMenu(newMenu);
157  currentMenu = newMenu;
158 
159  // Add this newMenu pointer to temporary datastructure,
160  // so we know we have already created it.
161  this->AddName(list, i, part, newMenu);
162  }
163  else
164  {
165  currentMenu = list[i]->value(part);
166  }
167  }
168  else
169  {
170  // Leaf node, just add the action.
171  QAction *action = currentMenu->addAction(part);
172 
173  // We set the object name, so we can retrieve it later when we want to
174  // rebuild a new GUI depending on the name of the action.
175  // see QmitkCmdLineModuleProgressWidget.
176  action->setObjectName(fullName);
177  }
178  }
179  }
180 
181  // Clearup termporary data structure
182  for (int i = 0; i < list.size(); i++)
183  {
184  delete list[i];
185  }
186 
187  // Set the constructed menu on the base class combo box.
188  this->setMenu(menu);
189 }
void SetManager(ctkCmdLineModuleManager *manager)
Inject the module manager, so that this widget can still easily be used via widget promotion in Qt De...
QmitkCmdLineModuleMenuComboBox(QWidget *parent=nullptr)
The custom viewer plugin implements simple viewer functionality presented in a customized look and feel It was developed to demonstrate extensibility and customizability of the blueberry application framework As an example for the GUI customization capabilities provided by the BlueBerry application the custom viewer plugin was developed It features simple viewer functionality presented in a customized look and feel The custom viewer consists of two i e a viewer perspective and a DICOM perspective As part of the viewer an instance of QmitkDataManagerView allows for data selection Visualization of the selected data is then performed by a simple render window view According data can either be directly loaded from file or be imported as DICOM data DICOM import functionality is accessible from the DICOM perspective incorporating the QmitkDicomExternalDataWidget The customization of Qt Stylesheets is used to give the application a non native look and feel This is further emphasized by a Tab Widget like unification of the perspectives with the according perspective bar In addition to an absence of menu
ctkCmdLineModuleManager * GetManager() const
Returns the ctkCmdLineModuleManager.