aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Szymon Tomasz Stefanek2010-06-26 03:29:31 +0000
committerGravatar Szymon Tomasz Stefanek2010-06-26 03:29:31 +0000
commitb0fe843132229e5be7aeab6750d824662d778c75 (patch)
treeaa468c215bf08ce745a9fdecefb29b6926b3299d /src
parentMore addon related tweaks (diff)
downloadKVIrc-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.h2
-rw-r--r--src/kvirc/kvs/kvi_kvs_scriptaddonmanager.cpp43
-rw-r--r--src/kvirc/kvs/kvi_kvs_scriptaddonmanager.h12
-rw-r--r--src/modules/addon/libkviaddon.cpp177
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);