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