Subversion Repositories Scribus

Rev

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