60 #include "ctkServiceReference.h"
61 #include "ctkServiceException.h"
62 #include "ctkPluginConstants.h"
64 #include <ctkConfig.h>
65 #include <ctkPluginException.h>
66 #include <ctkPluginFramework.h>
67 #include <ctkPluginContext.h>
70 #include <QApplication>
71 #include <QMainWindow>
72 #include <QStringList>
73 #include <QDirIterator>
76 #include <QCloseEvent>
86 : framework(framework)
88 mSettingsMainWindowStateTag =
"pluginbrowser/state";
89 mSettingsMainWindowGeometryTag =
"pluginbrowser/geometry";
91 pluginEventTypeToString[ctkPluginEvent::INSTALLED] =
"Installed";
92 pluginEventTypeToString[ctkPluginEvent::LAZY_ACTIVATION] =
"Lazy Activation";
93 pluginEventTypeToString[ctkPluginEvent::RESOLVED] =
"Resolved";
94 pluginEventTypeToString[ctkPluginEvent::STARTED] =
"Started";
95 pluginEventTypeToString[ctkPluginEvent::STARTING] =
"Starting";
96 pluginEventTypeToString[ctkPluginEvent::STOPPED] =
"Stopped";
97 pluginEventTypeToString[ctkPluginEvent::STOPPING] =
"Stopping";
98 pluginEventTypeToString[ctkPluginEvent::UNINSTALLED] =
"Uninstalled";
99 pluginEventTypeToString[ctkPluginEvent::UNRESOLVED] =
"Unresolved";
100 pluginEventTypeToString[ctkPluginEvent::UPDATED] =
"Updated";
105 framework->getPluginContext()->connectFrameworkListener(
this, SLOT(frameworkEvent(ctkPluginFrameworkEvent)));
106 framework->getPluginContext()->connectPluginListener(
this, SLOT(pluginEvent(ctkPluginEvent)));
107 framework->getPluginContext()->connectServiceListener(
this,
"serviceEvent");
113 pluginsTableView->setModel(mPluginTableModel);
115 connect(pluginsTableView->selectionModel(),
116 &QItemSelectionModel::currentChanged,
118 &ctkPluginBrowser::pluginSelected);
120 startPluginNowAction =
new QAction(QIcon(
":/icons/open_icon_library/arrow-right-double-3.png"),
"Start Plugin (ignore activation policy)",
this);
121 startPluginAction =
new QAction(QIcon(
":/icons/open_icon_library/arrow-right-3.png"),
"Start Plugin",
this);
122 stopPluginAction =
new QAction(QIcon(
":/icons/open_icon_library/media-record-3.png"),
"Stop Plugin",
this);
123 toggleInstallPluginAction =
new QAction(QIcon(
":/icons/preset_reset.png"),
"Toggle Install",
this);
125 connect(startPluginNowAction, SIGNAL(triggered()),
this, SLOT(startPluginNow()));
126 connect(startPluginAction, SIGNAL(triggered()),
this, SLOT(startPlugin()));
127 connect(stopPluginAction, SIGNAL(triggered()),
this, SLOT(stopPlugin()));
128 connect(toggleInstallPluginAction, SIGNAL(triggered()),
this, SLOT(toggleInstallPlugin()));
130 startPluginNowAction->setEnabled(
false);
131 startPluginAction->setEnabled(
false);
132 stopPluginAction->setEnabled(
false);
134 pluginToolBar->addAction(startPluginNowAction);
135 pluginToolBar->addAction(startPluginAction);
136 pluginToolBar->addAction(stopPluginAction);
137 pluginToolBar->addAction(toggleInstallPluginAction);
139 if(
settings()->contains(mSettingsMainWindowGeometryTag))
141 this->restoreGeometry(
settings()->value(mSettingsMainWindowGeometryTag).toByteArray());
143 if (
settings()->contains(mSettingsMainWindowStateTag))
145 this->restoreState(
settings()->value(mSettingsMainWindowStateTag).toByteArray());
148 QTimer::singleShot(0,
this, SLOT(resizePluginsTableView()));
157 void ctkPluginBrowser::resizePluginsTableView()
159 pluginsTableView->resizeColumnToContents(0);
162 void ctkPluginBrowser::setupUi()
164 pluginsTableView =
new QTableView(
this);
165 pluginsTableView->setObjectName(QString::fromUtf8(
"pluginsTableView"));
166 pluginsTableView->setWindowTitle(
"Plugins");
167 pluginsTableView->setAutoScroll(
false);
168 pluginsTableView->setSelectionMode(QAbstractItemView::SingleSelection);
169 pluginsTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
170 pluginsTableView->setShowGrid(
false);
171 pluginsTableView->setSortingEnabled(
true);
172 pluginsTableView->horizontalHeader()->setCascadingSectionResizes(
true);
173 pluginsTableView->horizontalHeader()->setHighlightSections(
false);
174 pluginsTableView->horizontalHeader()->setProperty(
"showSortIndicator", QVariant(
true));
175 pluginsTableView->horizontalHeader()->setStretchLastSection(
true);
176 pluginsTableView->verticalHeader()->setVisible(
false);
178 this->wrapInDockWidget(pluginsTableView);
180 pluginToolBar =
new QToolBar(
this);
181 pluginToolBar->setObjectName(QString::fromUtf8(
"pluginToolBar"));
182 this->addToolBar(Qt::TopToolBarArea, pluginToolBar);
186 searchPathSelectWidget->setWindowTitle(
"Search Paths");
188 searchPathSelectWidget->
setHelp(
"Select where to look for plugins");
189 searchPathSelectWidget->
setBrowseHelp(
"Browse for a search path");
191 searchPathSelectWidget->
setBasePath(qApp->applicationDirPath());
193 searchPathSelectWidget->
setFilenames(framework->getSearchPaths());
194 connect(searchPathSelectWidget, SIGNAL(fileChanged()),
this, SLOT(searchPathChanged()));
196 this->wrapInDockWidget(searchPathSelectWidget);
198 mPluginInfoWidget =
new QTextEdit(
this);
199 mPluginInfoWidget->setObjectName(
"PluginInfoWidget");
200 mPluginInfoWidget->setWindowTitle(
"Plugin Info");
201 this->wrapInDockWidget(mPluginInfoWidget);
205 void ctkPluginBrowser::wrapInDockWidget(QWidget* widget)
207 QDockWidget* dockWidget =
new QDockWidget(widget->windowTitle(),
this);
208 dockWidget->setObjectName(widget->objectName()+
"_dockwidget");
209 dockWidget->setFeatures(QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable);
210 dockWidget->setWidget(widget);
211 this->addDockWidget(static_cast<Qt::DockWidgetArea>(1), dockWidget);
214 void ctkPluginBrowser::searchPathChanged()
217 QStringList validFiles;
218 for (
int i=0; i<files.size(); ++i)
219 if (QFileInfo(files[i]).exists())
220 validFiles << files[i];
222 framework->setSearchPaths(validFiles);
225 void ctkPluginBrowser::pluginSelected(
const QModelIndex &index)
227 this->updatePluginToolbar();
228 this->updatePluginInfo();
231 void ctkPluginBrowser::updatePluginToolbar()
233 startPluginNowAction->setEnabled(
false);
234 startPluginAction->setEnabled(
false);
235 stopPluginAction->setEnabled(
false);
237 PluginData plugin = this->getSelectedPlugin();
241 toggleInstallPluginAction->setText(
"Install");
244 toggleInstallPluginAction->setText(
"Uninstall");
246 const ctkPlugin::States startStates = ctkPlugin::INSTALLED | ctkPlugin::RESOLVED | ctkPlugin::STOPPING;
247 const ctkPlugin::States stopStates = ctkPlugin::STARTING | ctkPlugin::ACTIVE;
248 if (startStates.testFlag(plugin.second->getState()))
250 startPluginNowAction->setEnabled(
true);
251 startPluginAction->setEnabled(
true);
254 if (stopStates.testFlag(plugin.second->getState()))
256 stopPluginAction->setEnabled(
true);
260 void ctkPluginBrowser::updatePluginInfo()
262 PluginData plugin = this->getSelectedPlugin();
268 QString manifest(
"/META-INF/MANIFEST.MF");
269 text += QString(
"%1").arg(manifest);
270 text += QString(
"<hr>");
271 QByteArray mfContent = plugin.second->getResource(manifest);
272 QString rawText(
"<div style=\"white-space: pre-wrap;\">%1</div>");
273 text += rawText.arg(QString(mfContent));
274 text += QString(
"<hr>");
275 text += QString(
"<p><b>Location:</b> %1</p>").arg(plugin.second->getLocation());
278 if (!plugin.second.isNull() && plugin.second->getPluginContext())
280 QStringList serviceTexts;
281 QList<ctkServiceReference> serviceRefs = plugin.second->getPluginContext()->getServiceReferences(
"");
282 QListIterator<ctkServiceReference> it(serviceRefs);
285 ctkServiceReference ref(it.next());
287 if (ref.getPlugin()->getSymbolicName() != plugin.first)
290 serviceTexts += QString(
"<tr><td><b>Service</td></tr>");
291 QStringList propKeys = ref.getPropertyKeys();
292 for (
int i=0; i<propKeys.size(); ++i)
294 QString val = ref.getProperty(propKeys[i]).toString();
295 QString bblue(
"<b><font color=\"blue\">%1</font></b>");
296 QString green(
"<b><font color=\"green\">%1</font></b>");
297 QString formattedKey = green.arg(propKeys[i]);
298 QString formattedVal = bblue.arg(val);
299 serviceTexts += QString(
"<tr> <td></td> <td>%1</td> <td>%2</td> </tr>").arg(formattedKey).arg(formattedVal);
303 text += QString(
"<table>%1</table>").arg(serviceTexts.join(
"\n"));
307 text += QString(
"<p>Service info not available</p>");
310 mPluginInfoWidget->setHtml(text);
313 void ctkPluginBrowser::frameworkEvent(
const ctkPluginFrameworkEvent& event)
315 qDebug() <<
"FrameworkEvent: [" <<
event.getPlugin()->getSymbolicName() <<
"]" <<
event.getErrorString();
318 void ctkPluginBrowser::pluginEvent(
const ctkPluginEvent& event)
320 qDebug() <<
"PluginEvent: [" <<
event.getPlugin()->getSymbolicName() <<
"]" << pluginEventTypeToString[
event.getType()];
322 updatePluginToolbar();
325 void ctkPluginBrowser::serviceEvent(
const ctkServiceEvent &event)
327 ctkServiceReference ref =
event.getServiceReference();
328 qDebug() <<
"ServiceEvent: [" <<
event.getType() <<
"]" <<
event.getServiceReference().getUsingPlugins();
329 qDebug() <<
" keys: " << ref.getPropertyKeys();
330 qDebug() <<
" objectclass: " << ref.getProperty(
"objectclass");
333 PluginData ctkPluginBrowser::getSelectedPlugin()
335 QModelIndex selection = pluginsTableView->selectionModel()->currentIndex();
336 QVariant v = selection.data(Qt::UserRole);
337 QString name = v.toString();
338 ctkPluginPtr plugin = framework->getInstalledPluginFromSymbolicName(name);
339 return std::make_pair(name, plugin);
342 void ctkPluginBrowser::toggleInstallPlugin()
344 PluginData plugin = this->getSelectedPlugin();
347 framework->uninstall(plugin.first);
351 framework->install(plugin.first);
355 void ctkPluginBrowser::startPlugin()
357 startPlugin(ctkPlugin::START_TRANSIENT | ctkPlugin::START_ACTIVATION_POLICY);
360 void ctkPluginBrowser::startPluginNow()
362 startPlugin(ctkPlugin::START_TRANSIENT);
365 void ctkPluginBrowser::startPlugin(ctkPlugin::StartOptions options)
367 PluginData plugin = this->getSelectedPlugin();
368 framework->start(plugin.first, options);
371 void ctkPluginBrowser::stopPlugin()
373 PluginData plugin = this->getSelectedPlugin();
374 framework->stop(plugin.first);
QSharedPointer< ctkPlugin > ctkPluginPtr
void setValue(const QString &key, const QVariant &value)
std::pair< QString, ctkPluginPtr > PluginData
ctkPluginBrowser(PluginFrameworkManagerPtr framework)
Settings * settings()
Shortcut for accessing the settings instance.
boost::shared_ptr< class PluginFrameworkManager > PluginFrameworkManagerPtr
virtual ~ctkPluginBrowser()