aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kvi_configstatus.h2
-rw-r--r--src/kvilib/build/Makefile.am63
-rw-r--r--src/kvilib/config/kvi_confignames.h46
-rw-r--r--src/kvilib/config/kvi_fileextensions.h37
-rw-r--r--src/kvilib/core/kvi_bswap.h25
-rw-r--r--src/kvilib/ext/kvi_osinfo.cpp3
-rw-r--r--src/kvilib/ext/kvi_osinfo.h2
-rw-r--r--src/kvilib/file/kvi_file.cpp105
-rw-r--r--src/kvilib/file/kvi_file.h38
-rw-r--r--src/kvilib/file/kvi_fileutils.cpp30
-rw-r--r--src/kvilib/file/kvi_fileutils.h2
-rw-r--r--src/kvilib/file/kvi_packagefile.cpp964
-rw-r--r--src/kvilib/file/kvi_packagefile.h141
-rw-r--r--src/kvilib/file/kvi_targzfile.h2
-rw-r--r--src/kvirc/kernel/kvi_coreactionnames.h2
-rw-r--r--src/kvirc/kernel/kvi_coreactions.cpp13
-rw-r--r--src/kvirc/kernel/kvi_iconmanager.cpp4
-rw-r--r--src/kvirc/kernel/kvi_iconmanager.h6
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionstatedata.h4
-rw-r--r--src/kvirc/sparser/kvi_ircmessage.h8
-rw-r--r--src/kvirc/sparser/kvi_sp_numeric.cpp20
-rw-r--r--src/kvirc/sparser/kvi_sparser.cpp27
-rw-r--r--src/kvirc/ui/kvi_menubar.cpp2
-rw-r--r--src/kvirc/ui/kvi_msgbox.cpp2
-rw-r--r--src/kvirc/ui/kvi_selectors.cpp26
-rw-r--r--src/kvirc/ui/kvi_selectors.h12
-rw-r--r--src/modules/Makefile.am1
-rw-r--r--src/modules/help/libkvihelp.cpp6
-rw-r--r--src/modules/options/instances.cpp41
-rw-r--r--src/modules/options/optw_theme.cpp583
-rw-r--r--src/modules/options/optw_theme.h87
-rw-r--r--src/modules/theme/.svnignore11
-rw-r--r--src/modules/theme/Makefile.am20
-rw-r--r--src/modules/theme/libkvitheme.cpp122
-rw-r--r--src/modules/theme/managementdialog.cpp1148
-rw-r--r--src/modules/theme/managementdialog.h164
36 files changed, 2944 insertions, 825 deletions
diff --git a/src/kvi_configstatus.h b/src/kvi_configstatus.h
index 5c3b21537..f4edc813c 100644
--- a/src/kvi_configstatus.h
+++ b/src/kvi_configstatus.h
@@ -8,7 +8,7 @@
/* #undef BIG_ENDIAN_MACHINE_BYTE_ORDER */
/* this is the build date (configure date rather) */
-#define BUILD_DATE "Mon Dec 18 04:12:50 UTC 2006"
+#define BUILD_DATE "Sat Dec 30 13:42:43 UTC 2006"
/* these are the build flags */
#define BUILD_FLAGS "x86_64-cefgikopsAGTZ"
diff --git a/src/kvilib/build/Makefile.am b/src/kvilib/build/Makefile.am
index 4a94ec214..cf7bbbbea 100644
--- a/src/kvilib/build/Makefile.am
+++ b/src/kvilib/build/Makefile.am
@@ -58,6 +58,7 @@ libkvilib_la_SOURCES = \
../ext/kvi_stringconversion.cpp \
../file/kvi_file.cpp \
../file/kvi_fileutils.cpp \
+ ../file/kvi_packagefile.cpp \
../file/kvi_targzfile.cpp \
../irc/kvi_avatar.cpp \
../irc/kvi_avatarcache.cpp \
@@ -91,21 +92,50 @@ libkvilib_la_SOURCES = \
#
-headers_HEADERS = ../config/kvi_confignames.h ../config/kvi_debug.h ../config/kvi_defaults.h \
-../config/kvi_settings.h ../config/kvi_sourcesdate.h ../config/kvi_wincfg.h ../core/kvi_bswap.h ../core/kvi_error.h \
-../core/kvi_heapobject.h ../core/kvi_inttypes.h ../core/kvi_list.h ../core/kvi_malloc.h \
-../core/kvi_memmove.h ../core/kvi_qstring.h ../core/kvi_strasm.h ../core/kvi_string.h \
-../core/kvi_stringarray.h \
-../ext/kvi_cmdformatter.h ../ext/kvi_config.h \
-../ext/kvi_crypt.h ../ext/kvi_databuffer.h \
-../ext/kvi_datacontainer.h \
-../ext/kvi_doublebuffer.h \
-../ext/kvi_osinfo.h \
-../ext/kvi_garbage.h ../ext/kvi_imagelib.h \
-../ext/kvi_md5.h ../ext/kvi_mediatype.h ../ext/kvi_msgtype.h ../ext/kvi_parameterlist.h ../ext/kvi_pixmap.h \
-../ext/kvi_proxydb.h ../ext/kvi_regchan.h ../ext/kvi_regusersdb.h ../ext/kvi_sharedfiles.h \
-../ext/kvi_stringconversion.h ../ext/kvi_xlib.h ../file/kvi_file.h \
-../file/kvi_fileutils.h ../file/kvi_targzfile.h ../irc/kvi_avatar.h ../irc/kvi_avatarcache.h ../irc/kvi_ircmask.h \
+headers_HEADERS = \
+ ../config/kvi_confignames.h \
+ ../config/kvi_debug.h \
+ ../config/kvi_defaults.h \
+ ../config/kvi_fileextensions.h \
+ ../config/kvi_settings.h \
+ ../config/kvi_sourcesdate.h \
+ ../config/kvi_wincfg.h \
+ ../core/kvi_bswap.h \
+ ../core/kvi_error.h \
+ ../core/kvi_heapobject.h \
+ ../core/kvi_inttypes.h \
+ ../core/kvi_list.h \
+ ../core/kvi_malloc.h \
+ ../core/kvi_memmove.h \
+ ../core/kvi_qstring.h \
+ ../core/kvi_strasm.h \
+ ../core/kvi_string.h \
+ ../core/kvi_stringarray.h \
+ ../ext/kvi_cmdformatter.h \
+ ../ext/kvi_config.h \
+ ../ext/kvi_crypt.h \
+ ../ext/kvi_databuffer.h \
+ ../ext/kvi_datacontainer.h \
+ ../ext/kvi_doublebuffer.h \
+ ../ext/kvi_osinfo.h \
+ ../ext/kvi_garbage.h \
+ ../ext/kvi_imagelib.h \
+ ../ext/kvi_md5.h \
+ ../ext/kvi_mediatype.h \
+ ../ext/kvi_msgtype.h \
+ ../ext/kvi_parameterlist.h \
+ ../ext/kvi_pixmap.h \
+ ../ext/kvi_proxydb.h \
+ ../ext/kvi_regchan.h \
+ ../ext/kvi_regusersdb.h \
+ ../ext/kvi_sharedfiles.h \
+ ../ext/kvi_stringconversion.h \
+ ../ext/kvi_xlib.h \
+ ../file/kvi_file.h \
+ ../file/kvi_fileutils.h \
+ ../file/kvi_packagefile.h \
+ ../file/kvi_targzfile.h \
+ ../irc/kvi_avatar.h ../irc/kvi_avatarcache.h ../irc/kvi_ircmask.h \
../irc/kvi_ircserverdb.h ../irc/kvi_ircserver.h ../irc/kvi_ircuserdb.h ../irc/kvi_mirccntrl.h \
../irc/kvi_nickserv.h ../net/kvi_dns.h ../net/kvi_http.h ../net/kvi_netutils.h ../net/kvi_socket.h \
../net/kvi_sockettype.h ../net/kvi_ssl.h ../net/kvi_url.h ../system/kvi_env.h \
@@ -123,6 +153,9 @@ headers_HEADERS = ../config/kvi_confignames.h ../config/kvi_debug.h ../con
../ext/moc_%.cpp: ../ext/%.h
$(SS_QT_MOC) $< -o $@
+../file/moc_%.cpp: ../file/%.h
+ $(SS_QT_MOC) $< -o $@
+
../irc/moc_%.cpp: ../irc/%.h
$(SS_QT_MOC) $< -o $@
diff --git a/src/kvilib/config/kvi_confignames.h b/src/kvilib/config/kvi_confignames.h
index 3005ef725..81612d226 100644
--- a/src/kvilib/config/kvi_confignames.h
+++ b/src/kvilib/config/kvi_confignames.h
@@ -25,6 +25,8 @@
//
//=============================================================================
+#include "kvi_fileextensions.h"
+
//=============================================================================
// This file contains the config file names used in KVIrc
//
@@ -32,27 +34,27 @@
// may find themselves in trouble
//=============================================================================
-#define KVI_CONFIGFILE_MAIN "main.kvc"
-#define KVI_CONFIGFILE_WINPROPERTIES "winproperties.kvc"
-#define KVI_CONFIGFILE_SERVERDB "serverdb.kvc"
-#define KVI_CONFIGFILE_PROXYDB "proxydb.kvc"
-#define KVI_CONFIGFILE_EVENTS "events.kvc"
-#define KVI_CONFIGFILE_RAWEVENTS "rawevents.kvc"
-#define KVI_CONFIGFILE_POPUPS "popups.kvc"
-#define KVI_CONFIGFILE_SCRIPTTOOLBARS "toolbars.kvc"
-#define KVI_CONFIGFILE_CUSTOMTOOLBARS "customtoolbars.kvc"
-#define KVI_CONFIGFILE_MEDIATYPES "mediatypes.kvc"
-#define KVI_CONFIGFILE_REGUSERDB "reguserdb.kvc"
-#define KVI_CONFIGFILE_SHAREDFILES "sharedfiles.kvc"
-#define KVI_CONFIGFILE_RECENT "recent.kvc"
-#define KVI_CONFIGFILE_TOOLBARS "toolbarpos.kvc"
-#define KVI_CONFIGFILE_ALIASES "aliases.kvc"
-#define KVI_CONFIGFILE_NICKSERVDATABASE "nickserv.kvc"
-#define KVI_CONFIGFILE_TEXTICONS "texticons.kvc"
-#define KVI_CONFIGFILE_REGCHANDB "regchan.kvc"
-#define KVI_CONFIGFILE_INPUTHISTORY "inputhistory.kvc"
-#define KVI_CONFIGFILE_AVATARCACHE "avatarcache.kvc"
-#define KVI_CONFIGFILE_USERACTIONS "useractions.kvc"
-#define KVI_CONFIGFILE_SCRIPTADDONS "scriptaddons.kvc"
+#define KVI_CONFIGFILE_MAIN "main." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_WINPROPERTIES "winproperties." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_SERVERDB "serverdb." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_PROXYDB "proxydb." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_EVENTS "events." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_RAWEVENTS "rawevents." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_POPUPS "popups." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_SCRIPTTOOLBARS "toolbars." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_CUSTOMTOOLBARS "customtoolbars." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_MEDIATYPES "mediatypes." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_REGUSERDB "reguserdb." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_SHAREDFILES "sharedfiles." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_RECENT "recent." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_TOOLBARS "toolbarpos." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_ALIASES "aliases." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_NICKSERVDATABASE "nickserv." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_TEXTICONS "texticons." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_REGCHANDB "regchan." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_INPUTHISTORY "inputhistory." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_AVATARCACHE "avatarcache." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_USERACTIONS "useractions." KVI_FILEEXTENSION_CONFIG
+#define KVI_CONFIGFILE_SCRIPTADDONS "scriptaddons." KVI_FILEEXTENSION_CONFIG
#endif //_KVI_CONFIGNAMES_H_
diff --git a/src/kvilib/config/kvi_fileextensions.h b/src/kvilib/config/kvi_fileextensions.h
new file mode 100644
index 000000000..7036e6d8d
--- /dev/null
+++ b/src/kvilib/config/kvi_fileextensions.h
@@ -0,0 +1,37 @@
+#ifndef _KVI_FILEEXTENSIONS_H_
+#define _KVI_FILEEXTENSIONS_H_
+
+//=============================================================================
+//
+// File : kvi_fileextensions.h
+// Creation date : Tue Dec 26 2006 05:09:22 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2006 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+//=============================================================================
+
+//=============================================================================
+// This file contains the file extensions used by KVIrc
+//=============================================================================
+
+#define KVI_FILEEXTENSION_CONFIG "kvc"
+#define KVI_FILEEXTENSION_SCRIPT "kvs"
+#define KVI_FILEEXTENSION_THEMEPACKAGE "kvt"
+#define KVI_FILEEXTENSION_ADDONPACKAGE "kva"
+
+#endif //_KVI_FILEEXTENSIONS_H_
diff --git a/src/kvilib/core/kvi_bswap.h b/src/kvilib/core/kvi_bswap.h
index 5f0c959bc..6da000f2a 100644
--- a/src/kvilib/core/kvi_bswap.h
+++ b/src/kvilib/core/kvi_bswap.h
@@ -7,7 +7,7 @@
// Creation date : Fri Mar 19 1999 03:15:21 CEST by Szymon Stefanek
//
// This file is part of the KVirc irc client distribution
-// Copyright (C) 1999-2001 Szymon Stefanek (pragma at kvirc dot net)
+// Copyright (C) 1999-2006 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
@@ -26,23 +26,38 @@
//=============================================================================
#include "kvi_settings.h"
+#include "kvi_inttypes.h"
-// Removed : kvi_settings.h includes qglobal.h for debug()
-//#include <qglobal.h> // for Q_UINT* and Q_INT*
// KVILIB_API has been removed from therse two functions
// these should always go inlined
-inline Q_UINT32 kvi_swap32(Q_UINT32 i)
+inline kvi_u64_t kvi_swap64(kvi_u64_t i)
{
+ // abcdefgh to hgfedcba
+ return ((i << 56) | /* h to a */
+ ((i & 0xff00) << 40) | /* g to b */
+ ((i & 0xff0000) << 24) | /* f to c */
+ ((i & 0xff000000) << 8) | /* e to d */
+ ((i >> 8) & 0xff000000) | /* d to e */
+ ((i >> 24) & 0xff0000) | /* c to f */
+ ((i >> 40) & 0xff00) | /* b to g */
+ (i >> 56)); /* a to h */
+}
+
+inline kvi_u32_t kvi_swap32(kvi_u32_t i)
+{
+ // abcd to dcba
return ((i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24));
}
-inline Q_UINT16 kvi_swap16(Q_UINT16 i)
+inline kvi_u16_t kvi_swap16(kvi_u16_t i)
{
+ // ab to ba
return ((i << 8) | (i >> 8));
}
+
#endif // !_KVI_BSWAP_H_
diff --git a/src/kvilib/ext/kvi_osinfo.cpp b/src/kvilib/ext/kvi_osinfo.cpp
index 3f31f5c46..a189454bf 100644
--- a/src/kvilib/ext/kvi_osinfo.cpp
+++ b/src/kvilib/ext/kvi_osinfo.cpp
@@ -376,4 +376,5 @@ namespace KviOsInfo
else
return QString::null;
}
-} \ No newline at end of file
+}
+
diff --git a/src/kvilib/ext/kvi_osinfo.h b/src/kvilib/ext/kvi_osinfo.h
index ee9052765..7409ddd12 100644
--- a/src/kvilib/ext/kvi_osinfo.h
+++ b/src/kvilib/ext/kvi_osinfo.h
@@ -40,4 +40,4 @@ namespace KviOsInfo
extern KVILIB_API QString hostname();
};
-#endif \ No newline at end of file
+#endif //!_KVI_OSINFO_H_
diff --git a/src/kvilib/file/kvi_file.cpp b/src/kvilib/file/kvi_file.cpp
index aec83daba..6d45be342 100644
--- a/src/kvilib/file/kvi_file.cpp
+++ b/src/kvilib/file/kvi_file.cpp
@@ -26,7 +26,7 @@
#include "kvi_file.h"
-#include "kvi_bswap.h"
+#include "kvi_byteorder.h"
KviFile::KviFile()
@@ -43,17 +43,48 @@ KviFile::~KviFile()
{
}
+bool KviFile::save(const QByteArray &bData)
+{
+ if(!save((kvi_u32_t)(bData.size())))return false;
+ return (writeBlock(bData.data(),bData.size()) == ((int)(bData.size())));
+}
+
+bool KviFile::load(QByteArray &bData)
+{
+ kvi_u32_t iLen;
+ if(!load(iLen))return false;
+ bData.resize(iLen);
+ if(readBlock((char *)(bData.data()),iLen) != iLen)return false;
+ return true;
+}
+
+bool KviFile::save(const QCString &szData)
+{
+ if(!save((kvi_u32_t)(szData.length())))return false;
+ return (writeBlock(szData.data(),szData.length()) == ((int)(szData.length())));
+}
+
+bool KviFile::load(QCString &szData)
+{
+ kvi_u32_t iLen;
+ if(!load(iLen))return false;
+ szData.resize(iLen + 1);
+ if(readBlock((char *)(szData.data()),iLen) != iLen)return false;
+ *(szData.data() + iLen) = 0;
+ return true;
+}
+
bool KviFile::save(const QString &szData)
{
QCString c = szData.utf8();
- if(!save(c.length()))return false;
+ if(!save((kvi_u32_t)(c.length())))return false;
return (writeBlock(c.data(),c.length()) == ((int)(c.length())));
}
bool KviFile::load(QString &szData)
{
- int iLen;
+ kvi_u32_t iLen;
if(!load(iLen))return false;
QCString tmp;
tmp.resize(iLen + 1);
@@ -65,67 +96,79 @@ bool KviFile::load(QString &szData)
bool KviFile::save(const KviStr &szData)
{
- if(!save(szData.len()))return false;
+ if(!save((kvi_u32_t)(szData.len())))return false;
return (writeBlock(szData.ptr(),szData.len()) == (int) szData.len());
}
bool KviFile::load(KviStr &szData)
{
- int iLen;
+ kvi_u32_t iLen;
if(!load(iLen))return false;
szData.setLength(iLen);
return (readBlock((char *)(szData.ptr()),iLen) == iLen);
}
-bool KviFile::save(kvi_i32_t t)
+bool KviFile::save(kvi_u32_t t)
{
-#ifdef BIGENDIAN_MACHINE_BYTE_ORDER
- t = kvi_swap32(t);
+#ifndef LOCAL_CPU_LITTLE_ENDIAN
+ t = kvi_localCpuToLittleEndian32(t);
#endif
- return (writeBlock((const char *)(&t),sizeof(kvi_i32_t)) == sizeof(kvi_i32_t));
+ return (writeBlock((const char *)(&t),sizeof(kvi_u32_t)) == sizeof(kvi_u32_t));
}
-bool KviFile::load(kvi_i32_t &t)
+bool KviFile::load(kvi_u32_t &t)
{
-#ifdef BIGENDIAN_MACHINE_BYTE_ORDER
- if(!(readBlock((char *)(&t),sizeof(kvi_i32_t)) == sizeof(kvi_i32_t)))return false;
- t = kvi_swap32(t);
- return true;
-#else
- return (readBlock((char *)(&t),sizeof(kvi_i32_t)) == sizeof(kvi_i32_t));
+ if(!(readBlock((char *)(&t),sizeof(kvi_u32_t)) == sizeof(kvi_u32_t)))return false;
+#ifndef LOCAL_CPU_LITTLE_ENDIAN
+ t = kvi_littleEndianToLocalCpu32(t)
#endif
+ return true;
}
-bool KviFile::save(kvi_i16_t t)
+bool KviFile::save(kvi_u64_t t)
{
-#ifdef BIGENDIAN_MACHINE_BYTE_ORDER
- t = kvi_swap16(t);
+#ifndef LOCAL_CPU_LITTLE_ENDIAN
+ t = kvi_localCpuToLittleEndian64(t);
#endif
- return (writeBlock((const char *)(&t),sizeof(kvi_i16_t)) == sizeof(kvi_i16_t));
+ return (writeBlock((const char *)(&t),sizeof(kvi_u64_t)) == sizeof(kvi_u64_t));
}
-bool KviFile::load(kvi_i16_t &t)
+bool KviFile::load(kvi_u64_t &t)
{
-#ifdef BIGENDIAN_MACHINE_BYTE_ORDER
- if(!(readBlock((char *)(&t),sizeof(kvi_i16_t)) == sizeof(kvi_i16_t)))return false;
- t = kvi_swap32(t);
- return true;
-#else
- return (readBlock((char *)(&t),sizeof(kvi_i16_t)) == sizeof(kvi_i16_t));
+ if(!(readBlock((char *)(&t),sizeof(kvi_u32_t)) == sizeof(kvi_u32_t)))return false;
+#ifndef LOCAL_CPU_LITTLE_ENDIAN
+ t = kvi_littleEndianToLocalCpu32(t)
#endif
+ return true;
}
-bool KviFile::save(kvi_i8_t t)
+
+bool KviFile::save(kvi_u16_t t)
{
- return (writeBlock((const char *)(&t),sizeof(kvi_i8_t)) == sizeof(kvi_i8_t));
+#ifndef LOCAL_CPU_LITTLE_ENDIAN
+ t = kvi_localCpuToLittleEndian16(t);
+#endif
+ return (writeBlock((const char *)(&t),sizeof(kvi_u16_t)) == sizeof(kvi_u16_t));
}
-bool KviFile::load(kvi_i8_t &t)
+bool KviFile::load(kvi_u16_t &t)
{
- return (readBlock((char *)(&t),sizeof(kvi_i8_t)) == sizeof(kvi_i8_t));
+ if(!(readBlock((char *)(&t),sizeof(kvi_u16_t)) == sizeof(kvi_u16_t)))return false;
+#ifndef LOCAL_CPU_LITTLE_ENDIAN
+ t = kvi_littleEndianToLocalCpu16(t);
+#endif
+ return true;
}
+bool KviFile::save(kvi_u8_t t)
+{
+ return (writeBlock((const char *)(&t),sizeof(kvi_u8_t)) == sizeof(kvi_u8_t));
+}
+bool KviFile::load(kvi_u8_t &t)
+{
+ return (readBlock((char *)(&t),sizeof(kvi_u8_t)) == sizeof(kvi_u8_t));
+}
bool KviFile::save(KviPtrList<KviStr> * pData)
diff --git a/src/kvilib/file/kvi_file.h b/src/kvilib/file/kvi_file.h
index 427944e0c..5d04fc7bd 100644
--- a/src/kvilib/file/kvi_file.h
+++ b/src/kvilib/file/kvi_file.h
@@ -30,7 +30,7 @@
#include "kvi_inttypes.h"
#include <qfile.h>
-
+#include <qcstring.h>
#include <time.h>
@@ -42,29 +42,41 @@ public:
~KviFile();
public:
// This stuff loads and saves LITTLE ENDIAN DATA!
- bool save(kvi_i32_t t);
- bool load(kvi_i32_t &t);
+ bool save(kvi_u64_t t);
+ bool load(kvi_u64_t &t);
+
+ bool save(kvi_i64_t t){ return save((kvi_u64_t)t); };
+ bool load(kvi_i64_t &t){ return load((kvi_u64_t &)t); };
- bool save(kvi_u32_t t){ return save((kvi_i32_t)t); };
- bool load(kvi_u32_t &t){ return load((kvi_i32_t &)t); };
+ bool save(kvi_u32_t t);
+ bool load(kvi_u32_t &t);
- bool save(kvi_i16_t t);
- bool load(kvi_i16_t &t);
+ bool save(kvi_i32_t t){ return save((kvi_u32_t)t); };
+ bool load(kvi_i32_t &t){ return load((kvi_u32_t &)t); };
- bool save(kvi_u16_t t){ return save((kvi_i16_t)t); };
- bool load(kvi_u16_t &t){ return load((kvi_i16_t &)t); };
+ bool save(kvi_u16_t t);
+ bool load(kvi_u16_t &t);
- bool save(kvi_i8_t t);
- bool load(kvi_i8_t &t);
+ bool save(kvi_i16_t t){ return save((kvi_u16_t)t); };
+ bool load(kvi_i16_t &t){ return load((kvi_u16_t &)t); };
- bool save(kvi_u8_t t){ return save((kvi_i8_t)t); };
- bool load(kvi_u8_t &t){ return load((kvi_i8_t &)t); };;
+ bool save(kvi_u8_t t);
+ bool load(kvi_u8_t &t);
+
+ bool save(kvi_i8_t t){ return save((kvi_u8_t)t); };
+ bool load(kvi_i8_t &t){ return load((kvi_u8_t &)t); };;
// bool save(time_t t){ return save((kvi_i32_t)t); };
// bool load(time_t &t){ return load((kvi_i32_t)t); };
bool save(const KviStr &szData);
bool load(KviStr &szData);
+
+ bool save(const QCString &szData);
+ bool load(QCString &szData);
+
+ bool save(const QByteArray &bData);
+ bool load(QByteArray &bData);
bool save(const QString &szData);
bool load(QString &szData);
diff --git a/src/kvilib/file/kvi_fileutils.cpp b/src/kvilib/file/kvi_fileutils.cpp
index 6ac83ef16..876659eb9 100644
--- a/src/kvilib/file/kvi_fileutils.cpp
+++ b/src/kvilib/file/kvi_fileutils.cpp
@@ -281,6 +281,36 @@ namespace KviFileUtils
return removeDir(szPath);
}
+ bool deleteDir(const QString &szPath)
+ {
+ QDir d(szPath);
+ QStringList sl = d.entryList(QDir::Dirs);
+ QStringList::Iterator it;
+ for(it=sl.begin();it != sl.end();it++)
+ {
+ QString szSubdir = *it;
+ if(!(KviQString::equalCS(szSubdir,"..") || KviQString::equalCS(szSubdir,".")))
+ {
+ QString szSubPath = szPath;
+ KviQString::ensureLastCharIs(szSubPath,QChar(KVI_PATH_SEPARATOR_CHAR));
+ szSubPath += szSubdir;
+ if(!KviFileUtils::deleteDir(szSubPath))
+ return false;
+ }
+ }
+
+ sl = d.entryList(QDir::Files);
+ for(it=sl.begin();it != sl.end();it++)
+ {
+ QString szFilePath = szPath;
+ KviQString::ensureLastCharIs(szFilePath,QChar(KVI_PATH_SEPARATOR_CHAR));
+ szFilePath += *it;
+ if(!KviFileUtils::removeFile(szFilePath))
+ return false;
+ }
+
+ return KviFileUtils::removeDir(szPath);
+ }
bool writeFile(const QString &szPath,const QString &szData,bool bAppend)
{
diff --git a/src/kvilib/file/kvi_fileutils.h b/src/kvilib/file/kvi_fileutils.h
index dbf112cb6..4a7580959 100644
--- a/src/kvilib/file/kvi_fileutils.h
+++ b/src/kvilib/file/kvi_fileutils.h
@@ -64,6 +64,8 @@ namespace KviFileUtils
// removes a dir (must be empty)
extern KVILIB_API bool removeDir(const QString &szPath);
extern KVILIB_API bool removeDir(const char* path);
+ // removes a dir recursively
+ extern KVILIB_API bool deleteDir(const QString &szPath);
// writes a complete file (utf8 version)
extern KVILIB_API bool writeFile(const QString &szPath,const QString &szData,bool bAppend = false);
extern KVILIB_API bool writeFile(const char* path,const QString &szData,bool bAppend = false);
diff --git a/src/kvilib/file/kvi_packagefile.cpp b/src/kvilib/file/kvi_packagefile.cpp
new file mode 100644
index 000000000..4c0b564c2
--- /dev/null
+++ b/src/kvilib/file/kvi_packagefile.cpp
@@ -0,0 +1,964 @@
+//=============================================================================
+//
+// File : kvi_packagefile.cpp
+// Created on Tue 26 Dec 2006 05:33:33 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2006 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+//=============================================================================
+
+#define __KVILIB__
+#include "kvi_packagefile.h"
+
+#include "kvi_file.h"
+#include "kvi_fileutils.h"
+#include "kvi_locale.h"
+#include "kvi_inttypes.h"
+
+#include <qprogressdialog.h>
+#include <qdir.h>
+
+#ifdef COMPILE_ZLIB_SUPPORT
+ #include <zlib.h>
+#endif
+
+//
+// A KVIrc Package File is basically a simple zip file with some additional meta-data.
+// The package file has the following format
+//
+
+// Field Type Bytes Description
+//-------------------------------------------------------------------------------
+ // PackageHeader:
+// Magic Bytes 4 'KVPF': Signature for the Kvirc Package File
+// Version uint32 4 0x00000001: Version of this package file
+// Flags uint32 4 0x00000000: Flags, in version 1 is reserved and must be zero
+// PackageInfo:
+// InfoFieldCount uint32 4 Number of package info fields
+// InfoField InfoField Variable A list of informational name-value pairs
+// InfoField InfoField Variable A list of informational name-value pairs
+// InfoField InfoField Variable A list of informational name-value pairs
+// .... .... ....
+// PackageData:
+// DataField DataField Variable A list of data fields with format defined below
+// DataField DataField Variable A list of data fields with format defined below
+// DataField DataField Variable A list of data fields with format defined below
+// .... .... ....
+
+// InfoField:
+// Name UniString Variable The "name" element of the info field
+// ValueType uint32 4 The type of the following ValueData field
+// ValueData ValueData Variable
+
+// ValueData for ValueType 1 (string field)
+// Value UniString Variable The value element of type string of the the info field
+
+// ValueData for ValueType 2 (binary buffer field)
+// BufferLen uint32 4 The length of the binary buffer
+// BufferData Bytes Variable The data for the binary buffer
+
+
+// UniString:
+// StringLen uint32 4 The length of the string data in BYTES (null terminator NOT included)
+// StringData Bytes StringLen An utf8 encoded string (do NOT write the NULL terminator)
+
+// Bytes:
+// Byte uint8 1 A byte
+// Byte uint8 1 A byte
+// .... .... ....
+
+// DataField:
+// FieldType uint32 4 The type of the field, see below for defined values
+// FieldLen uint32 4 FieldData length in bytes (useful for skipping a field if unsupported)
+// FieldData Variable FieldLen The data of the field, see below for defined values
+
+// FieldData for FieldType 1 (file field)
+// Flags uint32 4 Bitmask. Bits: 1=FileIsDeflated
+// Path UniString Variable A relative path expressed as utf8 string. \ AND / are considered to be separators
+// Size uint32 4 Size of the following file data
+// FilePayload Bytes Variable
+
+// Everything is stored in LITTLE ENDIAN byte order.
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Da Base Engine
+
+KviPackageIOEngine::KviPackageIOEngine()
+{
+ m_pProgressDialog = 0;
+ m_pStringInfoFields = new QDict<QString>();
+ m_pStringInfoFields->setAutoDelete(true);
+ m_pBinaryInfoFields = new QDict<QByteArray>();
+ m_pBinaryInfoFields->setAutoDelete(true);
+}
+
+KviPackageIOEngine::~KviPackageIOEngine()
+{
+ if(m_pProgressDialog)delete m_pProgressDialog;
+ delete m_pStringInfoFields;
+ delete m_pBinaryInfoFields;
+}
+
+
+bool KviPackageIOEngine::updateProgress(int iProgress,const QString &szLabel)
+{
+ if(!m_pProgressDialog)return true;
+ m_pProgressDialog->setProgress(iProgress);
+ m_pProgressDialogLabel->setText(szLabel);
+ qApp->processEvents();
+ if(m_pProgressDialog->wasCanceled())
+ {
+ setLastError(__tr2qs("Operation cancelled"));
+ return false;
+ }
+ return true;
+}
+
+void KviPackageIOEngine::showProgressDialog(const QString &szCaption,int iTotalSteps)
+{
+ m_pProgressDialog = new QProgressDialog(QString(""),__tr2qs("Cancel"),iTotalSteps,0,"",true);
+ m_pProgressDialog->setCaption(szCaption);
+ m_pProgressDialogLabel = new QLabel(m_pProgressDialog);
+ m_pProgressDialogLabel->setMaximumSize(500,300);
+ m_pProgressDialog->setLabel(m_pProgressDialogLabel);
+}
+
+void KviPackageIOEngine::hideProgressDialog()
+{
+ if(!m_pProgressDialog)return;
+ delete m_pProgressDialog;
+ m_pProgressDialog = 0;
+}
+
+bool KviPackageIOEngine::writeError()
+{
+ setLastError(__tr2qs("File write error"));
+ return false;
+}
+
+bool KviPackageIOEngine::readError()
+{
+ setLastError(__tr2qs("File read error"));
+ return false;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Da Writer
+
+
+KviPackageWriter::KviPackageWriter()
+: KviPackageIOEngine()
+{
+ m_pDataFields = new KviPtrList<DataField>();
+ m_pDataFields->setAutoDelete(true);
+}
+
+KviPackageWriter::~KviPackageWriter()
+{
+ delete m_pDataFields;
+}
+
+void KviPackageWriter::addInfoField(const QString &szName,const QString &szValue)
+{
+ m_pStringInfoFields->replace(szName,new QString(szValue));
+}
+
+void KviPackageWriter::addInfoField(const QString &szName,QByteArray * pValue)
+{
+ m_pBinaryInfoFields->replace(szName,pValue);
+}
+
+bool KviPackageWriter::addFile(const QString &szLocalFileName,const QString &szTargetFileName,kvi_u32_t uAddFileFlags)
+{
+ QFileInfo fi(szLocalFileName);
+ return addFileInternal(&fi,szLocalFileName,szTargetFileName,uAddFileFlags);
+}
+
+bool KviPackageWriter::addFileInternal(const QFileInfo * fi,const QString &szLocalFileName,const QString &szTargetFileName,kvi_u32_t uAddFileFlags)
+{
+ if(!(fi->isFile() && fi->isReadable()))
+ return false;
+
+ if(!(uAddFileFlags & FollowSymLinks))
+ {
+ if(fi->isSymLink())
+ return true; // do NOT add a symlink
+ }
+
+ DataField * f = new DataField();
+ f->m_uType = KVI_PACKAGE_DATAFIELD_TYPE_FILE;
+ f->m_bFileAllowCompression = !(uAddFileFlags & NoCompression);
+ f->m_szFileLocalName = szLocalFileName;
+ f->m_szFileTargetName = szTargetFileName;
+ m_pDataFields->append(f);
+
+ return true;
+}
+
+bool KviPackageWriter::addDirectory(const QString &szLocalDirectoryName,const QString &szTargetDirectoryPrefix,kvi_u32_t uAddFileFlags)
+{
+ QDir d(szLocalDirectoryName);
+ int iFlags = QDir::Files | QDir::Readable;
+ if(!(uAddFileFlags & FollowSymLinks))
+ iFlags |= QDir::NoSymLinks;
+ const QFileInfoList * sl = d.entryInfoList(iFlags);
+ if(!sl)return false;
+ QFileInfoListIterator it(*sl);
+ while(QFileInfo * fi = it.current())
+ {
+ QString szSFileName = szLocalDirectoryName;
+ KviQString::ensureLastCharIs(szSFileName,QChar(KVI_PATH_SEPARATOR_CHAR));
+ szSFileName += fi->fileName();
+ QString szDFileName = szTargetDirectoryPrefix;
+ KviQString::ensureLastCharIs(szDFileName,QChar(KVI_PATH_SEPARATOR_CHAR));
+ szDFileName += fi->fileName();
+ if(!addFileInternal(fi,szSFileName,szDFileName,uAddFileFlags))
+ return false;
+ ++it;
+ }
+ iFlags = QDir::Dirs | QDir::Readable;
+ if(!(uAddFileFlags & FollowSymLinks))
+ iFlags |= QDir::NoSymLinks;
+ sl = d.entryInfoList(iFlags);
+ if(!sl)return false;
+
+ QFileInfoListIterator it2(*sl);
+ while(QFileInfo * fi2 = it2.current())
+ {
+ QString szDir = fi2->fileName();
+ if(!KviQString::equalCS(szDir,"..") && !KviQString::equalCS(szDir,"."))
+ {
+ QString szSDirName = szLocalDirectoryName;
+ KviQString::ensureLastCharIs(szSDirName,QChar(KVI_PATH_SEPARATOR_CHAR));
+ szSDirName += szDir;
+ QString szDDirName = szTargetDirectoryPrefix;
+ KviQString::ensureLastCharIs(szDDirName,QChar(KVI_PATH_SEPARATOR_CHAR));
+ szDDirName += szDir;
+ if(!addDirectory(szSDirName,szDDirName,uAddFileFlags))
+ return false;
+ }
+ ++it2;
+ }
+
+ return true;
+}
+
+
+
+#define BUFFER_SIZE 32768
+
+bool KviPackageWriter::packFile(KviFile * pFile,DataField * pDataField)
+{
+ QString szProgressText;
+ KviQString::sprintf(szProgressText,__tr2qs("Packaging file %Q"),&(pDataField->m_szFileLocalName));
+ if(!updateProgress(m_iCurrentProgress,szProgressText))
+ return false; // aborted
+
+
+ KviFile source(pDataField->m_szFileLocalName);
+ if(!source.open(IO_ReadOnly))
+ {
+ setLastError(__tr2qs("Failed to open a source file for reading"));
+ return false;
+ }
+
+ kvi_u32_t uSize = source.size();
+
+ // Flags
+#ifdef COMPILE_ZLIB_SUPPORT
+ kvi_u32_t uFlags = pDataField->m_bFileAllowCompression ?
+ (uSize > 64 ? KVI_PACKAGE_DATAFIELD_FLAG_FILE_DEFLATE : 0)
+ : 0;
+#else
+ kvi_u32_t uFlags = 0;
+#endif
+
+ if(!pFile->save(uFlags))return writeError();
+
+ QCString szTargetFileName = pDataField->m_szFileTargetName.utf8();
+
+ // Path
+ if(!pFile->save(szTargetFileName))return writeError();
+
+ KviFile::Offset savedSizeOffset = pFile->at();
+
+ // Size : will update it if compression is requested
+ if(!pFile->save(uSize))return writeError();
+
+ pDataField->m_uWrittenFieldLength = 4 + 4 + 4 + szTargetFileName.length(); // sizeof(flags + uncompressed size + path len + path)
+
+ // FilePayload
+#ifdef COMPILE_ZLIB_SUPPORT
+ if(uFlags & KVI_PACKAGE_DATAFIELD_FLAG_FILE_DEFLATE)
+ {
+ unsigned char ibuffer[BUFFER_SIZE];
+ unsigned char obuffer[BUFFER_SIZE];
+
+ kvi_i32_t iReaded = source.readBlock((char *)ibuffer,BUFFER_SIZE);
+ if(iReaded < 0)
+ return readError();
+
+ z_stream zstr;
+ zstr.zalloc = Z_NULL;
+ zstr.zfree = Z_NULL;
+ zstr.opaque = Z_NULL;
+ zstr.next_in = ibuffer;
+ zstr.avail_in = iReaded;
+ zstr.next_out = obuffer;
+ zstr.avail_out = BUFFER_SIZE;
+
+ if(deflateInit(&zstr,9) != Z_OK)
+ {
+ setLastError(__tr2qs("Compression library initialization error"));
+ return false;
+ }
+
+ while(iReaded > 0)
+ {
+ zstr.next_out = obuffer;
+ zstr.avail_out = BUFFER_SIZE;
+
+ if(deflate(&zstr,Z_NO_FLUSH) != Z_OK)
+ {
+ setLastError(__tr2qs("Compression library error"));
+ return false;
+ }
+
+ if(zstr.avail_out < BUFFER_SIZE)
+ {
+ int iCompressed = zstr.next_out - obuffer;
+ pDataField->m_uWrittenFieldLength += iCompressed;
+ if(pFile->writeBlock((char *)obuffer,iCompressed) != iCompressed)
+ {
+ deflateEnd(&zstr);
+ return writeError();
+ }
+ }
+
+ if(zstr.avail_in < BUFFER_SIZE)
+ {
+ int iDataToRead = BUFFER_SIZE - zstr.avail_in;
+ if(iDataToRead < BUFFER_SIZE)
+ {
+ if(ibuffer != zstr.next_in)
+ {
+ // hum, there is still some data in the buffer to be readed
+ // and it is not at the beginning...move it to the beginning of ibuffer
+ memmove(ibuffer,zstr.next_in,zstr.avail_in);
+ }
+ }
+ iReaded = source.readBlock((char *)(ibuffer + zstr.avail_in),iDataToRead);
+ if(iReaded < 0)
+ {
+ deflateEnd(&zstr);
+ return readError();
+ }
+ zstr.avail_in += iReaded;
+ zstr.next_in = ibuffer;
+
+ if((zstr.total_in % 2000000) == 0)
+ {
+ QString szTmp;
+ KviQString::sprintf(szTmp,QString(" (%d of %d bytes)"),zstr.total_in,uSize);
+ QString szPrg = szProgressText + szTmp;
+ if(!updateProgress(m_iCurrentProgress,szPrg))
+ return false; // aborted
+ }
+
+
+ }
+ }
+
+ // flush pending output
+ zstr.next_out = obuffer;
+ zstr.avail_out = BUFFER_SIZE;
+
+ int ret;
+ do
+ {
+ ret = deflate(&zstr,Z_FINISH);
+
+ if((ret == Z_OK) || (ret == Z_STREAM_END))
+ {
+ if(zstr.avail_out < BUFFER_SIZE)
+ {
+ int iCompressed = zstr.next_out - obuffer;
+ pDataField->m_uWrittenFieldLength += iCompressed;
+ if(pFile->writeBlock((char *)obuffer,iCompressed) != iCompressed)
+ {
+ deflateEnd(&zstr);
+ return writeError();
+ }
+ } else {
+ deflateEnd(&zstr);
+ setLastError(__tr2qs("Compression library internal error"));
+ return false;
+ }
+
+ zstr.next_out = obuffer;
+ zstr.avail_out = BUFFER_SIZE;
+ }
+
+ } while(ret == Z_OK);
+
+ // store the compressed data size
+ KviFile::Offset here = pFile->at();
+ pFile->at(savedSizeOffset);
+ uSize = zstr.total_out;
+
+ deflateEnd(&zstr);
+ if(!pFile->save(uSize))return writeError();
+
+ if(ret != Z_STREAM_END)
+ {
+ setLastError(__tr2qs("Error while compressing a file stream"));
+ return false;
+ }
+
+ pFile->at(here);
+ } else {
+#endif
+ unsigned char buffer[BUFFER_SIZE];
+ int iTotalFileSize = 0;
+ kvi_i32_t iReaded = source.readBlock((char *)buffer,BUFFER_SIZE);
+ if(iReaded < 0)
+ return readError();
+ while(iReaded > 0)
+ {
+ iTotalFileSize += iReaded;
+ if((iTotalFileSize % 1000000) == 0)
+ {
+ QString szTmp;
+ KviQString::sprintf(szTmp,QString(" (%d of %d bytes)"),iTotalFileSize,uSize);
+ QString szPrg = szProgressText + szTmp;
+ if(!updateProgress(m_iCurrentProgress,szPrg))
+ return false; // aborted
+ }
+ pDataField->m_uWrittenFieldLength += iReaded;
+ if(pFile->writeBlock((char *)buffer,iReaded) != iReaded)
+ return writeError();
+ iReaded = source.readBlock((char *)buffer,BUFFER_SIZE);
+ }
+#ifdef COMPILE_ZLIB_SUPPORT
+ }
+#endif
+ source.close();
+
+ return true;
+}
+
+bool KviPackageWriter::pack(const QString &szFileName,kvi_u32_t uPackFlags)
+{
+ m_iCurrentProgress = 0;
+ if(!(uPackFlags & NoProgressDialog))
+ {
+ showProgressDialog(__tr2qs("Creating package..."),100);
+ updateProgress(m_iCurrentProgress,__tr2qs("Writing package header"));
+ }
+
+ bool bRet = packInternal(szFileName,uPackFlags);
+
+ hideProgressDialog();
+ return bRet;
+}
+
+bool KviPackageWriter::packInternal(const QString &szFileName,kvi_u32_t uPackFlags)
+{
+
+ KviFile f(szFileName);
+ if(!f.open(IO_WriteOnly | IO_Truncate))
+ {
+ setLastError(__tr2qs("Can't open file for writing"));
+ return false;
+ }
+
+ // write the PackageHeader
+
+ // Magic
+ char magic[4];
+ magic[0] = 'K';
+ magic[1] = 'V';
+ magic[2] = 'P';
+ magic[3] = 'F';
+ if(f.writeBlock(magic,4) != 4)return writeError();
+
+ // Version
+ kvi_u32_t uVersion = 0x1;
+ if(!f.save(uVersion))return writeError();
+
+ // Flags
+ kvi_u32_t uFlags = 0x0;
+ if(!f.save(uFlags))return writeError();
+
+ // write PackageInfo
+
+ // InfoFieldCount
+ kvi_u32_t uCount = m_pStringInfoFields->count() + m_pBinaryInfoFields->count();
+ if(!f.save(uCount))return writeError();
+
+ m_iCurrentProgress = 5;
+ if(!updateProgress(m_iCurrentProgress,__tr2qs("Writing informational fields")))
+ return false; // aborted
+
+ // InfoFields (string)
+ QDictIterator<QString> it(*m_pStringInfoFields);
+ while(QString * s = it.current())
+ {
+ if(!f.save(it.currentKey()))return writeError();
+ kvi_u32_t uType = KVI_PACKAGE_INFOFIELD_TYPE_STRING;
+ if(!f.save(uType))return writeError();
+ if(!f.save(*s))return writeError();
+ ++it;
+ }
+
+ // InfoFields (binary)
+ QDictIterator<QByteArray> it2(*m_pBinaryInfoFields);
+ while(QByteArray * b = it2.current())
+ {
+ if(!f.save(it2.currentKey()))return writeError();
+ kvi_u32_t uType = KVI_PACKAGE_INFOFIELD_TYPE_BINARYBUFFER;
+ if(!f.save(uType))return writeError();
+ if(!f.save(*b))return writeError();
+ ++it2;
+ }
+
+ m_iCurrentProgress = 10;
+ if(!updateProgress(m_iCurrentProgress,__tr2qs("Writing package data")))
+ return false; // aborted
+
+ // write PackageData
+ int iIdx = 0;
+ for(DataField * pDataField = m_pDataFields->first();pDataField;pDataField = m_pDataFields->next())
+ {
+ kvi_u32_t uDataFieldType = pDataField->m_uType;
+ if(!f.save(uDataFieldType))return writeError();
+
+ KviFile::Offset savedLenOffset = f.at();
+ // here we will store the length of the field once it's written
+ if(!f.save(uDataFieldType))return writeError();
+
+ m_iCurrentProgress = 10 + ((90 * iIdx) / m_pDataFields->count());
+
+ switch(pDataField->m_uType)
+ {
+ case KVI_PACKAGE_DATAFIELD_TYPE_FILE:
+ if(!packFile(&f,pDataField))
+ return false;
+ break;
+ default:
+ setLastError(__tr2qs("Internal error"));
+ return false;
+ break;
+ }
+
+ KviFile::Offset savedEndOffset = f.at();
+ f.at(savedLenOffset);
+ if(!f.save(pDataField->m_uWrittenFieldLength))
+ return writeError();
+
+ f.at(savedEndOffset);
+ iIdx++;
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Da Reader
+
+KviPackageReader::KviPackageReader()
+: KviPackageIOEngine()
+{
+}
+
+KviPackageReader::~KviPackageReader()
+{
+}
+
+bool KviPackageReader::readHeaderInternal(KviFile * pFile,const QString &szLocalFileName)
+{
+ // read the PackageHeader
+
+ // Magic
+ char magic[4];
+
+ if(pFile->readBlock(magic,4) != 4)return readError();
+ if((magic[0] != 'K') || (magic[1] != 'V') || (magic[2] != 'P') || (magic[3] != 'F'))
+ {
+ setLastError(__tr2qs("The file specified is not a valid KVIrc package"));
+ return false;
+ }
+
+ // Version
+ kvi_u32_t uVersion;
+ if(!pFile->load(uVersion))return readError();
+ if(uVersion != 0x1)
+ {
+ setLastError(__tr2qs("The package has an invalid version number, it might have been created by a newer KVIrc"));
+ return false;
+ }
+
+ // Flags
+ kvi_u32_t uFlags;
+ if(!pFile->load(uFlags))return readError();
+ // we ignore them at the moment
+
+ // read PackageInfo
+
+ // InfoFieldCount
+ kvi_u32_t uCount;
+ if(!pFile->load(uCount))return writeError();
+
+ m_pStringInfoFields->clear();
+ m_pBinaryInfoFields->clear();
+
+ kvi_u32_t uIdx = 0;
+ while(uIdx < uCount)
+ {
+ QString szKey;
+ if(!pFile->load(szKey))return readError();
+ kvi_u32_t uFieldType;
+ if(!pFile->load(uFieldType))return readError();
+ switch(uFieldType)
+ {
+ case KVI_PACKAGE_INFOFIELD_TYPE_STRING:
+ {
+ QString szValue;
+ if(!pFile->load(szValue))return readError();
+ m_pStringInfoFields->replace(szKey,new QString(szValue));
+ }
+ break;
+ case KVI_PACKAGE_INFOFIELD_TYPE_BINARYBUFFER:
+ {
+ QByteArray * pbValue = new QByteArray();
+ if(!pFile->load(*pbValue))
+ {
+ delete pbValue;
+ return readError();
+ }
+ m_pBinaryInfoFields->replace(szKey,pbValue);
+ }
+ break;
+ default:
+ setLastError(__tr2qs("Invalid info field: the package is probably corrupt"));
+ break;
+ }
+ uIdx++;
+ }
+
+ return true;
+}
+
+
+bool KviPackageReader::readHeader(const QString &szLocalFileName)
+{
+ KviFile f(szLocalFileName);
+ if(!f.open(IO_ReadOnly))
+ {
+ setLastError(__tr2qs("Can't open file for reading"));
+ return false;
+ }
+
+ return readHeaderInternal(&f,szLocalFileName);
+}
+
+bool KviPackageReader::unpackFile(KviFile * pFile,const QString &szUnpackPath)
+{
+ // Flags
+ kvi_u32_t uFlags;
+ if(!pFile->load(uFlags))return readError();
+
+#ifndef COMPILE_ZLIB_SUPPORT
+ if(uFlags & KVI_PACKAGE_DATAFIELD_FLAG_FILE_DEFLATE)
+ {
+ setLastError(__tr2qs("The package contains compressed data but this executable does not support compression"));
+ return false;
+ }
+#endif
+
+ // Path
+ QString szPath;
+ if(!pFile->load(szPath))return readError();
+
+ QString szFileName = szUnpackPath;
+ KviQString::ensureLastCharIs(szFileName,QChar(KVI_PATH_SEPARATOR_CHAR));
+
+ szFileName += szPath;
+
+ szFileName.replace(QString("..\\"),QString(""));
+ szFileName.replace(QString("..//"),QString(""));
+
+ KviFileUtils::adjustFilePath(szFileName);
+
+ int idx = szFileName.findRev(QChar(KVI_PATH_SEPARATOR_CHAR));
+ if(idx != -1)
+ {
+ QString szPrefixPath = szFileName.left(idx);
+ if(!KviFileUtils::makeDir(szPrefixPath))
+ {
+ setLastError(__tr2qs("Failed to create the target directory"));
+ return false;
+ }
+ }
+
+ KviFile dest(szFileName);
+ if(!dest.open(IO_WriteOnly | IO_Truncate))
+ {
+ setLastError(__tr2qs("Failed to open a source file for reading"));
+ return false;
+ }
+
+ QString szProgressText;
+ KviQString::sprintf(szProgressText,__tr2qs("Unpacking file %Q"),&szFileName);
+ if(!updateProgress(pFile->at(),szProgressText))
+ return false; // aborted
+
+ // Size
+ kvi_u32_t uSize;
+ if(!pFile->load(uSize))return readError();
+
+
+ // FilePayload
+#ifdef COMPILE_ZLIB_SUPPORT
+ if(uFlags & KVI_PACKAGE_DATAFIELD_FLAG_FILE_DEFLATE)
+ {
+ int iRemainingSize = uSize;
+ unsigned char ibuffer[BUFFER_SIZE];
+ unsigned char obuffer[BUFFER_SIZE];
+
+ int iToRead = iRemainingSize;
+ if(iToRead > BUFFER_SIZE)iToRead = BUFFER_SIZE;
+ int iReaded = pFile->readBlock((char *)ibuffer,iToRead);
+ iRemainingSize -= iReaded;
+
+ z_stream zstr;
+ zstr.zalloc = Z_NULL;
+ zstr.zfree = Z_NULL;
+ zstr.opaque = Z_NULL;
+ zstr.next_in = ibuffer;
+ zstr.avail_in = iReaded;
+ zstr.next_out = obuffer;
+ zstr.avail_out = BUFFER_SIZE;
+
+ if(inflateInit(&zstr) != Z_OK)
+ {
+ setLastError(__tr2qs("Compression library initialization error"));
+ return false;
+ }
+
+ while((iReaded > 0) && (iRemainingSize > 0))
+ {
+ zstr.next_out = obuffer;
+ zstr.avail_out = BUFFER_SIZE;
+
+ if(inflate(&zstr,Z_NO_FLUSH) != Z_OK)
+ {
+ setLastError(__tr2qs("Compression library error"));
+ return false;
+ }
+
+ if(zstr.avail_out < BUFFER_SIZE)
+ {
+ int iDecompressed = zstr.next_out - obuffer;
+ if(dest.writeBlock((char *)obuffer,iDecompressed) != iDecompressed)
+ {
+ inflateEnd(&zstr);
+ return writeError();
+ }
+ }
+
+ if(zstr.avail_in < BUFFER_SIZE)
+ {
+ int iDataToRead = BUFFER_SIZE - zstr.avail_in;
+ if(iDataToRead < BUFFER_SIZE)
+ {
+ if(ibuffer != zstr.next_in)
+ {
+ // hum, there is still some data in the buffer to be readed
+ // and it is not at the beginning...move it to the beginning of ibuffer
+ memmove(ibuffer,zstr.next_in,zstr.avail_in);
+ }
+ }
+
+ if(iDataToRead > iRemainingSize)
+ iDataToRead = iRemainingSize;
+
+ iReaded = pFile->readBlock((char *)(ibuffer + zstr.avail_in),iDataToRead);
+ if(iReaded < 0)
+ {
+ inflateEnd(&zstr);
+ return readError();
+ }
+
+ iRemainingSize -= iReaded;
+ zstr.avail_in += iReaded;
+ zstr.next_in = ibuffer;
+
+ if((zstr.total_in % 2000000) == 0)
+ {
+ QString szTmp;
+ KviQString::sprintf(szTmp,QString(" (%d of %d bytes)"),zstr.total_in,uSize);
+ QString szPrg = szProgressText + szTmp;
+ if(!updateProgress(pFile->at(),szPrg))
+ return false; // aborted
+ }
+ }
+ }
+
+ // flush pending output
+ zstr.next_out = obuffer;
+ zstr.avail_out = BUFFER_SIZE;
+
+ int ret;
+
+ do {
+ ret = inflate(&zstr,Z_FINISH);
+
+ if((ret == Z_OK) || (ret == Z_STREAM_END) || (ret == Z_BUF_ERROR))
+ {
+ if(zstr.avail_out < BUFFER_SIZE)
+ {
+ int iDecompressed = zstr.next_out - obuffer;
+ if(dest.writeBlock((char *)obuffer,iDecompressed) != iDecompressed)
+ {
+ inflateEnd(&zstr);
+ return writeError();
+ }
+ } /* else { THIS HAPPENS FOR ZERO SIZE FILES
+ debug("hum.... internal, rEWq (ret = %d) (avail_out = %d)",ret,zstr.avail_out);
+
+ inflateEnd(&zstr);
+ setLastError(__tr2qs("Compression library internal error"));
+ return false;
+ } */
+ zstr.next_out = obuffer;
+ zstr.avail_out = BUFFER_SIZE;
+ }
+
+ } while((ret == Z_OK) || (ret == Z_BUF_ERROR));
+
+ inflateEnd(&zstr);
+
+ if(ret != Z_STREAM_END)
+ {
+ setLastError(__tr2qs("Error in compressed file stream"));
+ return false;
+ }
+
+ } else {
+#endif
+ unsigned char buffer[BUFFER_SIZE];
+ int iTotalFileSize = 0;
+ int iRemainingData = uSize;
+ int iToRead = iRemainingData;
+ if(iToRead > BUFFER_SIZE)iToRead = BUFFER_SIZE;
+ int iReaded = 1;
+
+ while((iReaded > 0) && (iToRead > 0))
+ {
+ iReaded = pFile->readBlock((char *)buffer,iToRead);
+ if(iReaded > 0)
+ {
+ iTotalFileSize += iReaded;
+ iRemainingData -= iReaded;
+
+ if((iTotalFileSize % 3000000) == 0)
+ {
+ QString szTmp;
+ KviQString::sprintf(szTmp,QString(" (%d of %d bytes)"),iTotalFileSize,uSize);
+ QString szPrg = szProgressText + szTmp;
+ if(!updateProgress(pFile->at(),szPrg))
+ return false; // aborted
+ }
+
+ if(dest.writeBlock((char *)buffer,iReaded) != iReaded)
+ return writeError();
+ }
+
+ int iToRead = iRemainingData;
+ if(iToRead > BUFFER_SIZE)iToRead = BUFFER_SIZE;
+ }
+#ifdef COMPILE_ZLIB_SUPPORT
+ }
+#endif
+ dest.close();
+
+ return true;
+}
+
+bool KviPackageReader::unpack(const QString &szLocalFileName,const QString &szUnpackPath,kvi_u32_t uUnpackFlags)
+{
+ bool bRet = unpackInternal(szLocalFileName,szUnpackPath,uUnpackFlags);
+ hideProgressDialog();
+ return bRet;
+}
+
+bool KviPackageReader::unpackInternal(const QString &szLocalFileName,const QString &szUnpackPath,kvi_u32_t uUnpackFlags)
+{
+
+ KviFile f(szLocalFileName);
+ if(!f.open(IO_ReadOnly))
+ {
+ setLastError(__tr2qs("Can't open file for reading"));
+ return false;
+ }
+
+ KviFile::Offset size = f.size();
+
+ if(!(uUnpackFlags & NoProgressDialog))
+ {
+ showProgressDialog(__tr2qs("Reading package..."),size);
+ updateProgress(0,__tr2qs("Reading package header"));
+ }
+
+
+ if(!readHeaderInternal(&f,szLocalFileName))
+ return false;
+
+ if(!updateProgress(f.at(),__tr2qs("Reading package data")))
+ return false; // aborted
+
+ while(!f.atEnd())
+ {
+ // DataFieldType
+ kvi_u32_t uDataFieldType;
+ if(!f.load(uDataFieldType))return readError();
+ // DataFieldLen
+ kvi_u32_t uDataFieldLen;
+ if(!f.load(uDataFieldLen))return readError();
+
+ switch(uDataFieldType)
+ {
+ case KVI_PACKAGE_DATAFIELD_TYPE_FILE:
+ if(!unpackFile(&f,szUnpackPath))
+ return false;
+ break;
+ default:
+ setLastError(__tr2qs("Invalid data field: the package is probably corrupt"));
+ return false;
+ break;
+ }
+
+ }
+
+ return true;
+}
+
+
+
diff --git a/src/kvilib/file/kvi_packagefile.h b/src/kvilib/file/kvi_packagefile.h
new file mode 100644
index 000000000..f8e1439b6
--- /dev/null
+++ b/src/kvilib/file/kvi_packagefile.h
@@ -0,0 +1,141 @@
+#ifndef _KVI_PACKAGEFILE_H_
+#define _KVI_PACKAGEFILE_H_
+//=============================================================================
+//
+// File : kvi_packagefile.h
+// Created on Tue 26 Dec 2006 05:33:33 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2006 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+//=============================================================================
+
+#include "kvi_settings.h"
+#include "kvi_qstring.h"
+#include <qdict.h>
+#include <qobject.h>
+#include <qcstring.h> // QByteArray
+#include "kvi_list.h"
+
+class KviFile;
+class QProgressDialog;
+class QLabel;
+class QFileInfo;
+
+//
+// This class is used for creating KVIrc package files.
+// You simply instantiate it, add some info fields, add some files and then call pack().
+//
+
+class KVILIB_API KviPackageIOEngine
+{
+public:
+ KviPackageIOEngine();
+ virtual ~KviPackageIOEngine();
+protected:
+ QString m_szLastError;
+ QDict<QString> * m_pStringInfoFields;
+ QDict<QByteArray> * m_pBinaryInfoFields;
+ QProgressDialog * m_pProgressDialog;
+ QLabel * m_pProgressDialogLabel;
+public:
+ const QString & lastError(){ return m_szLastError; };
+ void setLastError(const QString &szLastError){ m_szLastError = szLastError; };
+ QDict<QString> * stringInfoFields(){ return m_pStringInfoFields; };
+ QDict<QByteArray> * binaryInfoFields(){ return m_pBinaryInfoFields; };
+protected:
+ void showProgressDialog(const QString &szCaption,int iTotalSteps);
+ void hideProgressDialog();
+ bool updateProgress(int iProgress,const QString &szLabel);
+ bool writeError();
+ bool readError();
+};
+
+#define KVI_PACKAGE_INFOFIELD_TYPE_STRING 1
+#define KVI_PACKAGE_INFOFIELD_TYPE_BINARYBUFFER 2
+
+#define KVI_PACKAGE_DATAFIELD_TYPE_FILE 1
+
+#define KVI_PACKAGE_DATAFIELD_FLAG_FILE_DEFLATE 1
+
+class KVILIB_API KviPackageWriter : public KviPackageIOEngine
+{
+public:
+ KviPackageWriter();
+ virtual ~KviPackageWriter();
+protected:
+
+ class DataField
+ {
+ public:
+ kvi_u32_t m_uType;
+ // output length of the field
+ kvi_u32_t m_uWrittenFieldLength;
+ // data fields for the File DataFieldType
+ bool m_bFileAllowCompression;
+ QString m_szFileLocalName;
+ QString m_szFileTargetName;
+ };
+
+ KviPtrList<DataField> * m_pDataFields;
+ int m_iCurrentProgress;
+public:
+ // Adds a file to the package. The file must be specified as absolute local
+ // path and as target path relative to the KVIrc local directory.
+ // ... more ?
+ enum AddFileFlags {
+ NoCompression = 1,
+ FollowSymLinks = 2
+ };
+ bool addFile(const QString &szLocalFileName,const QString &szTargetFileName,kvi_u32_t uAddFileFlags = 0);
+ bool addDirectory(const QString &szLocalDirectoryName,const QString &szTargetDirectoryPrefix,kvi_u32_t uAddFileFlags = 0);
+ // Adds an info field as a name=value pair
+ void addInfoField(const QString &szName,const QString &szValue);
+ void addInfoField(const QString &szName,QByteArray * pArray);
+ // Attempts to pack everything and store it as the specified file.
+ // There is no mandatory extension but you *should* use KVI_FILEEXTENSION_THEMEPACKAGE for themes
+ // and KVI_FILEEXTENSION_ADDONPACKAGE for addons. See kvi_fileextension.h
+ enum PackFlags {
+ NoProgressDialog = 1
+ };
+ bool pack(const QString &szFileName,kvi_u32_t uPackFlags = 0);
+private:
+ bool packInternal(const QString &szFileName,kvi_u32_t uPackFlags = 0);
+ bool packFile(KviFile * pFile,DataField * pDataField);
+ bool addFileInternal(const QFileInfo * fi,const QString &szLocalFileName,const QString &szTargetFileName,kvi_u32_t uAddFileFlags = 0);
+};
+
+class KVILIB_API KviPackageReader : public KviPackageIOEngine
+{
+public:
+ KviPackageReader();
+ virtual ~KviPackageReader();
+public:
+ bool readHeader(const QString &szLocalFileName);
+ enum UnpackFlags {
+ NoProgressDialog = 1
+ };
+ bool unpack(const QString &szLocalFileName,const QString &szUnpackPath,kvi_u32_t uUnpackFlags = 0);
+private:
+ bool unpackInternal(const QString &szLocalFileName,const QString &szUnpackPath,kvi_u32_t uUnpackFlags = 0);
+ bool unpackFile(KviFile * pFile,const QString &szUnpackPath);
+ bool readHeaderInternal(KviFile * pFile,const QString &szLocalFileName);
+};
+
+
+
+#endif //!_KVI_PACKAGEFILE_H_
diff --git a/src/kvilib/file/kvi_targzfile.h b/src/kvilib/file/kvi_targzfile.h
index af9462620..db38a4b82 100644
--- a/src/kvilib/file/kvi_targzfile.h
+++ b/src/kvilib/file/kvi_targzfile.h
@@ -33,4 +33,6 @@ public:
KviGzPacker(){};
~KviGzPacker(){};
}
+
+
#endif //_KVI_TARGZFILE_H_
diff --git a/src/kvirc/kernel/kvi_coreactionnames.h b/src/kvirc/kernel/kvi_coreactionnames.h
index c1635922f..18080825a 100644
--- a/src/kvirc/kernel/kvi_coreactionnames.h
+++ b/src/kvirc/kernel/kvi_coreactionnames.h
@@ -63,6 +63,6 @@
#define KVI_COREACTION_EDITREGUSERS (KVI_COREACTION_NAME_PREFIX "editregusers")
#define KVI_COREACTION_MANAGEADDONS (KVI_COREACTION_NAME_PREFIX "manageaddons")
#define KVI_COREACTION_THEMEOPTIONS (KVI_COREACTION_NAME_PREFIX "themeoptions")
-#define KVI_COREACTION_THEMESELECT (KVI_COREACTION_NAME_PREFIX "themeselect")
+#define KVI_COREACTION_MANAGETHEMES (KVI_COREACTION_NAME_PREFIX "managethemes")
#endif //!_KVI_COREACTIONNAMES_H_
diff --git a/src/kvirc/kernel/kvi_coreactions.cpp b/src/kvirc/kernel/kvi_coreactions.cpp
index 62acc8d0e..86dd1c712 100644
--- a/src/kvirc/kernel/kvi_coreactions.cpp
+++ b/src/kvirc/kernel/kvi_coreactions.cpp
@@ -68,6 +68,7 @@
// Ctrl+Alt+H : Show help index
// Ctrl+Alt+R : Edit regusers
// Ctrl+Alt+M : Manage Script Addons
+// Ctrl+Alt+L : Manage Themes
void register_core_actions(KviActionManager * m)
{
@@ -210,15 +211,15 @@ void register_core_actions(KviActionManager * m)
"Ctrl+Alt+T");
SCRIPT_ACTION(
- KVI_COREACTION_THEMESELECT,
- "options.edit KviThemeOptionsWidget",
+ KVI_COREACTION_MANAGETHEMES,
+ "theme.dialog",
__tr2qs("Manage Themes..."),
- __tr2qs("Shows the theme manager dialog"),
+ __tr2qs("Allows you to manage the themes"),
KviActionManager::categorySettings(),
- "kvi_bigicon_themeoptions.png",
- KVI_SMALLICON_THEMEOPTIONS,
+ "kvi_bigicon_themes.png",
+ KVI_SMALLICON_THEMES,
0,
- "");
+ "Ctrl+Alt+L");
SCRIPT_ACTION(
KVI_COREACTION_TOOLBAREDITOR,
diff --git a/src/kvirc/kernel/kvi_iconmanager.cpp b/src/kvirc/kernel/kvi_iconmanager.cpp
index e6da7e104..a2edb1fea 100644
--- a/src/kvirc/kernel/kvi_iconmanager.cpp
+++ b/src/kvirc/kernel/kvi_iconmanager.cpp
@@ -340,7 +340,9 @@ static const char * g_szIconNames[KVI_NUM_SMALL_ICONS]=
"saykvs", // 286
"themeoptions", // 287
"bug", // 288
- "refresh" //289
+ "refresh", //289
+ "theme", // 290
+ "themes" // 291
};
KviIconWidget::KviIconWidget()
diff --git a/src/kvirc/kernel/kvi_iconmanager.h b/src/kvirc/kernel/kvi_iconmanager.h
index 3328f810d..99e58e337 100644
--- a/src/kvirc/kernel/kvi_iconmanager.h
+++ b/src/kvirc/kernel/kvi_iconmanager.h
@@ -328,8 +328,10 @@
#define KVI_SMALLICON_THEMEOPTIONS 287
#define KVI_SMALLICON_BUG 288
#define KVI_SMALLICON_REFRESH 289
+#define KVI_SMALLICON_THEME 290
+#define KVI_SMALLICON_THEMES 291
-#define KVI_NUM_SMALL_ICONS 290
+#define KVI_NUM_SMALL_ICONS 292
#define KVI_BIGICON_DISCONNECTED "kvi_bigicon_disconnected.png"
@@ -343,6 +345,7 @@
#define KVI_BIGICON_KVS "kvi_bigicon_kvs.png"
#define KVI_BIGICON_THEME "kvi_bigicon_theme.png"
#define KVI_BIGICON_ADDONS "kvi_bigicon_addons.png"
+#define KVI_BIGICON_THEMES "kvi_bigicon_themes.png"
#define KVI_BIGICON_HELPINDEX "kvi_bigicon_helpindex.png"
#define KVI_BIGICON_HELPBACK "kvi_bigicon_helpback.png"
@@ -354,6 +357,7 @@
#define KVI_BIGICON_SAVE "kvi_bigicon_save.png"
#define KVI_BIGICON_REMOVE "kvi_bigicon_remove.png"
#define KVI_BIGICON_WWW "kvi_bigicon_www.png"
+#define KVI_BIGICON_PACK "kvi_bigicon_pack.png"
#define KVI_SMALLICONS_SUBDIRECTORY "coresmall"
#define KVI_SMALLICONS_PREFIX "kcs_"
diff --git a/src/kvirc/kernel/kvi_ircconnectionstatedata.h b/src/kvirc/kernel/kvi_ircconnectionstatedata.h
index 2860f1598..12da18bd4 100644
--- a/src/kvirc/kernel/kvi_ircconnectionstatedata.h
+++ b/src/kvirc/kernel/kvi_ircconnectionstatedata.h
@@ -50,6 +50,7 @@ protected:
bool m_bSimulateUnexpectedDisconnect; // this is set to true if we have to simulate an unexpected disconnect even if we have sent a normal quit message
kvi_time_t m_tLastReceivedChannelWhoReply; // the time that we have received our last channel who reply
kvi_time_t m_tLastSentChannelWhoRequest; // the time that we have sent our last channel who request
+ kvi_time_t m_tLastReceivedWhoisReply; // the time that we have received the last whois reply, reset to 0 when we receive an /END OF WHOIS
public:
bool sentQuit(){ return m_bSentQuit; };
void setSentQuit(){ m_bSentQuit = true; };
@@ -59,6 +60,9 @@ public:
kvi_time_t lastSentChannelWhoRequest(){ return m_tLastSentChannelWhoRequest; };
void setLastSentChannelWhoRequest(kvi_time_t tTime){ m_tLastSentChannelWhoRequest = tTime; };
+
+ kvi_time_t lastReceivedWhoisReply(){ return m_tLastReceivedWhoisReply; };
+ void setLastReceivedWhoisReply(kvi_time_t tTime){ m_tLastReceivedWhoisReply = tTime; };
bool simulateUnexpectedDisconnect(){ return m_bSimulateUnexpectedDisconnect; };
void setSimulateUnexpectedDisconnect(){ m_bSimulateUnexpectedDisconnect = true; };
diff --git a/src/kvirc/sparser/kvi_ircmessage.h b/src/kvirc/sparser/kvi_ircmessage.h
index a70d6ca3b..45d99817f 100644
--- a/src/kvirc/sparser/kvi_ircmessage.h
+++ b/src/kvirc/sparser/kvi_ircmessage.h
@@ -6,7 +6,7 @@
// Creation date : Fri Aug 2 23:08:55 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)
+// Copyright (C) 2002-2006 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
@@ -56,13 +56,10 @@ private:
KviStr m_szPrefix; // the extracted prefix string
KviStr m_szCommand; // the extracted command (may be numeric)
KviPtrList<KviStr> * m_pParams; // the list of parameters
- //KviPtrList<QCString> * m_pcParams; QCString has same data as KviStr and has worse management than KviStr (beside other thingies, it CAN be null)
- // the pointer was also mem-leaked :(
KviConsole * m_pConsole; // the console we're attacched to
KviIrcConnection * m_pConnection; // the connection we're attacched to
int m_iNumericCommand; // the numeric of the command (0 if non numeric)
int m_iFlags; // yes.. flags :D
- //QCString m_SafeTrailingString;
public:
KviConsole * console(){ return m_pConsole; };
KviIrcConnection * connection(){ return m_pConsole->connection(); };
@@ -82,17 +79,14 @@ public:
int paramCount(){ return m_pParams->count(); };
const char * param(unsigned int idx){ return (idx < m_pParams->count()) ? m_pParams->at(idx)->ptr() : 0; };
- //const QCString * cParam(unsigned int idx){ return (idx < m_pcParams->count()) ? m_pcParams->at(idx) : 0; };
const char * safeParam(unsigned int idx){ return (idx < m_pParams->count()) ? m_pParams->at(idx)->ptr() : KviStr::emptyString().ptr(); };
- //const QCString * cSafeParam(unsigned int idx){ return (idx < m_pcParams->count()) ? m_pcParams->at(idx) : new QCString(); }; <-- this leaks memory
KviStr * paramString(unsigned int idx){ return m_pParams->at(idx); };
const char * trailing(){ KviStr * tr = m_pParams->last(); return tr ? tr->ptr() : 0; };
KviStr * trailingString(){ return m_pParams->last(); };
KviStr & safeTrailingString(){ KviStr * tr = m_pParams->last(); return tr ? *tr : KviStr::emptyString(); };
- //QCString & qcSafeTrailingString() { return m_SafeTrailingString; };
const char * safeTrailing(){ KviStr * tr = m_pParams->last(); return tr ? tr->ptr() : KviStr::emptyString().ptr(); };
const char * allParams(){ return m_ptr; };
diff --git a/src/kvirc/sparser/kvi_sp_numeric.cpp b/src/kvirc/sparser/kvi_sp_numeric.cpp
index 0006e0f50..52f4d9f9d 100644
--- a/src/kvirc/sparser/kvi_sp_numeric.cpp
+++ b/src/kvirc/sparser/kvi_sp_numeric.cpp
@@ -1004,6 +1004,8 @@ void KviServerParser::parseNumericNicknameProblem(KviIrcMessage *msg)
void KviServerParser::parseNumericWhoisAway(KviIrcMessage * msg)
{
// FIXME: #warning "Need an icon here too: sth like KVI_OUT_WHOISSERVER, but with 'A' letter"
+ msg->connection()->stateData()->setLastReceivedWhoisReply(kvi_unixTime());
+
QString szNk = msg->connection()->decodeText(msg->safeParam(1));
KviIrcUserDataBase * db = msg->connection()->userDataBase();
KviIrcUserEntry * e = db->find(szNk);
@@ -1026,6 +1028,8 @@ void KviServerParser::parseNumericWhoisUser(KviIrcMessage *msg)
{
// 311: RPL_WHOISUSER [I,E,U,D]
// :prefix 311 <target> <nick> <user> <host> * :<real_name>
+ msg->connection()->stateData()->setLastReceivedWhoisReply(kvi_unixTime());
+
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
QString szUser = msg->connection()->decodeText(msg->safeParam(2));
QString szHost = msg->connection()->decodeText(msg->safeParam(3));
@@ -1076,6 +1080,7 @@ void KviServerParser::parseNumericWhowasUser(KviIrcMessage * msg)
{
// 314: RPL_WHOWASUSER [I,E,U,D]
// :prefix 314 <target> <nick> <user> <host> * :<real_name>
+
if(!msg->haltOutput())
{
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
@@ -1101,6 +1106,8 @@ void KviServerParser::parseNumericWhoisChannels(KviIrcMessage *msg)
// 319: RPL_WHOISCHANNELS [I,E,U,D]
// :prefix 319 <target> <nick> :<channel list>
+ msg->connection()->stateData()->setLastReceivedWhoisReply(kvi_unixTime());
+
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
QString szChans = msg->connection()->decodeText(msg->safeTrailing());
@@ -1163,6 +1170,7 @@ void KviServerParser::parseNumericWhoisIdle(KviIrcMessage *msg)
// :prefix 317 <target> <nick> <number> <number> :seconds idle, signon time
// FIXME: #warning "and NICK LINKS"
+ msg->connection()->stateData()->setLastReceivedWhoisReply(kvi_unixTime());
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
@@ -1218,6 +1226,7 @@ void KviServerParser::parseNumericWhoisServer(KviIrcMessage *msg)
{
// 312: RPL_WHOISSERVER [I,E,U,D] (sent also in response to WHOWAS)
// :prefix 312 <target> <nick> <server> :<server description / last whowas date>
+ msg->connection()->stateData()->setLastReceivedWhoisReply(kvi_unixTime());
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
QString szServ = msg->connection()->decodeText(msg->safeParam(2));
@@ -1250,6 +1259,7 @@ void KviServerParser::parseNumericWhoisAuth(KviIrcMessage *msg)
{
// :prefix RPL_WHOISAUTH <target> <nick> :is authed as
// actually seen only on Quakenet
+ msg->connection()->stateData()->setLastReceivedWhoisReply(kvi_unixTime());
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
QString szAuth = msg->connection()->decodeText(msg->safeParam(2));
@@ -1270,6 +1280,10 @@ void KviServerParser::parseNumericWhoisOther(KviIrcMessage *msg)
// :prefix * <target> <nick> :<description>
// used for RPL_WHOISCHANOP,RPL_WHOISADMIN,
// RPL_WHOISSADMIN,RPL_WHOISOPERATOR,RPL_WHOISREGNICK,RPL_WHOISSSL
+ // and all the other unrecognized codes that look really like a RPL_WHOIS*
+
+ msg->connection()->stateData()->setLastReceivedWhoisReply(kvi_unixTime());
+
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
QString szOth = msg->connection()->decodeText(msg->safeTrailing());
@@ -1298,6 +1312,9 @@ void KviServerParser::parseNumericEndOfWhois(KviIrcMessage *msg)
{
// 318: RPL_ENDOFWHOIS [I,E,U,D]
// :prefix 318 <target> <nick> :End of /WHOIS list
+
+ msg->connection()->stateData()->setLastReceivedWhoisReply(0);
+
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
KviAsyncWhoisInfo * i = msg->connection()->asyncWhoisData()->lookup(szNick);
@@ -1909,6 +1926,9 @@ void KviServerParser::parseNumericCodePageScheme(KviIrcMessage *msg)
// a nice extension for irc.wenet.ru
// 703: RPL_WHOISSCHEME
// :prefix 703 <mynick> <nick> <encoding> :translation scheme
+
+ msg->connection()->stateData()->setLastReceivedWhoisReply(kvi_unixTime());
+
if(msg->connection()->serverInfo()->supportsCodePages())
{
QString szNick = msg->connection()->decodeText(msg->safeParam(1));
diff --git a/src/kvirc/sparser/kvi_sparser.cpp b/src/kvirc/sparser/kvi_sparser.cpp
index cb39fb4a2..272728c91 100644
--- a/src/kvirc/sparser/kvi_sparser.cpp
+++ b/src/kvirc/sparser/kvi_sparser.cpp
@@ -32,6 +32,7 @@
#include "kvi_options.h"
#include "kvi_kvs_eventmanager.h"
#include "kvi_kvs_eventtriggers.h"
+#include "kvi_ircconnectionstatedata.h"
KviServerParser * g_pServerParser = 0;
@@ -70,6 +71,30 @@ void KviServerParser::parseMessage(const char * message,KviIrcConnection * pConn
{
(this->*proc)(&msg);
if(!msg.unrecognized())return; // parsed
+ } else {
+ // we don't have a proc for this
+
+ // special handling of unknown RPL_WHOIS* messages
+ // if
+ // - we're in the middle of a RPL_WHOIS* sequence (i.e. have received a RPL_WHOIS* message since less than 10 seconds)
+ // - we have not received RPL_ENDOFWHOIS yet (the time of the last RPL_WHOIS* is reset to zero when a RPL_ENDOFWHOIS is received)
+ // - this message is unrecognized and looks like a RPL_WHOIS*
+ // then pass it to the WhoisOther handler.
+ //
+ // Thnx Elephantman :)
+
+ if(msg.paramCount() >= 3) // might look like :prefix RPL_WHOIS* <target> <nick> [?] :<something>
+ {
+ kvi_time_t tNow = kvi_unixTime();
+
+ if((tNow - pConnection->stateData()->lastReceivedWhoisReply()) < 10)
+ {
+ // we're in the middle of a RPL_WHOIS* sequence and haven't
+ // received a RPL_ENDOFWHOIS yet.
+ parseNumericWhoisOther(&msg);
+ if(!msg.unrecognized())return;
+ }
+ }
}
} else {
for(int i=0;m_literalParseProcTable[i].msgName;i++)
@@ -97,6 +122,7 @@ void KviServerParser::parseMessage(const char * message,KviIrcConnection * pConn
}
+ // unhandled || unrecognized
if(!msg.haltOutput() && !_OUTPUT_MUTE)
{
QString szWText = pConnection->decodeText(msg.allParams());
@@ -108,7 +134,6 @@ void KviServerParser::parseMessage(const char * message,KviIrcConnection * pConn
__tr2qs("[Server parser]: [%s][%s] %Q"),msg.prefix(),msg.command(),&szWText);
pConnection->console()->output(KVI_OUT_UNRECOGNIZED,
__tr2qs("[Server parser]: %s"),m_szLastParserError.ptr());
-
} else {
// ignore spurious CRLF pairs (some servers send them a lot) unless we want PARANOID output
if((!msg.isEmpty()) || _OUTPUT_PARANOIC)
diff --git a/src/kvirc/ui/kvi_menubar.cpp b/src/kvirc/ui/kvi_menubar.cpp
index 836bf1b3c..be5ee7e88 100644
--- a/src/kvirc/ui/kvi_menubar.cpp
+++ b/src/kvirc/ui/kvi_menubar.cpp
@@ -144,7 +144,7 @@ void KviMenuBar::setupSettingsPopup()
// FIXME: #warning "Toggle these items on the fly ?"
ACTION_POPUP_ITEM(KVI_COREACTION_GENERALOPTIONS,opt)
ACTION_POPUP_ITEM(KVI_COREACTION_THEMEOPTIONS,opt)
- ACTION_POPUP_ITEM(KVI_COREACTION_THEMESELECT,opt)
+ ACTION_POPUP_ITEM(KVI_COREACTION_MANAGETHEMES,opt)
ACTION_POPUP_ITEM(KVI_COREACTION_MANAGEADDONS,opt)
ACTION_POPUP_ITEM(KVI_COREACTION_SERVEROPTIONS,opt)
ACTION_POPUP_ITEM(KVI_COREACTION_TOOLBAREDITOR,opt)
diff --git a/src/kvirc/ui/kvi_msgbox.cpp b/src/kvirc/ui/kvi_msgbox.cpp
index d54ac609c..b2ed8fde9 100644
--- a/src/kvirc/ui/kvi_msgbox.cpp
+++ b/src/kvirc/ui/kvi_msgbox.cpp
@@ -52,7 +52,7 @@ namespace KviMessageBox
#endif
}
- void infoBox(const QString &fmt,...)
+ void information(const QString &fmt,...)
{
kvi_va_list list;
kvi_va_start_by_reference(list,fmt);
diff --git a/src/kvirc/ui/kvi_selectors.cpp b/src/kvirc/ui/kvi_selectors.cpp
index 43285c140..93981d756 100644
--- a/src/kvirc/ui/kvi_selectors.cpp
+++ b/src/kvirc/ui/kvi_selectors.cpp
@@ -300,9 +300,11 @@ void KviPixmapSelector::setEnabled(bool bEnabled)
// FIXME: #warning "Option for DIR_MUST_EXISTS...(this widget could be turned into a file selector too)"
-KviFileSelector::KviFileSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled)
+KviFileSelector::KviFileSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled,unsigned int uFlags,const QString &szFilter)
: QHBox(par), KviSelectorInterface()
{
+ m_uFlags = uFlags;
+ m_szFilter = szFilter;
m_pLabel = new QLabel(txt,this);
m_pLineEdit = new QLineEdit(this);
//m_pLineEdit->setMinimumWidth(200);
@@ -337,13 +339,29 @@ void KviFileSelector::browseClicked()
select();
}
+void KviFileSelector::setSelection(const QString &szSelection)
+{
+ m_pLineEdit->setText(szSelection);
+}
+
+
void KviFileSelector::select()
{
//KviStr tmp;
- QString tmp;
- if(KviFileDialog::askForOpenFileName(tmp,__tr2qs("Choose a File - KVIrc")))
+ QString tmp = *m_pOption;
+ if(m_uFlags & ChooseSaveFileName)
{
- m_pLineEdit->setText(tmp);
+ if(KviFileDialog::askForSaveFileName(tmp,__tr2qs("Choose a File - KVIrc"),tmp,m_szFilter,true,!(m_uFlags & DontConfirmOverwrite)))
+ {
+ m_pLineEdit->setText(tmp);
+ emit selectionChanged(tmp);
+ }
+ } else {
+ if(KviFileDialog::askForOpenFileName(tmp,__tr2qs("Choose a File - KVIrc"),tmp,m_szFilter,true))
+ {
+ m_pLineEdit->setText(tmp);
+ emit selectionChanged(tmp);
+ }
}
}
diff --git a/src/kvirc/ui/kvi_selectors.h b/src/kvirc/ui/kvi_selectors.h
index eece52d63..d0fb3cedf 100644
--- a/src/kvirc/ui/kvi_selectors.h
+++ b/src/kvirc/ui/kvi_selectors.h
@@ -181,16 +181,26 @@ class KVIRC_API KviFileSelector : public QHBox, public KviSelectorInterface
{
Q_OBJECT
public:
- KviFileSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled);
+ KviFileSelector(QWidget * par,const QString & txt,QString * pOption,bool bEnabled,unsigned int uFlags = 0,const QString &szFilter = QString::null);
~KviFileSelector(){};
+public:
+ enum Flags {
+ ChooseSaveFileName = 1,
+ DontConfirmOverwrite = 2
+ };
protected:
QLabel * m_pLabel;
QLineEdit * m_pLineEdit;
QPushButton * m_pButton;
QString * m_pOption;
+ unsigned int m_uFlags;
+ QString m_szFilter;
public:
virtual void commit();
virtual void setEnabled(bool bEnabled);
+ void setSelection(const QString &szSelection);
+signals:
+ void selectionChanged(const QString &szNewValue);
private slots:
void browseClicked();
protected:
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
index f0290648e..388cb6daf 100644
--- a/src/modules/Makefile.am
+++ b/src/modules/Makefile.am
@@ -52,6 +52,7 @@ SUBDIRS = about \
system \
term \
texticons \
+ theme \
tip \
tmphighlight \
toolbar \
diff --git a/src/modules/help/libkvihelp.cpp b/src/modules/help/libkvihelp.cpp
index 46c8d8586..a9ea33eb3 100644
--- a/src/modules/help/libkvihelp.cpp
+++ b/src/modules/help/libkvihelp.cpp
@@ -135,7 +135,6 @@ static bool help_kvs_cmd_search(KviKvsModuleCommandCall * c)
static bool help_kvs_cmd_open(KviKvsModuleCommandCall * c)
{
-
QString doc;
KVSM_PARAMETERS_BEGIN(c)
KVSM_PARAMETER("document",KVS_PT_STRING,KVS_PF_OPTIONAL,doc)
@@ -150,12 +149,11 @@ static bool help_kvs_cmd_open(KviKvsModuleCommandCall * c)
if(!c->switches()->find('n',"new"))
{
- KviHelpWidget * w = (KviHelpWidget *)c->window()->frame()->child(
- "help_widget","KviHelpWidget");
-
+ KviHelpWidget * w = (KviHelpWidget *)c->window()->frame()->child("help_widget","KviHelpWidget");
if(w)
{
w->textBrowser()->setSource(doc);
+ return true;
}
}
if(c->switches()->find('m',"mdi"))
diff --git a/src/modules/options/instances.cpp b/src/modules/options/instances.cpp
index db11329f7..1e59137ae 100644
--- a/src/modules/options/instances.cpp
+++ b/src/modules/options/instances.cpp
@@ -426,11 +426,6 @@ KviOptionsWidget * classKviTextIconsOptionsWidget_createInstanceProc(QWidget * p
return new KviTextIconsOptionsWidget(parent);
}
-KviOptionsWidget * classKviThemeOptionsWidget_createInstanceProc(QWidget * parent)
-{
- return new KviThemeOptionsWidget(parent);
-}
-
KviOptionsWidget * classKviToolsOptionsWidget_createInstanceProc(QWidget * parent)
{
return new KviToolsOptionsWidget(parent);
@@ -618,8 +613,6 @@ static const char * g_szName_KviTextEncodingOptionsWidget = KVI_OPTIONS_WIDGET_N
static const char * g_szClassName_KviTextEncodingOptionsWidget = "KviTextEncodingOptionsWidget";
static const char * g_szName_KviTextIconsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTextIconsOptionsWidget;
static const char * g_szClassName_KviTextIconsOptionsWidget = "KviTextIconsOptionsWidget";
-static const char * g_szName_KviThemeOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviThemeOptionsWidget;
-static const char * g_szClassName_KviThemeOptionsWidget = "KviThemeOptionsWidget";
static const char * g_szName_KviToolsOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviToolsOptionsWidget;
static const char * g_szClassName_KviToolsOptionsWidget = "KviToolsOptionsWidget";
static const char * g_szName_KviTopicLabelLookOptionsWidget = KVI_OPTIONS_WIDGET_NAME_KviTopicLabelLookOptionsWidget;
@@ -3204,40 +3197,6 @@ KviOptionsInstanceManager::KviOptionsInstanceManager()
e1->pChildList = 0;
e0 = new KviOptionsWidgetInstanceEntry;
- e0->createProc = &classKviThemeOptionsWidget_createInstanceProc;
- e0->pWidget = 0;
- e0->szClassName = g_szClassName_KviThemeOptionsWidget;
- e0->iIcon = KVI_OPTIONS_WIDGET_ICON_KviThemeOptionsWidget;
- #ifdef KVI_OPTIONS_WIDGET_PRIORITY_KviThemeOptionsWidget
- e0->iPriority = KVI_OPTIONS_WIDGET_PRIORITY_KviThemeOptionsWidget;
- #else
- e0->iPriority = 0;
- #endif
- #ifdef KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeOptionsWidget
- e0->szKeywordsNoLocale = KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeOptionsWidget;
- e0->szKeywords = __tr2qs_ctx_no_xgettext(e0->szKeywordsNoLocale,"options");;
- #endif
- #ifdef KVI_OPTIONS_WIDGET_GROUP_KviThemeOptionsWidget
- e0->szGroup = KVI_OPTIONS_WIDGET_GROUP_KviThemeOptionsWidget;
- #else
- e0->szGroup = "general";
- #endif
- #ifdef KVI_OPTIONS_WIDGET_CONTAINER_KviThemeOptionsWidget
- e0->bIsContainer = KVI_OPTIONS_WIDGET_CONTAINER_KviThemeOptionsWidget;
- #else
- e0->bIsContainer = false;
- #endif
- #ifdef KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeOptionsWidget
- e0->bIsNotContained = KVI_OPTIONS_WIDGET_NOTCONTAINED_KviThemeOptionsWidget;
- #else
- e0->bIsNotContained = false;
- #endif
- e0->szNameNoLocale = g_szName_KviThemeOptionsWidget;
- e0->szName = __tr2qs_ctx_no_xgettext(g_szName_KviThemeOptionsWidget,"options");
- m_pInstanceTree->append(e0);
- e0->pChildList = 0;
-
- e0 = new KviOptionsWidgetInstanceEntry;
e0->createProc = &classKviTopicLabelLookOptionsWidget_createInstanceProc;
e0->pWidget = 0;
e0->szClassName = g_szClassName_KviTopicLabelLookOptionsWidget;
diff --git a/src/modules/options/optw_theme.cpp b/src/modules/options/optw_theme.cpp
index a4eb1bb4c..9906b7ec1 100644
--- a/src/modules/options/optw_theme.cpp
+++ b/src/modules/options/optw_theme.cpp
@@ -22,588 +22,5 @@
//
//=============================================================================
-#define LVI_ICON_SIZE 32
-#define LVI_BORDER 4
-#define LVI_SPACING 8
-#define LVI_MINIMUM_TEXT_WIDTH 300
-#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER)
-
-#include "optw_theme.h"
-#include "kvi_xmladdonloader.h"
-#include "kvi_iconmanager.h"
-#include "kvi_msgbox.h"
-
-#include <qlayout.h>
-#include <qpushbutton.h>
-#include <qlistbox.h>
-#include <qlineedit.h>
-#include <qtextedit.h>
-#include <qregexp.h>
-#include <qmessagebox.h>
-#include <qdir.h>
-#include <qstringlist.h>
-#include <qdatetime.h>
-#include <qfiledialog.h>
-#include <qpopupmenu.h>
-#include <qcombobox.h>
-#include <qpainter.h>
-#include <qtooltip.h>
-
-#include "kvi_options.h"
-#include "kvi_locale.h"
-#include "kvi_config.h"
-#include "kvi_fileutils.h"
-#include "kvi_app.h"
-#include "kvi_frame.h"
-#include "kvi_iconmanager.h"
-#include "kvi_internalcmd.h"
-#include "kvi_styled_controls.h"
-#include "kvi_doublebuffer.h"
-
-#include <stdlib.h> // rand & srand
-
-
-KviSaveThemeDialog::KviSaveThemeDialog(QWidget * par)
-: QDialog(par)
-{
- setCaption(__tr2qs_ctx("Save Current Theme","options"));
-
- QGridLayout * g = new QGridLayout(this,8,2,4,4);
-
- QLabel * l;
-
- l = new QLabel(__tr2qs_ctx("Theme name:","options"),this);
- g->addWidget(l,0,0);
-
- m_pThemeNameEdit = new QLineEdit(this);
- g->addMultiCellWidget(m_pThemeNameEdit,0,0,1,2);
- connect(m_pThemeNameEdit,SIGNAL(textChanged(const QString &)),this,SLOT(themeNameChanged(const QString &)));
-
-
- l = new QLabel(__tr2qs_ctx("Version:","options"),this);
- g->addWidget(l,1,0);
-
- m_pVersionEdit = new QLineEdit(this);
- g->addMultiCellWidget(m_pVersionEdit,1,1,1,2);
-
-
- l = new QLabel(__tr2qs_ctx("Author:","options"),this);
- g->addWidget(l,2,0);
-
- m_pAuthorEdit = new QLineEdit(this);
- g->addMultiCellWidget(m_pAuthorEdit,2,2,1,2);
-
- l = new QLabel(__tr2qs_ctx("Description:","options"),this);
- g->addWidget(l,3,0);
-
- m_pDescriptionEdit = new QTextEdit(this);
- g->addMultiCellWidget(m_pDescriptionEdit,3,4,1,2);
-
- m_pIncludeMsgcolors = new KviStyledCheckBox( __tr2qs_ctx("Include message colors information","options"), this );
- m_pIncludeMsgcolors->setChecked(TRUE);
- g->addMultiCellWidget(m_pIncludeMsgcolors,5,5,0,1);
-
- l = new QLabel(__tr2qs_ctx("Package type:","options"),this);
- g->addWidget(l,6,0);
-
- m_pFormatCombo = new QComboBox(this);
- m_pFormatCombo->insertItem(__tr2qs_ctx("KVIrc Package","options"),0);
-// m_pFormatCombo->insertItem(__tr2qs_ctx("New multi-file format","options"),1);
- m_pFormatCombo->insertItem(__tr2qs_ctx("Dublicate Theme","options"),1);
- g->addWidget(m_pFormatCombo,6,1);
-
- QHBox * h = new QHBox(this);
- h->setSpacing(7);
- g->addWidget(h,7,2);
- m_pOkButton = new QPushButton(__tr2qs_ctx("OK","options"),h);
- m_pOkButton->setEnabled(false);
- connect(m_pOkButton,SIGNAL(clicked()),this,SLOT(saveTheme()));
- m_pOkButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
-
- QPushButton * pb = new QPushButton(__tr2qs_ctx("Cancel","options"),h);
- connect(pb,SIGNAL(clicked()),this,SLOT(reject()));
- pb->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
-
-}
-
-KviSaveThemeDialog::~KviSaveThemeDialog()
-{
-
-}
-
-void KviSaveThemeDialog::themeNameChanged(const QString &txt)
-{
- m_pOkButton->setEnabled(!txt.isEmpty());
-}
-
-void KviSaveThemeDialog::saveThemeInOldFormat(KviThemeInfo& sto)
-{
- if(!KviFileUtils::directoryExists(sto.szAbsoluteDirectory))
- {
- g_pApp->getLocalKvircDirectory(sto.szAbsoluteDirectory,KviApp::Themes,sto.szSubdirectory,true);
- if(!KviFileUtils::makeDir(sto.szAbsoluteDirectory))
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("Unable to create theme directory.","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
- }
- g_pApp->saveTheme(sto);
- // write down the images
-
- QString szMsg = __tr2qs_ctx("Theme saved successfully to ","options");
- szMsg += sto.szAbsoluteDirectory;
-
- QMessageBox::information(this,__tr2qs_ctx("Save Theme - KVIrc","options"),szMsg,QMessageBox::Ok,
- QMessageBox::NoButton,QMessageBox::NoButton);
-}
-
-void KviSaveThemeDialog::saveThemeInNewFormat(KviThemeInfo& sto)
-{
- QString szBaseDir;
- QFileDialog * d = new QFileDialog(this);
- d->setCaption(__tr2qs_ctx("Choose save directory","options"));
- d->setMode(QFileDialog::DirectoryOnly);
- if(d->exec() == QDialog::Accepted)
- {
- szBaseDir = d->selectedFile();
- KviFileUtils::adjustFilePath(szBaseDir);
- delete d;
- if(szBaseDir.isEmpty())
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("You must select save directory","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
- } else {
- delete d;
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("You must select save directory","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
- KviQString::ensureLastCharIs(szBaseDir,KVI_PATH_SEPARATOR_CHAR);
- sto.szAbsoluteDirectory=szBaseDir+sto.szSubdirectory;
- KviQString::ensureLastCharIs(sto.szAbsoluteDirectory,KVI_PATH_SEPARATOR_CHAR);
- QString szThemeDir=sto.szAbsoluteDirectory;
- sto.szAbsoluteDirectory+="files";
-
- if(!KviFileUtils::makeDir(sto.szAbsoluteDirectory))
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("Unable to create theme files directory.","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
-
- g_pApp->saveTheme(sto);
-
- if(!KviFileUtils::makeDir(szThemeDir+"utils"))
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("Unable to create theme utils directory.","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
-
- QString szInstallerScript;
- g_pApp->getGlobalKvircDirectory(szInstallerScript,KviApp::DefScript,"installer.kvs");
- if(!KviFileUtils::fileExists(szInstallerScript))
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("Cannot find installer.kvs.","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
-
- if(!KviFileUtils::copyFile(szInstallerScript,szThemeDir+"utils/installer.kvs"))
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("Cannot write installer.kvs.","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
-
- g_pApp->getGlobalKvircDirectory(szInstallerScript,KviApp::DefScript,"theme-install.kvs");
- QString szMainScript=szThemeDir+"install.kvs";
- if(!KviFileUtils::copyFile(szInstallerScript,szMainScript))
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("Cannot write install.kvs.","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
- QFile installFile(szMainScript);
- if(!installFile.open(IO_ReadOnly))
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("Cannot open install.kvs for reading.","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
-
- QCString szFileContents;
- szFileContents=installFile.readAll();
- installFile.close();
-
- sto.szName.replace("\"","\\\"");
-
- szFileContents.replace("@THEMENAME@",sto.szName.utf8().data());
-// szFileContents.replace("@THEMENAME@",sto.szName.utf8().data());
- sto.szDescription.replace("\"","\\\"");
- if(sto.szDescription.isEmpty()) sto.szDescription="empty";
- szFileContents.replace("@THEMEDESCRIPTION@",sto.szDescription.utf8().data());
- sto.szVersion.replace("\"","\\\"");
- szFileContents.replace("@THEMEVERSION@",sto.szVersion.utf8().data());
- szFileContents.replace("@SUBDIR@",sto.szSubdirectory.utf8().data());
-
- QString szAliasName="";
- QString m_szId;
-
- struct timeval tv;
- kvi_gettimeofday(&tv,0);
-
- KviQString::sprintf(m_szId,"theme_%d%d%d",tv.tv_usec,rand() % 1000,rand() % 1000);
- szAliasName.prepend(m_szId);
- szFileContents.replace("@ALIASNAME@",szAliasName.utf8().data());
- if(!installFile.open(IO_WriteOnly))
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("Cannot open install.kvs for writing.","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
- installFile.writeBlock(szFileContents.data(),szFileContents.length());
- installFile.close();
-
- QString szMsg = __tr2qs_ctx("Theme saved successfully to ","options");
- szMsg += szThemeDir;
-
- QMessageBox::information(this,__tr2qs_ctx("Save Theme - KVIrc","options"),szMsg,QMessageBox::Ok,
- QMessageBox::NoButton,QMessageBox::NoButton);
-}
-
-void KviSaveThemeDialog::saveThemeInXmlFormat(KviThemeInfo& sto)
-{
- QString szFilename;
- QFileDialog * d = new QFileDialog(this);
- d->setCaption(__tr2qs_ctx("Choose filaname","options"));
- d->setMode(QFileDialog::AnyFile);
- d->setFilter( "KVIrc Packages (*.kvp)" );
- if(d->exec() == QDialog::Accepted)
- {
- szFilename = d->selectedFile();
- KviFileUtils::adjustFilePath(szFilename);
- delete d;
- if(szFilename.isEmpty())
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("You must select filename","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
- } else {
- delete d;
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("You must select filename","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
- if(QFileInfo(szFilename).extension()!="kvp") szFilename.append(".kvp");
- g_pApp->saveXmlTheme(sto,szFilename);
-}
-
-void KviSaveThemeDialog::saveTheme()
-{
- KviThemeInfo sto;
- sto.szName = m_pThemeNameEdit->text();
- if(sto.szName.isEmpty())
- {
- QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","options"),__tr2qs_ctx("You must choose a theme name!","options"),QMessageBox::Ok,
- QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
-
- sto.szAuthor = m_pAuthorEdit->text();
- sto.szDescription = m_pDescriptionEdit->text();
- sto.szDate = QDateTime::currentDateTime().toString();
- sto.szVersion = m_pVersionEdit->text();
- sto.szKvircVersion = KVI_VERSION;
- sto.bIncludeMsgColors=m_pIncludeMsgcolors->isChecked();
-
- if(sto.szVersion.isEmpty())sto.szVersion = "1.0.0";
-
- sto.szSubdirectory = sto.szName + QString("-") + sto.szVersion;
- sto.szSubdirectory.replace(QRegExp("[ \\\\/:][ \\\\/:]*"),"_");
-
- switch(m_pFormatCombo->currentItem())
- {
- case 0:
- saveThemeInXmlFormat(sto);
- break;
- case 1:
-/* saveThemeInNewFormat(sto);
- break;
- case 2:*/
- saveThemeInOldFormat(sto);
- break;
- }
-
- accept();
-}
-
-
-
-
-KviThemeListBoxItem::KviThemeListBoxItem(QListBox * box,KviThemeInfo * inf)
-: QListBoxText(box)
-{
- m_pThemeInfo = inf;
- QString t;
- t = "<nobr><b>";
- t += inf->szName;
- t += "</b>";
-
- if(!inf->szVersion.isEmpty()) {
- t += "[";
- t += inf->szVersion;
- t += "]";
- }
-
- if(!inf->szAuthor.isEmpty()) {
- t += " <font color=\"#a0a0a0\"> ";
- t += __tr2qs_ctx("by","options");
- t += " ";
- t += inf->szAuthor;
- t += "</font>";
- }
-
- t += "</nobr>";
- t += "<br><nobr><font size=\"-1\">";
- t += inf->szDescription;
- t += "</font></nobr>";
- m_pText = new QSimpleRichText(t,box->font());
- int iWidth = box->visibleWidth();
- if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
- iWidth -= LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER;
- m_pText->setWidth(iWidth);
-}
-
-KviThemeListBoxItem::~KviThemeListBoxItem()
-{
- delete m_pThemeInfo;
- delete m_pText;
-}
-
-void KviThemeListBoxItem::paint ( QPainter * p )
-{
- QListBoxText::paint(p);
- p->drawPixmap(LVI_BORDER,LVI_BORDER, *(g_pIconManager->getBigIcon(QString(KVI_BIGICON_THEME))) );
- int afterIcon = LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING;
- int www = p->window().width() - (afterIcon + LVI_BORDER);
- m_pText->setWidth(www);
- m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,p->window().height() - (LVI_BORDER * 2)),listBox()->viewport()->colorGroup());
-}
-
-int KviThemeListBoxItem::height ( const QListBox * lb ) const
-{
- int iHeight = m_pText->height() + (2 * LVI_BORDER);
- if(iHeight < (LVI_ICON_SIZE + (2 * LVI_BORDER)))iHeight = LVI_ICON_SIZE + (2 * LVI_BORDER);
- return iHeight;
-}
-
-KviThemeOptionsWidget::KviThemeOptionsWidget(QWidget * parent)
-: KviOptionsWidget(parent,"theme_options_widget")
-{
- m_pSaveThemeDialog = 0;
-
- createLayout(2,1);
-
- QHBox *hb = new QHBox(this);
- layout()->addWidget(hb,0,0);
-
- KviStyledToolButton * tb = new KviStyledToolButton(hb);
- tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_OPEN)));
- QToolTip::add(tb,__tr2qs_ctx("Install Theme Package","options"));
- connect(tb,SIGNAL(clicked()),this,SLOT(installFromXml()));
-
- tb = new KviStyledToolButton(hb);
- tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_SAVE)));
- QToolTip::add(tb,__tr2qs_ctx("Save Current Theme...","options"));
- connect(tb,SIGNAL(clicked()),this,SLOT(saveCurrentTheme()));
-
- tb = new KviStyledToolButton(hb);
- tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_REMOVE)));
- QToolTip::add(tb,__tr2qs_ctx("Delete Selected Theme","options"));
- connect(tb,SIGNAL(clicked()),this,SLOT(deleteTheme()));
-
- tb = new KviStyledToolButton(hb);
- tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_WWW)));
- QToolTip::add(tb,__tr2qs_ctx("Get More Themes...","options"));
- connect(tb,SIGNAL(clicked()),this,SLOT(getMoreThemes()));
-
- QWidget *w= new QWidget(hb);
- w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum);
-
- m_pListBox = new QListBox(this);
- m_pListBox->setMinimumHeight(400);
- m_pListBox->setMinimumWidth(400);
- connect(m_pListBox,SIGNAL(doubleClicked ( QListBoxItem * )),this,SLOT(applyTheme ( QListBoxItem * )));
- connect(m_pListBox,SIGNAL(contextMenuRequested(QListBoxItem *,const QPoint &)),
- this,SLOT(contextMenuRequested(QListBoxItem *,const QPoint &)));
- layout()->addWidget(m_pListBox,1,0);
-
- layout()->setRowStretch(1,0);
- layout()->setColStretch(1,0);
-
- fillThemeBox();
- m_pContextPopup = new QPopupMenu(this);
-}
-
-KviThemeOptionsWidget::~KviThemeOptionsWidget()
-{
- if(m_pSaveThemeDialog)
- {
- delete m_pSaveThemeDialog;
- m_pSaveThemeDialog = 0;
- }
-}
-
-void KviThemeOptionsWidget::contextMenuRequested ( QListBoxItem * it, const QPoint & pos )
-{
- if(it)
- {
- m_pListBox->setCurrentItem(it);
- m_pContextPopup->clear();
- m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINUS)),__tr2qs_ctx("&Remove Theme","options"),this,SLOT(deleteTheme()));
- m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)),__tr2qs_ctx("&Apply Theme","options"),this,SLOT(applyCurrentTheme()));
- m_pContextPopup->popup(pos);
- }
-}
-
-void KviThemeOptionsWidget::applyTheme ( QListBoxItem * it)
-{
- if(it) m_pListBox->setCurrentItem(it);
- applyCurrentTheme();
-}
-
-void KviThemeOptionsWidget::applyCurrentTheme()
-{
- KviThemeListBoxItem * it = (KviThemeListBoxItem *)m_pListBox->item(m_pListBox->currentItem());
- if(!it)return;
-
- if(KviMessageBox::yesNo(__tr2qs_ctx("Apply theme - KVIrc","options"),
- __tr2qs_ctx("Do you wish to apply theme \"%Q\" (version %Q)?","options"),
- &(it->themeInfo()->szName),&(it->themeInfo()->szVersion))) {
-
- QString szPath = it->themeInfo()->szAbsoluteDirectory;
- if(szPath.isEmpty())return;
-
- g_pApp->loadTheme(szPath);
- }
-}
-
-void KviThemeOptionsWidget::deleteTheme()
-{
- KviThemeListBoxItem* pItem=(KviThemeListBoxItem* )(m_pListBox->selectedItem());
- if(pItem)
- {
- KviThemeInfo * pInfo=pItem->themeInfo();
- QDir d(pInfo->szAbsoluteDirectory);
- KviQString::ensureLastCharIs(pInfo->szAbsoluteDirectory,KVI_PATH_SEPARATOR_CHAR);
- QStringList sl = d.entryList(QDir::Files);
- for(QStringList::Iterator it=sl.begin();it != sl.end();it++)
- {
- KviFileUtils::removeFile(pInfo->szAbsoluteDirectory+*it);
- }
- KviFileUtils::removeDir(pInfo->szAbsoluteDirectory);
- fillThemeBox();
- }
-}
-
-void KviThemeOptionsWidget::installFromXml()
-{
- QString szFilename;
- QFileDialog * d = new QFileDialog(this);
- d->setCaption(__tr2qs_ctx("Choose filaname","options"));
- d->setMode(QFileDialog::ExistingFile);
- d->setFilter( "KVIrc Packages (*.kvp, *.kvxml)" );
- if(d->exec() == QDialog::Accepted)
- {
- szFilename = d->selectedFile();
- KviFileUtils::adjustFilePath(szFilename);
- delete d;
- if(szFilename.isEmpty())
- {
- QMessageBox::critical(this,__tr2qs_ctx("Open Theme - KVIrc","options"),__tr2qs_ctx("You must select file","options"),
- QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
- return;
- }
- } else {
- delete d;
- return;
- }
- KviXmlAddonLoader * pLoader = new KviXmlAddonLoader(szFilename,this);
- pLoader->exec();
- fillThemeBox();
-}
-
-void KviThemeOptionsWidget::getMoreThemes()
-{
- if(!g_pFrame)return;
- g_pFrame->executeInternalCommand(KVI_INTERNALCOMMAND_OPENURL_KVIRC_THEMES);
-}
-
-void KviThemeOptionsWidget::saveCurrentTheme()
-{
- if(m_pSaveThemeDialog)return;
- m_pSaveThemeDialog = new KviSaveThemeDialog(this);
- m_pSaveThemeDialog->exec();
- if(m_pSaveThemeDialog)
- {
- delete m_pSaveThemeDialog;
- m_pSaveThemeDialog = 0;
- fillThemeBox();
- }
-}
-
-void KviThemeOptionsWidget::fillThemeBox(const QString &szDir)
-{
- QDir d(szDir);
-
- QStringList sl = d.entryList(QDir::Dirs);
-
- for(QStringList::Iterator it = sl.begin();it != sl.end();++it)
- {
- if(*it == ".")continue;
- if(*it == "..")continue;
-
- QString szTest = szDir;
- szTest += KVI_PATH_SEPARATOR_CHAR;
- szTest += *it;
-
- KviThemeInfo * inf = new KviThemeInfo;
- if(g_pApp->loadThemeInfo(szTest,*inf))
- {
- KviThemeListBoxItem * item = 0;
- item = new KviThemeListBoxItem(m_pListBox,inf);
- } else {
- delete inf;
- }
- }
-}
-
-void KviThemeOptionsWidget::fillThemeBox()
-{
- m_pListBox->clear();
-
- KviThemeInfo * ti = new KviThemeInfo;
- ti->szName = __tr2qs_ctx("Current Theme","options");
-
- KviThemeListBoxItem * itewrq = new KviThemeListBoxItem(m_pListBox,ti);
-
- QString szDir;
- g_pApp->getGlobalKvircDirectory(szDir,KviApp::Themes);
- fillThemeBox(szDir);
- g_pApp->getLocalKvircDirectory(szDir,KviApp::Themes);
- fillThemeBox(szDir);
-
- m_pListBox->setCurrentItem(itewrq);
-}
-
-void KviThemeOptionsWidget::commit()
-{
- KviOptionsWidget::commit();
-}
#include "m_optw_theme.moc"
diff --git a/src/modules/options/optw_theme.h b/src/modules/options/optw_theme.h
index 076e45a02..729c72e2c 100644
--- a/src/modules/options/optw_theme.h
+++ b/src/modules/options/optw_theme.h
@@ -1,12 +1,13 @@
#ifndef _OPTW_THEME_H_
#define _OPTW_THEME_H_
+//=============================================================================
//
// File : optw_theme.h
// Creation date : Sun May 25 2003 18:03:11 by Szymon Stefanek
//
// This file is part of the KVirc irc client distribution
-// Copyright (C) 2003 Szymon Stefanek (pragma at kvirc dot net)
+// Copyright (C) 2003-2006 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
@@ -22,90 +23,8 @@
// along with this program. If not, write to the Free Software Foundation,
// Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
+//=============================================================================
-#include "kvi_optionswidget.h"
-#include <qdialog.h>
-#include <qsimplerichtext.h>
-#include <qlistbox.h>
-#include <qcombobox.h>
-#include <qpopupmenu.h>
-#include <qcursor.h>
-#define KVI_OPTIONS_WIDGET_ICON_KviThemeOptionsWidget KVI_SMALLICON_GUI
-#define KVI_OPTIONS_WIDGET_NAME_KviThemeOptionsWidget __tr2qs_no_lookup("Load & Save")
-#define KVI_OPTIONS_WIDGET_PRIORITY_KviThemeOptionsWidget 90000
-#define KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeOptionsWidget __tr2qs_no_lookup("theme")
-#define KVI_OPTIONS_WIDGET_GROUP_KviThemeOptionsWidget "themeLoader"
-
-class QLineEdit;
-class QTextEdit;
-class QPushButton;
-class QLabel;
-class QCheckBox;
-typedef struct _KviThemeInfoTag KviThemeInfo;
-
-class KviSaveThemeDialog : public QDialog
-{
- Q_OBJECT
-public:
- KviSaveThemeDialog(QWidget *par);
- ~KviSaveThemeDialog();
-protected:
- QLineEdit * m_pAuthorEdit;
- QLineEdit * m_pThemeNameEdit;
- QLineEdit * m_pVersionEdit;
- QTextEdit * m_pDescriptionEdit;
- QPushButton * m_pOkButton;
- QComboBox * m_pFormatCombo;
- QCheckBox * m_pIncludeMsgcolors;
-
-private:
- void saveThemeInNewFormat(KviThemeInfo& info);
- void saveThemeInOldFormat(KviThemeInfo& info);
- void saveThemeInXmlFormat(KviThemeInfo& info);
-protected slots:
- void saveTheme();
- void themeNameChanged(const QString &txt);
-};
-
-class KviThemeListBoxItem : public QListBoxText
-{
-public:
- KviThemeListBoxItem(QListBox * box,KviThemeInfo * inf);
- ~KviThemeListBoxItem();
-public:
- KviThemeInfo * m_pThemeInfo;
- QSimpleRichText * m_pText;
-public:
- KviThemeInfo * themeInfo(){ return m_pThemeInfo; };
- virtual int height ( const QListBox * lb ) const ;
-protected:
- virtual void paint ( QPainter * painter );
-};
-
-
-class KviThemeOptionsWidget : public KviOptionsWidget
-{
- Q_OBJECT
-public:
- KviThemeOptionsWidget(QWidget * parent);
- ~KviThemeOptionsWidget();
-protected:
- QListBox * m_pListBox;
- QPopupMenu * m_pContextPopup;
- KviSaveThemeDialog * m_pSaveThemeDialog;
-protected:
- virtual void commit();
- void fillThemeBox(const QString &szDir);
-protected slots:
- void saveCurrentTheme();
- void getMoreThemes();
- void installFromXml();
- void fillThemeBox();
- void deleteTheme();
- void applyTheme ( QListBoxItem * );
- void applyCurrentTheme();
- void contextMenuRequested ( QListBoxItem * item, const QPoint & pos );
-};
#endif //!_OPTW_THEME_H_
diff --git a/src/modules/theme/.svnignore b/src/modules/theme/.svnignore
new file mode 100644
index 000000000..087a502ca
--- /dev/null
+++ b/src/modules/theme/.svnignore
@@ -0,0 +1,11 @@
+Makefile.in
+Makefile
+.deps
+*.o
+*.lo
+*.la
+*.moc
+.libs
+.mospics
+moc_*.cpp
+.pics \ No newline at end of file
diff --git a/src/modules/theme/Makefile.am b/src/modules/theme/Makefile.am
new file mode 100644
index 000000000..fba495058
--- /dev/null
+++ b/src/modules/theme/Makefile.am
@@ -0,0 +1,20 @@
+###############################################################################
+# KVirc IRC client Makefile - 30.12.2006 Szymon Stefanek <pragma at kvirc dot net>
+###############################################################################
+
+AM_CPPFLAGS = -I$(SS_TOPSRCDIR)/src/kvilib/include/ -I$(SS_TOPSRCDIR)/src/kvirc/include/ \
+$(SS_INCDIRS) $(SS_CPPFLAGS) -DGLOBAL_KVIRC_DIR=\"$(globalkvircdir)\"
+
+pluglib_LTLIBRARIES = libkvitheme.la
+
+libkvitheme_la_LDFLAGS = -module -avoid-version $(SS_LDFLAGS) $(SS_LIBDIRS)
+
+libkvitheme_la_SOURCES = libkvitheme.cpp managementdialog.cpp
+nodist_libkvitheme_la_SOURCES = moc_managementdialog.cpp
+
+libkvitheme_la_LIBADD = $(SS_LIBLINK) ../../kvilib/build/libkvilib.la
+
+noinst_HEADERS= managementdialog.h
+
+moc_managementdialog.cpp: managementdialog.h
+ $(SS_QT_MOC) $< -o $@
diff --git a/src/modules/theme/libkvitheme.cpp b/src/modules/theme/libkvitheme.cpp
new file mode 100644
index 000000000..72b6261a3
--- /dev/null
+++ b/src/modules/theme/libkvitheme.cpp
@@ -0,0 +1,122 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// File : libkvitheme.cpp
+// Created on Sat 30 Dec 2006 14:54:56 by Szymon Stefanek
+//
+// This toolbar is part of the KVirc irc client distribution
+// Copyright (C) 2006 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "kvi_module.h"
+#include "kvi_locale.h"
+#include "kvi_qstring.h"
+#include "kvi_parameterlist.h"
+#include "kvi_cmdformatter.h"
+#include "kvi_qstring.h"
+#include "kvi_error.h"
+#include "kvi_out.h"
+#include "kvi_iconmanager.h"
+#include "kvi_mirccntrl.h"
+#include "kvi_config.h"
+#include "kvi_sourcesdate.h"
+
+#include "managementdialog.h"
+
+QRect g_rectManagementDialogGeometry(0,0,0,0);
+
+
+/*
+ @doc: theme.install
+ @type:
+ command
+ @title:
+ theme.install
+ @short:
+ Shows the theme theme management editor
+ @syntax:
+ theme.install <package_path:string>
+ @description:
+ Attempts to install the themes in the package specified by <package_path>.
+*/
+
+static bool theme_kvs_cmd_install(KviKvsModuleCommandCall * c)
+{
+ return true;
+}
+
+/*
+ @doc: theme.dialog
+ @type:
+ command
+ @title:
+ theme.dialog
+ @short:
+ Shows the theme theme management editor
+ @syntax:
+ theme.dialog
+ @description:
+ Shows the theme theme management editor
+*/
+
+static bool theme_kvs_cmd_dialog(KviKvsModuleCommandCall * c)
+{
+ KviThemeManagementDialog::display();
+ return true;
+}
+
+static bool theme_module_init(KviModule *m)
+{
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"dialog",theme_kvs_cmd_dialog);
+ KVSM_REGISTER_SIMPLE_COMMAND(m,"install",theme_kvs_cmd_install);
+
+ QString szBuf;
+ m->getDefaultConfigFileName(szBuf);
+ KviConfig cfg(szBuf,KviConfig::Read);
+ g_rectManagementDialogGeometry = cfg.readRectEntry("EditorGeometry",QRect(10,10,390,440));
+
+ return true;
+}
+
+static bool theme_module_cleanup(KviModule *m)
+{
+ KviThemeManagementDialog::cleanup();
+
+ QString szBuf;
+ m->getDefaultConfigFileName(szBuf);
+ KviConfig cfg(szBuf,KviConfig::Write);
+ cfg.writeEntry("EditorGeometry",g_rectManagementDialogGeometry);
+
+ return true;
+}
+
+static bool theme_module_can_unload(KviModule * m)
+{
+ return (!KviThemeManagementDialog::instance());
+}
+
+
+KVIRC_MODULE(
+ "theme", // module name
+ "1.0.0", // module version
+ "Copyright (C) 2006 Szymon Stefanek (pragma at kvirc dot net)", // author & (C)
+ "Theme management functions",
+ theme_module_init,
+ theme_module_can_unload,
+ 0,
+ theme_module_cleanup
+)
diff --git a/src/modules/theme/managementdialog.cpp b/src/modules/theme/managementdialog.cpp
new file mode 100644
index 000000000..566b2691c
--- /dev/null
+++ b/src/modules/theme/managementdialog.cpp
@@ -0,0 +1,1148 @@
+//=============================================================================
+//
+// File : managementdialog.cpp
+// Created on Sat 30 Dec 2006 14:54:56 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2006 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+//=============================================================================
+
+#define LVI_ICON_SIZE 32
+#define LVI_BORDER 4
+#define LVI_SPACING 8
+#define LVI_MINIMUM_TEXT_WIDTH 300
+#define LVI_MINIMUM_CELL_WIDTH (LVI_MINIMUM_TEXT_WIDTH + LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER)
+
+#include "managementdialog.h"
+#include "kvi_xmladdonloader.h"
+#include "kvi_iconmanager.h"
+#include "kvi_msgbox.h"
+
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlistbox.h>
+#include <qlineedit.h>
+#include <qtextedit.h>
+#include <qregexp.h>
+#include <qmessagebox.h>
+#include <qdir.h>
+#include <qstringlist.h>
+#include <qdatetime.h>
+#include <qfiledialog.h>
+#include <qpopupmenu.h>
+#include <qcombobox.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qimage.h>
+#include <qtextedit.h>
+#include <qmultilineedit.h>
+#include <qbuffer.h>
+
+#include "kvi_options.h"
+#include "kvi_locale.h"
+#include "kvi_config.h"
+#include "kvi_fileutils.h"
+#include "kvi_app.h"
+#include "kvi_frame.h"
+#include "kvi_iconmanager.h"
+#include "kvi_internalcmd.h"
+#include "kvi_styled_controls.h"
+#include "kvi_doublebuffer.h"
+#include "kvi_packagefile.h"
+#include "kvi_fileextensions.h"
+#include "kvi_filedialog.h"
+
+#include <stdlib.h> // rand & srand
+
+extern QRect g_rectManagementDialogGeometry;
+
+KviSaveThemeDialog::KviSaveThemeDialog(QWidget * par)
+: QDialog(par)
+{
+ setCaption(__tr2qs_ctx("Save Current Theme","theme"));
+
+ QGridLayout * g = new QGridLayout(this,8,2,4,4);
+
+ QLabel * l;
+
+ l = new QLabel(__tr2qs_ctx("Theme name:","theme"),this);
+ g->addWidget(l,0,0);
+
+ m_pThemeNameEdit = new QLineEdit(this);
+ g->addMultiCellWidget(m_pThemeNameEdit,0,0,1,2);
+ connect(m_pThemeNameEdit,SIGNAL(textChanged(const QString &)),this,SLOT(themeNameChanged(const QString &)));
+
+
+ l = new QLabel(__tr2qs_ctx("Version:","theme"),this);
+ g->addWidget(l,1,0);
+
+ m_pVersionEdit = new QLineEdit(this);
+ g->addMultiCellWidget(m_pVersionEdit,1,1,1,2);
+
+
+ l = new QLabel(__tr2qs_ctx("Author:","theme"),this);
+ g->addWidget(l,2,0);
+
+ m_pAuthorEdit = new QLineEdit(this);
+ g->addMultiCellWidget(m_pAuthorEdit,2,2,1,2);
+
+ l = new QLabel(__tr2qs_ctx("Description:","theme"),this);
+ g->addWidget(l,3,0);
+
+ m_pDescriptionEdit = new QTextEdit(this);
+ g->addMultiCellWidget(m_pDescriptionEdit,3,4,1,2);
+
+ m_pIncludeMsgcolors = new KviStyledCheckBox( __tr2qs_ctx("Include message colors information","theme"), this );
+ m_pIncludeMsgcolors->setChecked(TRUE);
+ g->addMultiCellWidget(m_pIncludeMsgcolors,5,5,0,1);
+
+// l = new QLabel(__tr2qs_ctx("Package type:","theme"),this);
+// g->addWidget(l,6,0);
+
+// m_pFormatCombo = new QComboBox(this);
+// m_pFormatCombo->insertItem(__tr2qs_ctx("KVIrc Package","theme"),0);
+// m_pFormatCombo->insertItem(__tr2qs_ctx("New multi-file format","theme"),1);
+// m_pFormatCombo->insertItem(__tr2qs_ctx("Dublicate Theme","theme"),1);
+// g->addWidget(m_pFormatCombo,6,1);
+
+ QHBox * h = new QHBox(this);
+ h->setSpacing(7);
+ g->addWidget(h,7,2);
+ m_pOkButton = new QPushButton(__tr2qs_ctx("OK","theme"),h);
+ m_pOkButton->setEnabled(false);
+ connect(m_pOkButton,SIGNAL(clicked()),this,SLOT(saveTheme()));
+ m_pOkButton->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+
+ QPushButton * pb = new QPushButton(__tr2qs_ctx("Cancel","theme"),h);
+ connect(pb,SIGNAL(clicked()),this,SLOT(reject()));
+ pb->setIconSet(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+
+}
+
+KviSaveThemeDialog::~KviSaveThemeDialog()
+{
+
+}
+
+void KviSaveThemeDialog::themeNameChanged(const QString &txt)
+{
+ m_pOkButton->setEnabled(!txt.isEmpty());
+}
+
+void KviSaveThemeDialog::saveThemeInOldFormat(KviThemeInfo& sto)
+{
+ if(!KviFileUtils::directoryExists(sto.szAbsoluteDirectory))
+ {
+ g_pApp->getLocalKvircDirectory(sto.szAbsoluteDirectory,KviApp::Themes,sto.szSubdirectory,true);
+ if(!KviFileUtils::makeDir(sto.szAbsoluteDirectory))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("Unable to create theme directory.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ }
+ g_pApp->saveTheme(sto);
+ // write down the images
+
+ QString szMsg = __tr2qs_ctx("Theme saved successfully to ","theme");
+ szMsg += sto.szAbsoluteDirectory;
+
+ QMessageBox::information(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),szMsg,QMessageBox::Ok,
+ QMessageBox::NoButton,QMessageBox::NoButton);
+}
+
+void KviSaveThemeDialog::saveThemeInNewFormat(KviThemeInfo& sto)
+{
+ QString szBaseDir;
+ QFileDialog * d = new QFileDialog(this);
+ d->setCaption(__tr2qs_ctx("Choose save directory","theme"));
+ d->setMode(QFileDialog::DirectoryOnly);
+ if(d->exec() == QDialog::Accepted)
+ {
+ szBaseDir = d->selectedFile();
+ KviFileUtils::adjustFilePath(szBaseDir);
+ delete d;
+ if(szBaseDir.isEmpty())
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("You must select save directory","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ } else {
+ delete d;
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("You must select save directory","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ KviQString::ensureLastCharIs(szBaseDir,KVI_PATH_SEPARATOR_CHAR);
+ sto.szAbsoluteDirectory=szBaseDir+sto.szSubdirectory;
+ KviQString::ensureLastCharIs(sto.szAbsoluteDirectory,KVI_PATH_SEPARATOR_CHAR);
+ QString szThemeDir=sto.szAbsoluteDirectory;
+ sto.szAbsoluteDirectory+="files";
+
+ if(!KviFileUtils::makeDir(sto.szAbsoluteDirectory))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("Unable to create theme files directory.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+
+ g_pApp->saveTheme(sto);
+
+ if(!KviFileUtils::makeDir(szThemeDir+"utils"))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("Unable to create theme utils directory.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+
+ QString szInstallerScript;
+ g_pApp->getGlobalKvircDirectory(szInstallerScript,KviApp::DefScript,"installer.kvs");
+ if(!KviFileUtils::fileExists(szInstallerScript))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("Cannot find installer.kvs.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+
+ if(!KviFileUtils::copyFile(szInstallerScript,szThemeDir+"utils/installer.kvs"))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("Cannot write installer.kvs.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+
+ g_pApp->getGlobalKvircDirectory(szInstallerScript,KviApp::DefScript,"theme-install.kvs");
+ QString szMainScript=szThemeDir+"install.kvs";
+ if(!KviFileUtils::copyFile(szInstallerScript,szMainScript))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("Cannot write install.kvs.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ QFile installFile(szMainScript);
+ if(!installFile.open(IO_ReadOnly))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("Cannot open install.kvs for reading.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+
+ QCString szFileContents;
+ szFileContents=installFile.readAll();
+ installFile.close();
+
+ sto.szName.replace("\"","\\\"");
+
+ szFileContents.replace("@THEMENAME@",sto.szName.utf8().data());
+// szFileContents.replace("@THEMENAME@",sto.szName.utf8().data());
+ sto.szDescription.replace("\"","\\\"");
+ if(sto.szDescription.isEmpty()) sto.szDescription="empty";
+ szFileContents.replace("@THEMEDESCRIPTION@",sto.szDescription.utf8().data());
+ sto.szVersion.replace("\"","\\\"");
+ szFileContents.replace("@THEMEVERSION@",sto.szVersion.utf8().data());
+ szFileContents.replace("@SUBDIR@",sto.szSubdirectory.utf8().data());
+
+ QString szAliasName="";
+ QString m_szId;
+
+ struct timeval tv;
+ kvi_gettimeofday(&tv,0);
+
+ KviQString::sprintf(m_szId,"theme_%d%d%d",tv.tv_usec,rand() % 1000,rand() % 1000);
+ szAliasName.prepend(m_szId);
+ szFileContents.replace("@ALIASNAME@",szAliasName.utf8().data());
+ if(!installFile.open(IO_WriteOnly))
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("Cannot open install.kvs for writing.","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ installFile.writeBlock(szFileContents.data(),szFileContents.length());
+ installFile.close();
+
+ QString szMsg = __tr2qs_ctx("Theme saved successfully to ","theme");
+ szMsg += szThemeDir;
+
+ QMessageBox::information(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),szMsg,QMessageBox::Ok,
+ QMessageBox::NoButton,QMessageBox::NoButton);
+}
+
+void KviSaveThemeDialog::saveThemeInXmlFormat(KviThemeInfo& sto)
+{
+ QString szFilename;
+ QFileDialog * d = new QFileDialog(this);
+ d->setCaption(__tr2qs_ctx("Choose filaname","theme"));
+ d->setMode(QFileDialog::AnyFile);
+ d->setFilter( "KVIrc Packages (*.kvp)" );
+ if(d->exec() == QDialog::Accepted)
+ {
+ szFilename = d->selectedFile();
+ KviFileUtils::adjustFilePath(szFilename);
+ delete d;
+ if(szFilename.isEmpty())
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("You must select filename","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ } else {
+ delete d;
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("You must select filename","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+ if(QFileInfo(szFilename).extension()!="kvp") szFilename.append(".kvp");
+ g_pApp->saveXmlTheme(sto,szFilename);
+}
+
+void KviSaveThemeDialog::saveTheme()
+{
+ KviThemeInfo sto;
+ sto.szName = m_pThemeNameEdit->text();
+ if(sto.szName.isEmpty())
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Save Theme - KVIrc","theme"),__tr2qs_ctx("You must choose a theme name!","theme"),QMessageBox::Ok,
+ QMessageBox::NoButton,QMessageBox::NoButton);
+ return;
+ }
+
+ sto.szAuthor = m_pAuthorEdit->text();
+ sto.szDescription = m_pDescriptionEdit->text();
+ sto.szDate = QDateTime::currentDateTime().toString();
+ sto.szVersion = m_pVersionEdit->text();
+ sto.szKvircVersion = KVI_VERSION;
+ sto.bIncludeMsgColors=m_pIncludeMsgcolors->isChecked();
+
+ if(sto.szVersion.isEmpty())sto.szVersion = "1.0.0";
+
+ sto.szSubdirectory = sto.szName + QString("-") + sto.szVersion;
+ sto.szSubdirectory.replace(QRegExp("[ \\\\/:][ \\\\/:]*"),"_");
+
+/*
+ switch(m_pFormatCombo->currentItem())
+ {
+ case 0:
+ saveThemeInXmlFormat(sto);
+ break;
+ case 1:
+ saveThemeInNewFormat(sto);
+ break;
+ case 2:*/
+ saveThemeInOldFormat(sto);
+/* break;
+ }
+*/
+ accept();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+KviPackThemeDialog::KviPackThemeDialog(QWidget * pParent,KviPtrList<KviThemeInfo> * pThemeInfoList)
+: QWizard(pParent)
+{
+ m_pThemeInfoList = pThemeInfoList;
+
+ KviThemeInfo * pThemeInfo;
+ QString szPackageName;
+ QString szPackageAuthor;
+ QString szPackageDescription;
+ QString szPackageVersion;
+ if(m_pThemeInfoList->count() > 1)
+ {
+ szPackageName = "MyThemes";
+ szPackageAuthor = __tr2qs_ctx("Your name here","theme");
+ szPackageVersion = "1.0";
+ szPackageDescription = __tr2qs_ctx("Put a package description here...","theme");
+ } else {
+ if(m_pThemeInfoList->count() > 0)
+ {
+ pThemeInfo = m_pThemeInfoList->first();
+ szPackageName = pThemeInfo->szSubdirectory;
+ szPackageAuthor = pThemeInfo->szAuthor;
+ szPackageDescription = pThemeInfo->szDescription;
+ szPackageVersion = pThemeInfo->szVersion;
+ }
+ }
+
+
+ setCaption(__tr2qs_ctx("Export Theme - KVIrc","theme"));
+ setMinimumSize(400,350);
+
+ // welcome page ==================================================================================
+ QWidget * pPage = new QWidget(this);
+ QGridLayout * pLayout = new QGridLayout(pPage,2,1,4,4);
+
+ QLabel * pLabel = new QLabel(pPage);
+ QString szText = "<p>";
+ szText += __tr2qs_ctx("This procedure allows you to export the selected themes to a single package. It is useful when you want to distribute your themes to the public.","theme");
+ szText += "</p><p>";
+ szText += __tr2qs_ctx("You will be asked to provide a package name, a description and, if you want, an icon/screenshot.","theme");
+ szText += "</p><p>";
+ szText += __tr2qs_ctx("Hit the \"Next\" button to begin.","theme");
+ szText += "<p>";
+
+ pLabel->setText(szText);
+ pLayout->addWidget(pLabel,0,0);
+ pLayout->setRowStretch(1,1);
+
+ addPage(pPage,__tr2qs_ctx("Welcome","theme"));
+ setBackEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setFinishEnabled(pPage,false);
+
+ // theme data name ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,2,1,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("This is the information list for the themes you're packaging. If it looks OK press \"Next\" to continue, otherwise press \"Cancel\" and rewiew your themes first.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,0,0);
+
+ QString szAuthor = __tr2qs_ctx("Author","theme");
+ QString szCreatedAt = __tr2qs_ctx("Created at","theme");
+ QString szCreatedOn = __tr2qs_ctx("Created on","theme");
+ QString szSubdirectory = __tr2qs_ctx("Subdirectory","theme");
+
+ QString szThemesDescription = "<html><body bgcolor=\"#ffffff\">";
+
+ int iIdx = 0;
+ for(pThemeInfo = m_pThemeInfoList->first();pThemeInfo;pThemeInfo = m_pThemeInfoList->next())
+ {
+ QString szThemeDescription;
+ KviQString::sprintf(
+ szThemeDescription,
+ "<p>" \
+ "<h2>%Q %Q</h2>" \
+ "</p>" \
+ "<p>" \
+ "<i>%Q</i>" \
+ "</p>" \
+ "<p>" \
+ "%Q: <b>%Q</b><br>" \
+ "%Q: <b>%Q</b><br>" \
+ "</p>" \
+ "<p>" \
+ "<font color=\"#808080\">" \
+ "%Q: KVIrc %Q<br>" \
+ "%Q: %Q<br>" \
+ "</font>" \
+ "</p>",
+ &(pThemeInfo->szName),
+ &(pThemeInfo->szVersion),
+ &(pThemeInfo->szDescription),
+ &szAuthor,
+ &(pThemeInfo->szAuthor),
+ &szCreatedAt,
+ &(pThemeInfo->szDate),
+ &szCreatedOn,
+ &(pThemeInfo->szKvircVersion),
+ &szSubdirectory,
+ &(pThemeInfo->szSubdirectory)
+ );
+ if(iIdx > 0)
+ szThemesDescription += "<hr>";
+ szThemesDescription += szThemeDescription;
+ iIdx++;
+ }
+
+ szThemesDescription += "</body></html>";
+
+ QTextEdit * pTextEdit = new QTextEdit(pPage);
+ pTextEdit->setPaper(QBrush(QColor(255,255,255)));
+ pTextEdit->setReadOnly(true);
+ pTextEdit->setText(szThemesDescription);
+ pLayout->addWidget(pTextEdit,1,0);
+ pLayout->setRowStretch(1,1);
+
+ addPage(pPage,__tr2qs_ctx("Theme Data","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setFinishEnabled(pPage,false);
+
+ // packager informations ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,5,2,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Here you need to provide informations about you (the packager) and a short description of the package you're creating.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addMultiCellWidget(pLabel,0,0,0,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Package Name:","theme"));
+ pLayout->addWidget(pLabel,1,0);
+
+ m_pPackageNameEdit = new QLineEdit(pPage);
+ m_pPackageNameEdit->setText(szPackageName);
+ pLayout->addWidget(m_pPackageNameEdit,1,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Version:","theme"));
+ pLayout->addWidget(pLabel,2,0);
+
+ m_pPackageVersionEdit = new QLineEdit(pPage);
+ m_pPackageVersionEdit->setText(szPackageVersion);
+ pLayout->addWidget(m_pPackageVersionEdit,2,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Description:","theme"));
+ pLayout->addWidget(pLabel,3,0);
+
+ m_pPackageDescriptionEdit = new QMultiLineEdit(pPage);
+ m_pPackageDescriptionEdit->setText(szPackageDescription);
+ pLayout->addWidget(m_pPackageDescriptionEdit,3,1);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Package Author:","theme"));
+ pLayout->addWidget(pLabel,4,0);
+
+ m_pPackagerNameEdit = new QLineEdit(pPage);
+ m_pPackagerNameEdit->setText(szPackageAuthor);
+ pLayout->addWidget(m_pPackagerNameEdit,4,1);
+
+
+ pLayout->setRowStretch(3,1);
+ pLayout->setColStretch(1,1);
+
+ addPage(pPage,__tr2qs_ctx("Package Informations","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setFinishEnabled(pPage,false);
+
+ // screenshot/logo/icon ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,3,1,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Here you can choose the image that will appear in the installation dialog for your theme package. It can be an icon, a logo or a screenshot and it should be not larger than 300x225. If you don't provide an image a simple default icon will be used at installation stage.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,0,0);
+
+ m_pImageLabel = new QLabel(pPage);
+ m_pImageLabel->setFrameStyle(QFrame::Sunken | QFrame::Panel);
+ m_pImageLabel->setMinimumSize(300,225);
+ m_pImageLabel->setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
+ pLayout->addWidget(m_pImageLabel,1,0);
+
+ QString szFilter = "*.png *.jpg *.xpm";
+ m_pImageSelector = new KviFileSelector(pPage,"",&m_szImagePath,true,0,szFilter);
+ connect(m_pImageSelector,SIGNAL(selectionChanged(const QString &)),this,SLOT(imageSelectionChanged(const QString &)));
+ pLayout->addWidget(m_pImageSelector,2,0);
+ pLayout->setRowStretch(1,1);
+
+ m_pImageSelectionPage = pPage;
+ addPage(pPage,__tr2qs_ctx("Icon/Screenshot","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,true);
+ setFinishEnabled(pPage,false);
+
+ // save file name ================================================================================
+
+ pPage = new QWidget(this);
+ pLayout = new QGridLayout(pPage,4,1,4,4);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Here you must choose the file name for the theme package. It should have a *.%1 extension.","theme").arg(KVI_FILEEXTENSION_THEMEPACKAGE));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,0,0);
+
+ m_szPackagePath = QDir::homeDirPath();
+ KviQString::ensureLastCharIs(m_szPackagePath,QChar(KVI_PATH_SEPARATOR_CHAR));
+
+ m_szPackagePath += szPackageName;
+ m_szPackagePath += "-";
+ m_szPackagePath += szPackageVersion;
+ m_szPackagePath += ".";
+ m_szPackagePath += KVI_FILEEXTENSION_THEMEPACKAGE;
+
+ szFilter = "*.";
+ szFilter += KVI_FILEEXTENSION_THEMEPACKAGE;
+ m_pPathSelector = new KviFileSelector(pPage,"",&m_szPackagePath,true,KviFileSelector::ChooseSaveFileName,szFilter);
+ pLayout->addWidget(m_pPathSelector,1,0);
+
+ pLabel = new QLabel(pPage);
+ pLabel->setText(__tr2qs_ctx("Finally hit the \"Finish\" button to complete the packaging operation.","theme"));
+ pLabel->setTextFormat(Qt::RichText);
+ pLayout->addWidget(pLabel,3,0);
+
+ pLayout->setRowStretch(2,1);
+
+ addPage(pPage,__tr2qs_ctx("Package Path","theme"));
+ setBackEnabled(pPage,true);
+ setHelpEnabled(pPage,false);
+ setNextEnabled(pPage,false);
+ setFinishEnabled(pPage,true);
+
+}
+
+KviPackThemeDialog::~KviPackThemeDialog()
+{
+}
+
+void KviPackThemeDialog::imageSelectionChanged(const QString &szImagePath)
+{
+ QImage pix(szImagePath);
+ if(!pix.isNull())
+ {
+ QPixmap out;
+ if(pix.width() > 300 || pix.height() > 225)
+ out.convertFromImage(pix.smoothScale(300,225,QImage::ScaleMin));
+ else
+ out.convertFromImage(pix);
+ m_pImageLabel->setPixmap(out);
+ return;
+ }
+
+ QMessageBox::critical(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),__tr2qs_ctx("Failed to load the selected image","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+
+ m_pImageSelector->setSelection("");
+ m_pImageLabel->setPixmap(QPixmap());
+}
+
+
+void KviPackThemeDialog::accept()
+{
+ if(!packTheme())return;
+ QWizard::accept();
+}
+
+
+bool KviPackThemeDialog::packTheme()
+{
+ m_pImageSelector->commit();
+ m_pPathSelector->commit();
+
+ QString szPackageAuthor = m_pPackagerNameEdit->text();
+ QString szPackageName = m_pPackageNameEdit->text();
+ QString szPackageDescription = m_pPackageDescriptionEdit->text();
+ QString szPackageVersion = m_pPackageVersionEdit->text();
+
+ QImage pix(m_szImagePath);
+ QPixmap out;
+ if(!pix.isNull())
+ {
+ if(pix.width() > 300 || pix.height() > 225)
+ out.convertFromImage(pix.smoothScale(300,225,QImage::ScaleMin));
+ else
+ out.convertFromImage(pix);
+ } else {
+ if(!m_szImagePath.isEmpty())
+ {
+ QMessageBox::critical(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),__tr2qs_ctx("Failed to load the selected image: please fix it","theme"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ showPage(m_pImageSelectionPage);
+ return false;
+ }
+ }
+
+ KviPackageWriter f;
+
+ QString szTmp = QDateTime::currentDateTime().toString();
+
+ f.addInfoField("PackageType","ThemePack");
+ f.addInfoField("ThemePackVersion","1");
+ f.addInfoField("Name",szPackageName);
+ f.addInfoField("Version",szPackageVersion);
+ f.addInfoField("Author",szPackageAuthor);
+ f.addInfoField("Description",szPackageDescription);
+ f.addInfoField("Date",szTmp);
+ f.addInfoField("KVIrcVersion",KVI_VERSION);
+
+ if(!out.isNull())
+ {
+ QByteArray * pba = new QByteArray();
+ QBuffer buffer(*pba);
+ buffer.open(IO_WriteOnly);
+ out.save(&buffer,"PNG");
+ buffer.close();
+ f.addInfoField("Image",pba); // cool :) [no disk access needed]
+ }
+
+ szTmp.setNum(m_pThemeInfoList->count());
+ f.addInfoField("ThemeCount",szTmp);
+
+ int iIdx = 0;
+ for(KviThemeInfo * pInfo = m_pThemeInfoList->first();pInfo;pInfo = m_pThemeInfoList->next())
+ {
+ KviQString::sprintf(szTmp,"Theme%dName",iIdx);
+ f.addInfoField(szTmp,pInfo->szName);
+ KviQString::sprintf(szTmp,"Theme%dVersion",iIdx);
+ f.addInfoField(szTmp,pInfo->szVersion);
+ KviQString::sprintf(szTmp,"Theme%dDescription",iIdx);
+ f.addInfoField(szTmp,pInfo->szDescription);
+ KviQString::sprintf(szTmp,"Theme%dDate",iIdx);
+ f.addInfoField(szTmp,pInfo->szDate);
+ KviQString::sprintf(szTmp,"Theme%dSubdirectory",iIdx);
+ f.addInfoField(szTmp,pInfo->szSubdirectory);
+ KviQString::sprintf(szTmp,"Theme%dAuthor",iIdx);
+ f.addInfoField(szTmp,pInfo->szAuthor);
+ KviQString::sprintf(szTmp,"Theme%dKVIrcVersion",iIdx);
+ f.addInfoField(szTmp,pInfo->szKvircVersion);
+ if(!f.addDirectory(pInfo->szAbsoluteDirectory,pInfo->szSubdirectory))
+ {
+ szTmp = __tr2qs_ctx("Packaging failed","theme");
+ szTmp += ": ";
+ szTmp += f.lastError();
+ QMessageBox::critical(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),szTmp,
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ }
+ iIdx++;
+ }
+
+ if(!f.pack(m_szPackagePath))
+ {
+ szTmp = __tr2qs_ctx("Packaging failed","theme");
+ szTmp += ": ";
+ szTmp += f.lastError();
+ QMessageBox::critical(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),szTmp,
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ return false;
+ }
+
+ //KviPackageReader r;
+ //r.unpack("/root/test.kvt","/root/unpacked_test_kvt");
+
+ QMessageBox::information(this,__tr2qs_ctx("Export Theme - KVIrc","theme"),__tr2qs("Package saved succesfully"),
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+KviThemeListBoxItem::KviThemeListBoxItem(QListBox * box,KviThemeInfo * inf)
+: QListBoxText(box)
+{
+ m_pThemeInfo = inf;
+ QString t;
+ t = "<nobr><b>";
+ t += inf->szName;
+ t += "</b>";
+
+ if(!inf->szVersion.isEmpty()) {
+ t += "[";
+ t += inf->szVersion;
+ t += "]";
+ }
+
+ if(!inf->szAuthor.isEmpty()) {
+ t += " <font color=\"#a0a0a0\"> ";
+ t += __tr2qs_ctx("by","theme");
+ t += " ";
+ t += inf->szAuthor;
+ t += "</font>";
+ }
+
+ t += "</nobr>";
+ t += "<br><nobr><font size=\"-1\">";
+ t += inf->szDescription;
+ t += "</font></nobr>";
+ m_pText = new QSimpleRichText(t,box->font());
+ int iWidth = box->visibleWidth();
+ if(iWidth < LVI_MINIMUM_CELL_WIDTH)iWidth = LVI_MINIMUM_CELL_WIDTH;
+ iWidth -= LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING + LVI_BORDER;
+ m_pText->setWidth(iWidth);
+}
+
+KviThemeListBoxItem::~KviThemeListBoxItem()
+{
+ delete m_pThemeInfo;
+ delete m_pText;
+}
+
+void KviThemeListBoxItem::paint ( QPainter * p )
+{
+ QListBoxText::paint(p);
+ p->drawPixmap(LVI_BORDER,LVI_BORDER, *(g_pIconManager->getBigIcon(QString(KVI_BIGICON_THEME))) );
+ int afterIcon = LVI_BORDER + LVI_ICON_SIZE + LVI_SPACING;
+ int www = p->window().width() - (afterIcon + LVI_BORDER);
+ m_pText->setWidth(www);
+ m_pText->draw(p,afterIcon,LVI_BORDER,QRect(afterIcon,LVI_BORDER,www,p->window().height() - (LVI_BORDER * 2)),listBox()->viewport()->colorGroup());
+}
+
+int KviThemeListBoxItem::height ( const QListBox * lb ) const
+{
+ int iHeight = m_pText->height() + (2 * LVI_BORDER);
+ if(iHeight < (LVI_ICON_SIZE + (2 * LVI_BORDER)))iHeight = LVI_ICON_SIZE + (2 * LVI_BORDER);
+ return iHeight;
+}
+
+KviThemeManagementDialog * KviThemeManagementDialog::m_pInstance = 0;
+
+
+KviThemeManagementDialog::KviThemeManagementDialog(QWidget * parent)
+: QDialog(parent,"theme_options_widget")
+{
+ setCaption(__tr2qs_ctx("Manage Themes - KVIrc","theme"));
+ setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_THEMES)));
+
+ setModal(true);
+
+ m_pInstance = this;
+
+ m_pSaveThemeDialog = 0;
+
+ QGridLayout * g = new QGridLayout(this,3,2,4,4);
+
+ QHBox *hb = new QHBox(this);
+ g->addMultiCellWidget(hb,0,0,0,1);
+
+ KviStyledToolButton * tb = new KviStyledToolButton(hb);
+ tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_OPEN)));
+ tb->setUsesBigPixmap(true);
+ QToolTip::add(tb,__tr2qs_ctx("Install Theme Package From Disk","theme"));
+ connect(tb,SIGNAL(clicked()),this,SLOT(installFromXml()));
+
+ tb = new KviStyledToolButton(hb);
+ tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_SAVE)));
+ tb->setUsesBigPixmap(true);
+ QToolTip::add(tb,__tr2qs_ctx("Save Current Theme...","theme"));
+ connect(tb,SIGNAL(clicked()),this,SLOT(saveCurrentTheme()));
+
+ m_pPackThemeButton = new KviStyledToolButton(hb);
+ m_pPackThemeButton->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_PACK)));
+ m_pPackThemeButton->setUsesBigPixmap(true);
+ QToolTip::add(m_pPackThemeButton,__tr2qs_ctx("Export Selected Themes to a Distributable Package","theme"));
+ connect(m_pPackThemeButton,SIGNAL(clicked()),this,SLOT(packTheme()));
+
+ m_pDeleteThemeButton = new KviStyledToolButton(hb);
+ m_pDeleteThemeButton->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_REMOVE)));
+ m_pDeleteThemeButton->setUsesBigPixmap(true);
+ QToolTip::add(m_pDeleteThemeButton,__tr2qs_ctx("Delete Selected Themes","theme"));
+ connect(m_pDeleteThemeButton,SIGNAL(clicked()),this,SLOT(deleteTheme()));
+
+ tb = new KviStyledToolButton(hb);
+ tb->setIconSet(*(g_pIconManager->getBigIcon(KVI_BIGICON_WWW)));
+ tb->setUsesBigPixmap(true);
+ QToolTip::add(tb,__tr2qs_ctx("Get More Themes...","theme"));
+ connect(tb,SIGNAL(clicked()),this,SLOT(getMoreThemes()));
+
+ QWidget *w= new QWidget(hb);
+ w->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum);
+
+ m_pListBox = new QListBox(this);
+ m_pListBox->setMinimumHeight(400);
+ m_pListBox->setMinimumWidth(400);
+ m_pListBox->setSelectionMode(QListBox::Extended);
+ connect(m_pListBox,SIGNAL(doubleClicked(QListBoxItem *)),this,SLOT(applyTheme(QListBoxItem *)));
+ connect(m_pListBox,SIGNAL(contextMenuRequested(QListBoxItem *,const QPoint &)),
+ this,SLOT(contextMenuRequested(QListBoxItem *,const QPoint &)));
+ connect(m_pListBox,SIGNAL(selectionChanged()),this,SLOT(enableDisableButtons()));
+ g->addMultiCellWidget(m_pListBox,1,1,0,1);
+
+
+ QPushButton * b = new QPushButton(__tr2qs("Close"),this);
+ connect(b,SIGNAL(clicked()),this,SLOT(closeClicked()));
+ g->addWidget(b,2,1);
+
+ g->setRowStretch(1,0);
+ g->setColStretch(0,0);
+
+ fillThemeBox();
+ m_pContextPopup = new QPopupMenu(this);
+
+ if(g_rectManagementDialogGeometry.y() < 5)
+ {
+ g_rectManagementDialogGeometry.setY(5);
+ }
+ resize(g_rectManagementDialogGeometry.width(),
+ g_rectManagementDialogGeometry.height());
+ move(g_rectManagementDialogGeometry.x(),
+ g_rectManagementDialogGeometry.y());
+}
+
+KviThemeManagementDialog::~KviThemeManagementDialog()
+{
+ g_rectManagementDialogGeometry = QRect(pos().x(),pos().y(),size().width(),size().height());
+
+ if(m_pSaveThemeDialog)
+ {
+ delete m_pSaveThemeDialog;
+ m_pSaveThemeDialog = 0;
+ }
+
+ m_pInstance = 0;
+}
+
+void KviThemeManagementDialog::closeClicked()
+{
+ delete this;
+}
+
+
+void KviThemeManagementDialog::display()
+{
+ if(m_pInstance)return;
+ m_pInstance = new KviThemeManagementDialog(g_pFrame);
+ m_pInstance->show();
+}
+
+void KviThemeManagementDialog::cleanup()
+{
+ if(!m_pInstance)return;
+ delete m_pInstance;
+ m_pInstance = 0;
+}
+
+void KviThemeManagementDialog::packTheme()
+{
+ KviPtrList<KviThemeInfo> dl;
+ dl.setAutoDelete(false);
+ for(KviThemeListBoxItem * it = (KviThemeListBoxItem *)m_pListBox->firstItem();it;it = (KviThemeListBoxItem *)it->next())
+ {
+ if(it->isSelected())
+ dl.append(it->themeInfo());
+ }
+ if(dl.isEmpty())return;
+
+ KviPackThemeDialog * pDialog = new KviPackThemeDialog(this,&dl);
+ pDialog->exec();
+ delete pDialog;
+
+}
+
+void KviThemeManagementDialog::contextMenuRequested ( QListBoxItem * it, const QPoint & pos )
+{
+ if(it)
+ {
+ m_pListBox->setCurrentItem(it);
+ m_pContextPopup->clear();
+ m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_MINUS)),__tr2qs_ctx("&Remove Theme","theme"),this,SLOT(deleteTheme()));
+ m_pContextPopup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)),__tr2qs_ctx("&Apply Theme","theme"),this,SLOT(applyCurrentTheme()));
+ m_pContextPopup->popup(pos);
+ }
+}
+
+void KviThemeManagementDialog::applyTheme ( QListBoxItem * it)
+{
+ if(it) m_pListBox->setCurrentItem(it);
+ applyCurrentTheme();
+}
+
+void KviThemeManagementDialog::applyCurrentTheme()
+{
+ KviThemeListBoxItem * it = (KviThemeListBoxItem *)m_pListBox->item(m_pListBox->currentItem());
+ if(!it)return;
+
+ if(KviMessageBox::yesNo(__tr2qs_ctx("Apply theme - KVIrc","theme"),
+ __tr2qs_ctx("Do you wish to apply theme \"%Q\" (version %Q)?","theme"),
+ &(it->themeInfo()->szName),&(it->themeInfo()->szVersion))) {
+
+ QString szPath = it->themeInfo()->szAbsoluteDirectory;
+ if(szPath.isEmpty())return;
+
+ g_pApp->loadTheme(szPath);
+ }
+}
+
+void KviThemeManagementDialog::deleteTheme()
+{
+ for(KviThemeListBoxItem * pItem = (KviThemeListBoxItem *)m_pListBox->firstItem();pItem;pItem = (KviThemeListBoxItem *)pItem->next())
+ {
+ if(pItem->isSelected())
+ {
+ if(!KviMessageBox::yesNo(__tr2qs_ctx("Delete Theme - KVIrc","theme"),
+ __tr2qs_ctx("Do you really wish to delete theme \"%Q\" (version %Q)?","theme"),
+ &(pItem->themeInfo()->szName),&(pItem->themeInfo()->szVersion)))goto jump_out;
+
+ KviFileUtils::deleteDir(pItem->themeInfo()->szAbsoluteDirectory);
+ }
+ }
+jump_out:
+ fillThemeBox();
+}
+
+void KviThemeManagementDialog::installFromXml()
+{
+ QString szFileName;
+ QDict<QString> * pInfoFields;
+ QString * pValue;
+ bool bInstall;
+
+ const char * check_fields[] = { "Name", "Version", "Author", "Description", "Date", "KVIrcVersion" };
+
+ if(!KviFileDialog::askForOpenFileName(szFileName,__tr2qs_ctx("Open Theme - KVIrc","theme"),QString::null,"*.kvt"))
+ return;
+
+ // check if it is a valid theme file
+ KviPackageReader r;
+ if(!r.readHeader(szFileName))
+ {
+ QString szErr = r.lastError();
+ KviMessageBox::information(__tr2qs_ctx("The selected file does not seem to be a valid KVIrc package: %Q","theme"),&szErr);
+ return;
+ }
+
+ pInfoFields = r.stringInfoFields();
+
+ pValue = pInfoFields->find("PackageType");
+ if(!pValue)goto not_a_valid_theme_package;
+ if(!KviQString::equalCI(*pValue,"ThemePack"))goto not_a_valid_theme_package;
+ pValue = pInfoFields->find("ThemePackVersion");
+ if(!pValue)goto not_a_valid_theme_package;
+ if(!KviQString::equalCI(*pValue,"1"))goto not_a_valid_theme_package;
+
+ // make sure the default fields exist
+ for(int i=0;i<6;i++)
+ {
+ pValue = pInfoFields->find(check_fields[i]);
+ if(!pValue)goto not_a_valid_theme_package;
+ }
+
+ pValue = pInfoFields->find("ThemeCount");
+ if(!pValue)goto not_a_valid_theme_package;
+ bool bOk;
+ int iThemeCount = pValue->toInt(&bOk);
+ if(!bOk)goto not_a_valid_theme_package;
+ if(iThemeCount < 1)goto not_a_valid_theme_package;
+
+ // ok.. it should be really valid at this point
+
+ // load it's picture
+ /*
+ KviUnpackThemeDialog * pDialog = new KviUnpackThemeDialog(this,szFileName);
+ bool bInstall = pDialog->exec() == QDialog::Accepted;
+ delete pDialog;
+ */
+
+ bInstall = true;
+
+ if(bInstall)
+ {
+ QString szUnpackPath;
+ g_pApp->getLocalKvircDirectory(szUnpackPath,KviApp::Themes);
+ if(!r.unpack(szFileName,szUnpackPath))
+ {
+ QString szErr2 = r.lastError();
+ KviMessageBox::information(__tr2qs_ctx("Failed to unpack the selected file: %Q","theme"),&szErr2);
+ return;
+ }
+ }
+
+ /*
+ KviXmlAddonLoader * pLoader = new KviXmlAddonLoader(szFilename,this);
+ pLoader->exec();
+ */
+ fillThemeBox();
+ return;
+not_a_valid_theme_package:
+ KviMessageBox::information(__tr2qs_ctx("The selected file does not seem to be a valid KVIrc theme package","theme"));
+ return;
+}
+
+void KviThemeManagementDialog::getMoreThemes()
+{
+ if(!g_pFrame)return;
+ g_pFrame->executeInternalCommand(KVI_INTERNALCOMMAND_OPENURL_KVIRC_THEMES);
+}
+
+void KviThemeManagementDialog::saveCurrentTheme()
+{
+ if(m_pSaveThemeDialog)return;
+ m_pSaveThemeDialog = new KviSaveThemeDialog(this);
+ m_pSaveThemeDialog->exec();
+ if(m_pSaveThemeDialog)
+ {
+ delete m_pSaveThemeDialog;
+ m_pSaveThemeDialog = 0;
+ fillThemeBox();
+ }
+}
+
+void KviThemeManagementDialog::fillThemeBox(const QString &szDir)
+{
+ QDir d(szDir);
+
+ QStringList sl = d.entryList(QDir::Dirs);
+
+ for(QStringList::Iterator it = sl.begin();it != sl.end();++it)
+ {
+ if(*it == ".")continue;
+ if(*it == "..")continue;
+
+ QString szTest = szDir;
+ szTest += KVI_PATH_SEPARATOR_CHAR;
+ szTest += *it;
+
+ KviThemeInfo * inf = new KviThemeInfo;
+ inf->szSubdirectory = *it;
+ if(g_pApp->loadThemeInfo(szTest,*inf))
+ {
+ KviThemeListBoxItem * item = 0;
+ item = new KviThemeListBoxItem(m_pListBox,inf);
+ } else {
+ delete inf;
+ }
+ }
+}
+
+void KviThemeManagementDialog::fillThemeBox()
+{
+ m_pListBox->clear();
+
+// KviThemeInfo * ti = new KviThemeInfo;
+// ti->szName = __tr2qs_ctx("Current Theme","theme");
+
+// KviThemeListBoxItem * itewrq = new KviThemeListBoxItem(m_pListBox,ti);
+
+ QString szDir;
+ g_pApp->getGlobalKvircDirectory(szDir,KviApp::Themes);
+ fillThemeBox(szDir);
+ g_pApp->getLocalKvircDirectory(szDir,KviApp::Themes);
+ fillThemeBox(szDir);
+
+// m_pListBox->setCurrentItem(itewrq);
+ enableDisableButtons();
+}
+
+bool KviThemeManagementDialog::hasSelectedItems()
+{
+ for(QListBoxItem * it = m_pListBox->firstItem();it;it = it->next())
+ {
+ if(it->isSelected())return true;
+ }
+ return false;
+}
+
+
+void KviThemeManagementDialog::enableDisableButtons()
+{
+ bool b = hasSelectedItems();
+ m_pPackThemeButton->setEnabled(b);
+ m_pDeleteThemeButton->setEnabled(b);
+}
+
+
diff --git a/src/modules/theme/managementdialog.h b/src/modules/theme/managementdialog.h
new file mode 100644
index 000000000..d88be2ea0
--- /dev/null
+++ b/src/modules/theme/managementdialog.h
@@ -0,0 +1,164 @@
+#ifndef _MANAGEMENTDIALOG_H_
+#define _MANAGEMENTDIALOG_H_
+//=============================================================================
+//
+// File : managementdialog.h
+// Created on Sat 30 Dec 2006 14:54:56 by Szymon Stefanek
+//
+// This file is part of the KVIrc IRC Client distribution
+// Copyright (C) 2006 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+//=============================================================================
+
+#include "kvi_optionswidget.h"
+#include "kvi_list.h"
+
+#include <qdialog.h>
+#include <qsimplerichtext.h>
+#include <qlistbox.h>
+#include <qcombobox.h>
+#include <qpopupmenu.h>
+#include <qcursor.h>
+#include <qwizard.h>
+
+#define KVI_OPTIONS_WIDGET_ICON_KviThemeManagementDialog KVI_SMALLICON_GUI
+#define KVI_OPTIONS_WIDGET_NAME_KviThemeManagementDialog __tr2qs_no_lookup("Load & Save")
+#define KVI_OPTIONS_WIDGET_PRIORITY_KviThemeManagementDialog 90000
+#define KVI_OPTIONS_WIDGET_KEYWORDS_KviThemeManagementDialog __tr2qs_no_lookup("theme")
+#define KVI_OPTIONS_WIDGET_GROUP_KviThemeManagementDialog "themeLoader"
+
+class QLineEdit;
+class QTextEdit;
+class QPushButton;
+class QLabel;
+class QCheckBox;
+class QMultiLineEdit;
+
+typedef struct _KviThemeInfoTag KviThemeInfo;
+
+class KviSaveThemeDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviSaveThemeDialog(QWidget *par);
+ ~KviSaveThemeDialog();
+protected:
+ QLineEdit * m_pAuthorEdit;
+ QLineEdit * m_pThemeNameEdit;
+ QLineEdit * m_pVersionEdit;
+ QTextEdit * m_pDescriptionEdit;
+ QPushButton * m_pOkButton;
+// QComboBox * m_pFormatCombo;
+ QCheckBox * m_pIncludeMsgcolors;
+
+private:
+ void saveThemeInNewFormat(KviThemeInfo& info);
+ void saveThemeInOldFormat(KviThemeInfo& info);
+ void saveThemeInXmlFormat(KviThemeInfo& info);
+protected slots:
+ void saveTheme();
+ void themeNameChanged(const QString &txt);
+};
+
+class KviPackThemeDialog : public QWizard
+{
+ Q_OBJECT
+public:
+ KviPackThemeDialog(QWidget * pParent,KviPtrList<KviThemeInfo> * pThemeInfoList);
+ ~KviPackThemeDialog();
+protected:
+ QString m_szImagePath;
+ KviFileSelector * m_pImageSelector;
+ QString m_szPackagePath;
+ KviFileSelector * m_pPathSelector;
+ QLabel * m_pImageLabel;
+ KviPtrList<KviThemeInfo> * m_pThemeInfoList;
+ QLineEdit * m_pPackageNameEdit;
+ QMultiLineEdit * m_pPackageDescriptionEdit;
+ QLineEdit * m_pPackageVersionEdit;
+ QLineEdit * m_pPackagerNameEdit;
+ QWidget * m_pImageSelectionPage;
+protected:
+ virtual void accept();
+protected slots:
+ bool packTheme();
+ void imageSelectionChanged(const QString &szImagePath);
+};
+
+/*
+class KviUnpackThemeDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviUnpackThemeDialog(QWidget * pParent);
+ ~KviUnpackThemeDialog();
+};
+*/
+
+class KviThemeListBoxItem : public QListBoxText
+{
+public:
+ KviThemeListBoxItem(QListBox * box,KviThemeInfo * inf);
+ ~KviThemeListBoxItem();
+public:
+ KviThemeInfo * m_pThemeInfo;
+ QSimpleRichText * m_pText;
+public:
+ KviThemeInfo * themeInfo(){ return m_pThemeInfo; };
+ virtual int height ( const QListBox * lb ) const ;
+protected:
+ virtual void paint ( QPainter * painter );
+};
+
+
+class KviStyledToolButton;
+
+class KviThemeManagementDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ KviThemeManagementDialog(QWidget * parent);
+ ~KviThemeManagementDialog();
+protected:
+ static KviThemeManagementDialog * m_pInstance;
+ QListBox * m_pListBox;
+ QPopupMenu * m_pContextPopup;
+ KviSaveThemeDialog * m_pSaveThemeDialog;
+ KviStyledToolButton * m_pDeleteThemeButton;
+ KviStyledToolButton * m_pPackThemeButton;
+public:
+ static KviThemeManagementDialog * instance(){ return m_pInstance; };
+ static void display();
+ static void cleanup();
+protected:
+ void fillThemeBox(const QString &szDir);
+ bool hasSelectedItems();
+protected slots:
+ void saveCurrentTheme();
+ void getMoreThemes();
+ void installFromXml();
+ void fillThemeBox();
+ void deleteTheme();
+ void closeClicked();
+ void packTheme();
+ void applyTheme(QListBoxItem *);
+ void applyCurrentTheme();
+ void enableDisableButtons();
+ void contextMenuRequested(QListBoxItem * item, const QPoint & pos);
+};
+
+#endif //!_MANAGEMENTDIALOG_H_