Subversion Repositories Scribus

Rev

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