File indexing completed on 2025-01-19 06:54:46
0001 // 0002 // C++ Implementation: cActionManager 0003 // 0004 // Description: action manager 0005 // 0006 /* 0007 Copyright 2005-2011 Tomas Mecir <kmuddy@kmuddy.com> 0008 0009 This program is free software; you can redistribute it and/or 0010 modify it under the terms of the GNU General Public License as 0011 published by the Free Software Foundation; either version 2 of 0012 the License, or (at your option) any later version. 0013 0014 This program is distributed in the hope that it will be useful, 0015 but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 GNU General Public License for more details. 0018 0019 You should have received a copy of the GNU General Public License 0020 along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 */ 0022 0023 #include "cactionmanager.h" 0024 0025 #include "cactionbase.h" 0026 0027 #include <kactioncollection.h> 0028 #include <kmainwindow.h> 0029 0030 #include <QDebug> 0031 #include <QWidget> 0032 0033 #include <list> 0034 #include <map> 0035 0036 struct AMprivAction { 0037 cActionBase *ab; 0038 QString name; 0039 ParamType pt; 0040 }; 0041 0042 struct AMprivEvent { 0043 std::multimap<int, AMprivAction> handlers; 0044 }; 0045 0046 struct AMprivSessionInfo { 0047 // objects, accessible by names 0048 std::map<QString, cActionBase *> objects; 0049 // event handlers, accessible by event names 0050 std::map<QString, AMprivEvent> events; 0051 // attributes 0052 std::map<QString, int> attribs; 0053 // string attributes 0054 std::map<QString, QString> strattribs; 0055 }; 0056 0057 struct cActionManagerPrivate { 0058 std::map<int, AMprivSessionInfo *> sessions; 0059 std::list<int> sessionList; 0060 int activesess; 0061 0062 KMainWindow *mainWindow; 0063 0064 // Shortcuts - only here because I have no better place for them :D 0065 // and I need them in lib/ 0066 KActionCollection *acol; 0067 }; 0068 0069 cActionManager *cActionManager::_self = nullptr; 0070 0071 cActionManager::cActionManager () 0072 { 0073 d = new cActionManagerPrivate; 0074 d->activesess = 0; 0075 registerSession (0); 0076 d->acol = nullptr; 0077 d->mainWindow = nullptr; 0078 } 0079 0080 cActionManager::~cActionManager () 0081 { 0082 unregisterSession (0); 0083 delete d; 0084 _self = nullptr; 0085 if (d->acol) delete d->acol; 0086 } 0087 0088 cActionManager *cActionManager::self () 0089 { 0090 if (!_self) 0091 _self = new cActionManager; 0092 return _self; 0093 } 0094 0095 void cActionManager::registerSession (int id) 0096 { 0097 if (sessionExists (id)) return; 0098 if (id < 0) return; 0099 d->sessions[id] = new AMprivSessionInfo; 0100 if (id) d->sessionList.push_back (id); 0101 } 0102 0103 void cActionManager::unregisterSession (int id) 0104 { 0105 if (!sessionExists (id)) return; 0106 0107 // delete all objects within the session 0108 // we need to use a temporary list, because deleting cActionBase would 0109 // invalidate the iterator ... 0110 std::map<QString, cActionBase *>::iterator it; 0111 std::list<cActionBase *> delList; 0112 std::list<cActionBase *>::iterator itl; 0113 0114 for (it = d->sessions[id]->objects.begin(); it != d->sessions[id]->objects.end(); ++it) { 0115 qWarning() << "Object " << it->first << " in session " << id << " was not deleted properly."; 0116 delList.push_back (it->second); 0117 } 0118 for (itl = delList.begin(); itl != delList.end(); ++itl) 0119 delete *itl; 0120 0121 // delete the session 0122 delete d->sessions[id]; 0123 d->sessions.erase (id); 0124 if (id) d->sessionList.remove (id); 0125 } 0126 0127 bool cActionManager::sessionExists (int id) 0128 { 0129 return (d->sessions.count (id) != 0); 0130 } 0131 0132 list<int> cActionManager::sessionList () 0133 { 0134 return d->sessionList; 0135 } 0136 0137 int cActionManager::sessions () 0138 { 0139 return d->sessionList.size(); 0140 } 0141 0142 int cActionManager::activeSession () 0143 { 0144 return d->activesess; 0145 } 0146 0147 void cActionManager::setActiveSession (int sess) 0148 { 0149 d->activesess = sess; 0150 } 0151 0152 void cActionManager::setSessionAttrib (int sess, const QString &name, int value) 0153 { 0154 if (!sessionExists (sess)) return; 0155 d->sessions[sess]->attribs[name] = value; 0156 } 0157 0158 void cActionManager::setSessionStrAttrib (int sess, const QString &name, const QString &value) 0159 { 0160 if (!sessionExists (sess)) return; 0161 d->sessions[sess]->strattribs[name] = value; 0162 } 0163 0164 int cActionManager::sessionAttrib (int sess, const QString &name) 0165 { 0166 if (!sessionExists (sess)) return 0; 0167 if (d->sessions[sess]->attribs.count (name)) 0168 return d->sessions[sess]->attribs[name]; 0169 return 0; 0170 } 0171 0172 QString cActionManager::sessionStrAttrib (int sess, const QString &name) 0173 { 0174 if (!sessionExists (sess)) return QString(); 0175 if (d->sessions[sess]->strattribs.count (name)) 0176 return d->sessions[sess]->strattribs[name]; 0177 return QString(); 0178 } 0179 0180 void cActionManager::registerObject (cActionBase *ab, int session) 0181 { 0182 if (!sessionExists (session)) return; 0183 d->sessions[session]->objects[ab->objName()] = ab; 0184 } 0185 0186 void cActionManager::unregisterObject (cActionBase *ab, int session) 0187 { 0188 if (!sessionExists (session)) return; 0189 d->sessions[session]->objects.erase (ab->objName()); 0190 0191 // TODO: remove all event handlers for this object ... 0192 } 0193 0194 #include <iostream> 0195 cActionBase *cActionManager::object (const QString &name, int session) 0196 { 0197 if (!sessionExists (session)) { 0198 std::cerr << "Requested object " << name.toLatin1().data() << " from non-existant session " << session << std::endl; 0199 return nullptr; 0200 } 0201 if (d->sessions[session]->objects.count (name)) 0202 { 0203 cActionBase *ab = d->sessions[session]->objects[name]; 0204 return ab; 0205 } 0206 std::cerr << "Object " << name.toLatin1().data() << " from session " << session << " not found." << std::endl; 0207 return nullptr; 0208 } 0209 0210 void cActionManager::addEventHandler (cActionBase *ab, int session, QString name, 0211 int priority, ParamType pt) 0212 { 0213 if (!sessionExists (session)) return; 0214 AMprivAction a; 0215 a.ab = ab; 0216 a.name = name; 0217 a.pt = pt; 0218 d->sessions[session]->events[name].handlers.insert ( 0219 std::pair<int, AMprivAction> (priority, a)); 0220 } 0221 0222 void cActionManager::removeEventHandler (cActionBase *ab, int session, QString name) 0223 { 0224 if (!sessionExists (session)) return; 0225 std::multimap<int, AMprivAction>::iterator it; 0226 for (it = d->sessions[session]->events[name].handlers.begin(); 0227 it != d->sessions[session]->events[name].handlers.end(); ++it) 0228 { 0229 if ((it->second.name == name) && (it->second.ab == ab)) 0230 { 0231 d->sessions[session]->events[name].handlers.erase (it); 0232 return; 0233 } 0234 } 0235 } 0236 0237 QString cActionManager::callAction (QString objectName, QString action, int session, 0238 int par1, int par2) 0239 { 0240 if (!sessionExists (session)) return QString(); 0241 0242 cActionBase *ab = object (objectName, session); 0243 if (ab) 0244 return ab->actionIntHandler (action, session, par1, par2); 0245 0246 return QString(); 0247 } 0248 0249 QString cActionManager::callAction (QString objectName, QString action, int session, 0250 QString &par1, const QString &par2) 0251 { 0252 if (!sessionExists (session)) return QString(); 0253 0254 cActionBase *ab = object (objectName, session); 0255 if (ab) 0256 return ab->actionStringHandler (action, session, par1, par2); 0257 return QString(); 0258 } 0259 0260 QString cActionManager::callAction (QString objectName, QString action, int session, 0261 const QString &par1, const QString &par2) 0262 { 0263 if (!sessionExists (session)) return QString(); 0264 0265 QString p = par1; 0266 cActionBase *ab = object (objectName, session); 0267 if (ab) 0268 return ab->actionStringHandler (action, session, p, par2); 0269 return QString(); 0270 } 0271 0272 QString cActionManager::callAction (QString objectName, QString action, int session) 0273 { 0274 if (!sessionExists (session)) return QString(); 0275 0276 cActionBase *ab = object (objectName, session); 0277 if (ab) 0278 return ab->actionNothingHandler (action, session); 0279 return QString(); 0280 } 0281 0282 QString cActionManager::callAction (QString objectName, QString action, int session, 0283 cTextChunk *par) 0284 { 0285 if (!sessionExists (session)) return QString(); 0286 0287 cActionBase *ab = object (objectName, session); 0288 if (ab) 0289 return ab->actionChunkHandler (action, session, par); 0290 return QString(); 0291 } 0292 0293 QString cActionManager::callAction (QString objectName, QString action, int session, 0294 void *par) 0295 { 0296 if (!sessionExists (session)) return QString(); 0297 0298 cActionBase *ab = object (objectName, session); 0299 if (ab) 0300 return ab->actionVoidHandler (action, session, par); 0301 return QString(); 0302 } 0303 0304 0305 void cActionManager::invokeEvent (QString event, int session, int par1, int par2) 0306 { 0307 if (!sessionExists (session)) return; 0308 0309 std::multimap<int, AMprivAction>::iterator it; 0310 // events for session 0 go to event handlers of all sessions 0311 if (session == 0) { 0312 std::map<int, AMprivSessionInfo *>::iterator it2; 0313 for (it2 = d->sessions.begin(); it2 != d->sessions.end(); ++it2) 0314 for (it = it2->second->events[event].handlers.begin(); 0315 it != it2->second->events[event].handlers.end(); ++it) 0316 if (it->second.pt == PT_INT) 0317 it->second.ab->eventIntHandler (event, session, par1, par2); 0318 0319 } 0320 else 0321 { 0322 // send the event to the target session handlers 0323 for (it = d->sessions[session]->events[event].handlers.begin(); 0324 it != d->sessions[session]->events[event].handlers.end(); ++it) 0325 if (it->second.pt == PT_INT) 0326 it->second.ab->eventIntHandler (event, session, par1, par2); 0327 0328 // objects with session number 0 receive all events 0329 for (it = d->sessions[0]->events[event].handlers.begin(); 0330 it != d->sessions[0]->events[event].handlers.end(); ++it) 0331 if (it->second.pt == PT_INT) 0332 it->second.ab->eventIntHandler (event, session, par1, par2); 0333 } 0334 } 0335 0336 void cActionManager::invokeEvent (QString event, int session, 0337 QString &par1, const QString &par2) 0338 { 0339 if (!sessionExists (session)) return; 0340 0341 std::multimap<int, AMprivAction>::iterator it; 0342 // events for session 0 go to event handlers of all session 0343 if (session == 0) { 0344 std::map<int, AMprivSessionInfo *>::iterator it2; 0345 for (it2 = d->sessions.begin(); it2 != d->sessions.end(); ++it2) 0346 for (it = it2->second->events[event].handlers.begin(); 0347 it != it2->second->events[event].handlers.end(); ++it) 0348 if (it->second.pt == PT_STRING) 0349 it->second.ab->eventStringHandler (event, session, par1, par2); 0350 0351 } 0352 else 0353 { 0354 // send the event to the target session handlers 0355 for (it = d->sessions[session]->events[event].handlers.begin(); 0356 it != d->sessions[session]->events[event].handlers.end(); ++it) 0357 if (it->second.pt == PT_STRING) 0358 it->second.ab->eventStringHandler (event, session, par1, par2); 0359 0360 // objects with session number 0 receive all events 0361 for (it = d->sessions[0]->events[event].handlers.begin(); 0362 it != d->sessions[0]->events[event].handlers.end(); ++it) 0363 if (it->second.pt == PT_STRING) 0364 it->second.ab->eventStringHandler (event, session, par1, par2); 0365 } 0366 0367 } 0368 0369 void cActionManager::invokeEvent (QString event, int session, 0370 const QString &par1, const QString &par2) 0371 { 0372 QString p = par1; 0373 invokeEvent (event, session, p, par2); 0374 } 0375 0376 void cActionManager::invokeEvent (QString event, int session) 0377 { 0378 if (!sessionExists (session)) return; 0379 0380 std::multimap<int, AMprivAction>::iterator it; 0381 // events for session 0 go to event handlers of all session 0382 if (session == 0) { 0383 std::map<int, AMprivSessionInfo *>::iterator it2; 0384 for (it2 = d->sessions.begin(); it2 != d->sessions.end(); ++it2) 0385 for (it = it2->second->events[event].handlers.begin(); 0386 it != it2->second->events[event].handlers.end(); ++it) 0387 if (it->second.pt == PT_NOTHING) 0388 it->second.ab->eventNothingHandler (event, session); 0389 0390 } 0391 else 0392 { 0393 // send the event to the target session handlers 0394 for (it = d->sessions[session]->events[event].handlers.begin(); 0395 it != d->sessions[session]->events[event].handlers.end(); ++it) 0396 if (it->second.pt == PT_NOTHING) 0397 it->second.ab->eventNothingHandler (event, session); 0398 0399 // objects with session number 0 receive all events 0400 for (it = d->sessions[0]->events[event].handlers.begin(); 0401 it != d->sessions[0]->events[event].handlers.end(); ++it) 0402 if (it->second.pt == PT_NOTHING) 0403 it->second.ab->eventNothingHandler (event, session); 0404 } 0405 } 0406 0407 void cActionManager::invokeEvent (QString event, int session, cTextChunk *par) 0408 { 0409 if (!sessionExists (session)) return; 0410 0411 std::multimap<int, AMprivAction>::iterator it; 0412 // events for session 0 go to event handlers of all session 0413 if (session == 0) { 0414 std::map<int, AMprivSessionInfo *>::iterator it2; 0415 for (it2 = d->sessions.begin(); it2 != d->sessions.end(); ++it2) 0416 for (it = it2->second->events[event].handlers.begin(); 0417 it != it2->second->events[event].handlers.end(); ++it) 0418 if (it->second.pt == PT_TEXTCHUNK) 0419 it->second.ab->eventChunkHandler (event, session, par); 0420 0421 } 0422 else 0423 { 0424 // send the event to the target session handlers 0425 for (it = d->sessions[session]->events[event].handlers.begin(); 0426 it != d->sessions[session]->events[event].handlers.end(); ++it) 0427 if (it->second.pt == PT_TEXTCHUNK) 0428 it->second.ab->eventChunkHandler (event, session, par); 0429 0430 // objects with session number 0 receive all events 0431 for (it = d->sessions[0]->events[event].handlers.begin(); 0432 it != d->sessions[0]->events[event].handlers.end(); ++it) 0433 if (it->second.pt == PT_TEXTCHUNK) 0434 it->second.ab->eventChunkHandler (event, session, par); 0435 } 0436 } 0437 0438 void cActionManager::invokeEvent (QString event, int session, void *par) 0439 { 0440 if (!sessionExists (session)) return; 0441 0442 std::multimap<int, AMprivAction>::iterator it; 0443 // events for session 0 go to event handlers of all session 0444 if (session == 0) { 0445 std::map<int, AMprivSessionInfo *>::iterator it2; 0446 for (it2 = d->sessions.begin(); it2 != d->sessions.end(); ++it2) 0447 for (it = it2->second->events[event].handlers.begin(); 0448 it != it2->second->events[event].handlers.end(); ++it) 0449 if (it->second.pt == PT_TEXTCHUNK) 0450 it->second.ab->eventVoidHandler (event, session, par); 0451 0452 } 0453 else 0454 { 0455 // send the event to the target session handlers 0456 for (it = d->sessions[session]->events[event].handlers.begin(); 0457 it != d->sessions[session]->events[event].handlers.end(); ++it) 0458 if (it->second.pt == PT_POINTER) 0459 it->second.ab->eventVoidHandler (event, session, par); 0460 0461 // objects with session number 0 receive all events 0462 for (it = d->sessions[0]->events[event].handlers.begin(); 0463 it != d->sessions[0]->events[event].handlers.end(); ++it) 0464 if (it->second.pt == PT_POINTER) 0465 it->second.ab->eventVoidHandler (event, session, par); 0466 } 0467 } 0468 0469 void cActionManager::setMainWindow (KMainWindow *window) 0470 { 0471 if (d->mainWindow) return; // already set - do not override 0472 d->mainWindow = window; 0473 } 0474 0475 QWidget *cActionManager::mainWidget () 0476 { 0477 return d->mainWindow; 0478 } 0479 0480 KMainWindow *cActionManager::mainWindow () 0481 { 0482 return d->mainWindow; 0483 } 0484 0485 void cActionManager::createACol (QWidget *parent) 0486 { 0487 if (!d->acol) 0488 d->acol = new KActionCollection (parent); 0489 //create acol object if needed, but nothing more... readShortcutSettings() 0490 //is called in kmuddy->prepareObjects (); 0491 } 0492 0493 KActionCollection *cActionManager::getACol () 0494 { 0495 return d->acol; 0496 } 0497