|
@@ -25,37 +25,46 @@
|
|
|
#include <ctkCmdLineModuleBackend.h>
|
|
|
#include <ctkCmdLineModuleFrontendFactory.h>
|
|
|
#include <ctkCmdLineModuleDescription.h>
|
|
|
+#include <ctkCmdLineModuleXmlException.h>
|
|
|
|
|
|
+#include <QStandardItemModel>
|
|
|
+#include <QSortFilterProxyModel>
|
|
|
#include <QContextMenuEvent>
|
|
|
#include <QMenu>
|
|
|
#include <QDebug>
|
|
|
#include <QUrl>
|
|
|
#include <QApplication>
|
|
|
+#include <QMessageBox>
|
|
|
|
|
|
QString ctkCmdLineModuleExplorerTreeWidget::CATEGORY_UNKNOWN = "Uncategorized";
|
|
|
|
|
|
-class ctkCmdLineModuleTreeWidgetItem : public QTreeWidgetItem
|
|
|
+class ctkCmdLineModuleTreeWidgetItem : public QStandardItem
|
|
|
{
|
|
|
public:
|
|
|
|
|
|
- static const int CmdLineModuleType = 1001;
|
|
|
-
|
|
|
ctkCmdLineModuleTreeWidgetItem(const ctkCmdLineModuleReference& moduleRef)
|
|
|
- : QTreeWidgetItem(CmdLineModuleType), ModuleRef(moduleRef)
|
|
|
- {
|
|
|
- init();
|
|
|
- }
|
|
|
-
|
|
|
- ctkCmdLineModuleTreeWidgetItem(QTreeWidget* parent, const ctkCmdLineModuleReference& moduleRef)
|
|
|
- : QTreeWidgetItem(parent, CmdLineModuleType), ModuleRef(moduleRef)
|
|
|
+ : QStandardItem()
|
|
|
+ , ModuleRef(moduleRef)
|
|
|
{
|
|
|
- init();
|
|
|
- }
|
|
|
+ QString title;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ title = ModuleRef.description().title();
|
|
|
+ }
|
|
|
+ catch (const ctkCmdLineModuleXmlException&)
|
|
|
+ {
|
|
|
+ title = ModuleRef.location().toString();
|
|
|
+ }
|
|
|
|
|
|
- ctkCmdLineModuleTreeWidgetItem(QTreeWidgetItem* parent, const ctkCmdLineModuleReference& moduleRef)
|
|
|
- : QTreeWidgetItem(parent, CmdLineModuleType), ModuleRef(moduleRef)
|
|
|
- {
|
|
|
- init();
|
|
|
+ this->setText(title + " [" + ModuleRef.backend()->name() + "]");
|
|
|
+ this->setData(QVariant::fromValue(ModuleRef));
|
|
|
+ QString toolTip = ModuleRef.location().toString();
|
|
|
+ if (!ModuleRef.xmlValidationErrorString().isEmpty())
|
|
|
+ {
|
|
|
+ this->setIcon(QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning));
|
|
|
+ toolTip += "\n\nWarning:\n\n" + ModuleRef.xmlValidationErrorString();
|
|
|
+ }
|
|
|
+ this->setToolTip(toolTip);
|
|
|
}
|
|
|
|
|
|
ctkCmdLineModuleReference moduleReference() const
|
|
@@ -65,25 +74,13 @@ public:
|
|
|
|
|
|
private:
|
|
|
|
|
|
- void init()
|
|
|
- {
|
|
|
- this->setText(0, ModuleRef.description().title() + " [" + ModuleRef.backend()->name() + "]");
|
|
|
- this->setData(0, Qt::UserRole, QVariant::fromValue(ModuleRef));
|
|
|
- QString toolTip = ModuleRef.location().toString();
|
|
|
- if (!ModuleRef.xmlValidationErrorString().isEmpty())
|
|
|
- {
|
|
|
- this->setIcon(0, QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning));
|
|
|
- toolTip += "\n\nWarning:\n\n" + ModuleRef.xmlValidationErrorString();
|
|
|
- }
|
|
|
- this->setToolTip(0, toolTip);
|
|
|
- }
|
|
|
-
|
|
|
ctkCmdLineModuleReference ModuleRef;
|
|
|
|
|
|
};
|
|
|
|
|
|
ctkCmdLineModuleExplorerTreeWidget::ctkCmdLineModuleExplorerTreeWidget(QWidget *parent)
|
|
|
- : QTreeWidget(parent)
|
|
|
+ : QTreeView(parent)
|
|
|
+ , DefaultFrontendFactory(NULL)
|
|
|
{
|
|
|
this->ContextMenu = new QMenu(this);
|
|
|
this->ShowFrontendMenu = this->ContextMenu->addMenu("Create Frontend");
|
|
@@ -91,11 +88,21 @@ ctkCmdLineModuleExplorerTreeWidget::ctkCmdLineModuleExplorerTreeWidget(QWidget *
|
|
|
this->ContextMenu->addAction("Properties");
|
|
|
|
|
|
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(moduleDoubleClicked(QModelIndex)));
|
|
|
+
|
|
|
+ TreeModel = new QStandardItemModel(this);
|
|
|
+
|
|
|
+ FilterProxyModel = new ModuleSortFilterProxyModel(this);
|
|
|
+ FilterProxyModel->setSourceModel(TreeModel);
|
|
|
+ FilterProxyModel->setDynamicSortFilter(true);
|
|
|
+ FilterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
|
+ this->setModel(FilterProxyModel);
|
|
|
}
|
|
|
|
|
|
-void ctkCmdLineModuleExplorerTreeWidget::setModuleFrontendFactories(const QList<ctkCmdLineModuleFrontendFactory *> &frontendFactories)
|
|
|
+void ctkCmdLineModuleExplorerTreeWidget::setModuleFrontendFactories(const QList<ctkCmdLineModuleFrontendFactory *> &frontendFactories,
|
|
|
+ ctkCmdLineModuleFrontendFactory* defaultFactory)
|
|
|
{
|
|
|
this->FrontendFactories = frontendFactories;
|
|
|
+ this->DefaultFrontendFactory = defaultFactory;
|
|
|
|
|
|
this->ShowFrontendMenu->clear();
|
|
|
foreach(ctkCmdLineModuleFrontendFactory* factory, this->FrontendFactories)
|
|
@@ -108,9 +115,17 @@ void ctkCmdLineModuleExplorerTreeWidget::setModuleFrontendFactories(const QList<
|
|
|
|
|
|
void ctkCmdLineModuleExplorerTreeWidget::addModuleItem(const ctkCmdLineModuleReference &moduleRef)
|
|
|
{
|
|
|
- QString category = moduleRef.description().category();
|
|
|
+ QString category;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ category = moduleRef.description().category();
|
|
|
+ }
|
|
|
+ catch (const ctkCmdLineModuleXmlException&)
|
|
|
+ {
|
|
|
+ category = CATEGORY_UNKNOWN;
|
|
|
+ }
|
|
|
|
|
|
- QTreeWidgetItem* rootItem = NULL;
|
|
|
+ QStandardItem* rootItem = NULL;
|
|
|
|
|
|
if (category.isEmpty())
|
|
|
{
|
|
@@ -121,43 +136,54 @@ void ctkCmdLineModuleExplorerTreeWidget::addModuleItem(const ctkCmdLineModuleRef
|
|
|
if (rootItem == NULL)
|
|
|
{
|
|
|
// lazily create the root item for the category
|
|
|
- rootItem = new QTreeWidgetItem(this);
|
|
|
- rootItem->setText(0, category);
|
|
|
+ rootItem = new QStandardItem(category);
|
|
|
TreeWidgetCategories[category] = rootItem;
|
|
|
+ TreeModel->appendRow(rootItem);
|
|
|
}
|
|
|
- TreeWidgetItems[moduleRef] = new ctkCmdLineModuleTreeWidgetItem(rootItem, moduleRef);
|
|
|
+ QStandardItem* moduleItem = new ctkCmdLineModuleTreeWidgetItem(moduleRef);
|
|
|
+ TreeWidgetItems[moduleRef] = moduleItem;
|
|
|
+ rootItem->appendRow(moduleItem);
|
|
|
}
|
|
|
|
|
|
void ctkCmdLineModuleExplorerTreeWidget::removeModuleItem(const ctkCmdLineModuleReference &moduleRef)
|
|
|
{
|
|
|
- QString category = moduleRef.description().category();
|
|
|
+ QString category;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ category = moduleRef.description().category();
|
|
|
+ }
|
|
|
+ catch (const ctkCmdLineModuleXmlException&)
|
|
|
+ {
|
|
|
+ category = CATEGORY_UNKNOWN;
|
|
|
+ }
|
|
|
+
|
|
|
if (category.isEmpty())
|
|
|
{
|
|
|
category = CATEGORY_UNKNOWN;
|
|
|
}
|
|
|
|
|
|
|
|
|
- QTreeWidgetItem* treeWidgetItem = TreeWidgetItems.take(moduleRef);
|
|
|
+ QStandardItem* treeWidgetItem = TreeWidgetItems.take(moduleRef);
|
|
|
if (treeWidgetItem == NULL) return;
|
|
|
|
|
|
- this->removeItemWidget(treeWidgetItem, 0);
|
|
|
- delete treeWidgetItem;
|
|
|
+ QStandardItem* rootItem = TreeWidgetCategories[category];
|
|
|
+ Q_ASSERT(rootItem);
|
|
|
|
|
|
- QTreeWidgetItem* rootItem = TreeWidgetCategories[category];
|
|
|
- if (rootItem && rootItem->childCount() == 0)
|
|
|
+ rootItem->removeRow(treeWidgetItem->row());
|
|
|
+
|
|
|
+ if (rootItem->rowCount() == 0)
|
|
|
{
|
|
|
- this->removeItemWidget(rootItem, 0);
|
|
|
+ TreeModel->removeRow(rootItem->row());
|
|
|
TreeWidgetCategories.remove(category);
|
|
|
- delete rootItem;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void ctkCmdLineModuleExplorerTreeWidget::contextMenuEvent(QContextMenuEvent *event)
|
|
|
{
|
|
|
- QTreeWidgetItem* item = this->itemAt(this->viewport()->mapFromGlobal(event->globalPos()));
|
|
|
- if (item != NULL && item->type() == ctkCmdLineModuleTreeWidgetItem::CmdLineModuleType)
|
|
|
+ QModelIndex index = this->indexAt(this->viewport()->mapFromGlobal(event->globalPos()));
|
|
|
+ if (index.isValid() && index.data(Qt::UserRole+1).isValid())
|
|
|
{
|
|
|
- this->ContextReference = item->data(0, Qt::UserRole).value<ctkCmdLineModuleReference>();
|
|
|
+ this->ContextReference = index.data(Qt::UserRole+1).value<ctkCmdLineModuleReference>();
|
|
|
this->ContextMenu->exec(event->globalPos());
|
|
|
event->accept();
|
|
|
}
|
|
@@ -170,18 +196,72 @@ void ctkCmdLineModuleExplorerTreeWidget::contextMenuEvent(QContextMenuEvent *eve
|
|
|
|
|
|
void ctkCmdLineModuleExplorerTreeWidget::moduleDoubleClicked(const QModelIndex &index)
|
|
|
{
|
|
|
- QVariant data = index.data(Qt::UserRole);
|
|
|
+ if (this->DefaultFrontendFactory == NULL) return;
|
|
|
+
|
|
|
+ QVariant data = index.data(Qt::UserRole+1);
|
|
|
if (!data.isValid()) return;
|
|
|
|
|
|
ctkCmdLineModuleReference moduleRef = data.value<ctkCmdLineModuleReference>();
|
|
|
if (!moduleRef) return;
|
|
|
|
|
|
- emit moduleDoubleClicked(moduleRef);
|
|
|
+ this->createFrontend(moduleRef, this->DefaultFrontendFactory);
|
|
|
}
|
|
|
|
|
|
void ctkCmdLineModuleExplorerTreeWidget::frontendFactoryActionTriggered()
|
|
|
{
|
|
|
ctkCmdLineModuleFrontendFactory* frontendFactory = this->ActionsToFrontendFactoryMap[static_cast<QAction*>(this->sender())];
|
|
|
- ctkCmdLineModuleFrontend* frontend = frontendFactory->create(this->ContextReference);
|
|
|
- emit moduleFrontendCreated(frontend);
|
|
|
+ this->createFrontend(this->ContextReference, frontendFactory);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void ctkCmdLineModuleExplorerTreeWidget::setFilter(const QString &filter)
|
|
|
+{
|
|
|
+ this->FilterProxyModel->setFilterWildcard(filter);
|
|
|
+}
|
|
|
+
|
|
|
+ctkCmdLineModuleFrontend* ctkCmdLineModuleExplorerTreeWidget::createFrontend(const ctkCmdLineModuleReference &moduleRef,
|
|
|
+ ctkCmdLineModuleFrontendFactory* frontendFactory)
|
|
|
+{
|
|
|
+ try
|
|
|
+ {
|
|
|
+ moduleRef.description();
|
|
|
+ ctkCmdLineModuleFrontend* moduleFrontend = frontendFactory->create(moduleRef);
|
|
|
+ emit moduleFrontendCreated(moduleFrontend);
|
|
|
+ return moduleFrontend;
|
|
|
+ }
|
|
|
+ catch (const ctkException& e)
|
|
|
+ {
|
|
|
+ QMessageBox::information(this, "Frontend creation failed", "Creating a " + frontendFactory->name()
|
|
|
+ + " frontend failed:\n\n" + e.what());
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+bool ModuleSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
|
|
+{
|
|
|
+ QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
|
|
+
|
|
|
+ QModelIndex childIndex = index.child(0, 0);
|
|
|
+ if (childIndex.isValid())
|
|
|
+ {
|
|
|
+ int i = 0;
|
|
|
+ bool accept = false;
|
|
|
+ while(childIndex.isValid())
|
|
|
+ {
|
|
|
+ accept = this->filterAcceptsRow(childIndex.row(), index);
|
|
|
+ if (accept) return true;
|
|
|
+
|
|
|
+ childIndex = index.child(++i, 0);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (sourceModel()->data(index).toString().contains(filterRegExp()));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ModuleSortFilterProxyModel::ModuleSortFilterProxyModel(QObject *parent)
|
|
|
+ : QSortFilterProxyModel(parent)
|
|
|
+{
|
|
|
}
|