summaryrefslogtreecommitdiffstats
path: root/src/kvirc/module/kvi_moduleextension.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kvirc/module/kvi_moduleextension.cpp')
-rw-r--r--src/kvirc/module/kvi_moduleextension.cpp253
1 files changed, 253 insertions, 0 deletions
diff --git a/src/kvirc/module/kvi_moduleextension.cpp b/src/kvirc/module/kvi_moduleextension.cpp
new file mode 100644
index 00000000..fb6a9ae6
--- /dev/null
+++ b/src/kvirc/module/kvi_moduleextension.cpp
@@ -0,0 +1,253 @@
+//
+// File : kvi_moduleextension.cpp
+// Creation date : Tue Sep 10 01:16:25 2002 GMT by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2002 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#define __KVIRC__
+#define _KVI_MODULEEXTENSION_CPP_
+
+#include "kvi_moduleextension.h"
+#include "kvi_module.h"
+#include "kvi_modulemanager.h"
+#include "kvi_app.h"
+
+// created and destroyed in kvi_app.cpp
+KVIRC_API KviModuleExtensionManager * g_pModuleExtensionManager = 0;
+
+
+KviModuleExtensionDescriptor::KviModuleExtensionDescriptor(KviModule * m,const KviStr &szType,const KviStr &szName,const QString &szVisibleName,KviModuleExtensionAllocRoutine r,const QPixmap &pix)
+{
+ m_iId = KviApp::getGloballyUniqueId();
+
+ m_pModule = m;
+ m_szType = szType;
+ m_szName = szName;
+ m_szVisibleName = szVisibleName;
+ m_allocRoutine = r;
+ m_pObjectList = new KviPointerList<KviModuleExtension>;
+ m_pObjectList->setAutoDelete(false);
+ if(pix.isNull())m_pIcon = 0;
+ else m_pIcon = new QPixmap(pix);
+}
+
+KviModuleExtensionDescriptor::~KviModuleExtensionDescriptor()
+{
+ while(KviModuleExtension * e = m_pObjectList->first())e->die();
+ delete m_pObjectList;
+ if(m_pIcon)delete m_pIcon;
+}
+
+void KviModuleExtensionDescriptor::setIcon(const QPixmap &pix)
+{
+ if(m_pIcon)delete m_pIcon;
+ if(pix.isNull())m_pIcon = 0;
+ else m_pIcon = new QPixmap(pix);
+}
+
+KviModuleExtension * KviModuleExtensionDescriptor::allocate(KviWindow * pWnd,KviPointerHashTable<QString,QVariant> * pParams,void * pSpecial)
+{
+ KviModuleExtensionAllocStruct s;
+ s.pDescriptor = this;
+ s.pWindow = pWnd;
+ s.pParams = pParams;
+ s.pSpecial = pSpecial;
+ return m_allocRoutine(&s);
+}
+
+
+void KviModuleExtensionDescriptor::registerObject(KviModuleExtension * e)
+{
+ m_pObjectList->append(e);
+}
+
+void KviModuleExtensionDescriptor::unregisterObject(KviModuleExtension * e)
+{
+ m_pObjectList->removeRef(e);
+}
+
+
+
+
+
+
+
+
+KviModuleExtensionManager::KviModuleExtensionManager()
+{
+ m_pExtensionDict = new KviPointerHashTable<const char *,KviModuleExtensionDescriptorList>(17,false);
+ m_pExtensionDict->setAutoDelete(true);
+}
+
+KviModuleExtensionManager::~KviModuleExtensionManager()
+{
+ delete m_pExtensionDict;
+}
+
+KviModuleExtensionDescriptorList * KviModuleExtensionManager::getExtensionList(const KviStr &szType)
+{
+ g_pModuleManager->loadModulesByCaps(szType.ptr());
+ return m_pExtensionDict->find(szType.ptr());
+}
+
+KviModuleExtensionDescriptor * KviModuleExtensionManager::registerExtension(KviModule * m,const KviStr &szType,const KviStr &szName,const QString &szVisibleName,KviModuleExtensionAllocRoutine r,const QPixmap &icon)
+{
+ KviModuleExtensionDescriptor * d = new KviModuleExtensionDescriptor(m,szType,szName,szVisibleName,r,icon);
+ KviModuleExtensionDescriptorList * l = m_pExtensionDict->find(szType.ptr());
+ if(!l)
+ {
+ l = new KviModuleExtensionDescriptorList();
+ l->setAutoDelete(false);
+ m_pExtensionDict->insert(szType.ptr(),l);
+ }
+ l->append(d);
+ return d;
+}
+
+void KviModuleExtensionManager::unregisterExtensionsByModule(KviModule * m)
+{
+ KviPointerHashTableIterator<const char *,KviModuleExtensionDescriptorList> it(*m_pExtensionDict);
+ KviPointerList<KviStr> dying;
+ dying.setAutoDelete(true);
+ while(KviModuleExtensionDescriptorList * l = it.current())
+ {
+ KviPointerList<KviModuleExtensionDescriptor> dying2;
+ dying2.setAutoDelete(true);
+
+ for(KviModuleExtensionDescriptor * d = l->first();d;d = l->next())
+ {
+ if(d->module() == m)dying2.append(d);
+ }
+
+ for(KviModuleExtensionDescriptor * de = dying2.first();de;de = dying2.next())
+ {
+ l->removeRef(de);
+ }
+
+ if(l->isEmpty())dying.append(new KviStr(it.currentKey()));
+ ++it;
+ }
+ for(KviStr * li = dying.first();li;li = dying.next())
+ {
+ m_pExtensionDict->remove(li->ptr());
+ }
+}
+
+KviModuleExtensionDescriptorList * KviModuleExtensionManager::allocateExtensionGetDescriptorList(const KviStr &szType,const char * preloadModule)
+{
+ if(preloadModule)
+ {
+ KviModule * m = g_pModuleManager->getModule(preloadModule);
+ (void)m; // get rid of the unused warning :D
+ }
+
+ KviModuleExtensionDescriptorList * l = m_pExtensionDict->find(szType.ptr());
+ if(!l)
+ {
+ // retry : it might have been unloaded
+ g_pModuleManager->loadModulesByCaps(szType.ptr());
+ l = m_pExtensionDict->find(szType.ptr());
+ }
+
+ return l;
+}
+
+KviModuleExtensionDescriptor * KviModuleExtensionManager::findExtensionDescriptor(const KviStr &szType,const KviStr &szName)
+{
+ KviModuleExtensionDescriptorList * l = m_pExtensionDict->find(szType.ptr());
+ if(!l)return 0;
+
+ for(KviModuleExtensionDescriptor * d = l->first();d;d = l->next())
+ {
+ if(d->name().equalsCI(szName))return d;
+ }
+
+ return 0;
+}
+
+KviModuleExtension * KviModuleExtensionManager::allocateExtension(const KviStr &szType,const KviStr &szName,KviWindow * pWnd,KviPointerHashTable<QString,QVariant> * pParams,void * pSpecial,const char * preloadModule)
+{
+ KviModuleExtensionDescriptorList * l = allocateExtensionGetDescriptorList(szType,preloadModule);
+ if(!l)return 0;
+
+ KviModuleExtensionDescriptor * d;
+
+ for(d = l->first();d;d = l->next())
+ {
+ if(d->name().equalsCI(szName))return d->allocate(pWnd,pParams,pSpecial);
+ }
+
+ // uhm... not there ?
+ g_pModuleManager->loadModulesByCaps(szType.ptr());
+ // try again after loading the modules
+ // l = m_pExtensionDict->find(szType.ptr()); <--- this shouldn't change!
+ for(d = l->first();d;d = l->next())
+ {
+ if(d->name().equalsCI(szName))return d->allocate(pWnd,pParams,pSpecial);
+ }
+
+ // no way : no such extension
+
+ return 0;
+}
+
+
+KviModuleExtension * KviModuleExtensionManager::allocateExtension(const KviStr &szType,int id,KviWindow * pWnd,KviPointerHashTable<QString,QVariant> * pParams,void * pSpecial,const char * preloadModule)
+{
+ KviModuleExtensionDescriptorList * l = allocateExtensionGetDescriptorList(szType,preloadModule);
+ if(!l)return 0;
+
+ KviModuleExtensionDescriptor * d;
+ for(d = l->first();d;d = l->next())
+ {
+ if(d->id() == id)return d->allocate(pWnd,pParams,pSpecial);
+ }
+
+ // uhm... not there ?
+ g_pModuleManager->loadModulesByCaps(szType.ptr());
+ // try again after loading the modules
+ // l = m_pExtensionDict->find(szType.ptr()); <--- this shouldn't change!
+ for(d = l->first();d;d = l->next())
+ {
+ if(d->id() == id)return d->allocate(pWnd,pParams,pSpecial);
+ }
+ // no way : no such extension
+
+ return 0;
+}
+
+
+
+
+
+
+
+KviModuleExtension::KviModuleExtension(KviModuleExtensionDescriptor * d)
+: KviHeapObject()
+{
+ m_pDescriptor = d;
+ m_pDescriptor->registerObject(this);
+}
+
+KviModuleExtension::~KviModuleExtension()
+{
+ m_pDescriptor->unregisterObject(this);
+}
+
+