mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-20 04:14:27 -04:00
ccc
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1031 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
98911955d5
commit
b94e6f6386
7 changed files with 486 additions and 623 deletions
|
@ -7,31 +7,45 @@
|
||||||
#include <QWidget> //a strange thing: it compiles without this header, but
|
#include <QWidget> //a strange thing: it compiles without this header, but
|
||||||
//then segfaults in some place
|
//then segfaults in some place
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
#include "PluginManager.h"
|
#include "PluginManager.h"
|
||||||
|
#include "PluginManagerWidget.h"
|
||||||
#include "plugins/PluginInterface.h"
|
#include "plugins/PluginInterface.h"
|
||||||
|
#include "rshare.h"
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
//=============================================================================
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
PluginManager::PluginManager()
|
PluginManager::PluginManager()
|
||||||
{
|
{
|
||||||
|
baseFolder = //qApp->applicationDirPath()+"///plugins" ;
|
||||||
|
Rshare::dataDirectory() + "/plugins" ;
|
||||||
|
lastError = "No error.";
|
||||||
|
|
||||||
|
viewWidget = 0;
|
||||||
|
|
||||||
|
// defaultLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginManager::defaultLoad( QString baseDir )
|
PluginManager::defaultLoad( )
|
||||||
{
|
{
|
||||||
QDir workDir(baseDir);
|
qDebug() << " " << "Default load started" ;
|
||||||
/* //=== find a file with last loaded plugins =====
|
|
||||||
QStringList lastLoaded;
|
|
||||||
QFile llFile( workDir.absolutePath()+"last_loaded.txt" ) ;
|
|
||||||
if ( llFile.open(QIODevice::ReadOnly) )
|
|
||||||
{
|
|
||||||
QString tmps;
|
|
||||||
QTextStream stream( &llFile ); // Set the stream to read from myFile
|
|
||||||
tmps = stream.readLine();
|
|
||||||
|
|
||||||
lastLoaded = tmps.split(";");
|
QDir workDir(baseFolder);
|
||||||
llFile.close();
|
|
||||||
|
if ( !workDir.exists() )
|
||||||
|
{
|
||||||
|
QString em= QString("base folder %1 doesn't exist, default load failed")
|
||||||
|
.arg( baseFolder );
|
||||||
|
emit errorAppeared( em );
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
//=== get current available plugins =====
|
//=== get current available plugins =====
|
||||||
QStringList currAvailable = workDir.entryList(QDir::Files);
|
QStringList currAvailable = workDir.entryList(QDir::Files);
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
|
@ -49,7 +63,12 @@ PluginManager::defaultLoad( QString baseDir )
|
||||||
foreach(QString pluginFileName, currAvailable)
|
foreach(QString pluginFileName, currAvailable)
|
||||||
{
|
{
|
||||||
QString fullfn( workDir.absoluteFilePath( pluginFileName ) );
|
QString fullfn( workDir.absoluteFilePath( pluginFileName ) );
|
||||||
readPluginFromFile( fullfn);
|
QString newName;
|
||||||
|
int ti = readPluginInformation( fullfn, newName);
|
||||||
|
if (! ti )
|
||||||
|
{
|
||||||
|
acceptPlugin(fullfn, newName);
|
||||||
|
}
|
||||||
}// foreach(QString pluginFileName, currAvailable)
|
}// foreach(QString pluginFileName, currAvailable)
|
||||||
|
|
||||||
qDebug() << " " << "names are " << names;
|
qDebug() << " " << "names are " << names;
|
||||||
|
@ -57,58 +76,34 @@ PluginManager::defaultLoad( QString baseDir )
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void
|
int
|
||||||
PluginManager::readPluginFromFile(QString fullFileName)
|
PluginManager::readPluginInformation(QString fullFileName, QString& pluginName)
|
||||||
{
|
{
|
||||||
qDebug() << " " << "processing file " << fullFileName;
|
qDebug() << " " << "processing file " << fullFileName;
|
||||||
|
|
||||||
QString errMess;
|
PluginInterface* plugin = loadPluginInterface(fullFileName) ;
|
||||||
PluginInterface* plugin = loadPluginInterface(fullFileName, errMess) ;
|
pluginName = "Undefined name" ;
|
||||||
|
|
||||||
QString plName = "Name undefined" ;
|
|
||||||
QWidget* plWidget = 0;
|
|
||||||
if (plugin)
|
if (plugin)
|
||||||
{
|
{
|
||||||
plName = plugin->pluginName();
|
pluginName = plugin->pluginName();
|
||||||
qDebug() << " " << "got pluginName:" << plName;
|
qDebug() << " " << "got pluginName:" << pluginName;
|
||||||
/*
|
|
||||||
//=== load widget (only if this plugin was loaded last time)
|
|
||||||
if ( lastLoaded.indexOf( pluginFileName) >= 0)
|
|
||||||
{
|
|
||||||
plWidget = plugin->pluginWidget() ;
|
|
||||||
if (plWidget)
|
|
||||||
{
|
|
||||||
// all was good,
|
|
||||||
qDebug() << " " << "got widget..." ;
|
|
||||||
emit loadDone( plName, plWidget);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errMess = "Plugin Object can't create widget" ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
delete plugin;
|
delete plugin;
|
||||||
|
return 0 ;
|
||||||
names.append(plName);
|
|
||||||
// int tpi = (int)plWidget;
|
|
||||||
widgets.append(plWidget);
|
|
||||||
fileNames.append(fullFileName);
|
|
||||||
|
|
||||||
emit installComplete(plName);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emit installFailed( plName, errMess);
|
//do not emit anything, cuz error message already was sent
|
||||||
|
//from loadPluginInterface(..)
|
||||||
|
return 1; //this means, some rrror appeared
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
PluginInterface*
|
PluginInterface*
|
||||||
PluginManager::loadPluginInterface(QString fileName, QString& errorMessage)
|
PluginManager::loadPluginInterface(QString fileName)
|
||||||
{
|
{
|
||||||
errorMessage = "Default Error Message" ;
|
QString errorMessage = "Default Error Message" ;
|
||||||
PluginInterface* plugin = 0 ;
|
PluginInterface* plugin = 0 ;
|
||||||
QPluginLoader* plLoader = new QPluginLoader(fileName);
|
QPluginLoader* plLoader = new QPluginLoader(fileName);
|
||||||
|
|
||||||
|
@ -125,172 +120,208 @@ PluginManager::loadPluginInterface(QString fileName, QString& errorMessage)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errorMessage = "Cast to 'PluginInterface*' failed";
|
errorMessage = "Cast to 'PluginInterface*' failed";
|
||||||
|
emit errorAppeared( errorMessage );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errorMessage = "Istance wasn't created: " + plLoader->errorString() ;
|
errorMessage = "Istance wasn't created: " + plLoader->errorString() ;
|
||||||
|
emit errorAppeared( errorMessage );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
delete plLoader; // plugin instance will not be deleted with this action
|
delete plLoader; // plugin instance will not be deleted with this action
|
||||||
|
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
plName = plugin->pluginName();
|
|
||||||
// names.append(plddName);
|
|
||||||
qDebug() << " " << "got pluginName:" << plName;
|
|
||||||
|
|
||||||
//=== load widget (only if this plugin was loaded last time)
|
|
||||||
if ( lastLoaded.indexOf( pluginFileName) >= 0)
|
|
||||||
{
|
|
||||||
QWidget* pw = plugin->pluginWidget() ;
|
|
||||||
if (pw)
|
|
||||||
{
|
|
||||||
// all was good,
|
|
||||||
qDebug() << " " << "got widget..." ;
|
|
||||||
plState = PS_Loaded;
|
|
||||||
emit loadDone( plName, pw);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errMess = "Plugin Object can't create widget" ;
|
|
||||||
plState = PS_Failed ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plState = PS_Viewed ; //this is no error, all's normal
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// delete pluginObject;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errMess = "Instance wasn't created: " + plLoader->errorString() ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
PluginManager:: ~PluginManager()
|
PluginManager:: ~PluginManager()
|
||||||
{
|
|
||||||
// delete all widgets
|
|
||||||
foreach(QWidget* wp, widgets)
|
|
||||||
{
|
|
||||||
if (wp)
|
|
||||||
delete wp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
QStringList
|
|
||||||
PluginManager::availablePlugins()
|
|
||||||
{
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
QStringList
|
|
||||||
PluginManager::loadedPlugins()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
PluginManager::isLoaded(QString pluginName)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginManager::loadPlugin(QString pluginName)
|
PluginManager::acceptPlugin(QString fileName, QString pluginName)
|
||||||
{
|
{
|
||||||
qDebug() << "" << "PluginManager::loadPlugin called for" << pluginName;
|
qDebug() << " " << "accepting plugin " << pluginName;
|
||||||
|
|
||||||
|
names.append(pluginName);
|
||||||
|
fileNames.append(fileName);
|
||||||
|
|
||||||
|
if (viewWidget)
|
||||||
|
viewWidget->registerNewPlugin( pluginName );
|
||||||
|
|
||||||
|
emit newPluginRegistered( pluginName );
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
QWidget*
|
||||||
|
PluginManager::pluginWidget(QString pluginName)
|
||||||
|
{
|
||||||
|
QWidget* result = 0;
|
||||||
int plIndex = names.indexOf( pluginName ) ;
|
int plIndex = names.indexOf( pluginName ) ;
|
||||||
if (plIndex >=0 )
|
if (plIndex >=0 )
|
||||||
{
|
{
|
||||||
QWidget* plWidget = widgets.at(plIndex);
|
//=== load plugin's interface
|
||||||
//=== first, check if we loaded it before
|
|
||||||
if ( plWidget )
|
|
||||||
{
|
|
||||||
emit loadFailed( pluginName,
|
|
||||||
"Error: plugin already loaded") ;
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=== next, load it's interface
|
|
||||||
QString fn = fileNames.at(plIndex);
|
QString fn = fileNames.at(plIndex);
|
||||||
QString errMess;
|
PluginInterface* pliface = loadPluginInterface(fn);
|
||||||
PluginInterface* pliface = loadPluginInterface(fn, errMess);
|
|
||||||
if (pliface)
|
if (pliface)
|
||||||
{
|
{
|
||||||
//=== now, get a widget
|
//=== now, get a widget
|
||||||
plWidget = pliface->pluginWidget() ;
|
result = pliface->pluginWidget() ;
|
||||||
if (plWidget)
|
if (result)
|
||||||
{
|
{
|
||||||
// all was good,
|
// all was good,
|
||||||
qDebug() << " " << "got plg widget..." ;
|
qDebug() << " " << "got plg widget..." ;
|
||||||
emit loadDone( pluginName, plWidget );
|
return result;
|
||||||
widgets[plIndex] = plWidget;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emit loadFailed(pluginName,
|
QString em=QString("Error: instance '%1'can't create a widget")
|
||||||
"Error: instance can't create a widget");
|
.arg( pluginName );
|
||||||
return;
|
emit errorAppeared( em );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emit loadFailed( pluginName,
|
// do nothing here...
|
||||||
tr("Error: failed to load interface for ")
|
|
||||||
+ pluginName +"("+errMess+")");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emit loadFailed( pluginName,
|
QString em = QString("Error: no plugin with name '%1' found")
|
||||||
tr("Error: know nothing about plugin ") + pluginName );
|
.arg(pluginName);
|
||||||
|
emit errorAppeared( em );
|
||||||
qDebug() << " " << "error: request to load " << pluginName
|
}
|
||||||
<< " failed (unknown file)" ;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
QWidget*
|
||||||
|
PluginManager::getViewWidget(QWidget* parent )
|
||||||
|
{
|
||||||
|
if (viewWidget)
|
||||||
|
return viewWidget;
|
||||||
|
|
||||||
|
//=== else, create the viewWidget and return it
|
||||||
|
//
|
||||||
|
viewWidget = new PluginManagerWidget();
|
||||||
|
|
||||||
|
foreach(QString pn, names)
|
||||||
|
{
|
||||||
|
qDebug() << " " << "reg new plg " << pn;
|
||||||
|
viewWidget->registerNewPlugin( pn );
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(this , SIGNAL( errorAppeared(QString) ) ,
|
||||||
|
viewWidget, SLOT( acceptErrorMessage( QString)));
|
||||||
|
|
||||||
|
connect(viewWidget, SIGNAL( destroyed() ) ,
|
||||||
|
this , SLOT( viewWidgetDestroyed( )));
|
||||||
|
|
||||||
|
connect(viewWidget, SIGNAL( installPluginRequested(QString)),
|
||||||
|
this , SLOT( installPlugin( QString)));
|
||||||
|
|
||||||
|
connect(viewWidget, SIGNAL( removeRequested( QString ) ),
|
||||||
|
this , SLOT( removePlugin(QString )));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
qDebug() << " PluginManager::getViewWidget done";
|
||||||
|
|
||||||
|
return viewWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginManager::unloadPlugin(QString pluginName)
|
PluginManager::viewWidgetDestroyed(QObject* obj )
|
||||||
{
|
{
|
||||||
qDebug() << " " << "PluginManager::unloadPlugin called for" << pluginName;
|
qDebug() << " PluginManager::viewWidgetDestroyed is here";
|
||||||
|
|
||||||
|
viewWidget = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginManager::removePlugin(QString pluginName)
|
||||||
|
{
|
||||||
|
QWidget* result = 0;
|
||||||
int plIndex = names.indexOf( pluginName ) ;
|
int plIndex = names.indexOf( pluginName ) ;
|
||||||
if (plIndex >=0 )
|
if (plIndex >=0 )
|
||||||
{
|
{
|
||||||
QWidget* plWidget = widgets.at(plIndex);
|
QString fn = fileNames.at(plIndex);
|
||||||
qDebug() << "in pm is " << (void *)plWidget;
|
if (QDir::isRelativePath(fn))
|
||||||
if ( plWidget )
|
fn = QDir(baseFolder).path() + QDir::separator() + fn ;
|
||||||
{ //
|
|
||||||
widgets[plIndex] = 0;//(QWidget*)0;
|
QFile fl(fn);
|
||||||
qDebug() << "111" ;
|
if (!fl.remove())
|
||||||
delete plWidget;
|
{
|
||||||
qDebug() << "222" ;
|
QString em = QString("Error: failed to revove file %1"
|
||||||
|
"(uninstalling plugin '%2')")
|
||||||
|
.arg(fn).arg(pluginName);
|
||||||
|
emit errorAppeared( em);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (viewWidget)
|
||||||
|
viewWidget->removePluginFrame( pluginName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString em = QString("Error(uninstall): no plugin with name '%1' found")
|
||||||
|
.arg(pluginName);
|
||||||
|
emit errorAppeared( em );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginManager::installPlugin(QString fileName)
|
||||||
|
{
|
||||||
|
qDebug() << " " << "PluginManager::installPlugin is here" ;
|
||||||
|
|
||||||
|
if (!QFile::exists( fileName) )
|
||||||
|
{
|
||||||
|
QString em = QString("Error(installation): flugin file %1 doesn't exist")
|
||||||
|
.arg( fileName );
|
||||||
|
|
||||||
|
emit errorAppeared( em );
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString pn;
|
||||||
|
if (! readPluginInformation(fileName, pn))
|
||||||
|
{
|
||||||
|
QFile sf( fileName) ;
|
||||||
|
QString newFileName = baseFolder + QDir::separator() +
|
||||||
|
QFileInfo( fileName).fileName();
|
||||||
|
if ( QFile::copy( fileName, newFileName ) )
|
||||||
|
{
|
||||||
|
QString pn;
|
||||||
|
int ti = readPluginInformation( newFileName , pn );
|
||||||
|
if (! ti )
|
||||||
|
{
|
||||||
|
acceptPlugin(newFileName, pn);
|
||||||
|
}
|
||||||
|
} //
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString em = QString("Error: can't copy %1 as %2")
|
||||||
|
.arg(fileName, newFileName) ;
|
||||||
|
emit errorAppeared( em );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// do nothing here: read plugin information emits its own error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,14 @@
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
class PluginInterface;
|
class PluginInterface;
|
||||||
|
class PluginManagerWidget;
|
||||||
|
|
||||||
|
//! An engine for plugins management
|
||||||
|
|
||||||
|
//! This class performs oaa plugin management operations: installing,
|
||||||
|
//! loading, remowing. it also provides a PluginManagerWidget for controlling
|
||||||
|
//! itself. I supose, a appication has to create a global instance of the class,
|
||||||
|
//! so all pages (instances of the MainPage class) could receive plugin widgets.
|
||||||
class PluginManager: public QObject
|
class PluginManager: public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -21,37 +28,96 @@ public:
|
||||||
PluginManager();
|
PluginManager();
|
||||||
~PluginManager();
|
~PluginManager();
|
||||||
|
|
||||||
void defaultLoad(QString baseDir = "");
|
//! Checks up 'plugins' folder for loadable plugins
|
||||||
|
|
||||||
QStringList availablePlugins();
|
//! This is a separate method, becouse an application should create
|
||||||
QStringList loadedPlugins();
|
//! a PluginManager instance, then connect all its signals, optionally
|
||||||
|
//! create a view widget, and only after all perform lookup
|
||||||
|
void defaultLoad( ) ;
|
||||||
|
|
||||||
bool isLoaded(QString pluginName);
|
//! GUI for the loader.
|
||||||
void unloadPlugin(QString pluginName);
|
|
||||||
|
//! Returns a PluginManagerWidget instance. When called for the first time,
|
||||||
|
//! creates a new object; after that returns pointer to the same instance.
|
||||||
|
//! After the instance was deleteted (it could be safely done in usual way)
|
||||||
|
//! may create a new one.
|
||||||
|
QWidget* getViewWidget(QWidget* parent = 0);
|
||||||
|
|
||||||
|
//! Loads a widget of the plugin with given name
|
||||||
|
|
||||||
|
//! Loads a new copy (called twice will return different objects) of the
|
||||||
|
//! plugin widget. If there is no plugin with given name, returns 0 (also
|
||||||
|
//! emits errorAppeared(..) with an error description).
|
||||||
|
//! PluginManager provides ablolutely no control over returned widget;
|
||||||
|
//! the application should delete it, like all other widgets
|
||||||
|
QWidget* pluginWidget(QString pluginName);
|
||||||
|
|
||||||
|
//! returns last error appeared;
|
||||||
|
|
||||||
|
//! Sorry, doesn't work in current implementation
|
||||||
|
QString getLastError();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void loadPlugin(QString pluginName);
|
//! processes the desctucrion of the view widget;
|
||||||
void readPluginFromFile(QString fullFileName);
|
void viewWidgetDestroyed(QObject * obj = 0);
|
||||||
// void loadPluginFromFile(QString fileName);
|
|
||||||
|
|
||||||
|
//! processes the plugin installation request
|
||||||
|
|
||||||
|
//! After successful installatio a newPluginRegistered(..) signal will be
|
||||||
|
//! emitted. On some error -- errorAppeared(..) will be emitted;
|
||||||
|
//! 'Installation' means that plgin file (dll or so) will be checked and
|
||||||
|
//! copied to the 'plugins' directory. Later, in pluginWidget(..) call this
|
||||||
|
//! copy will be used
|
||||||
|
void installPlugin(QString fileName);
|
||||||
|
|
||||||
|
//! Processes plugin remove request
|
||||||
|
|
||||||
|
//! 'Remove' means that plugin file (so or dll) will be physically deleted
|
||||||
|
//! from 'plugins' folder.
|
||||||
|
void removePlugin(QString pluginName);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void loadDone(QString pluginName, QWidget* pluginWidget);
|
//! PluginManager emits this signal on every error;
|
||||||
void loadFailed(QString pluginName, QString errorMessage);
|
|
||||||
void installComplete(QString pluginName);
|
//! This signal is connected to the PluginManagerWidget::acceptErrorMessage.
|
||||||
void installFailed(QString pluginFileName, QString errorMessage);
|
//! So, all error messages will appear on the view widget (only if that one
|
||||||
|
//! was created, of course)
|
||||||
|
void errorAppeared(QString errorDescription);
|
||||||
|
|
||||||
|
//! Is emitted after plugin removing;
|
||||||
|
|
||||||
|
//! Already loaded plugin widgets, will not be deleted. Nobody will touch
|
||||||
|
//! them
|
||||||
|
void pluginRemoveCompleted(QString pluginName);
|
||||||
|
|
||||||
|
//! Is emitted for every loadable plugin
|
||||||
|
|
||||||
|
void newPluginRegistered(QString pluginName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
PluginManagerWidget* viewWidget;
|
||||||
|
|
||||||
//QList<QPluginLoader*> loaders;
|
|
||||||
QList<QWidget*> widgets;
|
|
||||||
// QList<int> widgets;
|
|
||||||
QStringList fileNames;
|
QStringList fileNames;
|
||||||
QList<QString> names;
|
QStringList names;
|
||||||
// QList<int> states;
|
|
||||||
|
|
||||||
PluginInterface* loadPluginInterface(QString fileName,
|
QString baseFolder;
|
||||||
QString& errorMessage) ;
|
QString lastError;
|
||||||
|
|
||||||
|
//! Reads information from plugin file
|
||||||
|
|
||||||
|
//! The function tries to read the info from the plugin file (in current
|
||||||
|
//! implementation only pluginName).
|
||||||
|
//! \returns 0 on success, error code (>0) on fail
|
||||||
|
int readPluginInformation( QString fileName, QString& pluginName);
|
||||||
|
|
||||||
|
//! ---
|
||||||
|
|
||||||
|
//! Adds plugin name and plugin filename to the lists, emits nesessary
|
||||||
|
//! signals, updates the view widget
|
||||||
|
void acceptPlugin( QString fileName, QString pluginName);
|
||||||
|
|
||||||
|
|
||||||
|
PluginInterface* loadPluginInterface(QString fileName ) ;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,21 +5,19 @@
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QTextEdit>
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "PluginManagerWidget.h"
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
PluginFrame::PluginFrame( QString pluginName, QWidget * parent)
|
||||||
enum {
|
|
||||||
LBS_Load , // load button state : load (it will send signal 'needToLoad')
|
|
||||||
LBS_Unload // load button state: unload
|
|
||||||
};
|
|
||||||
|
|
||||||
PluginFrame::PluginFrame(QWidget * parent, QString pluginName)
|
|
||||||
:QFrame(parent)
|
:QFrame(parent)
|
||||||
{
|
{
|
||||||
plgName = pluginName;
|
plgName = pluginName;
|
||||||
|
@ -31,20 +29,18 @@ PluginFrame::PluginFrame(QWidget * parent, QString pluginName)
|
||||||
nameLabel->setAlignment(Qt::AlignHCenter);
|
nameLabel->setAlignment(Qt::AlignHCenter);
|
||||||
labelsLay->addWidget(nameLabel);
|
labelsLay->addWidget(nameLabel);
|
||||||
descrLabel = new QLabel();
|
descrLabel = new QLabel();
|
||||||
descrLabel->setText("plugin description will appear here someday");
|
descrLabel->setText("# # # # # # # # # #");
|
||||||
|
// "plugin description will appear here someday");
|
||||||
descrLabel->setWordWrap(true);
|
descrLabel->setWordWrap(true);
|
||||||
labelsLay->addWidget(descrLabel);
|
labelsLay->addWidget(descrLabel);
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
buttonsLay = new QVBoxLayout() ;
|
buttonsLay = new QVBoxLayout() ;
|
||||||
loadBtn = new QPushButton;
|
|
||||||
loadBtn->setText( tr("Load") );
|
|
||||||
loadBtnState = LBS_Load;
|
|
||||||
connect( loadBtn, SIGNAL( clicked() ) ,
|
|
||||||
this , SLOT ( loadButtonClicked() ) );
|
|
||||||
buttonsLay->addWidget( loadBtn );
|
|
||||||
removeBtn = new QPushButton() ;
|
removeBtn = new QPushButton() ;
|
||||||
removeBtn->setText( tr("Remove") ) ;
|
removeBtn->setText( tr("Remove") ) ;
|
||||||
|
connect( removeBtn, SIGNAL( clicked() ) ,
|
||||||
|
this , SLOT ( removeButtonClicked() ) ) ;
|
||||||
buttonsLay->addWidget( removeBtn ) ;
|
buttonsLay->addWidget( removeBtn ) ;
|
||||||
|
|
||||||
//all together
|
//all together
|
||||||
|
@ -53,10 +49,6 @@ PluginFrame::PluginFrame(QWidget * parent, QString pluginName)
|
||||||
mainLay->addLayout(buttonsLay);
|
mainLay->addLayout(buttonsLay);
|
||||||
|
|
||||||
this->setFrameStyle(QFrame::Box | QFrame::Raised);
|
this->setFrameStyle(QFrame::Box | QFrame::Raised);
|
||||||
|
|
||||||
|
|
||||||
//hlay->addWidget(lbl);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -68,25 +60,6 @@ PluginFrame::~PluginFrame()
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void
|
|
||||||
PluginFrame::loadButtonClicked()
|
|
||||||
{
|
|
||||||
if (loadBtnState == LBS_Load)
|
|
||||||
{
|
|
||||||
emit needToLoad(plgName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( loadBtnState == LBS_Unload)
|
|
||||||
{
|
|
||||||
emit needToUnload(plgName);
|
|
||||||
loadBtn->setText( tr("Load") );
|
|
||||||
loadBtnState = LBS_Load ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginFrame::removeButtonClicked()
|
PluginFrame::removeButtonClicked()
|
||||||
{
|
{
|
||||||
|
@ -95,17 +68,10 @@ PluginFrame::removeButtonClicked()
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void
|
QString
|
||||||
PluginFrame::successfulLoad(QString pluginName, QWidget* wd)
|
PluginFrame::getPluginName()
|
||||||
{
|
{
|
||||||
qDebug() << " " << "PluginFrame::successfulLoad for " << pluginName
|
return plgName ;
|
||||||
<< " -- " << plgName ;
|
|
||||||
if (pluginName == plgName )
|
|
||||||
{
|
|
||||||
qDebug() << "so...";
|
|
||||||
loadBtn->setText( tr("Unload") );
|
|
||||||
loadBtnState = LBS_Unload ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -115,40 +81,64 @@ PluginFrame::successfulLoad(QString pluginName, QWidget* wd)
|
||||||
PluginManagerWidget::PluginManagerWidget(QWidget * parent)
|
PluginManagerWidget::PluginManagerWidget(QWidget * parent)
|
||||||
:QFrame(parent)
|
:QFrame(parent)
|
||||||
{
|
{
|
||||||
vlay = new QVBoxLayout(this);
|
qDebug() << " " << "PluginManagerWidget::PluginManagerWidget here";
|
||||||
|
|
||||||
instPlgLay = new QHBoxLayout();
|
mainLayout = new QVBoxLayout(this);
|
||||||
instPlgButton = new QPushButton();
|
|
||||||
|
|
||||||
instPlgButton->setText("Install New Plugin...");
|
//===
|
||||||
connect( instPlgButton, SIGNAL( clicked() ),
|
installPluginLayout = new QHBoxLayout();
|
||||||
this , SLOT( instPlgButtonClicked() ) );
|
installPluginButton = new QPushButton();
|
||||||
instPlgLay->addWidget(instPlgButton);
|
|
||||||
instPlgSpacer = new QSpacerItem(283, 20,
|
installPluginButton->setText("Install New Plugin...");
|
||||||
|
connect( installPluginButton, SIGNAL( clicked() ),
|
||||||
|
this , SLOT( installPluginButtonClicked() ) );
|
||||||
|
installPluginLayout->addWidget(installPluginButton);
|
||||||
|
installPluginSpacer = new QSpacerItem(283, 20,
|
||||||
QSizePolicy::Expanding, QSizePolicy::Minimum);
|
QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
instPlgLay->addItem(instPlgSpacer);
|
installPluginLayout->addItem(installPluginSpacer);
|
||||||
|
|
||||||
vlay->addLayout( instPlgLay );
|
mainLayout->addLayout( installPluginLayout );
|
||||||
|
|
||||||
|
//===
|
||||||
|
pluginFramesContainer = new QFrame();
|
||||||
|
pluginFramesLayout = new QVBoxLayout(pluginFramesContainer);
|
||||||
|
|
||||||
|
mainLayout->addWidget(pluginFramesContainer);
|
||||||
|
|
||||||
|
//===
|
||||||
|
errorsConsole = new QTextEdit();
|
||||||
|
|
||||||
|
mainLayout->addWidget( errorsConsole );
|
||||||
|
|
||||||
|
qDebug() << " " << "PluginManagerWidget::PluginManagerWidget done";
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
PluginManagerWidget::~PluginManagerWidget()
|
PluginManagerWidget::~PluginManagerWidget()
|
||||||
{
|
{
|
||||||
|
//nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginManagerWidget::addPluginWidget(PluginFrame* pf)
|
PluginManagerWidget::registerNewPlugin(QString pluginName)
|
||||||
{
|
{
|
||||||
vlay->addWidget(pf);
|
qDebug() << " " << "PluginManagerWidget::registerNewPlugin "<< pluginName;
|
||||||
|
|
||||||
|
PluginFrame* pf = new PluginFrame(pluginName, pluginFramesContainer) ;
|
||||||
|
|
||||||
|
connect( pf , SIGNAL( needToRemove(QString)),
|
||||||
|
this, SIGNAL( removeRequested(QString) ) );
|
||||||
|
|
||||||
|
pluginFramesLayout->addWidget(pf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginManagerWidget::instPlgButtonClicked()
|
PluginManagerWidget::installPluginButtonClicked()
|
||||||
{
|
{
|
||||||
QString fileName = QFileDialog::getOpenFileName(this,
|
QString fileName = QFileDialog::getOpenFileName(this,
|
||||||
tr("Open Plugin to install"),
|
tr("Open Plugin to install"),
|
||||||
|
@ -156,7 +146,42 @@ PluginManagerWidget::instPlgButtonClicked()
|
||||||
tr("Plugins (*.so *.dll)"));
|
tr("Plugins (*.so *.dll)"));
|
||||||
if (!fileName.isNull())
|
if (!fileName.isNull())
|
||||||
{
|
{
|
||||||
emit needToLoadFileWithPlugin(fileName);
|
emit installPluginRequested(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginManagerWidget::removePluginFrame(QString pluginName)
|
||||||
|
{
|
||||||
|
foreach(QObject* ob, pluginFramesContainer->children())
|
||||||
|
{
|
||||||
|
PluginFrame* pf = qobject_cast<PluginFrame*> (ob);
|
||||||
|
if (pf)
|
||||||
|
{
|
||||||
|
if (pf->getPluginName() == pluginName )
|
||||||
|
{
|
||||||
|
pf->setParent(0);
|
||||||
|
delete pf;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// normally unreachable place
|
||||||
|
QString em = QString("Widget for plugin %1 not found on plugins frame")
|
||||||
|
.arg( pluginName ) ;
|
||||||
|
acceptErrorMessage( em );
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
void
|
||||||
|
PluginManagerWidget::acceptErrorMessage(QString errorMessage)
|
||||||
|
{
|
||||||
|
errorsConsole->append( errorMessage );
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ class QHBoxLayout;
|
||||||
class QVBoxLayout;
|
class QVBoxLayout;
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
class QSpacerItem;
|
class QSpacerItem;
|
||||||
|
class QTextEdit;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
@ -19,26 +20,20 @@ class PluginFrame : public QFrame
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PluginFrame(QWidget* parent , QString pluginName );
|
PluginFrame( QString pluginName, QWidget* parent =0 );
|
||||||
virtual ~PluginFrame();
|
virtual ~PluginFrame();
|
||||||
|
|
||||||
|
QString getPluginName();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void needToLoad(QString pluginName);
|
|
||||||
void needToUnload(QString pluginName);
|
|
||||||
void needToRemove(QString pluginName);
|
void needToRemove(QString pluginName);
|
||||||
|
|
||||||
public slots:
|
|
||||||
void successfulLoad(QString pluginName, QWidget* wd=0);
|
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void loadButtonClicked() ;
|
|
||||||
void removeButtonClicked();
|
void removeButtonClicked();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString plgName;
|
QString plgName;
|
||||||
|
|
||||||
QPushButton* loadBtn;
|
|
||||||
unsigned char loadBtnState;
|
|
||||||
QPushButton* removeBtn;
|
QPushButton* removeBtn;
|
||||||
QVBoxLayout* buttonsLay;
|
QVBoxLayout* buttonsLay;
|
||||||
|
|
||||||
|
@ -52,28 +47,46 @@ protected:
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
//! GUI representation of the PluginManager class
|
||||||
|
|
||||||
|
//! This is something like GUI for PluginManager class. Or you can think
|
||||||
|
//! about PluginManagerWidget as a view, and a PluginManager as a model.
|
||||||
|
//! Instances should be created only by PluginManager class; maybe later i'll
|
||||||
|
//! hide constructor in some way. Parent (or somebody else) can delete it.
|
||||||
|
//! Widget itself can be used anywere, in some 'settings' dialogs.
|
||||||
class PluginManagerWidget: public QFrame
|
class PluginManagerWidget: public QFrame
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PluginManagerWidget(QWidget* parent);
|
PluginManagerWidget(QWidget* parent =0);
|
||||||
virtual ~PluginManagerWidget();
|
virtual ~PluginManagerWidget();
|
||||||
|
|
||||||
void addPluginWidget(PluginFrame* pf);
|
void registerNewPlugin(QString pluginName);
|
||||||
|
void removePluginFrame(QString pluginName);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void needToLoadFileWithPlugin(QString fileName) ;
|
void removeRequested(QString pluginName);
|
||||||
|
void installPluginRequested(QString fileName) ;
|
||||||
|
|
||||||
protected:
|
public slots:
|
||||||
QVBoxLayout* vlay;
|
void acceptErrorMessage(QString errorMessage);
|
||||||
|
|
||||||
QPushButton* instPlgButton;
|
|
||||||
QHBoxLayout* instPlgLay;
|
|
||||||
QSpacerItem* instPlgSpacer;
|
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void instPlgButtonClicked();
|
|
||||||
|
protected:
|
||||||
|
QVBoxLayout* mainLayout;
|
||||||
|
QFrame* pluginFramesContainer;
|
||||||
|
QVBoxLayout* pluginFramesLayout;
|
||||||
|
|
||||||
|
QPushButton* installPluginButton;
|
||||||
|
QHBoxLayout* installPluginLayout;
|
||||||
|
QSpacerItem* installPluginSpacer;
|
||||||
|
|
||||||
|
QTextEdit* errorsConsole;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void installPluginButtonClicked();
|
||||||
};
|
};
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
|
@ -6,348 +6,74 @@
|
||||||
#include <QSizePolicy>
|
#include <QSizePolicy>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
|
|
||||||
#include <QtPlugin>
|
//#include <QtPlugin>
|
||||||
#include <QPluginLoader>
|
//#include <QPluginLoader>
|
||||||
#include <QDir>
|
//#include <QDir>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
|
|
||||||
#include <QApplication> // for qApp->....
|
//#include <QApplication> // for qApp->....
|
||||||
//#include <QUiLoader>
|
//#include <QFile>
|
||||||
//#include <QtScript>
|
|
||||||
#include <QFile>
|
|
||||||
//#include <QIODevice>
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
|
|
||||||
#include "PluginsPage.h"
|
#include "PluginsPage.h"
|
||||||
#include "PluginManagerWidget.h"
|
|
||||||
#include "PluginManager.h"
|
#include "PluginManager.h"
|
||||||
#include "rshare.h"
|
|
||||||
//#include "plugins/PluginInterface.h"
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
PluginsPage::PluginsPage(QWidget *parent )
|
PluginsPage::PluginsPage(QWidget *parent )
|
||||||
// :QGroupBox(parent)
|
// :QGroupBox(parent) // this is for toy applications, do not remove
|
||||||
:MainPage(parent)
|
:MainPage(parent) // this for real retroshare app
|
||||||
{
|
{
|
||||||
|
//===
|
||||||
|
pluginManager = new PluginManager();
|
||||||
|
connect( pluginManager, SIGNAL( newPluginRegistered(QString) ),
|
||||||
|
this , SLOT( pluginRegistered(QString) ) );
|
||||||
|
|
||||||
//=== create some gui elements =====
|
//=== create some gui elements =====
|
||||||
pluginPageLayout = new QVBoxLayout(this);
|
pluginPageLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
// pluginPanel = new QGroupBox(this) ;
|
|
||||||
// pluginPanel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding) ;
|
|
||||||
// this->setTitle("RetroShare plugins");
|
// this->setTitle("RetroShare plugins");
|
||||||
|
|
||||||
pluginTabs = new QTabWidget(this) ;
|
pluginTabs = new QTabWidget(this) ;
|
||||||
pluginPageLayout->addWidget(pluginTabs);
|
pluginPageLayout->addWidget(pluginTabs);
|
||||||
|
|
||||||
pmFrame = new QFrame;
|
pmFrame = new QFrame(this);
|
||||||
pmLay = new QVBoxLayout(pmFrame);
|
pmLay = new QVBoxLayout(pmFrame);
|
||||||
|
|
||||||
pluginManagerWidget = new PluginManagerWidget(pmFrame);
|
QWidget* tw = pluginManager->getViewWidget();
|
||||||
pmLay->addWidget( pluginManagerWidget );
|
|
||||||
|
pmLay->addWidget( tw );
|
||||||
|
|
||||||
pmSpacer = new QSpacerItem(283, 20,
|
pmSpacer = new QSpacerItem(283, 20,
|
||||||
QSizePolicy::Expanding, QSizePolicy::Minimum);
|
QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||||
pmLay->addItem(pmSpacer);
|
pmLay->addItem(pmSpacer);
|
||||||
|
|
||||||
errlogConsole = new QTextEdit();
|
|
||||||
pmLay->addWidget( errlogConsole );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pluginTabs->addTab( pmFrame, "Manager" ) ;
|
pluginTabs->addTab( pmFrame, "Manager" ) ;
|
||||||
|
|
||||||
// pluginTabs->addTab( errlogConsole, "Error messages" );
|
|
||||||
|
|
||||||
//=== try to load binary plugins =====
|
pluginManager->defaultLoad( ) ;
|
||||||
pluginManager = new PluginManager();
|
|
||||||
connect( pluginManager, SIGNAL( loadDone(QString, QWidget*) ),
|
|
||||||
this , SLOT( loadDone(QString, QWidget*) ) );
|
|
||||||
connect( pluginManager, SIGNAL(loadFailed(QString, QString)) ,
|
|
||||||
this , SLOT( loadFailed(QString, QString ) ) );
|
|
||||||
connect( pluginManagerWidget, SIGNAL( needToLoadFileWithPlugin(QString)),
|
|
||||||
pluginManager , SLOT( readPluginFromFile(QString) ) );
|
|
||||||
|
|
||||||
connect( pluginManager, SIGNAL( installComplete(QString) ),
|
|
||||||
this , SLOT( installComplete(QString) ) );
|
|
||||||
connect( pluginManager, SIGNAL(installFailed(QString, QString)) ,
|
|
||||||
this , SLOT( installFailed(QString, QString ) ) );
|
|
||||||
|
|
||||||
pluginManager->defaultLoad( Rshare::dataDirectory() + "/plugins" );
|
|
||||||
// a variant for a toy app: qApp->applicationDirPath()+"///plugins" ) ;
|
|
||||||
|
|
||||||
//QStringList lll = pluginManager->availablePlugins();
|
|
||||||
//foreach( QString pn, lll)
|
|
||||||
//{
|
|
||||||
// qDebug() << " " << "----" << pn << "----" ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
/*
|
|
||||||
QDir pluginsDir(qApp->applicationDirPath()+"///plugins");
|
|
||||||
if (pluginsDir.exists())
|
|
||||||
loadBinaryPlugins( pluginsDir );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << " " << "plugins will not be loaded: " << pluginsDir.absolutePath() ;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// pluginPageLayout->addWidget(pluginPanel);
|
|
||||||
/*
|
|
||||||
pluginPanelLayout = new QVBoxLayout(pluginPanel);
|
|
||||||
|
|
||||||
pluginTabs = new QTabWidget(pluginPanel);
|
|
||||||
pluginPanelLayout->addWidget(pluginTabs);
|
|
||||||
|
|
||||||
QLabel* lbl1 = new QLabel();
|
|
||||||
lbl1->setText("If you see only this tab, it's a bug :( If you see this tub and calculator, it's a bug too");
|
|
||||||
pluginTabs->addTab(lbl1, "LLL");//Rshare::dataDirectory());
|
|
||||||
//"L #1");
|
|
||||||
|
|
||||||
//QLabel* lbl2 = new QLabel();
|
|
||||||
//lbl2->setText("Label #2");
|
|
||||||
//pluginTabs->addTab(lbl2, "L #2; for debugging purposes");
|
|
||||||
|
|
||||||
QDir pluginsDir(Rshare::dataDirectory());
|
|
||||||
|
|
||||||
// this piece of code is magical and untested ;
|
|
||||||
// but on Windows it works
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
|
|
||||||
pluginsDir.cdUp();
|
|
||||||
#elif defined(Q_OS_MAC)
|
|
||||||
if (pluginsDir.dirName() == "MacOS") {
|
|
||||||
pluginsDir.cdUp();
|
|
||||||
pluginsDir.cdUp();
|
|
||||||
pluginsDir.cdUp();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// eof magick
|
|
||||||
|
|
||||||
pluginsDir.cd("plugins");
|
|
||||||
|
|
||||||
foreach (QString fileName, pluginsDir.entryList(QDir::Files))
|
|
||||||
{
|
|
||||||
qDebug() << " "
|
|
||||||
<< "processing file "
|
|
||||||
<< pluginsDir.absoluteFilePath(fileName);
|
|
||||||
|
|
||||||
QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
|
|
||||||
QObject *pluginObject = loader.instance();
|
|
||||||
if (pluginObject)
|
|
||||||
{
|
|
||||||
qDebug() << " " << "loaded..." ;
|
|
||||||
PluginInterface* plugin = qobject_cast<PluginInterface*> (pluginObject) ;
|
|
||||||
|
|
||||||
if (plugin)
|
|
||||||
{
|
|
||||||
QString pn = plugin->pluginName();
|
|
||||||
qDebug() << " " << "got description:" << pn;
|
|
||||||
|
|
||||||
QWidget* pw = plugin->pluginWidget();
|
|
||||||
qDebug() << " " << "got widget..." ;
|
|
||||||
|
|
||||||
pluginsDir.absoluteFilePath(fileName);
|
|
||||||
pluginTabs->addTab(pw,pn);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << " " << "cast failed..." ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// script plugins loading; warning, code is dirty; will be changed later
|
|
||||||
engine = new QScriptEngine;
|
|
||||||
|
|
||||||
pluginsDir.cd("../script_plugins");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
foreach (QString scriptDirName, pluginsDir.entryList(QDir::Dirs))
|
|
||||||
{
|
|
||||||
qDebug() << " " << "sdn is " << scriptDirName ;
|
|
||||||
if ( (scriptDirName !=".") && (scriptDirName != "..") )
|
|
||||||
{
|
|
||||||
QDir spDir(pluginsDir) ;
|
|
||||||
spDir.cd(scriptDirName);
|
|
||||||
QStringList scfList = spDir.entryList(QDir::Files) ;
|
|
||||||
qDebug() << " "
|
|
||||||
<< "to process files: "
|
|
||||||
<< scfList ;// pluginsDir.absoluteFilePath(fileName);
|
|
||||||
|
|
||||||
int ti;
|
|
||||||
|
|
||||||
QRegExp rx_qs(".*js");
|
|
||||||
|
|
||||||
ti = scfList.indexOf(rx_qs);
|
|
||||||
QFile scriptFile( spDir.absoluteFilePath( scfList.at(ti) ) );
|
|
||||||
scriptFile.open(QIODevice::ReadOnly);
|
|
||||||
engine->evaluate(scriptFile.readAll());
|
|
||||||
scriptFile.close();
|
|
||||||
|
|
||||||
QUiLoader loader;
|
|
||||||
QRegExp rx_ui(".*ui");
|
|
||||||
ti = scfList.indexOf(rx_ui) ;
|
|
||||||
QFile uiFile( spDir.absoluteFilePath( scfList.at(ti) ) );
|
|
||||||
qDebug() << "ui file is " << scfList.at(ti) ;
|
|
||||||
uiFile.open(QIODevice::ReadOnly);
|
|
||||||
|
|
||||||
QWidget *ui = loader.load(&uiFile);
|
|
||||||
uiFile.close();
|
|
||||||
|
|
||||||
QScriptValue ctor = engine->evaluate("Plugin");
|
|
||||||
QScriptValue scriptUi = engine->newQObject(ui, QScriptEngine::ScriptOwnership);
|
|
||||||
QScriptValue calc = ctor.construct(QScriptValueList() << scriptUi);
|
|
||||||
|
|
||||||
if (!ui)
|
|
||||||
qDebug() << "ui is null :(" ;
|
|
||||||
|
|
||||||
//ui->show();
|
|
||||||
pluginTabs->addTab(ui,"Script plugin");
|
|
||||||
}
|
|
||||||
//What has a head like a cat, feet like a cat, a tail like a cat, but isn't a cat?
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
PluginsPage::~PluginsPage()
|
PluginsPage::~PluginsPage()
|
||||||
{
|
{
|
||||||
// remove all pages, exept first (i.e remove all pages with plugins)
|
delete pluginManager;
|
||||||
for( int pi=1; pi<pluginTabs->count(); pi++)
|
|
||||||
{
|
|
||||||
pluginTabs->removeTab(pi); // widgets itself will be deleted
|
|
||||||
//in ~PluginManager()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void
|
void
|
||||||
PluginsPage::installComplete(QString pluginName)
|
PluginsPage::pluginRegistered(QString pluginName)
|
||||||
{
|
{
|
||||||
PluginFrame* pf = new PluginFrame( pluginManagerWidget, pluginName);
|
//
|
||||||
|
QWidget* pw = pluginManager->pluginWidget( pluginName);
|
||||||
|
|
||||||
connect( pluginManager, SIGNAL( loadDone(QString, QWidget*) ),
|
pluginTabs->addTab( pw , pluginName );
|
||||||
pf , SLOT( successfulLoad(QString, QWidget*) ) );
|
|
||||||
|
|
||||||
connect( pf , SIGNAL( needToLoad(QString) ),
|
|
||||||
pluginManager, SLOT( loadPlugin(QString) ) );
|
|
||||||
|
|
||||||
// connect( pf , SIGNAL( needToUnload(QString) ),
|
|
||||||
// pluginManager, SLOT( unloadPlugin(QString) ) );
|
|
||||||
|
|
||||||
connect( pf , SIGNAL( needToUnload(QString) ),
|
|
||||||
this , SLOT( unloadPlugin(QString) ) );
|
|
||||||
|
|
||||||
pluginManagerWidget->addPluginWidget(pf);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
void
|
|
||||||
PluginsPage::installFailed(QString pluginFileName, QString errorMessage)
|
|
||||||
{
|
|
||||||
QString tmps = QString("failed to install plugin from %1 (%2)")
|
|
||||||
.arg(pluginFileName)
|
|
||||||
.arg(errorMessage);
|
|
||||||
errlogConsole->append(tmps);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
void
|
|
||||||
PluginsPage::loadDone(QString pluginName, QWidget* pluginWidget)
|
|
||||||
{
|
|
||||||
pluginTabs->addTab( pluginWidget, pluginName );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
void
|
|
||||||
PluginsPage::loadFailed(QString pluginName, QString errorMessage)
|
|
||||||
{
|
|
||||||
QString tmps = QString("failed to load plugin %1 (%2)")
|
|
||||||
.arg(pluginName)
|
|
||||||
.arg(errorMessage);
|
|
||||||
errlogConsole->append(tmps);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
void
|
|
||||||
PluginsPage::unloadPlugin(QString pluginName)
|
|
||||||
{
|
|
||||||
qDebug() << " " << "PluginsPage::unloadPlugin called for " << pluginName ;
|
|
||||||
for (int tabi=0; tabi< pluginTabs->count(); tabi++)
|
|
||||||
{
|
|
||||||
if( pluginTabs->tabText(tabi) == pluginName)
|
|
||||||
{
|
|
||||||
QWidget* tw= pluginTabs->widget(tabi);
|
|
||||||
pluginTabs->removeTab( tabi);//the plugin widget will not be deleted !!
|
|
||||||
//plugin manager will delete it in
|
|
||||||
//it's unloadPlugin
|
|
||||||
// qDebug() << " " << "in pp " << (int) tw ;
|
|
||||||
// delete tw;
|
|
||||||
|
|
||||||
pluginManager->unloadPlugin( pluginName );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
int
|
|
||||||
PluginsPage::loadBinaryPlugins(const QDir directory)
|
|
||||||
{/*
|
|
||||||
//=== find a file with last loaded plugins =====
|
|
||||||
QStringList lastLoaded;
|
|
||||||
QFile llFile( directory.absolutePath()+"last_loaded.txt" ) ;
|
|
||||||
if ( llFile.open(QIODevice::ReadOnly) )
|
|
||||||
{
|
|
||||||
QString tmps;
|
|
||||||
QTextStream stream( &llFile ); // Set the stream to read from myFile
|
|
||||||
tmps = stream.readLine();
|
|
||||||
|
|
||||||
lastLoaded = tmps.split(";");
|
|
||||||
llFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
//=== get current available plugins =====
|
|
||||||
QStringList currAvailable = directory.entryList(QDir::Files);
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
QRegExp trx("*.dll")
|
|
||||||
#else
|
|
||||||
QRegExp trx("*.so");
|
|
||||||
#endif
|
|
||||||
trx.setPatternSyntax(QRegExp::Wildcard );
|
|
||||||
|
|
||||||
currAvailable.filter( trx );
|
|
||||||
|
|
||||||
qDebug() << " " << "can load this plugins: " << currAvailable ;
|
|
||||||
|
|
||||||
//=== create widgets for all available; also load which were loaded before
|
|
||||||
foreach(QString pluginFileName, currAvailable)
|
|
||||||
{
|
|
||||||
QString tmps( directory.absoluteFilePath( pluginFileName ) );
|
|
||||||
pluginManagerWidget->addPluginWidget( tmps );
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
#ifndef _PLUGINS_PAGE_H_
|
#ifndef _PLUGINS_PAGE_H_
|
||||||
#define _PLUGINS_PAGE_H_
|
#define _PLUGINS_PAGE_H_
|
||||||
|
|
||||||
//#include <QFileDialog>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "mainpage.h"
|
#include "mainpage.h"
|
||||||
|
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
//class QGroupBox;
|
|
||||||
class QVBoxLayout;
|
class QVBoxLayout;
|
||||||
class QTabWidget;
|
class QTabWidget;
|
||||||
class QFrame;
|
class QFrame;
|
||||||
|
@ -21,9 +16,15 @@ class QSpacerItem;
|
||||||
|
|
||||||
class QScriptEngine;
|
class QScriptEngine;
|
||||||
|
|
||||||
class PluginManagerWidget;
|
|
||||||
class PluginManager;
|
class PluginManager;
|
||||||
|
|
||||||
|
|
||||||
|
//! A demo widget for showing plugin engine in action :)
|
||||||
|
|
||||||
|
//! In current version this is just a container for PluginManagerWidget and
|
||||||
|
//! loaded plugin widgets. All specific actions moved to
|
||||||
|
//! PluginManagerWidget class. It contains a PluginManager instance, but it's
|
||||||
|
//! supposed that in future a pluginManager will become a global variable
|
||||||
class PluginsPage : public MainPage
|
class PluginsPage : public MainPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -35,44 +36,29 @@ public:
|
||||||
virtual ~PluginsPage() ;
|
virtual ~PluginsPage() ;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void loadDone(QString pluginName, QWidget* pluginWidget);
|
//! A slot for processing new plugin registration events.
|
||||||
void loadFailed(QString pluginName, QString errorMessage);
|
|
||||||
|
|
||||||
void installComplete(QString pluginName);
|
//! Every page, which supports plugins, has to process
|
||||||
void installFailed(QString pluginFileName, QString errorMessage);
|
//! the PluginManager::newPluginRegistered signal. Suppose, the page knows,
|
||||||
|
//! that there is a possible plugin "PuzzleGame"; Then, the page should
|
||||||
void unloadPlugin(QString pluginName);
|
//! compare received pluginName with "PuzzleGame", and request the plugin
|
||||||
|
//! widget with PluginManager::pluginWidget(..) method
|
||||||
|
void pluginRegistered(QString pluginName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QVBoxLayout* pluginPageLayout;
|
QVBoxLayout* pluginPageLayout;
|
||||||
QGroupBox* pluginPanel;
|
QGroupBox* pluginPanel;
|
||||||
QVBoxLayout* pluginPanelLayout;
|
QVBoxLayout* pluginPanelLayout;
|
||||||
|
|
||||||
QTextEdit* errlogConsole;
|
//! Plugin widgets will be loaded into this tabs
|
||||||
|
|
||||||
// QPushButton* instPlgButton;
|
|
||||||
// QHBoxLayout* insPlgLay;
|
|
||||||
// QSpacerItem* instPlgSpacer;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QTabWidget* pluginTabs ;
|
QTabWidget* pluginTabs ;
|
||||||
|
|
||||||
QVBoxLayout* pmLay;
|
QVBoxLayout* pmLay;
|
||||||
QFrame* pmFrame;
|
QFrame* pmFrame;
|
||||||
QSpacerItem* pmSpacer;
|
QSpacerItem* pmSpacer;
|
||||||
QString errorStrLog;
|
|
||||||
PluginManagerWidget* pluginManagerWidget;
|
//! This should be global, every page should have access to it
|
||||||
// QFrame* pluginControlsContainer;
|
|
||||||
PluginManager* pluginManager;
|
PluginManager* pluginManager;
|
||||||
//QScriptEngine* engine;
|
|
||||||
|
|
||||||
int loadBinaryPlugins(const QDir directory);//tring& errorString);
|
|
||||||
int loadScriptPlugins(const QString directory, QString& errorString);
|
|
||||||
|
|
||||||
int loadBinaryPlugin(const QString fileName, QString& errorString);
|
|
||||||
int loadScriptPlugin(const QString dirName, QString& errorString);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,16 +8,32 @@ class QString;
|
||||||
class QWidget;
|
class QWidget;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
//
|
//! a base class for plugins
|
||||||
|
|
||||||
|
//! All plugin classes must inherite this class and QObject.
|
||||||
class PluginInterface
|
class PluginInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~PluginInterface() {}
|
virtual ~PluginInterface() {}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
//! A description of the plugin
|
||||||
|
|
||||||
|
//! A description of the plugin. Is not used in current version.
|
||||||
virtual QString pluginDescription() const = 0;
|
virtual QString pluginDescription() const = 0;
|
||||||
|
|
||||||
|
//! The plugin's name
|
||||||
|
|
||||||
|
//! A name serves like an unique ID. The name is used in all operations
|
||||||
|
//! such as installing, removing, receiving a widget
|
||||||
virtual QString pluginName() const = 0;
|
virtual QString pluginName() const = 0;
|
||||||
|
|
||||||
|
//! plugin's widget.
|
||||||
|
|
||||||
|
//! Returns the widget, which is actually a plugin. Main application must
|
||||||
|
//! delete the widget; usually, a parent widget does it. If you want to use
|
||||||
|
//! the widget as top-level (i.e. parent==0), please, set
|
||||||
|
//! Qt::WA_DeleteOnClose flag .
|
||||||
virtual QWidget* pluginWidget(QWidget * parent = 0) = 0;
|
virtual QWidget* pluginWidget(QWidget * parent = 0) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue