62#include <QPluginLoader>
110 m_d->channelmanager=
this;
111 m_d->scheduler=sched;
118 while(!
m_d->uniquename_2_channel.empty())
121 std::map<QString,QPluginLoader*>::const_iterator it, itE =
m_d->pluginfile_2_pluginloader.end();
122 for(it=
m_d->pluginfile_2_pluginloader.begin();it!=itE;++it)
125 for (QObject* o :
m_d->additionalOwnedObjects)
135 assert(
m_d->uniquename_2_channel.find(channeluniquename)!=
m_d->uniquename_2_channel.end());
137 QString bn = cw->
name();
138 assert(
m_d->basename_2_channels.find(bn)!=
m_d->basename_2_channels.end());
141 assert(
m_d->basename_2_channels[bn].find(cw)!=
m_d->basename_2_channels[bn].end());
142 m_d->basename_2_channels[bn].erase(
m_d->basename_2_channels[bn].find(cw));
143 m_d->uniquename_2_channel.erase(
m_d->uniquename_2_channel.find(channeluniquename));
145 m_d->scheduler->uncreateAndDelete(cw);
154 assert(
m_d->channel_2_controller.find(cw)!=
m_d->channel_2_controller.end());
155 m_d->channel_2_controller[cw]->deleteLater();
156 m_d->channel_2_controller.erase(
m_d->channel_2_controller.find(cw));
157 assert(
m_d->channel_2_controller.find(cw)==
m_d->channel_2_controller.end());
161 std::set<IVP1ChannelWidget*>::iterator it =
m_d->basename_2_channels[bn].begin();
162 std::set<IVP1ChannelWidget*>::iterator itE =
m_d->basename_2_channels[bn].end();
163 for (;it!=itE;++it) {
164 assert(
m_d->uniquename_2_channel.find((*it)->unique_name())!=
m_d->uniquename_2_channel.end());
165 m_d->uniquename_2_channel.erase(
m_d->uniquename_2_channel.find((*it)->unique_name()));
168 it =
m_d->basename_2_channels[bn].begin();
170 for (;it!=itE;++it) {
171 (*it)->setCloneID(
id++);
172 (*it)->unique_name();
173 assert(
m_d->uniquename_2_channel.find((*it)->unique_name())==
m_d->uniquename_2_channel.end());
174 m_d->uniquename_2_channel[(*it)->unique_name()]=(*it);
178 m_d->emit_basename_availableUnusedChannelListChanged();
188 if (
m_d->pluginfile_2_pluginloader.find(filename)==
m_d->pluginfile_2_pluginloader.end())
191 assert(
m_d->pluginfile_2_basenamesAndFactory.find(filename)!=
m_d->pluginfile_2_basenamesAndFactory.end());
192 assert(
m_d->pluginfile_2_pluginloader.find(filename)!=
m_d->pluginfile_2_pluginloader.end());
197 QPluginLoader* loader =
m_d->pluginfile_2_pluginloader[filename];
200 for (
const QString& bn : bns)
208 bool success = loader->unload();
212 m_d->pluginfile_2_basenamesAndFactory.erase(
m_d->pluginfile_2_basenamesAndFactory.find(filename));
213 m_d->pluginfile_2_pluginloader.erase(
m_d->pluginfile_2_pluginloader.find(filename));
214 for (
const QString& bn : bns) {
215 m_d->basename_2_channels.erase(
m_d->basename_2_channels.find(bn));
216 m_d->basename_2_pluginfile.erase(
m_d->basename_2_pluginfile.find(bn));
221 m_d->emit_basename_availableChannelListChanged();
222 m_d->emit_basename_availableUnusedChannelListChanged();
234 QString bn = QFileInfo(filename).fileName();
236 if (
m_d->pluginfile_2_basenamesAndFactory.find(filename)!=
m_d->pluginfile_2_basenamesAndFactory.end()) {
237 return "Error: Plugin already loaded.";
241 QFileInfo fi(filename);
243 return "File does not exist";
244 if (!fi.isReadable())
245 return "File is not readable";
251 QString pluginAbsPath = fi.absoluteFilePath();
253 QPluginLoader * loader =
new QPluginLoader(pluginAbsPath);
254 m_d->pluginfile_2_pluginloader[filename]=loader;
256 bool loadOk = loader->load();
259 VP1Msg::message(
"ERROR! Failed to load plugin. Error message: "+loader->errorString());
280 pluginAbsPath.replace(
"opt",
"dbg");
282 loader =
new QPluginLoader(pluginAbsPath);
283 loadOk = loader->load();
285 if (loadOk)
VP1Msg::message(
"Ok! 'dbg' build of the plugin successfully loaded!");
291 QObject *plugin = loader->instance();
296 bool error = loader->errorString().isNull();
299 QString errStr =
"ERROR!!";
301 errStr = QString(
"Did not find any compatible plugins in file");
303 errStr = loader->errorString();
311 m_d->additionalOwnedObjects << plugin;
315 return "Did not find any channel factory in plugin file";
321 if (providedbasenames.count()==0)
322 return "Found channel factory in plugin file, but no advertised channels!";
325 m_d->pluginfile_2_basenamesAndFactory[filename] = std::pair<QStringList,IVP1ChannelWidgetFactory *>(providedbasenames,fact);
328 for (
const QString& bn : providedbasenames) {
329 if (
m_d->basename_2_pluginfile.find(bn)!=
m_d->basename_2_pluginfile.end())
330 return "Channels navp1 '"+bn+
"' are already provided by plugin file "
331 +
m_d->basename_2_pluginfile[bn]+
" (ignoring other plugins in file '"+filename+
"')";
335 for (
const QString& bn : providedbasenames) {
336 m_d->basename_2_pluginfile[bn] = filename;
337 m_d->basename_2_channels[bn] = std::set<IVP1ChannelWidget*>();
341 m_d->emit_basename_availableChannelListChanged();
342 m_d->emit_basename_availableUnusedChannelListChanged();
349 m_d->mainwindow->addToMessageBox(
"Successfully loaded "+bn,
"color:#008b00" );
351 m_d->mainwindow->addToMessageBox( out,
"color:#008b00" );
359 if (
m_d->pluginfile_2_basenamesAndFactory.find(filename)==
m_d->pluginfile_2_basenamesAndFactory.end())
360 return QStringList();
361 return m_d->pluginfile_2_basenamesAndFactory[filename].first;
367 err =
"Did not find plugin providing channel named '"+channelbasename+
"'";
376 err =
"Plugin file '"+plf+
"' did not provide channel navp1 '"+channelbasename+
"' despite advertising this capability!";
382 if (channelbasename!=cw->
name()) {
383 err =
"Actual basename of channel widget constructed by factory is not the one requested: '"+cw->
name()
384 +
"' vs. '"+channelbasename+
"'. This is most likely due to a mistake in the plugin!!";
407 cw->setUpdatesEnabled(
false);
409 assert(
m_d->uniquename_2_channel.find(cw->
unique_name())==
m_d->uniquename_2_channel.end());
411 m_d->basename_2_channels[channelbasename].insert(cw);
414 m_d->scheduler->bringFromConstructedToReady(cw);
417 assert(
m_d->channel_2_controller.find(cw)==
m_d->channel_2_controller.end());
419 QScrollArea * scrollarea =
new QScrollArea;
421 scrollarea->setObjectName(
"VP1ControllerScrollArea");
422 scrollarea->setWidgetResizable(
true);
423 scrollarea->setFrameShape(QFrame::NoFrame);
424 scrollarea->setFrameShadow(QFrame::Plain);
428 scrollarea->setWidget(controller);
429 m_d->channel_2_controller[cw] = scrollarea;
432 m_d->emit_basename_availableUnusedChannelListChanged();
434 cw->setUpdatesEnabled(
true);
441 assert(
m_d->channel_2_controller.find(cw)!=
m_d->channel_2_controller.end());
442 return m_d->channel_2_controller[cw];
447 if (
m_d->basename_2_channels.find(channelbasename)==
m_d->basename_2_channels.end())
449 return m_d->basename_2_channels[channelbasename].size();
456 if (
m_d->uniquename_2_channel.find(uniquename)==
m_d->uniquename_2_channel.end())
458 return m_d->uniquename_2_channel[uniquename];
463 return (
m_d->uniquename_2_channel.find(uniquename)!=
m_d->uniquename_2_channel.end());
468 return (
m_d->basename_2_pluginfile.find(
basename)!=
m_d->basename_2_pluginfile.end());
474 std::map<QString,IVP1ChannelWidget*>::iterator it =
m_d->uniquename_2_channel.begin();
475 std::map<QString,IVP1ChannelWidget*>::iterator itE =
m_d->uniquename_2_channel.end();
490 for (;it!=itE;++it) {
500 std::map<QString,QString>::const_iterator it =
m_d->basename_2_pluginfile.begin();
501 std::map<QString,QString>::const_iterator itE =
m_d->basename_2_pluginfile.end();
502 for (;it!=itE;++it) {
514 for (;it!=itE;++it) {
524 std::map<QString,std::pair<QStringList,IVP1ChannelWidgetFactory *> >
::const_iterator
525 it, itE =
m_d->pluginfile_2_basenamesAndFactory.end();
528 for( it =
m_d->pluginfile_2_basenamesAndFactory.begin(); it!=itE; ++it ) {
529 l<<QFileInfo(it->first).fileName();
536 std::map<QString,QPluginLoader*>::const_iterator it =
m_d->pluginfile_2_pluginloader.begin();
537 std::map<QString,QPluginLoader*>::const_iterator itE =
m_d->pluginfile_2_pluginloader.end();
548 if (
m_d->basename_2_channels.find(
basename)==
m_d->basename_2_channels.end())
549 return QStringList();
551 std::set<IVP1ChannelWidget*>::const_iterator it =
m_d->basename_2_channels[
basename].begin();
552 std::set<IVP1ChannelWidget*>::const_iterator itE =
m_d->basename_2_channels[
basename].end();
555 for (;it!=itE;++it) {
556 l << (*it)->unique_name();
563 if (
m_d->basename_2_channels.find(
basename)==
m_d->basename_2_channels.end())
565 return !
m_d->basename_2_channels[
basename].empty();
594 return m_d->channelTypeToIconLocation(cw->
type());
597 if (
m_d->basename2iconlocation.contains(channelname))
598 return m_d->basename2iconlocation[channelname];
610 assert(
m_d->channel_2_controller.find(cw)==
m_d->channel_2_controller.end());
613 if (
m_d->basename2iconlocation.contains(channelname))
614 return m_d->basename2iconlocation[channelname];
std::map< QString, std::set< IVP1ChannelWidget * > > basename_2_channels
void emit_basename_availableChannelListChanged()
VP1MainWindow * mainwindow
std::map< QString, std::pair< QStringList, IVP1ChannelWidgetFactory * > > pluginfile_2_basenamesAndFactory
void emit_basename_availableUnusedChannelListChanged()
QString channelTypeToIconLocation(const IVP1ChannelWidget::Type &type) const
std::map< IVP1ChannelWidget *, QWidget * > channel_2_controller
QList< QObject * > additionalOwnedObjects
std::map< QString, QPluginLoader * > pluginfile_2_pluginloader
QMap< QString, QString > basename2iconlocation
VP1ExecutionScheduler * scheduler
std::map< QString, QString > basename_2_pluginfile
std::map< QString, IVP1ChannelWidget * > uniquename_2_channel
IVP1ChannelWidget * constructChannel(const QString &channelbasename, QString &err, bool init=true)
VP1ChannelManager * channelmanager
QStringList basename2UniqueNames(const QString &basename) const
bool hasRefreshingSystem(const QString &uniquename) const
bool baseNameExists(const QString &) const
bool uniqueNameExists(const QString &) const
QStringList serializePluginInfo() const
bool channelWithBasenameIsLoaded(const QString &basename) const
QStringList channelsInPluginFile(const QString &filename) const
bool deleteChannel(const QString &channeluniquename)
void channelUncreated(IVP1ChannelWidget *)
IVP1ChannelWidget * getChannel(const QString &channelbasename, QString &err)
QString loadPluginFile(const QString &filename)
QStringList currentPluginFiles() const
QString getIconLocation(const QString &channelname, const bool &isbasename=true)
bool unloadPluginFile(const QString &filename)
unsigned nActive(const QString &channelbasename) const
QWidget * getController(IVP1ChannelWidget *)
VP1ChannelManager(VP1ExecutionScheduler *, VP1MainWindow *)
QStringList uniquenames() const
void uniquename_channelListChanged(const QStringList &)
QStringList availableChannelList()
IVP1ChannelWidget * uniqueName2Channel(const QString &uniquename) const
void newChannelCreated(IVP1ChannelWidget *)
static void messageVerbose(const QString &)
static void message(const QString &, IVP1System *sys=0)
std::string basename(std::string name)