1 //=============================================================================
2 //
3 //   File : KviKvsModuleInterface.cpp
4 //   Creation date : Tue 16 Dec 2003 00:27:54 by Szymon Stefanek
5 //
6 //   This file is part of the KVIrc IRC client distribution
7 //   Copyright (C) 2003-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 "KviKvsModuleInterface.h"
26 #include "KviKvsEventManager.h"
27 #include "KviModule.h"
28 #include "KviModuleManager.h"
29 #include "KviLocale.h"
30 #include "KviKvsTreeNodeData.h"
31 #include "KviKvsTreeNodeDataList.h"
32 
getParameterCode(unsigned int uParamIdx,QString & szParamBuffer)33 bool KviKvsModuleCallbackCommandCall::getParameterCode(unsigned int uParamIdx, QString & szParamBuffer)
34 {
35 	if(!m_pParameterDataList)
36 		return false;
37 	KviKvsTreeNodeData * d = m_pParameterDataList->item(uParamIdx);
38 	if(!d)
39 		return false;
40 	const QChar * pBegin = d->location();
41 	const QChar * pEnd = d->endingLocation();
42 	if(!(pBegin && pEnd))
43 		return false;
44 	szParamBuffer.setUnicode(pBegin, pEnd - pBegin);
45 	szParamBuffer = szParamBuffer.trimmed();
46 	return true;
47 }
48 
KviKvsModuleInterface()49 KviKvsModuleInterface::KviKvsModuleInterface()
50 {
51 	m_pModuleSimpleCommandExecRoutineDict = new KviPointerHashTable<QString, KviKvsModuleSimpleCommandExecRoutine>(17, false);
52 	m_pModuleSimpleCommandExecRoutineDict->setAutoDelete(true);
53 	m_pModuleFunctionExecRoutineDict = new KviPointerHashTable<QString, KviKvsModuleFunctionExecRoutine>(17, false);
54 	m_pModuleFunctionExecRoutineDict->setAutoDelete(true);
55 	m_pModuleCallbackCommandExecRoutineDict = new KviPointerHashTable<QString, KviKvsModuleCallbackCommandExecRoutine>(17, false);
56 	m_pModuleCallbackCommandExecRoutineDict->setAutoDelete(true);
57 }
58 
~KviKvsModuleInterface()59 KviKvsModuleInterface::~KviKvsModuleInterface()
60 {
61 	kvsUnregisterAllEventHandlers();
62 	delete m_pModuleSimpleCommandExecRoutineDict;
63 	delete m_pModuleFunctionExecRoutineDict;
64 	delete m_pModuleCallbackCommandExecRoutineDict;
65 }
66 
67 #define COMPLETE_WORD_BY_DICT(word, list, type, dict)         \
68 	{                                                           \
69 		KviPointerHashTableIterator<QString, type> it(*dict);     \
70 		int l = word.length();                                    \
71 		while(it.current())                                       \
72 		{                                                         \
73 			if(KviQString::equalCIN(word, it.currentKey(), l))      \
74 				list.push_back(it.currentKey());                      \
75 			++it;                                                   \
76 		}                                                         \
77 	}
78 
completeCommand(const QString & szCommandBegin,std::vector<QString> & pMatches)79 void KviKvsModuleInterface::completeCommand(const QString & szCommandBegin, std::vector<QString> & pMatches)
80 {
81 	COMPLETE_WORD_BY_DICT(szCommandBegin, pMatches, KviKvsModuleSimpleCommandExecRoutine, m_pModuleSimpleCommandExecRoutineDict)
82 	COMPLETE_WORD_BY_DICT(szCommandBegin, pMatches, KviKvsModuleCallbackCommandExecRoutine, m_pModuleCallbackCommandExecRoutineDict)
83 }
84 
completeFunction(const QString & szFunctionBegin,std::vector<QString> & pMatches)85 void KviKvsModuleInterface::completeFunction(const QString & szFunctionBegin, std::vector<QString> & pMatches)
86 {
87 	COMPLETE_WORD_BY_DICT(szFunctionBegin, pMatches, KviKvsModuleFunctionExecRoutine, m_pModuleFunctionExecRoutineDict)
88 }
89 
kvsRegisterSimpleCommand(const QString & szCommand,KviKvsModuleSimpleCommandExecRoutine r)90 void KviKvsModuleInterface::kvsRegisterSimpleCommand(const QString & szCommand, KviKvsModuleSimpleCommandExecRoutine r)
91 {
92 	m_pModuleSimpleCommandExecRoutineDict->replace(szCommand, new KviKvsModuleSimpleCommandExecRoutine(r));
93 }
94 
kvsRegisterCallbackCommand(const QString & szCommand,KviKvsModuleCallbackCommandExecRoutine r)95 void KviKvsModuleInterface::kvsRegisterCallbackCommand(const QString & szCommand, KviKvsModuleCallbackCommandExecRoutine r)
96 {
97 	m_pModuleCallbackCommandExecRoutineDict->replace(szCommand, new KviKvsModuleCallbackCommandExecRoutine(r));
98 }
99 
kvsRegisterFunction(const QString & szFunction,KviKvsModuleFunctionExecRoutine r)100 void KviKvsModuleInterface::kvsRegisterFunction(const QString & szFunction, KviKvsModuleFunctionExecRoutine r)
101 {
102 	m_pModuleFunctionExecRoutineDict->replace(szFunction, new KviKvsModuleFunctionExecRoutine(r));
103 }
104 
kvsRegisterAppEventHandler(unsigned int iEventIdx,KviKvsModuleEventHandlerRoutine r)105 bool KviKvsModuleInterface::kvsRegisterAppEventHandler(unsigned int iEventIdx, KviKvsModuleEventHandlerRoutine r)
106 {
107 	KviKvsModuleEventHandler * h = new KviKvsModuleEventHandler(this, r);
108 	if(!KviKvsEventManager::instance()->addAppHandler(iEventIdx, h))
109 	{
110 		delete h;
111 		return false;
112 	}
113 	return true;
114 }
115 
kvsRegisterRawEventHandler(unsigned int iRawIdx,KviKvsModuleEventHandlerRoutine r)116 bool KviKvsModuleInterface::kvsRegisterRawEventHandler(unsigned int iRawIdx, KviKvsModuleEventHandlerRoutine r)
117 {
118 	KviKvsModuleEventHandler * h = new KviKvsModuleEventHandler(this, r);
119 	if(!KviKvsEventManager::instance()->addRawHandler(iRawIdx, h))
120 	{
121 		delete h;
122 		return false;
123 	}
124 	return true;
125 }
126 
kvsUnregisterAppEventHandler(unsigned int uEventIdx)127 void KviKvsModuleInterface::kvsUnregisterAppEventHandler(unsigned int uEventIdx)
128 {
129 	KviKvsEventManager::instance()->removeModuleAppHandler(uEventIdx, this);
130 }
131 
kvsUnregisterRawEventHandler(unsigned int uRawIdx)132 void KviKvsModuleInterface::kvsUnregisterRawEventHandler(unsigned int uRawIdx)
133 {
134 	KviKvsEventManager::instance()->removeModuleRawHandler(uRawIdx, this);
135 }
136 
kvsUnregisterAllAppEventHandlers()137 void KviKvsModuleInterface::kvsUnregisterAllAppEventHandlers()
138 {
139 	KviKvsEventManager::instance()->removeAllModuleAppHandlers(this);
140 }
141 
kvsUnregisterAllRawEventHandlers()142 void KviKvsModuleInterface::kvsUnregisterAllRawEventHandlers()
143 {
144 	KviKvsEventManager::instance()->removeAllModuleRawHandlers(this);
145 }
146 
kvsUnregisterAllEventHandlers()147 void KviKvsModuleInterface::kvsUnregisterAllEventHandlers()
148 {
149 	kvsUnregisterAllAppEventHandlers();
150 	kvsUnregisterAllRawEventHandlers();
151 }
152 
default_module_kvs_cmd_load(KviKvsModuleCommandCall *)153 static bool default_module_kvs_cmd_load(KviKvsModuleCommandCall *)
154 {
155 	return true;
156 }
157 
default_module_kvs_cmd_unload(KviKvsModuleCommandCall * c)158 static bool default_module_kvs_cmd_unload(KviKvsModuleCommandCall * c)
159 {
160 	if(c->module()->isLocked())
161 	{
162 		if(!c->switches()->find('f', "force"))
163 		{
164 			c->warning(__tr2qs_ctx("Can't unload the module: it has locked itself in memory", "kvs"));
165 			return true;
166 		}
167 	}
168 	g_pModuleManager->unloadModule(c->module()->name());
169 	return true;
170 }
171 
registerDefaultCommands()172 void KviKvsModuleInterface::registerDefaultCommands()
173 {
174 	kvsRegisterSimpleCommand("load", default_module_kvs_cmd_load);
175 	kvsRegisterSimpleCommand("unload", default_module_kvs_cmd_unload);
176 }
getAllFunctionsCommandsModule(QStringList * list,QString & szModuleName)177 void KviKvsModuleInterface::getAllFunctionsCommandsModule(QStringList * list, QString & szModuleName)
178 {
179 	KviPointerHashTableIterator<QString, KviKvsModuleFunctionExecRoutine> it(*m_pModuleFunctionExecRoutineDict);
180 	while(it.current())
181 	{
182 		QString szF("$" + szModuleName + ".");
183 		szF.append(it.currentKey());
184 		list->append(szF);
185 		++it;
186 	}
187 	KviPointerHashTableIterator<QString, KviKvsModuleSimpleCommandExecRoutine> it2(*m_pModuleSimpleCommandExecRoutineDict);
188 	while(it2.current())
189 	{
190 		QString szF(szModuleName + ".");
191 		szF.append(it2.currentKey());
192 		list->append(szF);
193 		++it2;
194 	}
195 }
196