You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.cpp

387 lines
10 KiB

//=============================================================================
//
// File : kvi_kvs_scriptaddonmanager.cpp
// Created on Thu 31 Mar 2005 01:21:23 by Szymon Stefanek
//
// This file is part of the KVIrc IRC client distribution
// Copyright (C) 2005 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__
#include "kvi_kvs_scriptaddonmanager.h"
#include "kvi_kvs_script.h"
#include "kvi_config.h"
#include "kvi_window.h"
#include "kvi_iconmanager.h"
KviKvsScriptAddonManager * KviKvsScriptAddonManager::m_pInstance = 0;
KviKvsScriptAddon::KviKvsScriptAddon(
const TQString &szName,
const TQString &szVersion,
const TQString &szVisibleNameCode,
const TQString &szDescriptionCode,
const TQString &szUninstallCallbackCode,
const TQString &szIconId
) : KviHeapObject(), m_szName(szName), m_szVersion(szVersion), m_szIconId(szIconId)
{
allocateScripts(szVisibleNameCode,szDescriptionCode,szUninstallCallbackCode);
m_pConfigureCallback = 0;
m_pHelpCallback = 0;
}
KviKvsScriptAddon::KviKvsScriptAddon(const KviKvsScriptAddon &a)
: KviHeapObject()
{
m_szName = a.m_szName;
m_szVersion = a.m_szVersion;
m_szIconId = a.m_szIconId;
allocateScripts(a.m_pVisibleNameScript->code(),a.m_pDescriptionScript->code(),a.m_pUninstallCallback ? a.m_pUninstallCallback->code() : TQString());
m_pConfigureCallback = 0;
setConfigureCallback(a.m_pConfigureCallback ? a.m_pConfigureCallback->code() : TQString());
m_pHelpCallback = 0;
setHelpCallback(a.m_pHelpCallback ? a.m_pHelpCallback->code() : TQString());
}
KviKvsScriptAddon::KviKvsScriptAddon()
: KviHeapObject()
{
m_pVisibleNameScript = 0;
m_pDescriptionScript = 0;
m_pUninstallCallback = 0;
m_pConfigureCallback = 0;
m_pHelpCallback = 0;
}
KviKvsScriptAddon::~KviKvsScriptAddon()
{
if(m_pVisibleNameScript)delete m_pVisibleNameScript;
if(m_pDescriptionScript)delete m_pDescriptionScript;
if(m_pUninstallCallback)delete m_pUninstallCallback;
if(m_pConfigureCallback)delete m_pConfigureCallback;
if(m_pHelpCallback)delete m_pHelpCallback;
}
TQPixmap * KviKvsScriptAddon::icon()
{
return g_pIconManager->getBigIcon(m_szIconId.isEmpty() ? TQString(KVI_BIGICON_KVS) : m_szIconId);
}
const TQString & KviKvsScriptAddon::visibleName()
{
if(!m_pVisibleNameScript)return m_szVisibleName;
if(!m_pVisibleNameScript->run(g_pActiveWindow,0,m_szVisibleName))m_szVisibleName = m_pVisibleNameScript->code();
return m_szVisibleName;
}
const TQString & KviKvsScriptAddon::description()
{
if(!m_pDescriptionScript)return m_szDescription;
if(!m_pDescriptionScript->run(g_pActiveWindow,0,m_szDescription))m_szDescription = m_pDescriptionScript->code();
return m_szDescription;
}
const TQString & KviKvsScriptAddon::visibleNameCode()
{
return m_pVisibleNameScript->code();
}
const TQString & KviKvsScriptAddon::descriptionCode()
{
return m_pDescriptionScript->code();
}
const TQString & KviKvsScriptAddon::uninstallCallbackCode()
{
return m_pUninstallCallback->code();
}
const TQString & KviKvsScriptAddon::configureCallbackCode()
{
if(m_pConfigureCallback)return m_pConfigureCallback->code();
return KviTQString::empty;
}
const TQString & KviKvsScriptAddon::helpCallbackCode()
{
if(m_pHelpCallback)return m_pHelpCallback->code();
return KviTQString::empty;
}
bool KviKvsScriptAddon::load(KviConfig * cfg,const TQString &szName)
{
m_szName = szName;
cfg->setGroup(m_szName);
m_szVersion = cfg->readTQStringEntry("Version");
m_szIconId = cfg->readTQStringEntry("IconId");
if(m_szVersion.isEmpty())return false;
TQString tmp1,tmp2,tmp3;
tmp1 = cfg->readTQStringEntry("VisibleNameCode");
tmp2 = cfg->readTQStringEntry("DescriptionCode");
tmp3 = cfg->readTQStringEntry("UninstallCallback");
if(tmp1.isEmpty())return false;
allocateScripts(tmp1,tmp2,tmp3);
tmp1 = cfg->readTQStringEntry("ConfigureCallback");
if(!tmp1.isEmpty())
setConfigureCallback(tmp1);
tmp1 = cfg->readTQStringEntry("HelpCallback");
if(!tmp1.isEmpty())
setHelpCallback(tmp1);
return true;
}
void KviKvsScriptAddon::setConfigureCallback(const TQString &szConfigureCallbackCode)
{
if(m_pConfigureCallback)delete m_pConfigureCallback;
if(szConfigureCallbackCode.isEmpty())
{
m_pConfigureCallback = 0;
return;
}
TQString szKvsName = "addon::";
szKvsName += m_szName;
TQString szTmp;
szTmp = szKvsName;
szTmp += "::configure";
m_pConfigureCallback = new KviKvsScript(szTmp,szConfigureCallbackCode,KviKvsScript::InstructionList);
}
void KviKvsScriptAddon::setHelpCallback(const TQString &szHelpCallbackCode)
{
if(m_pHelpCallback)delete m_pHelpCallback;
if(szHelpCallbackCode.isEmpty())
{
m_pHelpCallback = 0;
return;
}
TQString szKvsName = "addon::";
szKvsName += m_szName;
TQString szTmp;
szTmp = szKvsName;
szTmp += "::help";
m_pHelpCallback = new KviKvsScript(szTmp,szHelpCallbackCode,KviKvsScript::InstructionList);
}
void KviKvsScriptAddon::allocateScripts(const TQString &szVisibleNameCode,const TQString &szDescriptionCode,const TQString &szUninstallCallbackCode)
{
TQString szKvsName = "addon::";
szKvsName += m_szName;
TQString szTmp;
szTmp = szKvsName;
szTmp += "::name";
m_pVisibleNameScript = new KviKvsScript(szTmp,szVisibleNameCode,KviKvsScript::Parameter);
szTmp = szKvsName;
szTmp += "::description";
m_pDescriptionScript = new KviKvsScript(szTmp,szDescriptionCode,KviKvsScript::Parameter);
szTmp = szKvsName;
szTmp += "::uninstall";
m_pUninstallCallback = new KviKvsScript(szTmp,szUninstallCallbackCode,KviKvsScript::InstructionList);
}
void KviKvsScriptAddon::save(KviConfig * cfg)
{
cfg->setGroup(m_szName);
cfg->writeEntry("Version",m_szVersion);
cfg->writeEntry("VisibleNameCode",visibleNameCode());
cfg->writeEntry("DescriptionCode",descriptionCode());
cfg->writeEntry("UninstallCallback",uninstallCallbackCode());
cfg->writeEntry("ConfigureCallback",configureCallbackCode());
cfg->writeEntry("HelpCallback",helpCallbackCode());
cfg->writeEntry("IconId",m_szIconId);
}
void KviKvsScriptAddon::executeUninstallCallback(KviWindow * pWnd)
{
if(!m_pUninstallCallback)return;
m_pUninstallCallback->run(pWnd);
}
void KviKvsScriptAddon::executeConfigureCallback(KviWindow * pWnd)
{
if(!m_pConfigureCallback)return;
m_pConfigureCallback->run(pWnd);
}
void KviKvsScriptAddon::executeHelpCallback(KviWindow * pWnd)
{
if(!m_pHelpCallback)return;
m_pHelpCallback->run(pWnd);
}
KviKvsScriptAddonManager::KviKvsScriptAddonManager()
{
m_pInstance = this;
m_bLoaded = false;
m_pAddonDict = new KviPointerHashTable<TQString,KviKvsScriptAddon>(17,false);
m_pAddonDict->setAutoDelete(true);
}
KviKvsScriptAddonManager::~KviKvsScriptAddonManager()
{
delete m_pAddonDict;
}
void KviKvsScriptAddonManager::init()
{
if(KviKvsScriptAddonManager::instance())
{
tqDebug("WARNING: Trying to create the KviKvsScriptAddonManager twice!");
return;
}
(void)new KviKvsScriptAddonManager();
}
void KviKvsScriptAddonManager::done()
{
if(!KviKvsScriptAddonManager::instance())
{
tqDebug("WARNING: Trying to destroy the KviKvsScriptAddonManager twice!");
return;
}
delete KviKvsScriptAddonManager::instance();
}
void KviKvsScriptAddonManager::load(const TQString &szFileName)
{
// in fact we implement delayed loading
// so this function only stores the filename
// from which we will load at the first request
m_szFileName = szFileName;
// this to make sure that we reload the addons
// if someone explicitly requests a load after we have already loaded
// (this does not happen in kvirc tough at the moment)
m_bLoaded = false;
}
void KviKvsScriptAddonManager::save(const TQString &szFileName)
{
if(!m_bLoaded)return; // nothing to store anyway
// we're stored here from now on...
m_szFileName = szFileName;
KviConfig cfg(szFileName,KviConfig::Write);
cfg.clear();
KviPointerHashTableIterator<TQString,KviKvsScriptAddon> it(*m_pAddonDict);
while(KviKvsScriptAddon * a = it.current())
{
cfg.setGroup(a->name());
a->save(&cfg);
++it;
}
}
void KviKvsScriptAddonManager::delayedLoad()
{
if(m_bLoaded)return; // already loaded
m_bLoaded = true;
// ::load() might be never called if we don't have
// a scriptaddons.kvc file on disk, KviApp checks that.
// So finally m_szFileName may be empty here
if(m_szFileName.isEmpty())return;
KviConfig cfg(m_szFileName,KviConfig::Read);
KviPointerHashTable<TQString,KviConfigGroup> * d = cfg.dict();
if(!d)return;
KviPointerHashTableIterator<TQString,KviConfigGroup> it(*d);
while(it.current())
{
TQString szName = it.currentKey();
KviKvsScriptAddon * a = new KviKvsScriptAddon();
if(a->load(&cfg,szName))
m_pAddonDict->replace(szName,a);
else
delete a;
++it;
}
}
KviPointerHashTable<TQString,KviKvsScriptAddon> * KviKvsScriptAddonManager::addonDict()
{
if(!m_bLoaded)delayedLoad();
return m_pAddonDict;
}
bool KviKvsScriptAddonManager::registerAddon(KviKvsScriptAddonRegistrationData * d)
{
if(findAddon(d->szName))return false;
KviKvsScriptAddon * a = new KviKvsScriptAddon(
d->szName,
d->szVersion,
d->szVisibleNameScript,
d->szDescriptionScript,
d->szUninstallCallbackScript,
d->szIconId);
m_pAddonDict->replace(d->szName,a);
return true;
}
KviKvsScriptAddon * KviKvsScriptAddonManager::findAddon(const TQString &szName)
{
if(!m_bLoaded)delayedLoad();
return m_pAddonDict->find(szName);
}
bool KviKvsScriptAddonManager::unregisterAddon(const TQString &szName,KviWindow * pWnd,bool bExecuteUninstallCallback)
{
KviKvsScriptAddon * a = findAddon(szName);
if(!a)return false;
// remove the addon before executing the uninstall callback
// so the user effectively can't call addon.unregister on itself in the uninstall callback code :D
m_pAddonDict->setAutoDelete(false);
m_pAddonDict->remove(szName);
m_pAddonDict->setAutoDelete(true);
if(bExecuteUninstallCallback)
a->executeUninstallCallback(pWnd);
delete a;
return true;
}
void KviKvsScriptAddonManager::clear()
{
if(!m_bLoaded)delayedLoad();
m_pAddonDict->clear();
}