diff options
| author | 2010-06-26 03:29:31 +0000 | |
|---|---|---|
| committer | 2010-06-26 03:29:31 +0000 | |
| commit | b0fe843132229e5be7aeab6750d824662d778c75 (patch) | |
| tree | aa468c215bf08ce745a9fdecefb29b6926b3299d /src | |
| parent | More addon related tweaks (diff) | |
| download | KVIrc-b0fe843132229e5be7aeab6750d824662d778c75.tar.gz KVIrc-b0fe843132229e5be7aeab6750d824662d778c75.tar.bz2 KVIrc-b0fe843132229e5be7aeab6750d824662d778c75.zip | |
More addon tweaks. Added /addon.installfiles so the installer class (which may be screwed up by the user) is no longer necessary. Addons now automatically remove their files on uninstall.
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@4523 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src')
| -rw-r--r-- | src/kvilib/ext/kvi_config.h | 2 | ||||
| -rw-r--r-- | src/kvirc/kvs/kvi_kvs_scriptaddonmanager.cpp | 43 | ||||
| -rw-r--r-- | src/kvirc/kvs/kvi_kvs_scriptaddonmanager.h | 12 | ||||
| -rw-r--r-- | src/modules/addon/libkviaddon.cpp | 177 |
4 files changed, 223 insertions, 11 deletions
diff --git a/src/kvilib/ext/kvi_config.h b/src/kvilib/ext/kvi_config.h index bab3b8f76..45ed61e1d 100644 --- a/src/kvilib/ext/kvi_config.h +++ b/src/kvilib/ext/kvi_config.h @@ -123,7 +123,7 @@ public: bool readBoolEntry(const QString & szKey,bool bTrue); QRect readRectEntry(const QString & szKey,const QRect &rct); void writeEntry(const QString & szKey,const QRect &rct); - QStringList readStringListEntry(const QString & szKey,const QStringList &list); + QStringList readStringListEntry(const QString & szKey,const QStringList &list = QStringList()); void writeEntry(const QString & szKey,const QStringList &list); QList<int> readIntListEntry(const QString & ,const QList<int> &list); void writeEntry(const QString & szKey,const QList<int> &list); diff --git a/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.cpp b/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.cpp index 58009889a..10fd08da5 100644 --- a/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.cpp +++ b/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.cpp @@ -4,7 +4,7 @@ // Creation date : Thu 31 Mar 2005 01:21:23 by Szymon Stefanek // // This file is part of the KVIrc IRC client distribution -// Copyright (C) 2005-2008 Szymon Stefanek <pragma at kvirc dot net> +// Copyright (C) 2005-2010 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 @@ -27,6 +27,10 @@ #include "kvi_config.h" #include "kvi_window.h" #include "kvi_iconmanager.h" +#include "kvi_fileutils.h" +#include "kvi_app.h" + +#include <QFileInfo> KviKvsScriptAddonManager * KviKvsScriptAddonManager::m_pInstance = 0; @@ -144,9 +148,17 @@ bool KviKvsScriptAddon::load(KviConfig * cfg,const QString &szName) tmp1 = cfg->readQStringEntry("HelpCallback"); if(!tmp1.isEmpty()) setHelpCallback(tmp1); + m_lInstalledFiles = cfg->readStringListEntry("InstalledFiles"); return true; } +void KviKvsScriptAddon::addInstalledFile(const QString &szFileName) +{ + if(m_lInstalledFiles.contains(szFileName)) + return; + m_lInstalledFiles.append(szFileName); +} + void KviKvsScriptAddon::setConfigureCallback(const QString &szConfigureCallbackCode) { if(m_pConfigureCallback)delete m_pConfigureCallback; @@ -213,6 +225,7 @@ void KviKvsScriptAddon::save(KviConfig * cfg) cfg->writeEntry("ConfigureCallback",configureCallbackCode()); cfg->writeEntry("HelpCallback",helpCallbackCode()); cfg->writeEntry("IconId",m_szIconId); + cfg->writeEntry("InstalledFiles",m_lInstalledFiles); } void KviKvsScriptAddon::executeUninstallCallback(KviWindow * pWnd) @@ -348,14 +361,16 @@ bool KviKvsScriptAddonManager::registerAddon(KviKvsScriptAddonRegistrationData * KviKvsScriptAddon * KviKvsScriptAddonManager::findAddon(const QString &szName) { - if(!m_bLoaded)delayedLoad(); + if(!m_bLoaded) + delayedLoad(); return m_pAddonDict->find(szName); } -bool KviKvsScriptAddonManager::unregisterAddon(const QString &szName,KviWindow * pWnd,bool bExecuteUninstallCallback) +bool KviKvsScriptAddonManager::unregisterAddon(const QString &szName,KviWindow * pWnd,bool bExecuteUninstallCallback,bool bUninstallFiles) { KviKvsScriptAddon * a = findAddon(szName); - if(!a)return false; + 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 @@ -366,6 +381,26 @@ bool KviKvsScriptAddonManager::unregisterAddon(const QString &szName,KviWindow * if(bExecuteUninstallCallback) a->executeUninstallCallback(pWnd); + if(bUninstallFiles) + { + // uninstall files + QStringList lFiles = a->installedFiles(); + foreach(QString szFileName,lFiles) + { + QString szPath; + g_pApp->getLocalKvircDirectory(szPath,KviApp::None,szFileName); + + //qDebug("Uninstalling %s",szPath.toUtf8().data()); + + QFileInfo inf(szPath); + if(!inf.exists()) + continue; + + KviFileUtils::removeFile(szPath); + } + // FIXME: remove empty directories!! + } + delete a; return true; } diff --git a/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.h b/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.h index 67ff9e5ba..d9e45e43f 100644 --- a/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.h +++ b/src/kvirc/kvs/kvi_kvs_scriptaddonmanager.h @@ -29,6 +29,7 @@ #include "kvi_qstring.h" #include "kvi_pointerhashtable.h" +#include <QStringList> class KviConfig; class KviKvsScript; @@ -62,8 +63,10 @@ protected: KviKvsScript * m_pHelpCallback; // help callback QString m_szDescription; // parsed description QString m_szVisibleName; // parsed visible name - QString m_szIconId; + QString m_szIconId; // the id of the associated icon + QStringList m_lInstalledFiles; // the list of the installed files public: + const QStringList &installedFiles() const { return m_lInstalledFiles; }; const QString &name() const { return m_szName; }; const QString &version() const { return m_szVersion; }; const QString &visibleName(); @@ -75,6 +78,11 @@ public: const QString &helpCallbackCode(); const QString &iconId(){ return m_szIconId; }; QPixmap * icon(); + /// + /// Register a file to be uninstalled after the uninstall callback. + /// The file name *MUST* be relative to the local kvirc directory. + /// + void addInstalledFile(const QString &szFileName); void setConfigureCallback(const QString &szConfigureCallbackCode); void setHelpCallback(const QString &szHelpCallbackCode); void executeConfigureCallback(KviWindow * pWnd); @@ -116,7 +124,7 @@ public: bool registerAddon(KviKvsScriptAddonRegistrationData * d); KviKvsScriptAddon * findAddon(const QString &szName); - bool unregisterAddon(const QString &szName,KviWindow * pWnd,bool bExecuteUninstallCallback = true); + bool unregisterAddon(const QString &szName,KviWindow * pWnd,bool bExecuteUninstallCallback = true,bool bUninstallFiles = true); KviPointerHashTable<QString,KviKvsScriptAddon> * addonDict(); void clear(); diff --git a/src/modules/addon/libkviaddon.cpp b/src/modules/addon/libkviaddon.cpp index b99688db9..6bfe7bedf 100644 --- a/src/modules/addon/libkviaddon.cpp +++ b/src/modules/addon/libkviaddon.cpp @@ -172,8 +172,8 @@ static bool addon_kvs_cmd_list(KviKvsModuleCommandCall * c) !sw: -q | --quiet Makes the command run quietly @description: - Uninstalls the specified addon by executing its uninstall callback function. - It also removes the addon's registration entry. + Uninstalls the specified addon by executing its uninstall callback function + and removing its installed files. It also removes the addon's registration entry. If the -n switch is specified the the uninstall callback is not called, only the registration entry is removed. @seealso: @@ -502,7 +502,7 @@ static bool addon_kvs_cmd_sethelpcallback(KviKvsModuleCallbackCommandCall * c) @seealso: [cmd]addon.uninstall[/cmd], [fnc]$addon.exists[/fnc], [cmd]addon.setconfigurecallback[/cmd], [cmd]addon.configure[/cmd], - [cmd]addon.sethelpcallback[/cmd], [cmd]addon.help[/cmd] + [cmd]addon.sethelpcallback[/cmd], [cmd]addon.help[/cmd], [cmd]addon.installfiles[/cmd] @examples: [example] @@ -572,8 +572,10 @@ static bool addon_kvs_cmd_register(KviKvsModuleCallbackCommandCall * c) if(!c->switches()->find('q',"quiet")) c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs_ctx("Uninstalling existing addon version %Q","addon"),&(a->version())); + bool bUninstall = !c->switches()->find('n',"no-uninstall"); + // uninstall the existing version - KviKvsScriptAddonManager::instance()->unregisterAddon(rd.szName,c->window(),!c->switches()->find('n',"no-uninstall")); + KviKvsScriptAddonManager::instance()->unregisterAddon(rd.szName,c->window(),bUninstall,bUninstall); } if(!KviKvsScriptAddonManager::instance()->registerAddon(&rd)) @@ -589,6 +591,172 @@ static bool addon_kvs_cmd_register(KviKvsModuleCallbackCommandCall * c) } /* + @doc: addon.installfiles + @type: + command + @title: + addon.installfiles + @short: + Installs a set of files for an addon + @syntax: + addon.installfiles <id:string> <target:string> [files] + @switches: + !sw: -q | --quiet + Makes the command run quietly + !sw: -s | --skip-inexisting + Skip inexisting entries in the [files] list + @description: + Installs the [files] for the addon identified by the specified <id>. + The files will be automatically removed when the addon is uninstalled. + <target> is the target path inside the local kvirc directory. The following + standard paths should be used:[br] + [ul] + [li]"pics" for image files.[/li] + [li]"locale" for translation *.mo files.[/li] + [li]"audio" for sound files.[/li] + [li]"config" for configuration files.[/li] + [/ul] + Other target paths are allowed and subdirectories are supported (eg. "pics/myaddon"). + [files] is a list of filenames or directory names. + Each file will be copied to the specified target path in the local kvirc directory. + Filenames can contain wildcard characters in the last component. + @seealso: + [cmd]addon.register[/cmd] + [cmd]addon.uninstall[/cmd] +*/ + +static bool addon_kvs_cmd_installfiles(KviKvsModuleCommandCall * c) +{ + QString szName; + QString szTarget; + QStringList lEntries; + + KVSM_PARAMETERS_BEGIN(c) + KVSM_PARAMETER("name",KVS_PT_NONEMPTYSTRING,0,szName) + KVSM_PARAMETER("target",KVS_PT_NONEMPTYSTRING,0,szTarget) + KVSM_PARAMETER("files",KVS_PT_STRINGLIST,0,lEntries) + KVSM_PARAMETERS_END(c) + + bool bQuiet = c->switches()->find('q',"quiet"); + bool bSkipInexisting = c->switches()->find('i',"skip-inexisting"); + + KviKvsScriptAddon * a = KviKvsScriptAddonManager::instance()->findAddon(szName); + if(!a) + { + if(!bQuiet) + c->warning(__tr2qs_ctx("The addon \"%1\" does not exist","addon").arg(szName)); + return true; + } + + if(szTarget.isEmpty()) + return c->error(__tr2qs_ctx("The target path can't be empty","addon")); + + if(szTarget.indexOf("..") != -1) + return c->error(__tr2qs_ctx("The target path can't contain ..","addon")); + + if(lEntries.isEmpty()) + { + if(!bQuiet) + c->warning(__tr2qs_ctx("Empty file list","addon")); + return true; // nothing to do + } + + QStringList lExpandedEntries; + + foreach(QString szEntry,lEntries) + { + KviFileUtils::adjustFilePath(szEntry); + + if(szEntry.contains("*")) + { + // filtered entry + int idx = szEntry.lastIndexOf(QChar(KVI_PATH_SEPARATOR_CHAR)); + QString szPath; + QString szFilter; + if(idx < 0) + { + szPath = "."; + szFilter = szEntry; + } else { + szPath = szEntry.left(idx); + szFilter = szEntry.mid(idx+1); + } + + QDir dir(szPath); + if(!dir.exists()) + { + if(!bSkipInexisting) + return c->error(__tr2qs_ctx("The directory '%1' doesn't exist","addon").arg(szPath)); + if(!bQuiet) + c->warning(__tr2qs_ctx("Skipping inexisting entry '%1'","addon").arg(szEntry)); + continue; + } + + QStringList sl = dir.entryList( + QStringList(szFilter), + QDir::Files | QDir::NoSymLinks | QDir::Readable | QDir::Hidden | QDir::System, + QDir::Unsorted + ); + + foreach(QString sz,sl) + { + lExpandedEntries.append(QString("%1%2%3").arg(szPath).arg(QString(KVI_PATH_SEPARATOR_CHAR)).arg(sz)); + } + continue; + } + + QFileInfo inf(szEntry); + if(!inf.exists()) + { + if(!bSkipInexisting) + return c->error(__tr2qs_ctx("The file '%1' doesn't exist","addon").arg(szEntry)); + if(!bQuiet) + c->warning(__tr2qs_ctx("Skipping inexisting entry '%1'","addon").arg(szEntry)); + continue; + } + + if(!inf.isFile()) + { + if(!bSkipInexisting) + return c->error(__tr2qs_ctx("The entry '%1' is not a file","addon").arg(szEntry)); + if(!bQuiet) + c->warning(__tr2qs_ctx("Skipping invalid entry '%1'","addon").arg(szEntry)); + continue; + } + + lExpandedEntries.append(szEntry); + } + + // create target path + QString szTargetPath; + g_pApp->getLocalKvircDirectory(szTargetPath,KviApp::None,szTarget); + + KviFileUtils::makeDir(szTargetPath); + + for(QStringList::Iterator it = lExpandedEntries.begin();it != lExpandedEntries.end();++it) + { + QFileInfo inf(*it); + if(!inf.exists()) + { + qDebug("ERROR: File %s doesn't exist, but it should...",inf.fileName().toUtf8().data()); + continue; // bleah.. should never happen + } + + QString szEntry = QString("%1%2%3").arg(szTarget).arg(QString(KVI_PATH_SEPARATOR_CHAR)).arg(inf.fileName()); + g_pApp->getLocalKvircDirectory(szTargetPath,KviApp::None,szEntry); + + if(!bQuiet) + c->window()->output(KVI_OUT_SYSTEMMESSAGE,__tr2qs_ctx("Installing file '%1' into '%2'","addon").arg(*it).arg(szTargetPath)); + + KviFileUtils::copyFile(*it,szTargetPath); + + a->addInstalledFile(szEntry); + } + + return true; +} + +/* @doc: addon.dialog @type: command @@ -651,6 +819,7 @@ static bool addon_module_init(KviModule *m) KVSM_REGISTER_SIMPLE_COMMAND(m,"uninstall",addon_kvs_cmd_uninstall); KVSM_REGISTER_SIMPLE_COMMAND(m,"configure",addon_kvs_cmd_configure); KVSM_REGISTER_SIMPLE_COMMAND(m,"help",addon_kvs_cmd_help); + KVSM_REGISTER_SIMPLE_COMMAND(m,"installfiles",addon_kvs_cmd_installfiles); KVSM_REGISTER_CALLBACK_COMMAND(m,"setconfigurecallback",addon_kvs_cmd_setconfigurecallback); KVSM_REGISTER_CALLBACK_COMMAND(m,"sethelpcallback",addon_kvs_cmd_sethelpcallback); |
