39 #include "ctkServiceReference.h"
40 #include "ctkServiceException.h"
41 #include "ctkPluginConstants.h"
43 #include <ctkConfig.h>
44 #include <ctkPluginException.h>
45 #include <ctkPluginFramework.h>
46 #include <ctkPluginContext.h>
49 #include <QApplication>
50 #include <QMainWindow>
51 #include <QStringList>
52 #include <QDirIterator>
55 #include <QCloseEvent>
65 : framework(framework)
67 mSettingsMainWindowStateTag =
"pluginbrowser/state";
68 mSettingsMainWindowGeometryTag =
"pluginbrowser/geometry";
70 pluginEventTypeToString[ctkPluginEvent::INSTALLED] =
"Installed";
71 pluginEventTypeToString[ctkPluginEvent::LAZY_ACTIVATION] =
"Lazy Activation";
72 pluginEventTypeToString[ctkPluginEvent::RESOLVED] =
"Resolved";
73 pluginEventTypeToString[ctkPluginEvent::STARTED] =
"Started";
74 pluginEventTypeToString[ctkPluginEvent::STARTING] =
"Starting";
75 pluginEventTypeToString[ctkPluginEvent::STOPPED] =
"Stopped";
76 pluginEventTypeToString[ctkPluginEvent::STOPPING] =
"Stopping";
77 pluginEventTypeToString[ctkPluginEvent::UNINSTALLED] =
"Uninstalled";
78 pluginEventTypeToString[ctkPluginEvent::UNRESOLVED] =
"Unresolved";
79 pluginEventTypeToString[ctkPluginEvent::UPDATED] =
"Updated";
84 framework->getPluginContext()->connectFrameworkListener(
this, SLOT(frameworkEvent(ctkPluginFrameworkEvent)));
85 framework->getPluginContext()->connectPluginListener(
this, SLOT(pluginEvent(ctkPluginEvent)));
86 framework->getPluginContext()->connectServiceListener(
this,
"serviceEvent");
92 pluginsTableView->setModel(mPluginTableModel);
94 connect(pluginsTableView->selectionModel(),
95 &QItemSelectionModel::currentChanged,
97 &ctkPluginBrowser::pluginSelected);
99 startPluginNowAction =
new QAction(QIcon(
":/icons/open_icon_library/arrow-right-double-3.png"),
"Start Plugin (ignore activation policy)",
this);
100 startPluginAction =
new QAction(QIcon(
":/icons/open_icon_library/arrow-right-3.png"),
"Start Plugin",
this);
101 stopPluginAction =
new QAction(QIcon(
":/icons/open_icon_library/media-record-3.png"),
"Stop Plugin",
this);
102 toggleInstallPluginAction =
new QAction(QIcon(
":/icons/preset_reset.png"),
"Toggle Install",
this);
104 connect(startPluginNowAction, SIGNAL(triggered()),
this, SLOT(startPluginNow()));
105 connect(startPluginAction, SIGNAL(triggered()),
this, SLOT(startPlugin()));
106 connect(stopPluginAction, SIGNAL(triggered()),
this, SLOT(stopPlugin()));
107 connect(toggleInstallPluginAction, SIGNAL(triggered()),
this, SLOT(toggleInstallPlugin()));
109 startPluginNowAction->setEnabled(
false);
110 startPluginAction->setEnabled(
false);
111 stopPluginAction->setEnabled(
false);
113 pluginToolBar->addAction(startPluginNowAction);
114 pluginToolBar->addAction(startPluginAction);
115 pluginToolBar->addAction(stopPluginAction);
116 pluginToolBar->addAction(toggleInstallPluginAction);
118 if(
settings()->contains(mSettingsMainWindowGeometryTag))
120 this->restoreGeometry(
settings()->value(mSettingsMainWindowGeometryTag).toByteArray());
122 if (
settings()->contains(mSettingsMainWindowStateTag))
124 this->restoreState(
settings()->value(mSettingsMainWindowStateTag).toByteArray());
127 QTimer::singleShot(0,
this, SLOT(resizePluginsTableView()));
136 void ctkPluginBrowser::resizePluginsTableView()
138 pluginsTableView->resizeColumnToContents(0);
141 void ctkPluginBrowser::setupUi()
143 pluginsTableView =
new QTableView(
this);
144 pluginsTableView->setObjectName(QString::fromUtf8(
"pluginsTableView"));
145 pluginsTableView->setWindowTitle(
"Plugins");
146 pluginsTableView->setAutoScroll(
false);
147 pluginsTableView->setSelectionMode(QAbstractItemView::SingleSelection);
148 pluginsTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
149 pluginsTableView->setShowGrid(
false);
150 pluginsTableView->setSortingEnabled(
true);
151 pluginsTableView->horizontalHeader()->setCascadingSectionResizes(
true);
152 pluginsTableView->horizontalHeader()->setHighlightSections(
false);
153 pluginsTableView->horizontalHeader()->setProperty(
"showSortIndicator", QVariant(
true));
154 pluginsTableView->horizontalHeader()->setStretchLastSection(
true);
155 pluginsTableView->verticalHeader()->setVisible(
false);
157 this->wrapInDockWidget(pluginsTableView);
159 pluginToolBar =
new QToolBar(
this);
160 pluginToolBar->setObjectName(QString::fromUtf8(
"pluginToolBar"));
161 this->addToolBar(Qt::TopToolBarArea, pluginToolBar);
165 searchPathSelectWidget->setWindowTitle(
"Search Paths");
167 searchPathSelectWidget->
setHelp(
"Select where to look for plugins");
168 searchPathSelectWidget->
setBrowseHelp(
"Browse for a search path");
170 searchPathSelectWidget->
setBasePath(qApp->applicationDirPath());
172 searchPathSelectWidget->
setFilenames(framework->getSearchPaths());
173 connect(searchPathSelectWidget, SIGNAL(fileChanged()),
this, SLOT(searchPathChanged()));
175 this->wrapInDockWidget(searchPathSelectWidget);
177 mPluginInfoWidget =
new QTextEdit(
this);
178 mPluginInfoWidget->setObjectName(
"PluginInfoWidget");
179 mPluginInfoWidget->setWindowTitle(
"Plugin Info");
180 this->wrapInDockWidget(mPluginInfoWidget);
184 void ctkPluginBrowser::wrapInDockWidget(QWidget* widget)
186 QDockWidget* dockWidget =
new QDockWidget(widget->windowTitle(),
this);
187 dockWidget->setObjectName(widget->objectName()+
"_dockwidget");
188 dockWidget->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable);
189 dockWidget->setWidget(widget);
190 this->addDockWidget(
static_cast<Qt::DockWidgetArea
>(1), dockWidget);
193 void ctkPluginBrowser::searchPathChanged()
196 QStringList validFiles;
197 for (
int i=0; i<files.size(); ++i)
198 if (QFileInfo(files[i]).exists())
199 validFiles << files[i];
201 framework->setSearchPaths(validFiles);
204 void ctkPluginBrowser::pluginSelected(
const QModelIndex &index)
206 this->updatePluginToolbar();
207 this->updatePluginInfo();
210 void ctkPluginBrowser::updatePluginToolbar()
212 startPluginNowAction->setEnabled(
false);
213 startPluginAction->setEnabled(
false);
214 stopPluginAction->setEnabled(
false);
216 PluginData plugin = this->getSelectedPlugin();
220 toggleInstallPluginAction->setText(
"Install");
223 toggleInstallPluginAction->setText(
"Uninstall");
225 const ctkPlugin::States startStates = ctkPlugin::INSTALLED | ctkPlugin::RESOLVED | ctkPlugin::STOPPING;
226 const ctkPlugin::States stopStates = ctkPlugin::STARTING | ctkPlugin::ACTIVE;
227 if (startStates.testFlag(plugin.second->getState()))
229 startPluginNowAction->setEnabled(
true);
230 startPluginAction->setEnabled(
true);
233 if (stopStates.testFlag(plugin.second->getState()))
235 stopPluginAction->setEnabled(
true);
239 void ctkPluginBrowser::updatePluginInfo()
241 PluginData plugin = this->getSelectedPlugin();
247 QString manifest(
"/META-INF/MANIFEST.MF");
248 text += QString(
"%1").arg(manifest);
249 text += QString(
"<hr>");
250 QByteArray mfContent = plugin.second->getResource(manifest);
251 QString rawText(
"<div style=\"white-space: pre-wrap;\">%1</div>");
252 text += rawText.arg(QString(mfContent));
253 text += QString(
"<hr>");
254 text += QString(
"<p><b>Location:</b> %1</p>").arg(plugin.second->getLocation());
257 if (!plugin.second.isNull() && plugin.second->getPluginContext())
259 QStringList serviceTexts;
260 QList<ctkServiceReference> serviceRefs = plugin.second->getPluginContext()->getServiceReferences(
"");
261 QListIterator<ctkServiceReference> it(serviceRefs);
264 ctkServiceReference ref(it.next());
266 if (ref.getPlugin()->getSymbolicName() != plugin.first)
269 serviceTexts += QString(
"<tr><td><b>Service</td></tr>");
270 QStringList propKeys = ref.getPropertyKeys();
271 for (
int i=0; i<propKeys.size(); ++i)
273 QString val = ref.getProperty(propKeys[i]).toString();
274 QString bblue(
"<b><font color=\"blue\">%1</font></b>");
275 QString green(
"<b><font color=\"green\">%1</font></b>");
276 QString formattedKey = green.arg(propKeys[i]);
277 QString formattedVal = bblue.arg(val);
278 serviceTexts += QString(
"<tr> <td></td> <td>%1</td> <td>%2</td> </tr>").arg(formattedKey).arg(formattedVal);
282 text += QString(
"<table>%1</table>").arg(serviceTexts.join(
"\n"));
286 text += QString(
"<p>Service info not available</p>");
289 mPluginInfoWidget->setHtml(text);
292 void ctkPluginBrowser::frameworkEvent(
const ctkPluginFrameworkEvent& event)
294 qDebug() <<
"FrameworkEvent: [" <<
event.getPlugin()->getSymbolicName() <<
"]" <<
event.getErrorString();
297 void ctkPluginBrowser::pluginEvent(
const ctkPluginEvent& event)
299 qDebug() <<
"PluginEvent: [" <<
event.getPlugin()->getSymbolicName() <<
"]" << pluginEventTypeToString[
event.getType()];
301 updatePluginToolbar();
304 void ctkPluginBrowser::serviceEvent(
const ctkServiceEvent &event)
306 ctkServiceReference ref =
event.getServiceReference();
307 qDebug() <<
"ServiceEvent: [" <<
event.getType() <<
"]" <<
event.getServiceReference().getUsingPlugins();
308 qDebug() <<
" keys: " << ref.getPropertyKeys();
309 qDebug() <<
" objectclass: " << ref.getProperty(
"objectclass");
312 PluginData ctkPluginBrowser::getSelectedPlugin()
314 QModelIndex selection = pluginsTableView->selectionModel()->currentIndex();
315 QVariant v = selection.data(Qt::UserRole);
316 QString name = v.toString();
317 ctkPluginPtr plugin = framework->getInstalledPluginFromSymbolicName(name);
318 return std::make_pair(name, plugin);
321 void ctkPluginBrowser::toggleInstallPlugin()
323 PluginData plugin = this->getSelectedPlugin();
326 framework->uninstall(plugin.first);
330 framework->install(plugin.first);
334 void ctkPluginBrowser::startPlugin()
336 startPlugin(ctkPlugin::START_TRANSIENT | ctkPlugin::START_ACTIVATION_POLICY);
339 void ctkPluginBrowser::startPluginNow()
341 startPlugin(ctkPlugin::START_TRANSIENT);
344 void ctkPluginBrowser::startPlugin(ctkPlugin::StartOptions options)
346 PluginData plugin = this->getSelectedPlugin();
347 framework->start(plugin.first, options);
350 void ctkPluginBrowser::stopPlugin()
352 PluginData plugin = this->getSelectedPlugin();
353 framework->stop(plugin.first);