1 //=============================================================================
2 //
3 // File : KviKvsEventManager.cpp
4 // Creation date : Thu Aug 17 2000 13:59:12 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 2000-2010 Szymon Stefanek <pragma at kvirc dot net>
8 //
9 // This program is FREE software. You can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the HOPE that it will be USEFUL,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 // See the GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24
25 #include "KviKvsEventManager.h"
26 #include "KviConfigurationFile.h"
27 #include "KviKvsScript.h"
28 #include "KviKvsVariant.h"
29 #include "KviOptions.h"
30 #include "KviLocale.h"
31 #include "kvi_out.h"
32 #include "KviModule.h"
33 #include "KviWindow.h"
34 #include "KviKvsVariantList.h"
35
36 #include <QRegExp>
37
38 /*
39 @doc: events
40 @type:
41 language
42 @keyterms:
43 events,event handlers,event
44 @title:
45 Events
46 @short:
47 Events: user reactions
48 @body:
49 KVIrc triggers an event when a particular situation occurs.[br]
50 You can define a set of event handlers for each event type.[br]
51 An event handler is a snippet of user-defined code that gets executed when the event is triggered.[br]
52 Event handlers can be created or destroyed by using the scriptcenter (graphic interface)
53 or even from the commandline (or script) by using the [cmd]event[/cmd] command.[br]
54 For example, the [event:onirc]OnIRC[/event] is triggered when the login operations have
55 been terminated and you can consider yourself [i]completely[/i] on IRC. For example, you might
56 want to [i]auto-join[/i] some channels. Nothing easier! The following snippet of code
57 adds a handler to the OnIRC event that joins three channels:
58 [example]
59 [cmd]event[/cmd](OnIRC,autojoin)
60 {
61 [cmd]echo[/cmd] Auto-joining my preferred channels...
62 [cmd]join[/cmd] #kvirc,#siena,#linux
63 }
64 [/example]
65 Now try to connect to a server and you'll see that it joins automatically the three channels!.[br]
66 You might also want to do some other actions just after the connection has been established,
67 for example you might want to look immediately for a friend of yours by issuing a [cmd]whois[/cmd]
68 to the server (you could use the notify list for that).[br]
69 You can add the [cmd]whois[/cmd] request to the handler above or just create a new one:
70 [example]
71 [cmd]event[/cmd](OnIRC,lookforfred)
72 {
73 [cmd]echo[/cmd] Looking for fred...
74 [cmd]whois[/cmd] fred
75 }
76 [/example]
77 (An even nicer idea would be to use the [cmd]awhois[/cmd] command, but that's left to the reader as an exercise.[br]
78 To remove an event handler you still use the [cmd]event[/cmd] command, but with an empty code block:
79 [example]
80 [cmd]event[/cmd](OnIRC,lookforfred){}[br]
81 [/example]
82 [br]
83 Certain events will pass you some data in the positional parameters.[br]
84 For example, when you are being banned from a channel, KVIrc triggers the [event:onmeban]OnMeBan[/event]
85 event: you might be interested in WHO has banned you. KVIrc will pass the [i]ban source[/i] information
86 in the positional parameters $0,$1 and $2.[br]
87 (Please note that the parameters started from $1 in KVIrc versions older than 3.0.0!).[br]
88 You may take a look at the list of available [doc:event_index_all]events[/doc].[br]
89 */
90
91 KviKvsEventManager * KviKvsEventManager::m_pInstance = nullptr;
92
KviKvsEventManager()93 KviKvsEventManager::KviKvsEventManager()
94 {
95 m_pInstance = this;
96 for(auto & i : m_rawEventTable)
97 i = nullptr;
98 }
99
~KviKvsEventManager()100 KviKvsEventManager::~KviKvsEventManager()
101 {
102 clear();
103 }
104
init()105 void KviKvsEventManager::init()
106 {
107 if(KviKvsEventManager::instance())
108 {
109 qDebug("WARNING: trying to create KviKvsEventManager twice!");
110 return;
111 }
112 (void)new KviKvsEventManager();
113 }
114
done()115 void KviKvsEventManager::done()
116 {
117 if(!KviKvsEventManager::instance())
118 {
119 qDebug("WARNING: trying to destroy the KviKvsEventManager twice!");
120 return;
121 }
122 delete KviKvsEventManager::instance();
123 }
124
findAppEventIndexByName(const QString & szName)125 unsigned int KviKvsEventManager::findAppEventIndexByName(const QString & szName)
126 {
127 for(unsigned int u = 0; u < KVI_KVS_NUM_APP_EVENTS; u++)
128 {
129 if(KviQString::equalCI(szName, m_appEventTable[u].name()))
130 return u;
131 //Backwards compatibility >_<
132 if((u == 4) && KviQString::equalCI(szName, "OnIrcConnectionEstablished"))
133 return u;
134 }
135 return KVI_KVS_NUM_APP_EVENTS; // <-- invalid event number
136 }
137
findAppEventByName(const QString & szName)138 KviKvsEvent * KviKvsEventManager::findAppEventByName(const QString & szName)
139 {
140 for(unsigned int u = 0; u < KVI_KVS_NUM_APP_EVENTS; u++)
141 {
142 if(KviQString::equalCI(szName, m_appEventTable[u].name()))
143 return &(m_appEventTable[u]);
144 //Backwards compatibility >_<
145 if((u == 4) && KviQString::equalCI(szName, "OnIrcConnectionEstablished"))
146 return &(m_appEventTable[u]);
147 }
148 return nullptr;
149 }
150
addAppHandler(unsigned int uEvIdx,KviKvsEventHandler * h)151 bool KviKvsEventManager::addAppHandler(unsigned int uEvIdx, KviKvsEventHandler * h)
152 {
153 if(uEvIdx >= KVI_KVS_NUM_APP_EVENTS)
154 return false;
155 m_appEventTable[uEvIdx].addHandler(h);
156 return true;
157 }
158
addRawHandler(unsigned int uRawIdx,KviKvsEventHandler * h)159 bool KviKvsEventManager::addRawHandler(unsigned int uRawIdx, KviKvsEventHandler * h)
160 {
161 if(uRawIdx >= KVI_KVS_NUM_RAW_EVENTS)
162 return false;
163 if(!m_rawEventTable[uRawIdx])
164 {
165 m_rawEventTable[uRawIdx] = new KviPointerList<KviKvsEventHandler>();
166 m_rawEventTable[uRawIdx]->setAutoDelete(true);
167 }
168 m_rawEventTable[uRawIdx]->append(h);
169 return true;
170 }
171
addRawHandler(unsigned int uRawIdx,const KviKvsEventHandler & h)172 bool KviKvsEventManager::addRawHandler(unsigned int uRawIdx, const KviKvsEventHandler & h)
173 {
174 if(uRawIdx >= KVI_KVS_NUM_RAW_EVENTS)
175 return false;
176 KviKvsEventHandler * copy = new KviKvsEventHandler(h);
177 return addRawHandler(uRawIdx, copy);
178 }
179
removeScriptAppHandler(unsigned int uEvIdx,const QString & szName)180 bool KviKvsEventManager::removeScriptAppHandler(unsigned int uEvIdx, const QString & szName)
181 {
182 if(uEvIdx >= KVI_KVS_NUM_APP_EVENTS)
183 return false;
184 KviKvsEventHandler * h;
185 if(!(m_appEventTable[uEvIdx].handlers()))
186 return false;
187 for(h = m_appEventTable[uEvIdx].handlers()->first(); h; h = m_appEventTable[uEvIdx].handlers()->next())
188 {
189 if(h->type() == KviKvsEventHandler::Script)
190 {
191 if(KviQString::equalCI(((KviKvsScriptEventHandler *)h)->name(), szName))
192 {
193 m_appEventTable[uEvIdx].removeHandler(h);
194 return true;
195 }
196 }
197 }
198 return false;
199 }
200
findScriptRawHandler(unsigned int uEvIdx,const QString & szName)201 KviKvsScriptEventHandler * KviKvsEventManager::findScriptRawHandler(unsigned int uEvIdx, const QString & szName)
202 {
203 if(uEvIdx >= KVI_KVS_NUM_RAW_EVENTS)
204 return nullptr;
205 if(!m_rawEventTable[uEvIdx])
206 return nullptr;
207 KviKvsEventHandler * h;
208 for(h = m_rawEventTable[uEvIdx]->first(); h; h = m_rawEventTable[uEvIdx]->next())
209 {
210 if(h->type() == KviKvsEventHandler::Script)
211 {
212 if(KviQString::equalCI(((KviKvsScriptEventHandler *)h)->name(), szName))
213 {
214 return (KviKvsScriptEventHandler *)h;
215 }
216 }
217 }
218 return nullptr;
219 }
220
findScriptAppHandler(unsigned int uEvIdx,const QString & szName)221 KviKvsScriptEventHandler * KviKvsEventManager::findScriptAppHandler(unsigned int uEvIdx, const QString & szName)
222 {
223 if(uEvIdx >= KVI_KVS_NUM_APP_EVENTS)
224 return nullptr;
225 KviKvsEventHandler * h;
226 if(!(m_appEventTable[uEvIdx].handlers()))
227 return nullptr;
228 for(h = m_appEventTable[uEvIdx].handlers()->first(); h; h = m_appEventTable[uEvIdx].handlers()->next())
229 {
230 if(h->type() == KviKvsEventHandler::Script)
231 {
232 if(KviQString::equalCI(((KviKvsScriptEventHandler *)h)->name(), szName))
233 {
234 return (KviKvsScriptEventHandler *)h;
235 }
236 }
237 }
238 return nullptr;
239 }
240
enableScriptAppHandler(unsigned int uEvIdx,const QString & szName,bool bEnable)241 bool KviKvsEventManager::enableScriptAppHandler(unsigned int uEvIdx, const QString & szName, bool bEnable)
242 {
243 KviKvsScriptEventHandler * h = findScriptAppHandler(uEvIdx, szName);
244 if(!h)
245 return false;
246 h->setEnabled(bEnable);
247 return true;
248 }
249
removeModuleAppHandler(unsigned int uEvIdx,KviKvsModuleInterface * i)250 bool KviKvsEventManager::removeModuleAppHandler(unsigned int uEvIdx, KviKvsModuleInterface * i)
251 {
252 if(uEvIdx >= KVI_KVS_NUM_APP_EVENTS)
253 return false;
254 KviKvsEventHandler * h;
255 if(!(m_appEventTable[uEvIdx].handlers()))
256 return false;
257 for(h = m_appEventTable[uEvIdx].handlers()->first(); h; h = m_appEventTable[uEvIdx].handlers()->next())
258 {
259 if(h->type() == KviKvsEventHandler::Module)
260 {
261 if(((KviKvsModuleEventHandler *)h)->moduleInterface() == i)
262 {
263 m_appEventTable[uEvIdx].removeHandler(h);
264 return true;
265 }
266 }
267 }
268 return false;
269 }
270
removeAllModuleAppHandlers(KviKvsModuleInterface * pIface)271 void KviKvsEventManager::removeAllModuleAppHandlers(KviKvsModuleInterface * pIface)
272 {
273 KviKvsEventHandler * h;
274 for(auto & i : m_appEventTable)
275 {
276 if(!i.handlers())
277 continue;
278
279 KviPointerList<KviKvsEventHandler> l;
280 l.setAutoDelete(false);
281 for(h = i.handlers()->first(); h; h = i.handlers()->next())
282 {
283 if(h->type() == KviKvsEventHandler::Module)
284 {
285 if(((KviKvsModuleEventHandler *)h)->moduleInterface() == pIface)
286 {
287 l.append(h);
288 }
289 }
290 }
291 for(h = l.first(); h; h = l.next())
292 i.removeHandler(h);
293 }
294 }
295
removeAllModuleRawHandlers(KviKvsModuleInterface * pIface)296 void KviKvsEventManager::removeAllModuleRawHandlers(KviKvsModuleInterface * pIface)
297 {
298 KviKvsEventHandler * h;
299 for(auto & i : m_rawEventTable)
300 {
301 if(!i)
302 continue;
303
304 KviPointerList<KviKvsEventHandler> l;
305 l.setAutoDelete(false);
306 for(h = i->first(); h; h = i->next())
307 {
308 if(h->type() == KviKvsEventHandler::Module)
309 {
310 if(((KviKvsModuleEventHandler *)h)->moduleInterface() == pIface)
311 {
312 l.append(h);
313 }
314 }
315 }
316 for(h = l.first(); h; h = l.next())
317 i->removeRef(h);
318 if(i->isEmpty())
319 {
320 delete i;
321 i = nullptr;
322 }
323 }
324 }
325
removeScriptRawHandler(unsigned int uEvIdx,const QString & szName)326 bool KviKvsEventManager::removeScriptRawHandler(unsigned int uEvIdx, const QString & szName)
327 {
328 if(uEvIdx >= KVI_KVS_NUM_RAW_EVENTS)
329 return false;
330 if(!m_rawEventTable[uEvIdx])
331 return false;
332 KviKvsEventHandler * h;
333 for(h = m_rawEventTable[uEvIdx]->first(); h; h = m_rawEventTable[uEvIdx]->next())
334 {
335 if(h->type() == KviKvsEventHandler::Script)
336 {
337 if(KviQString::equalCI(((KviKvsScriptEventHandler *)h)->name(), szName))
338 {
339 m_rawEventTable[uEvIdx]->removeRef(h);
340 if(m_rawEventTable[uEvIdx]->isEmpty())
341 {
342 delete m_rawEventTable[uEvIdx];
343 m_rawEventTable[uEvIdx] = nullptr;
344 }
345 return true;
346 }
347 }
348 }
349 return false;
350 }
351
enableScriptRawHandler(unsigned int uEvIdx,const QString & szName,bool bEnable)352 bool KviKvsEventManager::enableScriptRawHandler(unsigned int uEvIdx, const QString & szName, bool bEnable)
353 {
354 KviKvsScriptEventHandler * h = findScriptRawHandler(uEvIdx, szName);
355 if(!h)
356 return false;
357 h->setEnabled(bEnable);
358 return true;
359 }
360
removeModuleRawHandler(unsigned int uRawIdx,KviKvsModuleInterface * i)361 bool KviKvsEventManager::removeModuleRawHandler(unsigned int uRawIdx, KviKvsModuleInterface * i)
362 {
363 if(uRawIdx >= KVI_KVS_NUM_RAW_EVENTS)
364 return false;
365 if(!m_rawEventTable[uRawIdx])
366 return false;
367 KviKvsEventHandler * h;
368 for(h = m_rawEventTable[uRawIdx]->first(); h; h = m_rawEventTable[uRawIdx]->next())
369 {
370 if(h->type() == KviKvsEventHandler::Module)
371 {
372 if(((KviKvsModuleEventHandler *)h)->moduleInterface() == i)
373 {
374 m_rawEventTable[uRawIdx]->removeRef(h);
375 if(m_rawEventTable[uRawIdx]->isEmpty())
376 {
377 delete m_rawEventTable[uRawIdx];
378 m_rawEventTable[uRawIdx] = nullptr;
379 }
380 return true;
381 }
382 }
383 }
384 return false;
385 }
386
removeAllModuleHandlers(KviKvsModuleInterface * pIface)387 void KviKvsEventManager::removeAllModuleHandlers(KviKvsModuleInterface * pIface)
388 {
389 removeAllModuleAppHandlers(pIface);
390 removeAllModuleRawHandlers(pIface);
391 }
392
removeAllScriptAppHandlers()393 void KviKvsEventManager::removeAllScriptAppHandlers()
394 {
395 for(auto & i : m_appEventTable)
396 {
397 i.clearScriptHandlers();
398 }
399 }
400
removeAllScriptRawHandlers()401 void KviKvsEventManager::removeAllScriptRawHandlers()
402 {
403 for(auto & i : m_rawEventTable)
404 {
405 if(i)
406 {
407 KviPointerList<KviKvsEventHandler> dl;
408 dl.setAutoDelete(false);
409 KviKvsEventHandler * e;
410 for(e = i->first(); e; e = i->next())
411 {
412 if(e->type() == KviKvsEventHandler::Script)
413 dl.append(e);
414 }
415
416 for(e = dl.first(); e; e = dl.next())
417 {
418 i->removeRef(e);
419 }
420
421 if(i->isEmpty())
422 {
423 delete i;
424 i = nullptr;
425 }
426 }
427 }
428 }
429
clearRawEvents()430 void KviKvsEventManager::clearRawEvents()
431 {
432 for(auto & i : m_rawEventTable)
433 {
434 if(i)
435 delete i;
436 i = nullptr;
437 }
438 }
439
clearAppEvents()440 void KviKvsEventManager::clearAppEvents()
441 {
442 for(auto & i : m_appEventTable)
443 {
444 i.clear();
445 }
446 }
447
clear()448 void KviKvsEventManager::clear()
449 {
450 clearRawEvents();
451 clearAppEvents();
452 }
453
triggerHandlers(KviPointerList<KviKvsEventHandler> * pHandlers,KviWindow * pWnd,KviKvsVariantList * pParams)454 bool KviKvsEventManager::triggerHandlers(KviPointerList<KviKvsEventHandler> * pHandlers, KviWindow * pWnd, KviKvsVariantList * pParams)
455 {
456 if(!pHandlers)
457 return false;
458
459 bool bGotHalt = false;
460 for(KviKvsEventHandler * h = pHandlers->first(); h; h = pHandlers->next())
461 {
462 switch(h->type())
463 {
464 case KviKvsEventHandler::Script:
465 {
466 if(((KviKvsScriptEventHandler *)h)->isEnabled())
467 {
468 KviKvsScript * s = ((KviKvsScriptEventHandler *)h)->script();
469 KviKvsScript copy(*s);
470 KviKvsVariant retVal;
471 int iRet = copy.run(pWnd, pParams, &retVal, KviKvsScript::PreserveParams);
472 if(!iRet)
473 {
474 // error! disable the handler if it's broken
475 if(KVI_OPTION_BOOL(KviOption_boolDisableBrokenEventHandlers))
476 {
477 ((KviKvsScriptEventHandler *)h)->setEnabled(false);
478 pWnd->output(KVI_OUT_PARSERERROR, __tr2qs_ctx("Event handler %Q is broken: disabling", "kvs"), &(s->name()));
479 emit eventHandlerDisabled(s->name());
480 }
481 }
482 if(!bGotHalt)
483 bGotHalt = (iRet & KviKvsScript::HaltEncountered);
484 }
485 }
486 break;
487 case KviKvsEventHandler::Module:
488 {
489 KviModule * m = (KviModule *)((KviKvsModuleEventHandler *)h)->moduleInterface();
490 KviKvsModuleEventHandlerRoutine * proc = ((KviKvsModuleEventHandler *)h)->handlerRoutine();
491 KviKvsVariant retVal;
492 KviKvsRunTimeContext ctx(nullptr, pWnd, pParams, &retVal);
493 KviKvsModuleEventCall call(m, &ctx, pParams);
494 if(!(*proc)(&call))
495 bGotHalt = true;
496 }
497 break;
498 }
499 }
500 return bGotHalt;
501 }
502
loadRawEvents(const QString & szFileName)503 void KviKvsEventManager::loadRawEvents(const QString & szFileName)
504 {
505 KviConfigurationFile cfg(szFileName, KviConfigurationFile::Read);
506 removeAllScriptRawHandlers();
507
508 for(size_t i = 0; i < KVI_KVS_NUM_RAW_EVENTS; i++)
509 {
510 QString szTmp = QString("RAW%1").arg(i);
511 if(cfg.hasGroup(szTmp))
512 {
513 cfg.setGroup(szTmp);
514 unsigned int uHandlers = cfg.readUIntEntry("NHandlers", 0);
515 if(uHandlers)
516 {
517 m_rawEventTable[i] = new KviPointerList<KviKvsEventHandler>();
518 m_rawEventTable[i]->setAutoDelete(true);
519 for(unsigned int uIdx = 0; uIdx < uHandlers; uIdx++)
520 {
521 szTmp = QString("Name%1").arg(uIdx);
522 QString szName = cfg.readEntry(szTmp, "unnamed");
523 szTmp = QString("Buffer%1").arg(uIdx);
524 QString szCode = cfg.readEntry(szTmp, "");
525 szTmp = QString("RawEvent%1::%2").arg(uIdx).arg(szName);
526 KviKvsScriptEventHandler * pScript = new KviKvsScriptEventHandler(szName, szTmp, szCode);
527 szTmp = QString("Enabled%1").arg(uIdx);
528 pScript->setEnabled(cfg.readBoolEntry(szTmp, false));
529 m_rawEventTable[i]->append(pScript);
530 }
531 }
532 }
533 }
534 }
535
saveRawEvents(const QString & szFileName)536 void KviKvsEventManager::saveRawEvents(const QString & szFileName)
537 {
538 KviConfigurationFile cfg(szFileName, KviConfigurationFile::Write);
539 cfg.clear();
540
541 for(size_t i = 0; i < KVI_KVS_NUM_RAW_EVENTS; i++)
542 {
543 if(m_rawEventTable[i])
544 {
545 QString szTmp = QString("RAW%1").arg(i);
546 cfg.setGroup(szTmp);
547
548 int iIdx = 0;
549 for(KviKvsEventHandler * pEvent = m_rawEventTable[i]->first(); pEvent; pEvent = m_rawEventTable[i]->next())
550 {
551 if(pEvent->type() == KviKvsEventHandler::Script)
552 {
553 szTmp = QString("Name%1").arg(iIdx);
554 cfg.writeEntry(szTmp, ((KviKvsScriptEventHandler *)pEvent)->name());
555 szTmp = QString("Buffer%1").arg(iIdx);
556 cfg.writeEntry(szTmp, ((KviKvsScriptEventHandler *)pEvent)->code());
557 szTmp = QString("Enabled%1").arg(iIdx);
558 cfg.writeEntry(szTmp, ((KviKvsScriptEventHandler *)pEvent)->isEnabled());
559 iIdx++;
560 }
561 }
562 cfg.writeEntry("NHandlers", iIdx);
563 }
564 }
565 }
566
loadAppEvents(const QString & szFileName)567 void KviKvsEventManager::loadAppEvents(const QString & szFileName)
568 {
569 KviConfigurationFile cfg(szFileName, KviConfigurationFile::Read);
570 removeAllScriptAppHandlers();
571
572 for(size_t i = 0; i < KVI_KVS_NUM_APP_EVENTS; i++)
573 {
574 QString szEventName(m_appEventTable[i].name());
575 // Backwards compatibility >_<
576 if((i == 4) && !cfg.hasGroup(szEventName))
577 szEventName = "OnIrcConnectionEstablished";
578 if(cfg.hasGroup(szEventName))
579 {
580 cfg.setGroup(szEventName);
581 unsigned int uHandlers = cfg.readUIntEntry("NHandlers", 0);
582 if(uHandlers)
583 {
584 for(unsigned int uIdx = 0; uIdx < uHandlers; uIdx++)
585 {
586 QString szTmp = QString("Name%1").arg(uIdx);
587 QString szName = cfg.readEntry(szTmp, "unnamed");
588 szTmp = QString("Buffer%1").arg(uIdx);
589 QString szCode = cfg.readEntry(szTmp, "");
590 szTmp = QString("Enabled%1").arg(uIdx);
591 bool bEnabled = cfg.readBoolEntry(szTmp, false);
592 QString szCntx = QString("%1::%2").arg(m_appEventTable[i].name(), szName);
593 KviKvsScriptEventHandler * pEvent = new KviKvsScriptEventHandler(szName, szCntx, szCode, bEnabled);
594 m_appEventTable[i].addHandler(pEvent);
595 }
596 }
597 }
598 }
599 }
600
saveAppEvents(const QString & szFileName)601 void KviKvsEventManager::saveAppEvents(const QString & szFileName)
602 {
603 KviConfigurationFile cfg(szFileName, KviConfigurationFile::Write);
604 cfg.clear();
605 bool bCompat = false;
606
607 for(size_t i = 0; i < KVI_KVS_NUM_APP_EVENTS; i++)
608 {
609 if(m_appEventTable[i].hasHandlers())
610 {
611 QString szEventName(m_appEventTable[i].name());
612 // Backwards compatibility >_<
613 if((i == 4) && cfg.hasGroup(szEventName))
614 {
615 szEventName = "OnIRCConnectionEstablished";
616 bCompat = true;
617 }
618 cfg.setGroup(szEventName);
619 int iIdx = 0;
620 for(KviKvsEventHandler * pEvent = m_appEventTable[i].handlers()->first(); pEvent; pEvent = m_appEventTable[i].handlers()->next())
621 {
622 if(pEvent->type() == KviKvsEventHandler::Script)
623 {
624 QString szTmp = QString("Name%1").arg(iIdx);
625 cfg.writeEntry(szTmp, ((KviKvsScriptEventHandler *)pEvent)->name());
626 szTmp = QString("Buffer%1").arg(iIdx);
627 cfg.writeEntry(szTmp, ((KviKvsScriptEventHandler *)pEvent)->code());
628 szTmp = QString("Enabled%1").arg(iIdx);
629 cfg.writeEntry(szTmp, ((KviKvsScriptEventHandler *)pEvent)->isEnabled());
630 iIdx++;
631 }
632 }
633 cfg.writeEntry("NHandlers", iIdx);
634
635 // Backwards compatibility >_<
636 if((i == 4) && !bCompat)
637 i--;
638 }
639 }
640 }
641
cleanHandlerName(QString & szHandlerName)642 void KviKvsEventManager::cleanHandlerName(QString & szHandlerName)
643 {
644 static QRegExp re(KVI_KVS_EVENT_HANDLER_NAME_INVALID_CHARS_REG_EXP);
645 szHandlerName.replace(re, "");
646 if (szHandlerName.isEmpty())
647 szHandlerName = "unnamed";
648 }
649