Browse Source

Improved handling of invalide modules. Added filter box and load menu.

Sascha Zelzer 12 years ago
parent
commit
0421597623

+ 3 - 0
Applications/ctkCommandLineModuleExplorer/CMakeLists.txt

@@ -14,8 +14,10 @@ set(KIT_SRCS
   ctkCmdLineModuleExplorerOutputText.cpp
   ctkCmdLineModuleExplorerProgressListWidget.cpp
   ctkCmdLineModuleExplorerProgressWidget.cpp
+  ctkCmdLineModuleExplorerShowXmlAction.cpp
   ctkCmdLineModuleExplorerTabList.cpp
   ctkCmdLineModuleExplorerTreeWidget.cpp
+  ctkCmdLineModuleExplorerUtils.cpp
 )
 
 # Headers that should run through moc
@@ -25,6 +27,7 @@ set(KIT_MOC_SRCS
   ctkCmdLineModuleExplorerOutputText.h
   ctkCmdLineModuleExplorerProgressListWidget.h
   ctkCmdLineModuleExplorerProgressWidget.h
+  ctkCmdLineModuleExplorerShowXmlAction.h
   ctkCmdLineModuleExplorerTabList.h
   ctkCmdLineModuleExplorerTreeWidget.h
 )

+ 47 - 9
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerMainWindow.cpp

@@ -45,6 +45,7 @@
 #include <QMessageBox>
 #include <QFutureSynchronizer>
 #include <QCloseEvent>
+#include <QFileDialog>
 
 
 ctkCLModuleExplorerMainWindow::ctkCLModuleExplorerMainWindow(QWidget *parent) :
@@ -52,7 +53,8 @@ ctkCLModuleExplorerMainWindow::ctkCLModuleExplorerMainWindow(QWidget *parent) :
   ui(new Ui::ctkCmdLineModuleExplorerMainWindow),
   defaultModuleFrontendFactory(NULL),
   moduleManager(ctkCmdLineModuleManager::WEAK_VALIDATION, QDesktopServices::storageLocation(QDesktopServices::CacheLocation)),
-  directoryWatcher(&moduleManager)
+  directoryWatcher(&moduleManager),
+  settingsDialog(NULL)
 {
   ui->setupUi(this);
 
@@ -77,12 +79,6 @@ ctkCLModuleExplorerMainWindow::ctkCLModuleExplorerMainWindow(QWidget *parent) :
     moduleManager.registerBackend(moduleBackends[i]);
   }
 
-  settingsDialog = new ctkSettingsDialog(this);
-  settings.restoreState(settingsDialog->objectName(), *settingsDialog);
-  settingsDialog->setSettings(&settings);
-  settingsDialog->addPanel(new ctkCmdLineModuleExplorerDirectorySettings(&directoryWatcher));
-  settingsDialog->addPanel(new ctkCmdLineModuleExplorerModulesSettings(&moduleManager));
-
   tabList.reset(new ctkCmdLineModuleExplorerTabList(ui->mainTabWidget));
 
   // If a module is registered via the ModuleManager, add it to the tree
@@ -116,8 +112,8 @@ ctkCLModuleExplorerMainWindow::ctkCLModuleExplorerMainWindow(QWidget *parent) :
   }
 
   // Register persistent modules
-  QtConcurrent::mapped(settings.value(ctkCmdLineModuleExplorerConstants::KEY_REGISTERED_MODULES).toStringList(),
-                       ctkCmdLineModuleConcurrentRegister(&moduleManager, true));
+  QFuture<void> future = QtConcurrent::mapped(settings.value(ctkCmdLineModuleExplorerConstants::KEY_REGISTERED_MODULES).toStringList(),
+                                              ctkCmdLineModuleConcurrentRegister(&moduleManager, true));
 
   // Start watching directories
   directoryWatcher.setDebug(true);
@@ -126,6 +122,8 @@ ctkCLModuleExplorerMainWindow::ctkCLModuleExplorerMainWindow(QWidget *parent) :
   moduleTabActivated(NULL);
 
   pollPauseTimer.start();
+
+  future.waitForFinished();
 }
 
 ctkCLModuleExplorerMainWindow::~ctkCLModuleExplorerMainWindow()
@@ -218,9 +216,49 @@ void ctkCLModuleExplorerMainWindow::on_actionCancel_triggered()
 
 void ctkCLModuleExplorerMainWindow::on_actionOptions_triggered()
 {
+  if (settingsDialog == NULL)
+  {
+    settingsDialog = new ctkSettingsDialog(this);
+    settings.restoreState(settingsDialog->objectName(), *settingsDialog);
+    settingsDialog->setSettings(&settings);
+    settingsDialog->addPanel(new ctkCmdLineModuleExplorerDirectorySettings(&directoryWatcher));
+    settingsDialog->addPanel(new ctkCmdLineModuleExplorerModulesSettings(&moduleManager));
+  }
+
   settingsDialog->exec();
 }
 
+void ctkCLModuleExplorerMainWindow::on_actionLoad_triggered()
+{
+  QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Load modules..."));
+
+  this->setCursor(Qt::BusyCursor);
+  QFuture<ctkCmdLineModuleReference> future = QtConcurrent::mapped(fileNames, ctkCmdLineModuleConcurrentRegister(&this->moduleManager));
+  future.waitForFinished();
+
+  QString errorMsg;
+  QList<ctkCmdLineModuleReference> refs = future.results();
+  for(int i = 0; i < fileNames.size(); ++i)
+  {
+    if (!refs.at(i))
+    {
+      errorMsg += tr("Failed to register ") + fileNames.at(i) + "\n\n";
+    }
+    else if (!refs.at(i).xmlValidationErrorString().isEmpty() &&
+             this->moduleManager.validationMode() == ctkCmdLineModuleManager::STRICT_VALIDATION)
+    {
+      errorMsg += tr("Failed to register ") + fileNames.at(i) + ":\n" + refs.at(i).xmlValidationErrorString() + "\n\n";
+    }
+  }
+
+  this->unsetCursor();
+
+  if (!errorMsg.isEmpty())
+  {
+    QMessageBox::critical(this, "Failed to register modules", errorMsg);
+  }
+}
+
 void ctkCLModuleExplorerMainWindow::on_actionQuit_triggered()
 {
   this->close();

+ 1 - 0
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerMainWindow.h

@@ -64,6 +64,7 @@ protected Q_SLOTS:
   void on_actionPause_toggled(bool toggled);
   void on_actionCancel_triggered();
   void on_actionOptions_triggered();
+  void on_actionLoad_triggered();
   void on_actionQuit_triggered();
 
   void on_actionReset_triggered();

+ 5 - 2
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerMainWindow.ui

@@ -116,6 +116,9 @@
        <property name="textElideMode">
         <enum>Qt::ElideMiddle</enum>
        </property>
+       <property name="sortingEnabled">
+        <bool>true</bool>
+       </property>
        <property name="headerHidden">
         <bool>true</bool>
        </property>
@@ -198,7 +201,7 @@
              <x>0</x>
              <y>0</y>
              <width>250</width>
-             <height>213</height>
+             <height>194</height>
             </rect>
            </property>
            <layout class="QVBoxLayout" name="verticalLayout_5">
@@ -301,7 +304,7 @@
   </action>
   <action name="actionLoad">
    <property name="text">
-    <string>&amp;Load Module...</string>
+    <string>&amp;Load Modules...</string>
    </property>
    <property name="toolTip">
     <string>Load module</string>

+ 53 - 2
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerModulesSettings.cpp

@@ -21,6 +21,8 @@
 
 #include "ctkCmdLineModuleExplorerModulesSettings.h"
 #include "ctkCmdLineModuleExplorerConstants.h"
+#include "ctkCmdLineModuleExplorerUtils.h"
+#include "ctkCmdLineModuleExplorerShowXmlAction.h"
 
 #include "ui_ctkCmdLineModuleExplorerModulesSettings.h"
 
@@ -28,15 +30,25 @@
 #include <ctkCmdLineModuleConcurrentHelpers.h>
 
 #include <QUrl>
+#include <QStandardItem>
 #include <QtConcurrentMap>
+#include <QFutureSynchronizer>
 
 ctkCmdLineModuleExplorerModulesSettings::ctkCmdLineModuleExplorerModulesSettings(ctkCmdLineModuleManager *moduleManager)
   : ui(new Ui::ctkCmdLineModuleExplorerModulesSettings)
   , ModuleManager(moduleManager)
+  , ShowXmlAction(new ctkCmdLineModuleExplorerShowXmlAction(this))
 {
   ui->setupUi(this);
 
   ui->PathListButtonsWidget->init(ui->PathListWidget);
+  ui->PathListWidget->addAction(this->ShowXmlAction);
+  ui->PathListWidget->setContextMenuPolicy(Qt::ActionsContextMenu);
+
+  this->ShowXmlAction->setEnabled(false);
+
+  connect(ui->PathListWidget, SIGNAL(currentPathChanged(QString,QString)), SLOT(pathSelected(QString)));
+  connect(ui->PathListWidget, SIGNAL(pathsChanged(QStringList,QStringList)), SLOT(pathsAdded(QStringList)));
 
   this->registerProperty(ctkCmdLineModuleExplorerConstants::KEY_REGISTERED_MODULES,
                          ui->PathListWidget, "paths", SIGNAL(pathsChanged(QStringList,QStringList)));
@@ -66,8 +78,47 @@ void ctkCmdLineModuleExplorerModulesSettings::applySettings()
     }
   }
 
-  QtConcurrent::mapped(removedModules, ctkCmdLineModuleConcurrentUnRegister(this->ModuleManager));
-  QtConcurrent::mapped(addedModules, ctkCmdLineModuleConcurrentRegister(this->ModuleManager));
+  this->setCursor(Qt::BusyCursor);
+
+  QFuture<void> future1 = QtConcurrent::mapped(removedModules, ctkCmdLineModuleConcurrentUnRegister(this->ModuleManager));
+  QFuture<void> future2 = QtConcurrent::mapped(addedModules, ctkCmdLineModuleConcurrentRegister(this->ModuleManager));
 
   ctkSettingsPanel::applySettings();
+
+  QFutureSynchronizer<void> sync;
+  sync.addFuture(future1);
+  sync.addFuture(future2);
+  sync.waitForFinished();
+
+  this->pathsAdded(addedModules);
+
+  this->unsetCursor();
+}
+
+void ctkCmdLineModuleExplorerModulesSettings::pathSelected(const QString &path)
+{
+  this->ShowXmlAction->setEnabled(!path.isEmpty());
+  ctkCmdLineModuleReference moduleRef = this->ModuleManager->moduleReference(QUrl::fromLocalFile(path));
+  this->ShowXmlAction->setModuleReference(moduleRef);
+}
+
+void ctkCmdLineModuleExplorerModulesSettings::pathsAdded(const QStringList &paths)
+{
+  // Check the validity of the entries
+  foreach(const QString& path, paths)
+  {
+    ctkCmdLineModuleReference moduleRef = this->ModuleManager->moduleReference(QUrl::fromLocalFile(path));
+    if (moduleRef && !moduleRef.xmlValidationErrorString().isEmpty())
+    {
+      QStandardItem* item = ui->PathListWidget->item(path);
+      item->setToolTip(item->toolTip() + "\n\nWarning:\n\n" + moduleRef.xmlValidationErrorString());
+      if (this->WarningIcon.isNull())
+      {
+        this->WarningIcon = ctkCmdLineModuleExplorerUtils::createIconOverlay(
+              item->icon().pixmap(item->icon().availableSizes().front()),
+              QApplication::style()->standardPixmap(QStyle::SP_MessageBoxWarning));
+      }
+      item->setIcon(this->WarningIcon);
+    }
+  }
 }

+ 11 - 1
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerModulesSettings.h

@@ -24,7 +24,10 @@
 
 #include <ctkSettingsPanel.h>
 
+#include <QIcon>
+
 class ctkCmdLineModuleManager;
+class ctkCmdLineModuleExplorerShowXmlAction;
 
 namespace Ui {
 class ctkCmdLineModuleExplorerModulesSettings;
@@ -39,11 +42,18 @@ public:
   ~ctkCmdLineModuleExplorerModulesSettings();
 
   void applySettings();
-  
+
 private:
+
+  Q_SLOT void pathSelected(const QString& path);
+
+  Q_SLOT void pathsAdded(const QStringList& paths);
+
   Ui::ctkCmdLineModuleExplorerModulesSettings *ui;
 
   ctkCmdLineModuleManager* ModuleManager;
+  ctkCmdLineModuleExplorerShowXmlAction* ShowXmlAction;
+  QIcon WarningIcon;
 };
 
 #endif // CTKCMDLINEMODULEEXPLORERMODULESSETTINGS_H

+ 89 - 0
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerShowXmlAction.cpp

@@ -0,0 +1,89 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#include "ctkCmdLineModuleExplorerShowXmlAction.h"
+#include "ctkCmdLineModuleDescription.h"
+#include "ctkCmdLineModuleXmlException.h"
+
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QPushButton>
+#include <QSpacerItem>
+#include <QTextEdit>
+#include <QUrl>
+#include <QLabel>
+
+ctkCmdLineModuleExplorerShowXmlAction::ctkCmdLineModuleExplorerShowXmlAction(QObject *parent)
+  : QAction(parent)
+{
+  this->setText("Show XML Description");
+
+  connect(this, SIGNAL(triggered()), SLOT(run()));
+}
+
+void ctkCmdLineModuleExplorerShowXmlAction::setModuleReference(const ctkCmdLineModuleReference& ref)
+{
+  this->ModuleRef = ref;
+}
+
+void ctkCmdLineModuleExplorerShowXmlAction::run()
+{
+  QDialog* dialog = new QDialog();
+  try
+  {
+    dialog->setWindowTitle(this->ModuleRef.description().title());
+  }
+  catch (const ctkCmdLineModuleXmlException&)
+  {
+    dialog->setWindowTitle(this->ModuleRef.location().toString());
+  }
+
+  dialog->setLayout(new QVBoxLayout());
+
+  QHBoxLayout* buttonLayout = new QHBoxLayout();
+  buttonLayout->addStretch(1);
+  QPushButton* closeButton = new QPushButton(tr("Close"), dialog);
+  buttonLayout->addWidget(closeButton);
+
+  QTextEdit* textEdit = new QTextEdit(dialog);
+  textEdit->setPlainText(this->ModuleRef.rawXmlDescription().data());
+
+  QLabel* statusLabel = new QLabel(dialog);
+  statusLabel->setWordWrap(true);
+  if (this->ModuleRef.xmlValidationErrorString().isEmpty())
+  {
+    statusLabel->setText(tr("No validation errors."));
+  }
+  else
+  {
+    statusLabel->setText(this->ModuleRef.xmlValidationErrorString());
+  }
+  dialog->layout()->addWidget(statusLabel);
+  dialog->layout()->addWidget(textEdit);
+  dialog->layout()->addItem(buttonLayout);
+
+  connect(closeButton, SIGNAL(clicked()), dialog, SLOT(close()));
+
+  dialog->resize(800, 600);
+  dialog->show();
+}

+ 49 - 0
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerShowXmlAction.h

@@ -0,0 +1,49 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+
+#ifndef CTKCMDLINEMODULEEXPLORERSHOWXMLACTION_H
+#define CTKCMDLINEMODULEEXPLORERSHOWXMLACTION_H
+
+#include "ctkCmdLineModuleReference.h"
+
+#include <QAction>
+
+class ctkCmdLineModuleExplorerShowXmlAction : public QAction
+{
+  Q_OBJECT
+
+public:
+
+  ctkCmdLineModuleExplorerShowXmlAction(QObject* parent);
+
+  void setModuleReference(const ctkCmdLineModuleReference& ref);
+
+protected:
+
+  Q_SLOT virtual void run();
+
+private:
+
+  ctkCmdLineModuleReference ModuleRef;
+};
+
+#endif // CTKCMDLINEMODULEEXPLORERSHOWXMLACTION_H

+ 65 - 31
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerTreeWidget.cpp

@@ -20,6 +20,7 @@
 =============================================================================*/
 
 #include "ctkCmdLineModuleExplorerTreeWidget.h"
+#include "ctkCmdLineModuleExplorerShowXmlAction.h"
 
 #include <ctkCmdLineModuleFrontend.h>
 #include <ctkCmdLineModuleBackend.h>
@@ -85,7 +86,8 @@ ctkCmdLineModuleExplorerTreeWidget::ctkCmdLineModuleExplorerTreeWidget(QWidget *
   this->ContextMenu = new QMenu(this);
   this->ShowFrontendMenu = this->ContextMenu->addMenu("Create Frontend");
 
-  this->ContextMenu->addAction("Properties");
+  this->ShowXmlAction = new ctkCmdLineModuleExplorerShowXmlAction(this);
+  this->ContextMenu->addAction(ShowXmlAction);
 
   connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(moduleDoubleClicked(QModelIndex)));
 
@@ -93,8 +95,8 @@ ctkCmdLineModuleExplorerTreeWidget::ctkCmdLineModuleExplorerTreeWidget(QWidget *
 
   FilterProxyModel = new ModuleSortFilterProxyModel(this);
   FilterProxyModel->setSourceModel(TreeModel);
-  FilterProxyModel->setDynamicSortFilter(true);
   FilterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+  FilterProxyModel->setDynamicSortFilter(true);
   this->setModel(FilterProxyModel);
 }
 
@@ -115,66 +117,90 @@ void ctkCmdLineModuleExplorerTreeWidget::setModuleFrontendFactories(const QList<
 
 void ctkCmdLineModuleExplorerTreeWidget::addModuleItem(const ctkCmdLineModuleReference &moduleRef)
 {
-  QString category;
+  QString categories;
   try
   {
-    category = moduleRef.description().category();
+    categories = moduleRef.description().category();
   }
   catch (const ctkCmdLineModuleXmlException&)
   {
-    category = CATEGORY_UNKNOWN;
+    categories = CATEGORY_UNKNOWN;
   }
 
-  QStandardItem* rootItem = NULL;
-
-  if (category.isEmpty())
+  if (categories.isEmpty())
   {
-    category = CATEGORY_UNKNOWN;
+    categories = CATEGORY_UNKNOWN;
   }
 
-  rootItem = TreeWidgetCategories[category];
-  if (rootItem == NULL)
+  QString currentCategories;
+  QStandardItem* oldRootItem = NULL;
+  foreach (const QString& category, categories.split('.', QString::SkipEmptyParts))
   {
-    // lazily create the root item for the category
-    rootItem = new QStandardItem(category);
-    TreeWidgetCategories[category] = rootItem;
-    TreeModel->appendRow(rootItem);
+    currentCategories += (currentCategories.isEmpty() ? QString() : QString(".")) + category;
+    QStandardItem* rootItem = TreeWidgetCategories[currentCategories];
+    if (rootItem == NULL)
+    {
+      rootItem = new QStandardItem(category);
+      TreeWidgetCategories[currentCategories] = rootItem;
+      if (oldRootItem != NULL)
+      {
+        oldRootItem->appendRow(rootItem);
+      }
+      else
+      {
+        TreeModel->appendRow(rootItem);
+      }
+    }
+    oldRootItem = rootItem;
   }
+
   QStandardItem* moduleItem =  new ctkCmdLineModuleTreeWidgetItem(moduleRef);
   TreeWidgetItems[moduleRef] = moduleItem;
-  rootItem->appendRow(moduleItem);
+  oldRootItem->appendRow(moduleItem);
 }
 
 void ctkCmdLineModuleExplorerTreeWidget::removeModuleItem(const ctkCmdLineModuleReference &moduleRef)
 {
-  QString category;
+  QStandardItem* treeWidgetItem = TreeWidgetItems.take(moduleRef);
+  if (treeWidgetItem == NULL) return;
+
+  QString categories;
   try
   {
-    category = moduleRef.description().category();
+    categories = moduleRef.description().category();
   }
   catch (const ctkCmdLineModuleXmlException&)
   {
-    category = CATEGORY_UNKNOWN;
+    categories = CATEGORY_UNKNOWN;
   }
 
-  if (category.isEmpty())
+  if (categories.isEmpty())
   {
-    category = CATEGORY_UNKNOWN;
+    categories = CATEGORY_UNKNOWN;
   }
 
+  QStringList categoryList = categories.split('.', QString::SkipEmptyParts);
+  while (!categoryList.isEmpty())
+  {
+    QStandardItem* rootItem = TreeWidgetCategories[categoryList.join(".")];
+    Q_ASSERT(rootItem);
 
-  QStandardItem* treeWidgetItem = TreeWidgetItems.take(moduleRef);
-  if (treeWidgetItem == NULL) return;
-
-  QStandardItem* rootItem = TreeWidgetCategories[category];
-  Q_ASSERT(rootItem);
-
-  rootItem->removeRow(treeWidgetItem->row());
+    rootItem->removeRow(treeWidgetItem->row());
 
-  if (rootItem->rowCount() == 0)
+    if (rootItem->rowCount() == 0)
+    {
+      treeWidgetItem = rootItem;
+      TreeWidgetCategories.remove(categoryList.join("."));
+      categoryList.pop_back();
+    }
+    else
+    {
+      break;
+    }
+  }
+  if (categoryList.isEmpty())
   {
-    TreeModel->removeRow(rootItem->row());
-    TreeWidgetCategories.remove(category);
+    TreeModel->removeRow(treeWidgetItem->row());
   }
 }
 
@@ -184,6 +210,7 @@ void ctkCmdLineModuleExplorerTreeWidget::contextMenuEvent(QContextMenuEvent *eve
   if (index.isValid() && index.data(Qt::UserRole+1).isValid())
   {
     this->ContextReference = index.data(Qt::UserRole+1).value<ctkCmdLineModuleReference>();
+    this->ShowXmlAction->setModuleReference(this->ContextReference);
     this->ContextMenu->exec(event->globalPos());
     event->accept();
   }
@@ -260,6 +287,13 @@ bool ModuleSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelInd
   return (sourceModel()->data(index).toString().contains(filterRegExp()));
 }
 
+bool ModuleSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
+{
+    QVariant l = (left.model() ? left.model()->data(left, this->sortRole()) : QVariant());
+    QVariant r = (right.model() ? right.model()->data(right, this->sortRole()) : QVariant());
+    return l.toString().compare(r.toString(), this->sortCaseSensitivity()) > 0;
+}
+
 
 ModuleSortFilterProxyModel::ModuleSortFilterProxyModel(QObject *parent)
   : QSortFilterProxyModel(parent)

+ 5 - 0
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerTreeWidget.h

@@ -29,6 +29,7 @@
 
 class ctkCmdLineModuleFrontend;
 struct ctkCmdLineModuleFrontendFactory;
+class ctkCmdLineModuleExplorerShowXmlAction;
 
 class QStandardItem;
 class QStandardItemModel;
@@ -44,6 +45,8 @@ public:
 protected:
 
   bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+
+  bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
 };
 
 /**
@@ -84,6 +87,8 @@ private:
   QMenu* ContextMenu;
   QMenu* ShowFrontendMenu;
 
+  ctkCmdLineModuleExplorerShowXmlAction* ShowXmlAction;
+
   ctkCmdLineModuleReference ContextReference;
   QList<ctkCmdLineModuleFrontendFactory*> FrontendFactories;
   ctkCmdLineModuleFrontendFactory* DefaultFrontendFactory;

+ 36 - 0
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerUtils.cpp

@@ -0,0 +1,36 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#include "ctkCmdLineModuleExplorerUtils.h"
+
+#include <QPainter>
+
+QPixmap ctkCmdLineModuleExplorerUtils::createIconOverlay(const QPixmap &base, const QPixmap &overlay)
+{
+  QPixmap result(base.width(), base.height());
+  result.fill(Qt::transparent);
+  QPainter painter(&result);
+  painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+  painter.drawPixmap(0, 0, base);
+  painter.drawPixmap(base.width()/2, base.height()/2,
+                     overlay.scaled(base.width()/2, base.height()/2, Qt::KeepAspectRatio));
+  return result;
+}

+ 34 - 0
Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerUtils.h

@@ -0,0 +1,34 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=============================================================================*/
+
+#ifndef CTKCOMMANDLINEMODULEEXPLORERUTILS_H
+#define CTKCOMMANDLINEMODULEEXPLORERUTILS_H
+
+#include <QPixmap>
+
+struct ctkCmdLineModuleExplorerUtils
+{
+
+  static QPixmap createIconOverlay(const QPixmap& base, const QPixmap& overlay);
+
+};
+
+#endif // CTKCOMMANDLINEMODULEEXPLORERUTILS_H