Subversion Repositories Scribus

Rev

Rev 2186 | Rev 2217 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1549 subik 1
#include "pluginmanager.h"
1551 fschmid 2
#include "pluginmanager.moc"
1549 subik 3
#include <dlfcn.h>
4
#include <qdir.h>
5
#include "scribus.h"
2187 cbradney 6
#include "scribusapp.h"
1549 subik 7
#include "menumanager.h"
8
#include "scraction.h"
9
#include "splash.h"
10
#include "mpalette.h"
11
#include "tree.h"
1552 subik 12
#include "prefsfile.h"
1693 craig 13
#include "scpaths.h"
1549 subik 14
 
15
extern ScribusApp *ScApp;
2187 cbradney 16
extern ScribusQApp *ScQApp;
1552 subik 17
extern PrefsFile *prefsFile;
1549 subik 18
 
19
 
20
PluginManager::PluginManager()
21
{
22
        dllInput = "";
23
        dllReturn = "";
1552 subik 24
        prefs = prefsFile->getPluginContext("pluginmanager");
1549 subik 25
}
26
 
27
PluginManager::~PluginManager()
28
{
29
}
30
 
1596 subik 31
void PluginManager::savePreferences()
32
{
33
        // write configuration
34
        for (QMap<int, PluginData>::Iterator it = pluginMap.begin(); it != pluginMap.end(); ++it)
35
                prefs->set(it.data().pluginFile, it.data().loadPlugin);
36
}
37
 
1549 subik 38
void PluginManager::initPlugs()
39
{
1552 subik 40
        QString name = "";
1549 subik 41
        int id = 0;
42
        struct PluginData pda;
1665 craig 43
        QString libPattern = QString("*.%1*").arg(PluginManager::platformDllExtension());
1693 craig 44
 
45
        QDir dirList(ScPaths::instance().pluginDir(),
46
                                 libPattern, QDir::Name,
47
                                 QDir::Files | QDir::Executable | QDir::NoSymLinks);
48
 
1552 subik 49
        if ((dirList.exists()) && (dirList.count() != 0))
1549 subik 50
        {
51
                ScApp->scrMenuMgr->addMenuSeparator("Extras");
1552 subik 52
                for (uint dc = 0; dc < dirList.count(); ++dc)
1549 subik 53
                {
1552 subik 54
                        pda.index = 0;
55
                        pda.pluginFile = "";
56
                        pda.menuID = 0;
57
                        pda.pluginFile = dirList[dc];
58
                        pda.loadPlugin = prefs->getBool(dirList[dc], true);
59
 
60
                        if (DLLname(dirList[dc], &pda.name, &pda.type, &pda.index, &id, &pda.actName, &pda.actKeySequence, &pda.actMenu, &pda.actMenuAfterName, &pda.actEnabledOnStartup, pda.loadPlugin))
1549 subik 61
                        {
2186 cbradney 62
                                pda.actMenuText=pda.name;
1596 subik 63
                                if (ScApp->splashScreen != NULL)
64
                                        ScApp->splashScreen->setStatus(tr(QString("Loading: %1").arg(pda.name), "plugin manager"));
1552 subik 65
                                if (pda.loadPlugin)
1549 subik 66
                                {
1552 subik 67
                                        if (pda.type == Persistent || pda.type == Standard || pda.type == Import)
68
                                        {
69
                                                //Add in ScrAction based plugin linkage
70
                                                //Insert DLL Action into Dictionary with values from plugin interface
71
                                                ScApp->scrActions.insert(pda.actName, new ScrAction(ScrAction::DLL, QIconSet(), pda.name, QKeySequence(pda.actKeySequence), ScApp, pda.actName, id));
1549 subik 72
 
1552 subik 73
                                                if (ScApp->scrActions[pda.actName])
74
                                                {
75
                                                        ScApp->scrActions[pda.actName]->setEnabled(pda.actEnabledOnStartup);
76
                                                        //Connect DLL Action's activated signal with ID to Scribus DLL loader
77
                                                        connect( ScApp->scrActions[pda.actName], SIGNAL(activatedData(int)) , ScApp->pluginManager, SLOT(callDLLBySlot(int)) );
78
                                                        //Get the menu manager to add the DLL's menu item to the right menu, after the chosen existing item
79
                                                        if (QString(pda.actMenuAfterName).length()==0)
80
                                                                ScApp->scrMenuMgr->addMenuItem(ScApp->scrActions[pda.actName], pda.actMenu);
81
                                                        else
82
                                                                ScApp->scrMenuMgr->addMenuItemAfter(ScApp->scrActions[pda.actName], pda.actMenu, pda.actMenuAfterName);
83
                                                }
1549 subik 84
                                        }
1552 subik 85
                                        else
86
                                                qDebug(tr(QString("Old type plugins are not supported anymore")), "plugin manager");
1596 subik 87
                                        pda.loaded = true;
1552 subik 88
                                } // load
1596 subik 89
                                else
90
                                        pda.loaded = false;
1549 subik 91
                                pluginMap.insert(id, pda);
92
                        }
93
                }
94
        }
95
}
96
 
97
void PluginManager::callDLLBySlot(int pluginID)
98
{
99
        //Run old type 2 Import pre call code
1552 subik 100
        if (pluginMap[pluginID].type == 7)
1549 subik 101
        {
102
                if (ScApp->HaveDoc)
103
                        ScApp->doc->OpenNodes = ScApp->outlinePalette->buildReopenVals();
104
        }
105
 
106
        callDLL(pluginID);
107
 
108
        //Run old type 2 Import post call code
1552 subik 109
        if (pluginMap[pluginID].type == 7)
1549 subik 110
        {
111
                if (ScApp->HaveDoc)
112
                {
113
                        ScApp->outlinePalette->BuildTree(ScApp->doc);
114
                        ScApp->outlinePalette->reopenTree(ScApp->doc->OpenNodes);
115
                        ScApp->propertiesPalette->updateCList();
116
                }
117
        }
118
}
119
 
120
void PluginManager::callDLL(int pluginID)
121
{
122
        void *mo;
123
        const char *error;
124
        struct PluginData pda;
125
        pda = pluginMap[pluginID];
126
        typedef void (*sdem)(QWidget *d, ScribusApp *plug);
127
        sdem demo;
1693 craig 128
        QString plugDir = ScPaths::instance().pluginDir();
1552 subik 129
        if (pda.type != 4 && pda.type !=5)
1549 subik 130
        {
1552 subik 131
                plugDir += pda.pluginFile;
1549 subik 132
                mo = dlopen(plugDir, RTLD_LAZY | RTLD_GLOBAL);
133
                if (!mo)
134
                {
1552 subik 135
                        qDebug(tr("Can't find Plug-in"), "plugin manager");
1549 subik 136
                        return;
137
                }
138
        }
139
        else
1552 subik 140
                mo = pda.index;
1549 subik 141
        dlerror();
1552 subik 142
        demo = (sdem)dlsym(mo, "run");
1549 subik 143
        if ((error = dlerror()) != NULL)
144
        {
1552 subik 145
                qDebug(tr(QString("Can't find Symbol (%1)").arg(error)), "plugin manager");
1549 subik 146
                dlclose(mo);
147
                return;
148
        }
149
        (*demo)(ScApp, ScApp);
150
        // FIXME: how is the menu organized? (*demo)(ScApp->scrActions[pluginMap[pluginID].actName], ScApp);
1552 subik 151
        if (pda.type != 4 && pda.type != 5)
1549 subik 152
                dlclose(mo);
153
        if (ScApp->HaveDoc)
154
                ScApp->view->DrawNew();
155
}
156
 
157
bool PluginManager::DLLexists(int pluginID)
158
{
159
        return pluginMap.contains(pluginID);
160
}
161
 
162
// used anywhere?
163
void PluginManager::callDLLbyMenu(int pluginID)
164
{
165
        QMap<int, PluginData>::Iterator it;
166
        struct PluginData pda;
167
        for (it = pluginMap.begin(); it != pluginMap.end(); ++it)
168
        {
1552 subik 169
                if (it.data().menuID == pluginID)
1549 subik 170
                {
171
                        callDLL(it.key());
172
                        break;
173
                }
174
        }
175
}
176
 
1552 subik 177
bool PluginManager::DLLname(QString name, QString *pluginName, PluginType *type, void **index, int *idNr, QString *actName, QString *actKeySequence, QString *actMenu, QString *actMenuAfterName, bool *actEnabledOnStartup, bool loadPlugin)
1549 subik 178
{
179
        void *mo;
180
        const char *error;
181
        typedef QString (*sdem0)();
1552 subik 182
        typedef PluginType (*sdem1)();
1549 subik 183
        typedef void (*sdem2)(QWidget *d, ScribusApp *plug);
184
        typedef bool (*sdem3)();
1552 subik 185
        typedef int (*sdemID)();
1549 subik 186
        sdem0 demo;
187
        sdem1 demo1;
188
        sdem2 demo2;
189
        sdem3 demo3;
1552 subik 190
        sdemID plugID;
1693 craig 191
        QString plugName = ScPaths::instance().pluginDir();
1549 subik 192
        plugName += name;
1596 subik 193
 
1549 subik 194
        mo = dlopen(plugName, RTLD_LAZY | RTLD_GLOBAL);
195
        if (!mo)
196
        {
1552 subik 197
                qDebug(tr(QString("Error: %1").arg(dlerror())), "plugin manager");
1549 subik 198
                return false;
199
        }
200
        dlerror();
1552 subik 201
        demo = (sdem0)dlsym(mo, "name");
1549 subik 202
        if ((error = dlerror()) != NULL)
203
        {
204
                dlclose(mo);
205
                return false;
206
        }
1552 subik 207
        *pluginName = (*demo)();
1549 subik 208
        dlerror();
1552 subik 209
        demo1 = (sdem1)dlsym(mo, "type");
1549 subik 210
        if ((error = dlerror()) != NULL)
211
        {
212
                dlclose(mo);
213
                return false;
214
        }
1552 subik 215
        *type = (*demo1)();
216
        *index = mo;
217
        plugID = (sdemID)dlsym(mo, "ID");
1549 subik 218
        if ((error = dlerror()) != NULL)
219
        {
220
                dlclose(mo);
221
                return false;
222
        }
1552 subik 223
        *idNr = (*plugID)();
1549 subik 224
        //ScrAction based plugins
1552 subik 225
        if (*type == Persistent || *type == Standard || *type == Import)
1549 subik 226
        {
227
                demo = (sdem0)dlsym(mo, "actionName");
228
                if ((error = dlerror()) != NULL)
229
                {
230
                        dlclose(mo);
231
                        return false;
232
                }
233
                *actName = (*demo)();
234
                dlerror();
235
                demo = (sdem0)dlsym(mo, "actionKeySequence");
236
                if ((error = dlerror()) != NULL)
237
                {
238
                        dlclose(mo);
239
                        return false;
240
                }
241
                *actKeySequence = (*demo)();
242
                dlerror();
243
                demo = (sdem0)dlsym(mo, "actionMenu");
244
                if ((error = dlerror()) != NULL)
245
                {
246
                        dlclose(mo);
247
                        return false;
248
                }
249
                *actMenu = (*demo)();
250
                dlerror();
251
                demo = (sdem0)dlsym(mo, "actionMenuAfterName");
252
                if ((error = dlerror()) != NULL)
253
                {
254
                        dlclose(mo);
255
                        return false;
256
                }
257
                *actMenuAfterName = (*demo)();
258
                dlerror();
259
                demo3 = (sdem3)dlsym(mo, "actionEnabledOnStartup");
260
                if ((error = dlerror()) != NULL)
261
                {
262
                        dlclose(mo);
263
                        return false;
264
                }
265
                *actEnabledOnStartup = (*demo3)();
266
        }
267
        else
268
        {
269
                *actName = QString::null;
270
                *actKeySequence = QString::null;
271
                *actMenu = QString::null;
272
                *actMenuAfterName = QString::null;
273
                *actEnabledOnStartup = false;
274
        }
1552 subik 275
        if (*type != Persistent && *type!= Type5)
1549 subik 276
                dlclose(mo);
277
        else
278
        {
1596 subik 279
                if (loadPlugin)
1549 subik 280
                {
1596 subik 281
                        dlerror();
282
                        demo2 = (sdem2)dlsym(mo, "initPlug");
283
                        if ((error = dlerror()) != NULL)
284
                        {
285
                                dlclose(mo);
286
                                return false;
287
                        }
288
                        (*demo2)(ScApp, ScApp);
1549 subik 289
                }
290
        }
291
 
292
        return true;
293
}
294
 
295
void PluginManager::finalizePlugs()
296
{
1552 subik 297
        for (QMap<int, PluginData>::Iterator it = pluginMap.begin(); it != pluginMap.end(); ++it)
1596 subik 298
                if (it.data().loaded == true)
299
                        finalizePlug(it.key());
1552 subik 300
}
301
 
302
void PluginManager::finalizePlug(int pluginID)
303
{
1549 subik 304
        const char *error;
305
        struct PluginData pda;
306
        typedef void (*sdem2)();
307
        sdem2 demo2;
1552 subik 308
        PluginData plug = pluginMap[pluginID];
309
        if (plug.type == Persistent || plug.type == Type5)
1549 subik 310
        {
1552 subik 311
                dlerror();
312
                demo2 = (sdem2)dlsym(plug.index, "cleanUpPlug");
313
                if ((error = dlerror()) != NULL)
1549 subik 314
                {
1552 subik 315
                        dlclose(plug.index);
1549 subik 316
                }
1552 subik 317
                else
318
                        (*demo2)();
1549 subik 319
        }
320
}
1552 subik 321
 
322
QString PluginManager::getPluginType(PluginType aType)
323
{
324
        switch(aType)
325
        {
326
                case Persistent:
327
                        return tr("Persistent", "plugin manager");
328
                        break;
329
                case Import:
330
                        return tr("Import", "plugin manager");
331
                        break;
332
                case Standard:
333
                        return tr("Standard", "plugin manager");
334
                        break;
335
                default:
336
                        return tr("Unknown", "plugin manager");
337
        }
338
}
1665 craig 339
 
340
QCString PluginManager::platformDllExtension()
341
{
342
#ifdef __hpux
343
        // HP/UX
344
        return "sl";
345
#elif defined(__APPLE__) && defined(__MACH__)
346
        // MacOS/X, Darwin
1731 craig 347
 
348
        // MacOS/X may actually use both 'so' and 'dylib'. .so is usually used
349
        // for plugins etc, dylib for system and app libraries We need to
350
        // support this distinction in the plugin manager, but for now it's
351
        // most appropriate to return the extension used by plugins -- CR
352
 
353
        //return "dylib";
354
        return "so";
1665 craig 355
#else
356
        // Generic *NIX
357
        return "so";
358
#endif
359
}
2187 cbradney 360
 
361
void PluginManager::languageChange()
362
{
363
        for (QMap<int, PluginData>::Iterator it = pluginMap.begin(); it != pluginMap.end(); ++it)
364
        {
365
                QString fromTranslator=ScQApp->translate("QObject", (*it).actMenuText);
366
                ScrAction* pluginAction=ScApp->scrActions[(*it).actName];
367
                if (pluginAction!=NULL)
368
                        pluginAction->setMenuText(fromTranslator);
369
        }
370
}