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 | } |