diff options
Diffstat (limited to 'src/kvirc/module/kvi_moduleextension.cpp')
-rw-r--r-- | src/kvirc/module/kvi_moduleextension.cpp | 253 |
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); +} + + |