Hi, this patch adds a new feature: emoticons (nobody seems to use this word...all is about smiles) can be seen as pictures. Which emoticons do we translate? User-defined ones. That means that you can map what ever you want to an image. How do you define a new theme? The theme is defined in an XML file. The format is the same as kopete. Why? Because i didn't want to find images to test.
The patch still has some room to performance gain. Also i didn't test if it compiles on another version of QT of my system ( qt2 handles XML?). If you like the patch, and you want it on qt2, we can add in configure a test for libxml2 and implement it also over that. Also, I thought in building an finite state machine (with output) dinamicaly (at SetTheme) to parse the message in O(n) where n = characters of message, instead of O(n*m) where m is the number of files available in the theme (i consider m lineal because i bet that each QRegExp is an state machine). To apply please do: [EMAIL PROTECTED]:/tmp$ cd licq [EMAIL PROTECTED]:/tmp/licq$ tar vxjf ../emoticons.tar.bz2 plugins/qt-gui/share/qt-gui/emoticons/ plugins/qt-gui/share/qt-gui/emoticons/None/ plugins/qt-gui/share/qt-gui/emoticons/None/emoticon .... [EMAIL PROTECTED]:/tmp/licq$ patch -p0 < ../emoticons.diff patching file plugins/qt-gui/share/Makefile.am patching file plugins/qt-gui/src/Makefile.am patching file plugins/qt-gui/src/gui-defines.h ... [EMAIL PROTECTED]:/tmp/licq$ cd plugins/qt-gui/ [EMAIL PROTECTED]:/tmp/licq/plugins/qt-gui$ make ... [EMAIL PROTECTED]:/tmp/licq/plugins/qt-gui$ make install (so the emoticons themes are installed). To disable this, just select the theme None. What format are available? I don't know. It depends of your qt installation. Maybe it support animated gifs. I have 15 icons themes in my harddisk that came from kopete. Some dont have a license notice in them, and some do (an even somes says you can redistribute it only for noncomercial ...). So for this mail i have only included the few that made sense. Now that i remember...emoticons at ~/.licq/qt-gui... are not supported (hey! i install licq on my home). -- Buenos Aires, Argentina 8�C with winds at 25 km/h ESE
? plugins/qt-gui/src/emoticon.cpp
? plugins/qt-gui/src/emoticon.h
Index: plugins/qt-gui/share/Makefile.am
===================================================================
RCS file: /cvsroot/licq/qt-gui/share/Makefile.am,v
retrieving revision 1.11
diff -u -d -p -r1.11 Makefile.am
--- plugins/qt-gui/share/Makefile.am 8 Nov 2002 01:01:01 -0000 1.11
+++ plugins/qt-gui/share/Makefile.am 23 Aug 2003 01:26:29 -0000
@@ -55,4 +55,12 @@ install-data-local:
fi \
done; \
done
-
+ @for j in qt-gui/emoticons/*; do \
+ echo "Installing emoticon $$j"; \
+ $(mkinstalldirs) $(DESTDIR)$(sharedir)/$$j; \
+ for i in $$j/*; do \
+ if test -f $$i; then \
+ $(INSTALL_DATA) $$i $(DESTDIR)$(sharedir)/$$j; \
+ fi \
+ done; \
+ done
Index: plugins/qt-gui/src/Makefile.am
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/Makefile.am,v
retrieving revision 1.39
diff -u -d -p -r1.39 Makefile.am
--- plugins/qt-gui/src/Makefile.am 11 Feb 2003 19:40:25 -0000 1.39
+++ plugins/qt-gui/src/Makefile.am 23 Aug 2003 01:26:42 -0000
@@ -9,6 +9,8 @@ INCLUDES = -D_REENTRANT \
EXTRA_LTLIBRARIES = licq_qt-gui.la licq_kde-gui.la
+# EXTRA_PROGRAMS = testemoticons
+
lib_LTLIBRARIES = @LIB_NAME@
noinst_HEADERS = adduserdlg.h authuserdlg.h awaymsgdlg.h refusedlg.h \
@@ -20,7 +22,7 @@ noinst_HEADERS = adduserdlg.h authuserdl
utilitydlg.h wharf.h randomchatdlg.h forwarddlg.h chatjoin.h \
mmlistview.h mmsenddlg.h userinfodlg.h usereventdlg.h keyrequestdlg.h \
jfcstyle.h usercodec.h reqauthdlg.h licqdialog.h userselectdlg.h \
- editfilelistdlg.h
+ editfilelistdlg.h emoticon.h
licq_gui = adduserdlg.cpp authuserdlg.cpp awaymsgdlg.cpp \
refusedlg.cpp chatdlg.cpp editgrp.cpp editfile.cpp eventdesc.cpp \
@@ -32,7 +34,7 @@ licq_gui = adduserdlg.cpp authuserdlg.cp
wharf.cpp randomchatdlg.cpp forwarddlg.cpp chatjoin.cpp mmlistview.cpp \
mmsenddlg.cpp userinfodlg.cpp usereventdlg.cpp keyrequestdlg.cpp \
jfcstyle.cpp usercodec.cpp reqauthdlg.cpp licqdialog.cpp userselectdlg.cpp \
- editfilelistdlg.cpp
+ editfilelistdlg.cpp emoticon.cpp
licq_qt_gui_la_SOURCES = $(licq_gui)
licq_kde_gui_la_SOURCES = $(licq_gui) wrap_kde_malloc.cpp
@@ -49,3 +51,7 @@ licq_kde_gui_la_LIBADD = $(KDE_LIBS) $(X
METASOURCES = AUTO
KDE_OPTIONS = qtonly
+
+# testemoticons_SOURCES = emoticon.cpp ../../../src/log.cpp
+# testemoticons_CFLAGS = -DEMOTICON_TEST_DRIVER $(LICQ_INCLUDES)
+# testemoticons_LDADD = -L$(QT_LIBDIR) $(LIB_QT)
Index: plugins/qt-gui/src/gui-defines.h
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/gui-defines.h,v
retrieving revision 1.20
diff -u -d -p -r1.20 gui-defines.h
--- plugins/qt-gui/src/gui-defines.h 11 Sep 2002 01:50:47 -0000 1.20
+++ plugins/qt-gui/src/gui-defines.h 23 Aug 2003 01:26:42 -0000
@@ -2,6 +2,7 @@
#define GUIDEFINES_H
#define QTGUI_DIR "qt-gui/"
+#define EMOTICONS_DIR "emoticons/"
#define NUM_MSG_PER_HISTORY 40
#define COLOR_SENT "blue"
Index: plugins/qt-gui/src/licq_qt-gui.conf.h
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/licq_qt-gui.conf.h,v
retrieving revision 1.8
diff -u -d -p -r1.8 licq_qt-gui.conf.h
--- plugins/qt-gui/src/licq_qt-gui.conf.h 8 Nov 2002 00:59:41 -0000 1.8
+++ plugins/qt-gui/src/licq_qt-gui.conf.h 23 Aug 2003 01:26:42 -0000
@@ -2,6 +2,7 @@ static const char QTGUI_CONF[] =
"[appearance]\n"
"Skin = basic\n"
"Icons = computer\n"
+"Emoticons = Default\n"
"ExtendedIcons = basic\n"
"Font = default\n"
"GridLines = 0\n"
Index: plugins/qt-gui/src/mainwin.cpp
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/mainwin.cpp,v
retrieving revision 1.294
diff -u -d -p -r1.294 mainwin.cpp
--- plugins/qt-gui/src/mainwin.cpp 9 Jul 2003 16:33:26 -0000 1.294
+++ plugins/qt-gui/src/mainwin.cpp 23 Aug 2003 01:26:44 -0000
@@ -80,6 +80,7 @@
#include "wharf.h"
#include "keyrequestdlg.h"
#include "usercodec.h"
+#include "emoticon.h"
#include "xpm/history.xpm"
#include "xpm/info.xpm"
@@ -93,7 +94,6 @@
#include "xpm/pixCellular.xpm"
#include "xpm/pixBirthday.xpm"
#include "xpm/pixInvisible.xpm"
-
#include "licq_qt-gui.conf.h"
extern "C" {
@@ -367,8 +367,7 @@ CMainWindow::CMainWindow(CICQDaemon *the
licqConf.ReadBool("showPopLastOnelin",m_bPopLastOnline, false);
licqConf.ReadBool("showPopOnlineSince", m_bPopOnlineSince, false);
licqConf.ReadBool("showPopIdleTime", m_bPopIdleTime, true);
-
-
+
unsigned short nFlash;
licqConf.ReadNum("Flash", nFlash, FLASH_URGENT);
m_nFlash = (FlashType)nFlash;
@@ -448,6 +447,15 @@ CMainWindow::CMainWindow(CICQDaemon *the
strcpy(szExtendedIcons, extendedIconsName);
m_szExtendedIconSet = NULL;
+ // Load the Emoticons
+ char szEmoticons[MAX_FILENAME_LEN];
+ licqConf.ReadStr("Emoticons", szEmoticons, "Default" );
+ QString s = QString::fromAscii(SHARE_DIR) + QTGUI_DIR + EMOTICONS_DIR;
+ emoticons = new CEmoticons(s.latin1());
+ if( *szEmoticons )
+ if( emoticons->SetTheme(szEmoticons) < 0 )
+ gLog.Error("%s Loading emoticons theme `%s'",L_ERRORxSTR, szEmoticons);
+
// Load the skin
char szSkin[MAX_FILENAME_LEN] = "basic";
if (strlen(skinName) == 0)
@@ -3297,6 +3305,8 @@ void CMainWindow::saveOptions()
licqConf.WriteStr("Skin", skin->szSkinName);
licqConf.WriteStr("Icons", m_szIconSet);
licqConf.WriteStr("ExtendedIcons", m_szExtendedIconSet);
+ licqConf.WriteStr("Emoticons", emoticons->Theme() ? emoticons->Theme() : "");
+
#if QT_VERSION >= 300
licqConf.WriteStr("Font", qApp->font() == defaultFont ?
"default" : qApp->font().toString().latin1());
Index: plugins/qt-gui/src/mainwin.h
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/mainwin.h,v
retrieving revision 1.112
diff -u -d -p -r1.112 mainwin.h
--- plugins/qt-gui/src/mainwin.h 8 Jul 2003 11:37:52 -0000 1.112
+++ plugins/qt-gui/src/mainwin.h 23 Aug 2003 01:26:44 -0000
@@ -32,6 +32,7 @@ class QTextView;
class CSignalManager;
class CQtLogWindow;
class CSkin;
+class CEmoticons;
class CICQDaemon;
class ICQEvent;
class OptionsDlg;
@@ -96,7 +97,6 @@ public:
m_nUserMenuPPID = n;
m_nUserMenuUin = strtoul(s, (char **)NULL, 10);
}
-
static QPixmap &iconForStatus(unsigned long FullStatus);
static QPixmap &iconForEvent(unsigned short SubCommand);
@@ -143,6 +143,7 @@ public:
ColumnInfos colInfo;
FlashType m_nFlash;
CSkin *skin;
+ CEmoticons *emoticons;
unsigned long m_nCurrentGroup, m_nGroupStates;
unsigned short m_nSortByStatus,
@@ -209,7 +210,8 @@ public:
QPixmap pmOnline, pmOffline, pmAway, pmDnd, pmOccupied, pmNa,
pmPrivate, pmFFC, pmMessage, pmUrl, pmChat, pmFile, pmContact, pmSms,
pmAuthorize, pmSMS, pmSecureOn, pmSecureOff, pmHistory, pmInfo, pmEncoding,
- pmBirthday, pmPhone, pmCellular, pmInvisible, pmCustomAR, pmCollapsed, pmExpanded;
+ pmBirthday, pmPhone, pmCellular, pmInvisible, pmCustomAR, pmCollapsed,
+ pmExpanded;
unsigned long m_nUserMenuUin;
unsigned int positionChanges;
unsigned long m_nProtoNum;
Index: plugins/qt-gui/src/mlview3.cpp
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/mlview3.cpp,v
retrieving revision 1.15
diff -u -d -p -r1.15 mlview3.cpp
--- plugins/qt-gui/src/mlview3.cpp 2 Jul 2003 04:41:02 -0000 1.15
+++ plugins/qt-gui/src/mlview3.cpp 23 Aug 2003 01:26:46 -0000
@@ -73,6 +73,9 @@ void MLView::append(const QString& s)
}
}
+#include "emoticon.h"
+#include "mainwin.h" // for the CEmoticon instance
+
QString MLView::toRichText(const QString& s, bool highlightURLs)
{
// We cannot use QStyleSheet::convertFromPlainText
@@ -123,6 +126,8 @@ QString MLView::toRichText(const QString
text.replace(pos+1, longSpaces.matchedLength()-1, cap);
}
text.replace(QRegExp("\t"), " ");
+
+ gMainWindow->emoticons->ParseMessage(text);
return text;
}
Index: plugins/qt-gui/src/skinbrowser.cpp
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/skinbrowser.cpp,v
retrieving revision 1.23
diff -u -d -p -r1.23 skinbrowser.cpp
--- plugins/qt-gui/src/skinbrowser.cpp 24 Mar 2003 15:33:53 -0000 1.23
+++ plugins/qt-gui/src/skinbrowser.cpp 23 Aug 2003 01:26:46 -0000
@@ -35,6 +35,12 @@
#include "mainwin.h"
#include "skin.h"
#include "skinbrowser.h"
+#include "mainwin.h" /* to get the CMainWindow::emoticons */
+#include "emoticon.h"
+
+enum {
+ MAX_HEIGHT = 170
+};
SkinBrowserDlg::SkinBrowserDlg(CMainWindow *_mainwin, QWidget *parent)
: LicqDialog(parent, "SkinBrowserDialog")
@@ -43,9 +49,10 @@ SkinBrowserDlg::SkinBrowserDlg(CMainWind
pmSkin = new QPixmap();
lstIcons = new QValueList<QPixmap>;
lstExtIcons = new QValueList<QPixmap>;
+ lstEmoticons = new QValueList<QPixmap>;
lstAIcons = new QStringList();
lstAExtIcons = new QStringList();
-
+
// Setup a list of previewable icons
// The strings reflect what we exptect to find in the *.icons files.
// The result of these two lists is used to load the icons, the order of
@@ -76,22 +83,30 @@ SkinBrowserDlg::SkinBrowserDlg(CMainWind
cmbSkin = new QComboBox(boxSkin);
QWhatsThis::add(cmbSkin, tr("Use this combo box to select one of the available skins"));
lblSkin->setBuddy(cmbSkin);
+
QLabel *lblIcon = new QLabel(tr("&Icons:"), boxSkin);
cmbIcon = new QComboBox(boxSkin);
QWhatsThis::add(cmbIcon, tr("Use this combo box to select one of the available icon sets"));
lblIcon->setBuddy(cmbIcon);
+
QLabel *lblExtIcon = new QLabel(tr("E&xtended Icons:"), boxSkin);
cmbExtIcon = new QComboBox(boxSkin);
QWhatsThis::add(cmbExtIcon, tr("Use this combo box to select one of the available extended icon sets"));
lblExtIcon->setBuddy(cmbExtIcon);
-
+
+ QLabel *lblEmoticons = new QLabel(tr("E&moticons"), boxSkin);
+ cmbEmoticon = new QComboBox(boxSkin);
+ QWhatsThis::add(cmbEmoticon, tr("Use this combo box to select one of "
+ "the available emoticon icon sets"));
+ lblEmoticons->setBuddy(cmbEmoticon);
+
// Preview Box
QFrame *frmPrevSkin = new QFrame(boxPreview);
QVBoxLayout *layPrevSkin = new QVBoxLayout(frmPrevSkin);
QLabel *lblPrevSkin = new QLabel(tr("Skin:"), frmPrevSkin);
lblPrevSkin->setAlignment(Qt::AlignHCenter);
lblPaintSkin = new QLabel(frmPrevSkin);
- lblPaintSkin->setFixedSize(75, 130);
+ lblPaintSkin->setFixedSize(75, MAX_HEIGHT);
layPrevSkin->addWidget(lblPrevSkin, 0, Qt::AlignHCenter);
layPrevSkin->addWidget(lblPaintSkin, 0, Qt::AlignHCenter);
layPrevSkin->addStretch();
@@ -101,7 +116,7 @@ SkinBrowserDlg::SkinBrowserDlg(CMainWind
QLabel *lblPrevIcon = new QLabel(tr("Icons:"), frmPrevIcon);
lblPrevIcon->setAlignment(Qt::AlignHCenter);
lblPaintIcon = new SkinBrowserPreviewArea(frmPrevIcon);
- lblPaintIcon->setFixedSize(54, 130);
+ lblPaintIcon->setFixedSize(54, MAX_HEIGHT);
layPrevIcon->addWidget(lblPrevIcon, 0, Qt::AlignHCenter);
layPrevIcon->addWidget(lblPaintIcon, 0, Qt::AlignHCenter);
layPrevIcon->addStretch();
@@ -111,10 +126,20 @@ SkinBrowserDlg::SkinBrowserDlg(CMainWind
QLabel *lblPrevExtIcon = new QLabel(tr("Extended Icons:"), frmPrevExtIcon);
lblPrevExtIcon->setAlignment(Qt::AlignHCenter);
lblPaintExtIcon = new SkinBrowserPreviewArea(frmPrevExtIcon);
- lblPaintExtIcon->setFixedSize(54, 130);
+ lblPaintExtIcon->setFixedSize(54, MAX_HEIGHT);
layPrevExtIcon->addWidget(lblPrevExtIcon, 0, Qt::AlignHCenter);
layPrevExtIcon->addWidget(lblPaintExtIcon, 0, Qt::AlignHCenter);
layPrevExtIcon->addStretch();
+
+ QFrame *frmPrevEmoticon= new QFrame(boxPreview);
+ QVBoxLayout *layPrevEmoticon = new QVBoxLayout(frmPrevEmoticon);
+ QLabel *lblPrevEmoticon = new QLabel(tr("Emoticons:"), frmPrevEmoticon);
+ lblPrevEmoticon->setAlignment(Qt::AlignHCenter);
+ lblPaintEmoticon= new SkinBrowserPreviewArea(frmPrevEmoticon);
+ lblPaintEmoticon->setFixedSize(54, MAX_HEIGHT);
+ layPrevEmoticon->addWidget(lblPrevEmoticon, 0, Qt::AlignHCenter);
+ layPrevEmoticon->addWidget(lblPaintEmoticon, 0, Qt::AlignHCenter);
+ layPrevEmoticon->addStretch();
// Buttons
QHBoxLayout *layButtons = new QHBoxLayout(frmButtons, 8, 4);
@@ -301,6 +326,19 @@ SkinBrowserDlg::SkinBrowserDlg(CMainWind
}
}
}
+
+ CEmoticons *emoticons = gMainWindow->emoticons;
+ QStringList themes = emoticons->Themes();
+ const char *selected = emoticons->Theme();
+ int i=0, emoticonid= 0;
+ for ( QStringList::Iterator it = themes.begin();
+ it != themes.end(); ++it, i++ )
+ {
+ cmbEmoticon->insertItem(*it, i);
+ if( selected && !strcmp(selected, (*it).ascii() ))
+ emoticonid = i;
+ }
+ cmbEmoticon->setCurrentItem(emoticonid);
// setup connections
connect(btnEdit, SIGNAL(clicked()), this, SLOT(slot_edtSkin()));
@@ -310,11 +348,13 @@ SkinBrowserDlg::SkinBrowserDlg(CMainWind
connect(cmbSkin, SIGNAL(highlighted(const QString &)), this, SLOT(slot_loadSkin(const QString &)));
connect(cmbIcon, SIGNAL(highlighted(const QString &)), this, SLOT(slot_loadIcons(const QString &)));
connect(cmbExtIcon, SIGNAL(highlighted(const QString &)), this, SLOT(slot_loadExtIcons(const QString &)));
+ connect(cmbEmoticon, SIGNAL(highlighted(const QString&)), this, SLOT(slot_loadEmoticons(const QString &)));
// Create initial preview
slot_loadSkin(cmbSkin->currentText());
slot_loadIcons(cmbIcon->currentText());
slot_loadExtIcons(cmbExtIcon->currentText());
+ slot_loadEmoticons(cmbEmoticon->currentText());
setCaption(tr("Licq Skin Browser"));
show();
@@ -357,6 +397,8 @@ void SkinBrowserDlg::slot_apply()
if (cmbExtIcon->currentText() != mainwin->m_szExtendedIconSet)
mainwin->ApplyExtendedIcons(cmbExtIcon->currentText().local8Bit());
+ if (cmbEmoticon->currentText() != mainwin->emoticons->Theme())
+ mainwin->emoticons->SetTheme(cmbEmoticon->currentText());
}
/*! \brief Creates a new skin editor dialog
@@ -456,6 +498,36 @@ void SkinBrowserDlg::slot_loadExtIcons(c
}
lblPaintExtIcon->setPixmapList(lstExtIcons);
}
+/*! \brief Reloads the current preview emoticons
+ *
+ * This slot reloads all preview emoicons. It loads the complete
+ * set of emoticons that is currently highlighted in the relevant combo
+ * box.
+ * If it was successful it makes these icons to be rendered in the preview.
+ */
+void SkinBrowserDlg::slot_loadEmoticons(const QString &emoticon)
+{
+ lstEmoticons->clear();
+ CEmoticons *e = gMainWindow->emoticons;
+ QStringList files = e->fileList(emoticon);
+ for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it)
+ {
+ QImage img = QImage(*it);
+ /* hack: SkinBrowserPreviewArea only draws the
+ * first 16 pixels
+ */
+ int max_area = 16;
+ QSize size = img.size();
+ if( size.isValid() &&
+ size.width() > max_area && size.height() > max_area )
+ img = img.scale(max_area, max_area, QImage::ScaleFree);
+
+ QPixmap pm(img);
+ if( ! pm.isNull())
+ lstEmoticons->append(pm);
+ }
+ lblPaintEmoticon->setPixmapList(lstEmoticons);
+}
/*! \brief provide correct repainting when resizing the main widget
*
@@ -661,7 +733,7 @@ QPixmap SkinBrowserDlg::renderSkin(const
QPixmap tmp(QPixmap::grabWidget(&w));
QPixmap ret;
- ret.convertFromImage(QImage(tmp.convertToImage().smoothScale(75, 130)));
+ ret.convertFromImage(QImage(tmp.convertToImage().smoothScale(75, MAX_HEIGHT)));
// Reset origin colors
userView.setColors(c_online, c_away, c_offline, c_newuser, c_background, c_gridlines);
Index: plugins/qt-gui/src/skinbrowser.h
===================================================================
RCS file: /cvsroot/licq/qt-gui/src/skinbrowser.h,v
retrieving revision 1.8
diff -u -d -p -r1.8 skinbrowser.h
--- plugins/qt-gui/src/skinbrowser.h 18 Jan 2003 16:25:07 -0000 1.8
+++ plugins/qt-gui/src/skinbrowser.h 23 Aug 2003 01:26:46 -0000
@@ -42,12 +42,16 @@ private:
QComboBox *cmbIcon;
/*! This Combo contains all available extended icon packs */
QComboBox *cmbExtIcon;
+ /*! This Combo contains all available emoticons themes */
+ QComboBox *cmbEmoticon;
/*! This QLabel contains the skin preview pixmap (75 x 130 Pixel)*/
QLabel *lblPaintSkin;
/*! This SkinBrowserPreviewArea contains the icon pixmaps (54 x 130 Pixel)*/
SkinBrowserPreviewArea *lblPaintIcon;
/*! This SkinBrowserPreviewArea contains the extended icons pixmaps (54 x 130 Pixel)*/
SkinBrowserPreviewArea *lblPaintExtIcon;
+ /*! This SkinBrowserPreviewArea contains the emoticons pixmaps (54x130 Px) */
+ SkinBrowserPreviewArea *lblPaintEmoticon;
/*! Holds the list of possible themeable icons in normal icon sets */
QStringList *lstAIcons;
/*! Holds the list of possible themeable icons in extended icon sets */
@@ -58,6 +62,8 @@ private:
QValueList<QPixmap> *lstIcons;
/*! Stores the list of the current QPixmaps for the Extended Icons preview */
QValueList<QPixmap> *lstExtIcons;
+ /*! Stores the list of the current QPixmaps for the emoticons preview */
+ QValueList<QPixmap> *lstEmoticons;
/*! Renders a dynamic skin preview */
QPixmap renderSkin(const QString &skin);
CSkin *skin;
@@ -73,6 +79,7 @@ protected slots:
void slot_loadSkin(const QString &skin);
void slot_loadIcons(const QString &icon);
void slot_loadExtIcons(const QString &extIcon);
+ void slot_loadEmoticons(const QString &emoticon);
};
/*! \brief Helper class to provide a preview area for our icons using a modified QFrame
--- /dev/null 1969-12-31 21:00:00.000000000 -0300
+++ plugins/qt-gui/src/emoticon.h 2003-08-19 21:41:47.000000000 -0300
@@ -0,0 +1,40 @@
+#ifndef zE1D68C95080DE073514FA90C07628F92
+#define zE1D68C95080DE073514FA90C07628F92
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+class CEmoticons {
+
+public:
+ /*!
+ * \param basedir base dir for icons
+ * \param theme sets the current theme
+ */
+ CEmoticons(const char *basedir, const char *theme = 0 );
+ ~CEmoticons();
+
+ /*! \returns the list of themes available */
+ QStringList Themes();
+
+ /*!
+ * sets the current theme
+ * \retuns a negative number on error
+ */
+ int SetTheme(const char *theme);
+
+ /*! \returns the current theme */
+ const char *Theme(void);
+
+ /*! \returns the list of files of the current emoticon theme */
+ QStringList fileList();
+
+ /*! \returns the list of files for `theme` */
+ QStringList fileList(const char *theme);
+
+ void ParseMessage(QString &msg);
+
+private:
+ struct Emoticons *data;
+};
+#endif
--- /dev/null 1969-12-31 21:00:00.000000000 -0300
+++ plugins/qt-gui/src/emoticon.cpp 2003-08-22 20:08:12.000000000 -0300
@@ -0,0 +1,314 @@
+/*
+ * Licq - A ICQ Client for Unix
+ *
+ * Copyright (C) 2003 Licq developers <[EMAIL PROTECTED]>
+ *
+ * This program is licensed under the terms found in the LICENSE file.
+ *
+ * \file support for emoticons themes. Compatible with kopete 0.6 format.
+ * \todo lot of improvents (memory vs time)
+ */
+
+#include <list>
+#include <qmap.h>
+#include <qdir.h>
+#include <qdom.h>
+#include <qregexp.h>
+
+#include "licq_log.h"
+
+#include "emoticon.h"
+
+struct node
+{ QStringList emoticon;
+ QString file;
+ QRegExp reg;
+};
+
+typedef std::list<struct node> node_list_t;
+
+/*! private definition of CEmotions */
+struct Emoticons
+{
+ QString basedir; /* base directory for resourses */
+ QString theme; /* current theme */
+
+ node_list_t emoticons;
+};
+
+CEmoticons::CEmoticons(const char *basedir, const char *theme )
+{
+ this->data = new struct Emoticons;
+ data->basedir = basedir;
+}
+
+CEmoticons::~CEmoticons()
+{
+ delete this->data;
+}
+
+QStringList CEmoticons::Themes()
+{
+ QDir dir(data->basedir, "*", 0, QDir::Dirs);
+
+ return dir.entryList().grep(QRegExp("^[^.].*"));
+}
+
+/*!
+ * helper funcction of #loadFile. Try to add file to the list of emoticons
+ *
+ * \returns true on success
+ */
+static QString realFile(const struct Emoticons *data, const QString &theme,
+ const QString &file)
+{
+ QString s;
+
+ if( file != QString::null )
+ {
+ s= data->basedir + "/" + theme + "/" + file + ".png";
+
+ if( !QFile(s).exists() )
+ { gLog.Warn("%sWarning unknown file `%s'\n", L_WARNxSTR,
+ s.ascii());
+ s = QString::null;
+ }
+ }
+
+ return s;
+}
+
+/*!
+ * helper function for #loadFile
+ *
+ * \return a list of characters
+ *
+ * <string>:^)</string>
+ * <string>:)</string>
+ * <string>:-)</string>
+ */
+static QStringList loadStrings(const struct Emoticons *data, QDomNode node,
+ unsigned *n)
+{ QStringList ret;
+
+ *n = 0U;
+
+ for( ; !node.isNull() ; node=node.nextSibling() )
+ {
+ QDomElement emo = node.toElement();
+ if( !emo.isNull() && emo.tagName() == "string" )
+ {
+ (*n) +=1;
+ ret << emo.text();
+ }
+ else
+ gLog.Warn("%sWarning element `%s'", L_WARNxSTR,
+ emo.tagName().ascii());
+ }
+
+ return ret;
+}
+
+static void create_regexp(QStringList &list, QRegExp ®)
+{
+ unsigned n = 0;
+ QString s = "(^|\\W)(";
+
+ for ( QStringList::Iterator it = list.begin(); it!=list.end(); ++it)
+ {
+ if( n != 0)
+ s += "|";
+ s += QRegExp::escape(*it);
+ n++;
+ }
+ s += ")($|\\W)";
+
+ reg = QRegExp(s);
+}
+
+static unsigned loadFile(const struct Emoticons *data,
+ const QString &theme, const char *szfile,
+ node_list_t &list)
+{
+ struct node node;
+ unsigned size;
+ QDomDocument doc("doc");
+ QFile file(szfile);
+ unsigned ret = 0;
+
+ if ( file.open( IO_ReadOnly ) && doc.setContent( &file ) )
+ {
+ QDomElement elem = doc.documentElement();
+ QDomNode n = elem.firstChild();
+ for( ; !n.isNull() ; n= n.nextSibling() )
+ {
+ if ( n.isElement() )
+ {
+ elem = n.toElement();
+ if( !elem.isNull() && elem.tagName() ==
+ QString::fromAscii("emoticon") )
+ {
+ QString file = elem.attribute("file");
+ QString f;
+ QStringList items= loadStrings(data,
+ n.firstChild(),
+ &size);
+ if( size &&
+ (f=realFile(data,theme, file))
+ !=QString::null)
+ {
+
+ node.emoticon = items;
+ node.file = f;
+ create_regexp(items, node.reg);
+ list.push_back(node);
+ ret +=size;
+ }
+ }
+ }
+ }
+ }
+
+ file.close();
+ return ret;
+};
+
+int CEmoticons::SetTheme(const char *theme)
+{ QString szdir = data->basedir + "/" + theme + "/";
+ node_list_t list;
+ QDir d(szdir);
+ int ret = -1;
+ unsigned n;
+
+ if( d.exists() )
+ {
+ szdir += "emoticons.xml";
+ n = loadFile(data, theme, szdir.ascii(), list);
+ ret = n;
+ data->theme = theme;
+ data->emoticons = list;
+ }
+
+ return ret;
+}
+
+const char *CEmoticons::Theme(void)
+{
+ return data->theme == QString::null ? 0 : data->theme.ascii() ;
+}
+
+QStringList CEmoticons::fileList()
+{
+ node_list_t::iterator iter;
+ QStringList ret;
+ struct node n;
+
+ for( iter = data->emoticons.begin();
+ iter != data->emoticons.end() ;
+ iter++ )
+ {
+ n = *iter;
+ ret << n.file;
+ }
+
+ return ret;
+}
+
+QStringList CEmoticons::fileList(const char *theme)
+{ QString szdir = data->basedir + "/" + theme + "/";
+ QStringList ret;
+ QDir d(szdir);
+ node_list_t list;
+ node_list_t::iterator iter;
+ struct node n;
+
+ if( d.exists() )
+ {
+ szdir += "emoticons.xml";
+ loadFile(data, theme, szdir.ascii(), list);
+
+ for( iter = list.begin();
+ iter != list.end() ; iter++ )
+ {
+ n = *iter;
+ ret << n.file;
+ }
+ }
+
+ return ret;
+}
+
+void CEmoticons::ParseMessage(QString &msg)
+{
+ /**
+ * \todo this sucks: solution create a finite state machine to parse
+ * the message
+ */
+ node_list_t::iterator iter;
+ struct node n;
+
+ if( data->theme != QString::null )
+ {
+ QString r;
+ for( iter = data->emoticons.begin();
+ iter != data->emoticons.end() ; iter++ )
+ {
+ n = *iter;
+ for ( QStringList::Iterator it = n.emoticon.begin();
+ it != n.emoticon.end(); ++it)
+ {
+ msg.replace(n.reg," <img src=\""+n.file+"\"/> ");
+ }
+ }
+ }
+}
+
+#ifdef EMOTICON_TEST_DRIVER
+#include <stdio.h>
+#include <iostream>
+
+int
+main(int argc, char **argv)
+{
+ CEmoticons e = CEmoticons("/tmp/emoticons/");
+ QStringList themes = e.Themes();
+
+ std::cout << "Themes available:\n";
+ for ( QStringList::Iterator it = themes.begin();
+ it != themes.end(); ++it )
+ std::cout << "\t" << *it << "\n";
+
+ std::cout << "\n";
+ printf("Current theme %s\n",e.Theme());
+ std::cout << "Set Theme: to abcde(" << e.SetTheme("abcde") << ")\n";
+ printf("Current theme %s\n",e.Theme());
+
+ std::cout << "\n";
+ printf("Current theme %s\n",e.Theme());
+
+ const char *d = argc != 1 ? argv[1] :"Default";
+ std::cout << "Set Theme: to (" << d << e.SetTheme(d) << ")\n";
+ printf("Current theme %s\n",e.Theme());
+
+ std::cout << "\n";
+ std::cout << "Filelist:\n";
+ QStringList files = e.fileList();
+ for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it)
+ std::cout << "\t" << *it << "\n";
+
+ std::cout << "\nFilelist for theme: KMess\n";
+ files = e.fileList("KMess");
+ for( QStringList::Iterator it = files.begin(); it != files.end(); ++it)
+ std::cout << "\t" << *it << "\n";
+
+ QString s = "hello word :) :( :P :-) :P";
+ std::cout << "-- Before\n";
+ std::cout << s;
+ e.ParseMessage(s);
+ std::cout << "\n-- After\n";
+ std::cout << s;
+ std::cout << "\n";
+
+ return 0;
+}
+#endif
emoticons.tar.bz2
Description: application/tbz
<<inline: 82.png>>
<<inline: 81.png>>
pgp00000.pgp
Description: signature
