[prev in list] [next in list] [prev in thread] [next in thread]
List: kopete-devel
Subject: [kopete-devel] patch to use the emoticonslib in kopete
From: Carlo <brandon.ml () gmail ! com>
Date: 2008-05-12 23:08:05
Message-ID: 3262b6180805121608o23e83a1ap6118a1327d99df0a () mail ! gmail ! com
[Download RAW message or body]
Hi,
I've made a patch to use the emoticonslib in kopete, the library is in
kdereview right now and it will be moved to kdelibs before the hard
feature freeze of May 19th
Carlo
["kop.diff" (text/plain)]
Index: protocols/msn/msnswitchboardsocket.cpp
===================================================================
--- protocols/msn/msnswitchboardsocket.cpp (revision 807115)
+++ protocols/msn/msnswitchboardsocket.cpp (working copy)
@@ -47,6 +47,7 @@
#include <kstandarddirs.h>
#include <klocale.h>
#include <KComponentData>
+#include <kemoticons.h>
// for the display picture
#include <msncontact.h>
@@ -688,7 +689,7 @@
KConfigGroup *config=m_account->configGroup();
if ( config->readEntry( "exportEmoticons", false ) )
{
- QMap<QString, QStringList> emap = Kopete::Emoticons::self()->emoticonAndPicList();
+ QMap<QString, QStringList> emap = \
Kopete::Emoticons::self()->theme().emoticonsMap();
// Check the list for any custom emoticons
for (QMap<QString, QStringList>::const_iterator itr = emap.begin(); itr != \
emap.end(); itr++)
Index: kopete/contactlist/kopetemetacontactlvi.cpp
===================================================================
--- kopete/contactlist/kopetemetacontactlvi.cpp (revision 807115)
+++ kopete/contactlist/kopetemetacontactlvi.cpp (working copy)
@@ -45,6 +45,7 @@
#include <kdeversion.h>
#include <kinputdialog.h>
+#include <kemoticons.h>
#include "addcontactpage.h"
@@ -108,15 +109,15 @@
toolTip += QLatin1String("</td><td>");
QString displayName;
- Kopete::Emoticons *e = Kopete::Emoticons::self();
- QList<Emoticons::Token> t = e->tokenize( metaContact->displayName());
- QList<Emoticons::Token>::iterator it;
+ KEmoticonsTheme e = Kopete::Emoticons::self()->theme();
+ QList<KEmoticonsTheme::Token> t = e.tokenize( metaContact->displayName());
+ QList<KEmoticonsTheme::Token>::iterator it;
for( it = t.begin(); it != t.end(); ++it )
{
- if( (*it).type == Kopete::Emoticons::Image )
+ if( (*it).type == KEmoticonsTheme::Image )
{
displayName += (*it).picHTMLCode;
- } else if( (*it).type == Kopete::Emoticons::Text )
+ } else if( (*it).type == KEmoticonsTheme::Text )
{
displayName += Qt::escape( (*it).text );
}
@@ -146,7 +147,7 @@
toolTip += i18nc("<tr><td>STATUS ICON <b>PROTOCOL NAME</b> (ACCOUNT \
NAME)</td><td>STATUS DESCRIPTION</td></tr>",
"<tr><td><img \
src=\"%1\"> <nobr><b>%2</b></nobr> <nobr>(%3)</nobr></td><td \
align=\"right\"><nobr>%4</nobr></td></tr>",
- iconName, Kopete::Emoticons::parseEmoticons(c->property(Kopete::Global::Properties::self()->nickName()).value().toString()) \
, c->contactId(), c->onlineStatus().description() ); + iconName, \
Kopete::Emoticons::self()->theme().parseEmoticons(c->property(Kopete::Global::Properties::self()->nickName()).value().toString()) \
, c->contactId(), c->onlineStatus().description() ); }
return toolTip + QLatin1String("</table></td></tr></table></qt>");
@@ -469,7 +470,7 @@
if(notify)
{
QString text = i18n( "<qt><i>%1</i> is now %2.</qt>",
- Kopete::Emoticons::parseEmoticons( \
Qt::escape(m_metaContact->displayName()) ) , + \
Kopete::Emoticons::self()->theme().parseEmoticons( \
Qt::escape(m_metaContact->displayName()) ) , \
Qt::escape(c->onlineStatus().description()));
notify->setText(text);
Index: kopete/kopetewindow.cpp
===================================================================
--- kopete/kopetewindow.cpp (revision 807115)
+++ kopete/kopetewindow.cpp (working copy)
@@ -68,6 +68,7 @@
#include <kstandardaction.h>
#include <solid/networking.h>
#include <kstatusbarofflineindicator.h>
+#include <kemoticons.h>
#include "addcontactpage.h"
#include "addressbooklinkwidget.h"
@@ -1108,10 +1109,10 @@
QString toolTip;
toolTip += i18nc("@label:textbox formatted status title", \
"<b>Status Title:</b> %1",
- Kopete::Emoticons::parseEmoticons( \
Kopete::Message::escape(statusTitle) ) ); + \
Kopete::Emoticons::self()->theme().parseEmoticons( \
Kopete::Message::escape(statusTitle) ) );
toolTip += i18nc("@label:textbox formatted status message", "<br \
/><b>Status Message:</b> %1",
- Kopete::Emoticons::parseEmoticons( \
Kopete::Message::escape(statusMessage) ) ); + \
Kopete::Emoticons::self()->theme().parseEmoticons( \
Kopete::Message::escape(statusMessage) ) );
d->globalStatusMessage->setToolTip( toolTip );
}
Index: kopete/config/chatwindow/emoticonthemeitem.cpp
===================================================================
--- kopete/config/chatwindow/emoticonthemeitem.cpp (revision 807115)
+++ kopete/config/chatwindow/emoticonthemeitem.cpp (working copy)
@@ -18,13 +18,14 @@
#include "emoticonthemeitem.h"
#include <kopeteemoticons.h>
+#include <kemoticons.h>
EmoticonThemeItem::EmoticonThemeItem(const QString &theme)
: QListWidgetItem(theme, 0, UserType)
{
// list the theme
- Kopete::Emoticons emoticons( theme );
- setData(EmoticonList, QStringList(emoticons.emoticonAndPicList().keys()));
+ KEmoticonsTheme emoticons = Kopete::Emoticons::self()->theme( theme );
+ setData(EmoticonList, QStringList(emoticons.emoticonsMap().keys()));
// set the emoticon pixmap list as an empty list: pixmaps will be added to
// the list as they are rendered by the delegator
Index: kopete/config/chatwindow/chatwindowconfig_emoticons.ui
===================================================================
--- kopete/config/chatwindow/chatwindowconfig_emoticons.ui (revision 807115)
+++ kopete/config/chatwindow/chatwindowconfig_emoticons.ui (working copy)
@@ -30,25 +30,6 @@
</widget>
</item>
<item row="1" column="0" colspan="4" >
- <widget class="QCheckBox" name="kcfg_emoticonsRequireSpace" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="whatsThis" >
- <string>If this is checked, only emoticons that are separated from the text by \
spaces will be shown as images.</string>
- </property>
- <property name="text" >
- <string>&Require separators (spaces) around emoticons</string>
- </property>
- <property name="checked" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="4" >
<widget class="QLabel" name="textLabel1" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
@@ -64,14 +45,14 @@
</property>
</widget>
</item>
- <item row="3" column="0" colspan="4" >
+ <item row="2" column="0" colspan="4" >
<widget class="QListWidget" name="icon_theme_list" >
<property name="alternatingRowColors" >
<bool>true</bool>
</property>
</widget>
</item>
- <item row="4" column="0" >
+ <item row="3" column="0" >
<widget class="QPushButton" name="btnGetThemes" >
<property name="enabled" >
<bool>false</bool>
@@ -90,7 +71,7 @@
</property>
</widget>
</item>
- <item row="4" column="1" >
+ <item row="3" column="1" >
<widget class="QPushButton" name="btnInstallTheme" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
@@ -103,7 +84,7 @@
</property>
</widget>
</item>
- <item row="4" column="2" >
+ <item row="3" column="2" >
<widget class="QPushButton" name="btnRemoveTheme" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Maximum" >
@@ -116,7 +97,7 @@
</property>
</widget>
</item>
- <item row="4" column="3" >
+ <item row="3" column="3" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
@@ -124,7 +105,7 @@
<property name="sizeType" >
<enum>QSizePolicy::Preferred</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>31</width>
<height>20</height>
@@ -141,22 +122,6 @@
<connection>
<sender>kcfg_useEmoticons</sender>
<signal>toggled(bool)</signal>
- <receiver>kcfg_emoticonsRequireSpace</receiver>
- <slot>setEnabled(bool)</slot>
- <hints>
- <hint type="sourcelabel" >
- <x>20</x>
- <y>20</y>
- </hint>
- <hint type="destinationlabel" >
- <x>20</x>
- <y>20</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>kcfg_useEmoticons</sender>
- <signal>toggled(bool)</signal>
<receiver>textLabel1</receiver>
<slot>setEnabled(bool)</slot>
<hints>
Index: kopete/config/chatwindow/chatwindowconfig.cpp
===================================================================
--- kopete/config/chatwindow/chatwindowconfig.cpp (revision 807115)
+++ kopete/config/chatwindow/chatwindowconfig.cpp (working copy)
@@ -49,6 +49,7 @@
#include <krun.h>
#include <kfiledialog.h>
#include <kurl.h>
+#include <kemoticons.h>
// KNewStuff
#include <knewstuff2/engine.h>
@@ -265,7 +266,7 @@
QListWidgetItem *item = m_emoticonsUi.icon_theme_list->currentItem();
if (item)
- appearanceSettings->setEmoticonTheme( item->text() );
+ KEmoticons::setTheme( item->text() );
appearanceSettings->writeConfig();
settings->writeConfig();
@@ -665,7 +666,7 @@
// Where is that theme in our big-list-o-themes?
- QList<QListWidgetItem*> items = m_emoticonsUi.icon_theme_list->findItems( \
Kopete::AppearanceSettings::self()->emoticonTheme(), Qt::MatchExactly ); \
+ QList<QListWidgetItem*> items = m_emoticonsUi.icon_theme_list->findItems( \
KEmoticons::currentThemeName(), Qt::MatchExactly );
if (items.count()) // found it... make it the currently selected theme
m_emoticonsUi.icon_theme_list->setCurrentItem( items.first() );
@@ -700,7 +701,7 @@
return;
}
- Kopete::Global::installEmoticonTheme( themeURL.path() );
+ Kopete::Emoticons::self()->installTheme( themeURL.path() );
updateEmoticonList();
}
Index: kopete/chatwindow/emoticonselector.cpp
===================================================================
--- kopete/chatwindow/emoticonselector.cpp (revision 807115)
+++ kopete/chatwindow/emoticonselector.cpp (working copy)
@@ -32,6 +32,7 @@
#include <QShowEvent>
#include <kdebug.h>
+#include <kemoticons.h>
EmoticonItem::EmoticonItem(const QString &emoticonText, const QString &pixmapPath, \
QListWidget *parent) : QListWidgetItem(parent)
@@ -97,7 +98,7 @@
{
m_emoticonList->clear();
// kDebug(14000) << "called.";
- QMap<QString, QStringList> list = Kopete::Emoticons::self()->emoticonAndPicList();
+ QMap<QString, QStringList> list = \
Kopete::Emoticons::self()->theme().emoticonsMap();
for (QMap<QString, QStringList>::const_iterator it = list.constBegin(); it != \
list.constEnd(); ++it ) (void) new EmoticonItem(it.value().first(), it.key(), \
m_emoticonList);
Index: kopete/chatwindow/kopeteemoticonaction.cpp
===================================================================
--- kopete/chatwindow/kopeteemoticonaction.cpp (revision 807115)
+++ kopete/chatwindow/kopeteemoticonaction.cpp (working copy)
@@ -29,6 +29,7 @@
#include <ktoolbar.h>
#include <kauthorized.h>
#include <kicon.h>
+#include <kemoticons.h>
#include "emoticonselector.h"
#include "kopeteemoticons.h"
@@ -68,7 +69,7 @@
// Try to load the icon for our current emoticon theme, when it fails
// fall back to our own default
QString icon;
- QMap<QString, QStringList> emoticonsMap = \
Kopete::Emoticons::self()->emoticonAndPicList(); + QMap<QString, QStringList> \
emoticonsMap = Kopete::Emoticons::self()->theme().emoticonsMap(); for( QMap<QString, \
QStringList>::const_iterator it = emoticonsMap.constBegin(); it != \
emoticonsMap.constEnd(); ++it ) {
Index: libkopete/kopeteappearancesettings.kcfg
===================================================================
--- libkopete/kopeteappearancesettings.kcfg (revision 807115)
+++ libkopete/kopeteappearancesettings.kcfg (working copy)
@@ -22,24 +22,12 @@
<group name="Appearance">
<!-- Emoticon config -->
- <entry key="emoticonTheme" type="String">
- <label>Current emoticon theme.</label>
- <default>kde4</default>
- <emit signal="contactListAppearanceChanged" />
- <emit signal="messageOverridesChanged" />
- </entry>
<entry key="useEmoticons" type="Bool">
<label>Enable emoticon support in Kopete.</label>
<default>true</default>
<emit signal="contactListAppearanceChanged" />
<emit signal="messageOverridesChanged" />
</entry>
- <entry key="emoticonsRequireSpace" type="Bool">
- <label>Use strict mode in emoticon parsing.</label>
- <default>true</default>
- <emit signal="contactListAppearanceChanged" />
- <emit signal="messageOverridesChanged" />
- </entry>
<!-- Hightlight preferences -->
Index: libkopete/kopetemessage.cpp
===================================================================
--- libkopete/kopetemessage.cpp (revision 807115)
+++ libkopete/kopetemessage.cpp (working copy)
@@ -30,6 +30,7 @@
#include <kdebug.h>
#include <kstringhandler.h>
+#include <kemoticons.h>
#include "kopetemessage.h"
#include "kopetemetacontact.h"
@@ -336,7 +337,7 @@
{
//kDebug(14000) << "messageformat: " << d->format;
- return Kopete::Emoticons::parseEmoticons(parseLinks(escapedBody(), Qt::RichText));
+ return Kopete::Emoticons::self()->theme().parseEmoticons(parseLinks(escapedBody(), \
Qt::RichText)); }
static QString makeRegExp( const char *pattern )
Index: libkopete/kopeteglobal.cpp
===================================================================
--- libkopete/kopeteglobal.cpp (revision 807115)
+++ libkopete/kopeteglobal.cpp (working copy)
@@ -235,138 +235,6 @@
return d->mTemplates;
}
-
-// -----------------------------------------------------------------------------
-
-
-void installEmoticonTheme(const QString &archiveName)
-{
- QStringList foundThemes;
- KArchiveEntry *currentEntry = 0L;
- KArchiveDirectory* currentDir = 0L;
- KProgressDialog *progressDlg = 0L;
- KArchive *archive = 0L;
-
- QString localThemesDir(KStandardDirs::locateLocal("emoticons", QString()) );
-
- if(localThemesDir.isEmpty())
- {
- KMessageBox::queuedMessageBox(Kopete::UI::Global::mainWidget(),
- KMessageBox::Error, i18n("Could not find suitable place " \
- "to install emoticon themes into."));
- return;
- }
-
- progressDlg = new KProgressDialog(0,
- i18n("Installing Emoticon Themes..."));
- progressDlg->setModal(true);
- progressDlg->progressBar()->setMaximum(foundThemes.count());
- progressDlg->show();
- qApp->processEvents();
-
- QString currentBundleMimeType = KMimeType::findByPath(archiveName, 0, \
false)->name();
- if( currentBundleMimeType == QLatin1String("application/zip") ||
- currentBundleMimeType == QLatin1String("application/x-zip") ||
- currentBundleMimeType == QLatin1String("application/x-zip-compressed"))
- archive = new KZip(archiveName);
- else if( currentBundleMimeType == QLatin1String("application/x-compressed-tar") ||
- currentBundleMimeType == QLatin1String("application/x-bzip-compressed-tar") ||
- currentBundleMimeType == QLatin1String("application/x-gzip") ||
- currentBundleMimeType == QLatin1String("application/x-bzip") )
- archive = new KTar(archiveName);
- else if(archiveName.endsWith(QLatin1String("jisp")) || \
archiveName.endsWith(QLatin1String("zip")) )
- archive = new KZip(archiveName);
- else
- archive = new KTar(archiveName);
-
- if ( !archive || !archive->open(QIODevice::ReadOnly) )
- {
- KMessageBox::queuedMessageBox(Kopete::UI::Global::mainWidget(),
- KMessageBox::Error,
- i18n("Could not open \"%1\" for unpacking.", archiveName));
- delete archive;
- delete progressDlg;
- return;
- }
-
- const KArchiveDirectory* rootDir = archive->directory();
-
- // iterate all the dirs looking for an emoticons.xml file
- QStringList entries = rootDir->entries();
- for (QStringList::Iterator it = entries.begin(); it != entries.end(); ++it)
- {
- currentEntry = const_cast<KArchiveEntry*>(rootDir->entry(*it));
- if (currentEntry->isDirectory())
- {
- currentDir = dynamic_cast<KArchiveDirectory*>( currentEntry );
- if (currentDir && ( currentDir->entry(QLatin1String("emoticons.xml")) != NULL ||
- currentDir->entry(QLatin1String("icondef.xml")) != NULL ) )
- foundThemes.append(currentDir->name());
- }
- }
-
- if (foundThemes.isEmpty())
- {
- KMessageBox::queuedMessageBox(Kopete::UI::Global::mainWidget(),
- KMessageBox::Error, i18n("<qt>The file \"%1\" is not a valid" \
- " emoticon theme archive.</qt>", archiveName));
- archive->close();
- delete archive;
- delete progressDlg;
- return;
- }
-
- for (int themeIndex = 0; themeIndex < foundThemes.size(); ++themeIndex)
- {
- const QString &theme = foundThemes[themeIndex];
-
- progressDlg->setLabelText(
- i18n("<qt>Installing <strong>%1</strong> emoticon theme</qt>",
- theme));
- progressDlg->progressBar()->setValue(themeIndex);
- progressDlg->resize(progressDlg->sizeHint());
- qApp->processEvents();
-
- if (progressDlg->wasCancelled())
- break;
-
- currentEntry = const_cast<KArchiveEntry *>(rootDir->entry(theme));
- if (currentEntry == 0)
- {
- kDebug(14010) << "couldn't get next archive entry";
- continue;
- }
-
- if(currentEntry->isDirectory())
- {
- currentDir = dynamic_cast<KArchiveDirectory*>(currentEntry);
- if (currentDir == 0)
- {
- kDebug(14010) <<
- "couldn't cast archive entry to KArchiveDirectory" << endl;
- continue;
- }
- currentDir->copyTo(localThemesDir + theme);
- }
- }
-
- archive->close();
- delete archive;
-
- // check if all steps were done, if there are skipped ones then we didn't
- // succeed copying all dirs from the tarball
- if (progressDlg->progressBar()->maximum() > progressDlg->progressBar()->value())
- {
- KMessageBox::queuedMessageBox(Kopete::UI::Global::mainWidget(),
- KMessageBox::Error,
- i18n("<qt>A problem occurred during the installation process. "
- "However, some of the emoticon themes in the archive may have been "
- "installed.</qt>"));
- }
-
- delete progressDlg;
-}
-
} // END namespace Global
} // END namespace Kopete
Index: libkopete/private/kopeteemoticons.cpp
===================================================================
--- libkopete/private/kopeteemoticons.cpp (revision 807115)
+++ libkopete/private/kopeteemoticons.cpp (working copy)
@@ -19,20 +19,9 @@
#include "kopeteemoticons.h"
-#include "kopeteappearancesettings.h"
+#include <kemoticons.h>
-#include <QtXml>
-#include <QFile>
-#include <QTextDocument>
-#include <QPixmap>
-#include <QDateTime>
-#include <kapplication.h>
-#include <kdebug.h>
-#include <kstandarddirs.h>
-#include <kdeversion.h>
-
-
/*
* Testcases can be found in the kopeteemoticontest app in the tests/ directory.
*/
@@ -40,523 +29,15 @@
namespace Kopete {
+KEmoticons *Emoticons::s_self = 0L;
-struct Emoticons::Emoticon
+KEmoticons *Emoticons::self()
{
- Emoticon(){}
- /* sort by longest to shortest matchText */
- bool operator < (const Emoticon &e) const { return matchText.length() > \
e.matchText.length(); }
- QString matchText;
- QString matchTextEscaped;
- QString picPath;
- QString picHTMLCode;
-};
-
-/* This is the object we will store each emoticon match in */
-struct Emoticons::EmoticonNode {
- Emoticon emoticon;
- int pos;
- EmoticonNode() : emoticon(), pos( -1 ) {}
- EmoticonNode( const Emoticon e, int p ) : emoticon( e ), pos( p ) {}
-};
-
-class Emoticons::Private
-{
-public:
- QMap<QChar, QList<Emoticon> > emoticonMap;
- QMap<QString, QStringList> emoticonAndPicList;
-
- /**
- * The current icon theme from Kopete::AppearanceSettings
- */
- QString theme;
-
-
-};
-
-
-Emoticons *Emoticons::s_self = 0L;
-
-Emoticons *Emoticons::self()
-{
if( !s_self )
- s_self = new Emoticons;
+ s_self = new KEmoticons;
return s_self;
}
-
-QString Emoticons::parseEmoticons(const QString& message, ParseMode mode ) //static
-{
- return self()->parse( message, mode );
-}
-
-QList<Emoticons::Token> Emoticons::tokenizeEmoticons( const QString& message, \
ParseMode mode ) // static
-{
- return self()->tokenize( message, mode );
-}
-
-QList<Emoticons::Token> Emoticons::tokenize( const QString& message, ParseMode mode \
)
-{
- QList<Token> result;
- if ( !Kopete::AppearanceSettings::self()->useEmoticons() )
- {
- result.append( Token( Text, message ) );
- return result;
- }
-
- if( ! ( mode & (StrictParse|RelaxedParse) ) )
- {
- //if none of theses two mode are selected, use the mode from the config
- mode |= Kopete::AppearanceSettings::self()->emoticonsRequireSpace() ? StrictParse \
: RelaxedParse ;
- }
-
- /* previous char, in the firs iteration assume that it is space since we want
- * to let emoticons at the beginning, the very first previous QChar must be a \
space. */
- QChar p = ' ';
- QChar c; /* current char */
- QChar n;
-
- /* This is the EmoticonNode container, it will represent each matched emoticon */
- QList<EmoticonNode> foundEmoticons;
- QList<EmoticonNode>::const_iterator found;
- /* First-pass, store the matched emoticon locations in foundEmoticons */
- QList<Emoticon> emoticonList;
- QList<Emoticon>::const_iterator it;
- int pos;
-
- bool inHTMLTag = false;
- bool inHTMLLink = false;
- bool inHTMLEntity = false;
- QString needle; // search for this
- for ( pos = 0; pos < message.length(); pos++ )
- {
- c = message[ pos ];
-
- if ( mode & SkipHTML ) // Shall we skip HTML ?
- {
- if ( !inHTMLTag ) // Are we already in an HTML tag ?
- {
- if ( c == '<' ) { // If not check if are going into one
- inHTMLTag = true; // If we are, change the state to inHTML
- p = c;
- continue;
- }
- }
- else // We are already in a HTML tag
- {
- if ( c == '>' ) { // Check if it ends
- inHTMLTag = false; // If so, change the state
- if ( p == 'a' )
- {
- inHTMLLink = false;
- }
- }
- else if ( c == 'a' && p == '<' ) // check if we just entered an achor tag
- {
- inHTMLLink = true; // don't put smileys in urls
- }
- p = c;
- continue;
- }
-
- if( !inHTMLEntity )
- { // are we
- if( c == '&' )
- {
- inHTMLEntity = true;
- }
- }
- }
-
- if ( inHTMLLink ) // i can't think of any situation where a link address might \
need emoticons
- {
- p = c;
- continue;
- }
-
- if ( (mode & StrictParse) && !p.isSpace() && p != '>')
- { // '>' may mark the end of an html tag
- p = c;
- continue;
- } /* strict requires space before the emoticon */
- if ( d->emoticonMap.contains( c ) )
- {
- emoticonList = d->emoticonMap[ c ];
- bool found = false;
- for ( it = emoticonList.begin(); it != emoticonList.end(); ++it )
- {
- // If this is an HTML, then search for the HTML form of the emoticon.
- // For instance <o) => >o)
- needle = ( mode & SkipHTML ) ? (*it).matchTextEscaped : (*it).matchText;
- if ( ( pos == message.indexOf( needle, pos ) ) )
- {
- if( mode & StrictParse )
- {
- /* check if the character after this match is space or end of string*/
- if ( message.length() > pos + needle.length() )
- {
- n = message[ pos + needle.length() ];
- //<br/> marks the end of a line
- if( n != '<' && !n.isSpace() && !n.isNull() && n!= '&')
- break;
- }
- }
- /* Perfect match */
- foundEmoticons.append( EmoticonNode( (*it), pos ) );
- found = true;
- /* Skip the matched emoticon's matchText */
- pos += needle.length() - 1;
- break;
- }
- }
- if( !found )
- {
- if( inHTMLEntity ){
- // If we are in an HTML entitiy such as >
- int htmlEnd = message.indexOf( ';', pos );
- // Search for where it ends
- if( htmlEnd == -1 )
- {
- // Apparently this HTML entity isn't ended, something is wrong, try skip the \
'&'
- // and continue
- kDebug( 14000 ) << "Broken HTML entity, trying to recover.";
- inHTMLEntity = false;
- pos++;
- }
- else
- {
- pos = htmlEnd;
- inHTMLEntity = false;
- }
- }
- }
- } /* else no emoticons begin with this character, so don't do anything */
- p = c;
- }
-
- /* if no emoticons found just return the text */
- if ( foundEmoticons.isEmpty() )
- {
- result.append( Token( Text, message ) );
- return result;
- }
-
- /* Second-pass, generate tokens based on the matches */
-
- pos = 0;
- int length;
-
- for ( found = foundEmoticons.begin(); found != foundEmoticons.end(); ++found )
- {
- needle = ( mode & SkipHTML ) ? (*found).emoticon.matchTextEscaped : \
(*found).emoticon.matchText;
- if ( ( length = ( (*found).pos - pos ) ) )
- {
- result.append( Token( Text, message.mid( pos, length ) ) );
- result.append( Token( Image, (*found).emoticon.matchTextEscaped, \
(*found).emoticon.picPath, (*found).emoticon.picHTMLCode ) );
- pos += length + needle.length();
- }
- else
- {
- result.append( Token( Image, (*found).emoticon.matchTextEscaped, \
(*found).emoticon.picPath, (*found).emoticon.picHTMLCode ) );
- pos += needle.length();
- }
- }
-
- if ( message.length() - pos ) // if there is remaining regular text
- {
- result.append( Token( Text, message.mid( pos ) ) );
- }
-
- return result;
-}
-
-Emoticons::Emoticons( const QString &theme ) : QObject( kapp )
-{
- setObjectName( "KopeteEmoticons" );
-// kDebug(14010) << "KopeteEmoticons::KopeteEmoticons";
- d=new Private;
- if(theme.isNull())
- {
- initEmoticons();
- connect( Kopete::AppearanceSettings::self(), SIGNAL(configChanged()), this, \
SLOT(initEmoticons()) );
- }
- else
- {
- initEmoticons( theme );
- }
-}
-
-
-Emoticons::~Emoticons( )
-{
- delete d;
-}
-
-
-
-void Emoticons::addIfPossible( const QString& filenameNoExt, const QStringList \
&emoticons )
-{
- KStandardDirs *dir = KGlobal::dirs();
- QString pic;
-
- //maybe an extension was given, so try to find the exact file
- pic = dir->findResource( "emoticons", d->theme + QLatin1String( "/" ) + \
filenameNoExt );
-
- if( pic.isNull() )
- pic = dir->findResource( "emoticons", d->theme + QLatin1String( "/" ) + \
filenameNoExt + QLatin1String( ".mng" ) );
- if ( pic.isNull() )
- pic = dir->findResource( "emoticons", d->theme + QLatin1String( "/" ) + \
filenameNoExt + QLatin1String( ".png" ) );
- if ( pic.isNull() )
- pic = dir->findResource( "emoticons", d->theme + QLatin1String( "/" ) + \
filenameNoExt + QLatin1String( ".gif" ) );
-
- if( !pic.isNull() ) // only add if we found one file
- {
- QPixmap p;
- QString result;
-
- d->emoticonAndPicList.insert( pic, emoticons );
-
- for ( QStringList::const_iterator it = emoticons.constBegin(), end = \
emoticons.constEnd();
- it != end; ++it )
- {
- if ( (*it).isEmpty() )
- continue;
-
- QString matchEscaped=Qt::escape(*it);
-
- Emoticon e;
- e.picPath = pic;
-
- // We need to include size (width, height attributes) hints in the emoticon HTML \
code
- // Unless we do so, ChatMessagePart::slotScrollView does not work properly and \
causing
- // HTMLPart not to be scrolled to the very last message.
- p.load( e.picPath );
- result = QLatin1String( "<img align=\"center\" src=\"" ) +
- e.picPath +
- QLatin1String( "\" title=\"" ) +
- matchEscaped +
- QLatin1String( "\" width=\"" ) +
- QString::number( p.width() ) +
- QLatin1String( "\" height=\"" ) +
- QString::number( p.height() ) +
- QLatin1String( "\" />" );
-
- e.picHTMLCode = result;
- e.matchTextEscaped = matchEscaped;
- e.matchText = *it;
- d->emoticonMap[ matchEscaped[0] ].append( e );
- d->emoticonMap[ (*it)[0] ].append( e );
- }
- }
-}
-
-void Emoticons::initEmoticons( const QString &theme )
-{
- if(theme.isNull())
- {
- QString themeFromSettings = Kopete::AppearanceSettings::self()->emoticonTheme();
- if (themeFromSettings == "Default")
- themeFromSettings = "kde4";
- if ( d->theme == themeFromSettings )
- return;
-
- d->theme = themeFromSettings;
- }
- else
- {
- d->theme = theme;
- }
-
-// kDebug(14010) << "Called";
- d->emoticonAndPicList.clear();
- d->emoticonMap.clear();
-
- QString filename= KGlobal::dirs()->findResource( "emoticons", d->theme + \
QLatin1String( "/emoticons.xml" ) );
- if(!filename.isEmpty())
- return initEmoticon_emoticonsxml( filename );
- filename= KGlobal::dirs()->findResource( "emoticons", d->theme + QLatin1String( \
"/icondef.xml" ) );
- if(!filename.isEmpty())
- return initEmoticon_JEP0038( filename );
- kWarning(14010) << "emotiucon XML theme description not found";
-}
-
-void Emoticons::initEmoticon_emoticonsxml( const QString & filename)
-{
- QDomDocument emoticonMap( QLatin1String( "messaging-emoticon-map" ) );
-
- QFile mapFile( filename );
- mapFile.open( QIODevice::ReadOnly );
- emoticonMap.setContent( &mapFile );
-
- QDomElement list = emoticonMap.documentElement();
- QDomNode node = list.firstChild();
- while( !node.isNull() )
- {
- QDomElement element = node.toElement();
- if( !element.isNull() )
- {
- if( element.tagName() == QLatin1String( "emoticon" ) )
- {
- QString emoticon_file = element.attribute(
- QLatin1String( "file" ), QString() );
- QStringList items;
-
- QDomNode emoticonNode = node.firstChild();
- while( !emoticonNode.isNull() )
- {
- QDomElement emoticonElement = emoticonNode.toElement();
- if( !emoticonElement.isNull() )
- {
- if( emoticonElement.tagName() == QLatin1String( "string" ) )
- {
- QString emoticonText = emoticonElement.text();
- if ( !emoticonText.isEmpty() )
- items << emoticonText;
- }
- else
- {
- kDebug(14010) <<
- "Warning: Unknown element '" << element.tagName() <<
- "' in emoticon data" << endl;
- }
- }
- emoticonNode = emoticonNode.nextSibling();
- }
-
- if ( !items.isEmpty() && !emoticon_file.isEmpty() )
- addIfPossible ( emoticon_file, items );
- }
- else
- {
- kDebug(14010) << "Warning: Unknown element '" <<
- element.tagName() << "' in map file" << endl;
- }
- }
- node = node.nextSibling();
- }
- mapFile.close();
- sortEmoticons();
-}
-
-
-void Emoticons::initEmoticon_JEP0038( const QString & filename)
-{
- QDomDocument emoticonMap( QLatin1String( "icondef" ) );
-
- QFile mapFile( filename );
- mapFile.open( QIODevice::ReadOnly );
- emoticonMap.setContent( &mapFile );
-
- QDomElement list = emoticonMap.documentElement();
- QDomNode node = list.firstChild();
- while( !node.isNull() )
- {
- QDomElement element = node.toElement();
- if( !element.isNull() )
- {
- if( element.tagName() == QLatin1String( "icon" ) )
- {
- QStringList items;
- QString emoticon_file;
-
- QDomNode emoticonNode = node.firstChild();
- while( !emoticonNode.isNull() )
- {
- QDomElement emoticonElement = emoticonNode.toElement();
- if( !emoticonElement.isNull() )
- {
- if( emoticonElement.tagName() == QLatin1String( "text" ) )
- {
- //TODO xml:lang
- QString emoticonText = emoticonElement.text();
- if ( !emoticonText.isEmpty() )
- items << emoticonText;
- }
- else if( emoticonElement.tagName() == QLatin1String( "object" ) && \
emoticon_file.isEmpty() )
- {
- QString mime= emoticonElement.attribute(
- QLatin1String( "mime" ), QLatin1String("image/*") );
- if(mime.startsWith(QLatin1String("image/")) && \
!mime.endsWith(QLatin1String("/svg+xml")))
- {
- emoticon_file = emoticonElement.text();
- }
- else
- {
- kDebug(14010) << "Warning: Unsupported format '" << mime;
- }
- }
- /*else
- {
- kDebug(14010) <<
- "Warning: Unknown element '" << element.tagName() <<
- "' in emoticon data" << endl;
- }*/
- }
- emoticonNode = emoticonNode.nextSibling();
- }
- if( !items.isEmpty() && !emoticon_file.isEmpty() )
- addIfPossible ( emoticon_file, items );
- }
- else
- {
- kDebug(14010) << "Warning: Unknown element '" <<
- element.tagName() << "' in map file" << endl;
- }
- }
- node = node.nextSibling();
- }
- mapFile.close();
- sortEmoticons();
-}
-
-
-void Emoticons::sortEmoticons()
-{
- /* sort strings in order of longest to shortest to provide convenient input for
- greedy matching in the tokenizer */
- foreach (const QChar &key, d->emoticonMap.keys())
- qSort(d->emoticonMap[key]);
-}
-
-
-
-
-QMap<QString, QStringList> Emoticons::emoticonAndPicList()
-{
- return d->emoticonAndPicList;
-}
-
-
-QString Emoticons::parse( const QString &message, ParseMode mode )
-{
- if ( !Kopete::AppearanceSettings::self()->useEmoticons() )
- return message;
-
- QList<Token> tokens = tokenize( message, mode );
- QString result;
- foreach (Token token , tokens )
- {
- switch ( token.type )
- {
- case Text:
- result += token.text;
- break;
- case Image:
- result += token.picHTMLCode;
- kDebug( 14010 ) << "Emoticon html code: " << result;
- break;
- default:
- kDebug( 14010 ) << "Unknown token type. Something's broken.";
- }
- }
- return result;
-}
-
} //END namesapce Kopete
-#include "kopeteemoticons.moc"
-
-
-
// vim: set noet ts=4 sts=4 sw=4:
-
Index: libkopete/private/kopeteemoticons.h
===================================================================
--- libkopete/private/kopeteemoticons.h (revision 807115)
+++ libkopete/private/kopeteemoticons.h (working copy)
@@ -20,172 +20,27 @@
#ifndef kopeteemoticons_h__
#define kopeteemoticons_h__
-#include <QObject>
-#include <QList>
-#include <QRegExp>
-#include <QMap>
-#include <QFlags>
-
#include "kopete_export.h"
-
-
+class KEmoticons;
namespace Kopete {
-class KOPETE_EXPORT Emoticons : public QObject
+class KOPETE_EXPORT Emoticons
{
- Q_OBJECT
public:
/**
- * Constructor: DON'T use it if you want to use the emoticon theme
- * chosen by the user.
- * Instead, use @ref Kopete::Emoticons::self()
- **/
- Emoticons( const QString &theme = QString() );
-
- ~Emoticons();
-
- /**
* The emoticons container-class by default is a singleton object.
* Use this method to retrieve the instance.
*/
- static Emoticons *self();
+ static KEmoticons *self();
- /**
- * The possible parse modes
- */
- enum ParseModeEnum { DefaultParseMode = 0x0 , /** Use strict or relaxed \
according the config */
- StrictParse = 0x1, /** Strict parsing requires a space between each emoticon */
- RelaxedParse = 0x4, /** Parse mode where all possible emoticon matches \
are allowed */
- SkipHTML = 0x2 /** Skip emoticons within HTML */
- };
-
- Q_DECLARE_FLAGS(ParseMode, ParseModeEnum)
-
- /**
- * Use it to parse emoticons in a text.
- * You don't need to use this for chat windows,
- * There is a special class that abstract a chat view
- * and uses emoticons parser.
- * This function will use the selected emoticon theme.
- * If nicks is provided, they will not be parsed if they
- * exist in message.
- */
- static QString parseEmoticons( const QString &message, ParseMode mode = SkipHTML ) \
;
-
-
- QString parse( const QString &message, ParseMode mode = SkipHTML );
-
- /**
- * TokenType, a token might be an image ( emoticon ) or text.
- */
- enum TokenType { Undefined, /** Undefined, for completeness only */
- Image, /** Token contains a path to an image */
- Text /** Token contains test */
- };
-
- /**
- * A token consists of a QString text which is either a regular text
- * or a path to image depending on the type.
- * If type is Image the text refers to an image path.
- * If type is Text the text refers to a regular text.
- */
- struct Token {
- Token() : type( Undefined ) {}
- Token( TokenType t, const QString &m ) : type( t ), text(m) {}
- Token( TokenType t, const QString &m, const QString &p, const QString &html )
- : type( t ), text( m ), picPath( p ), picHTMLCode( html ) {}
- TokenType type;
- QString text;
- QString picPath;
- QString picHTMLCode;
- };
-
-
- /**
- * Static function which will call tokenize
- * @see tokenize( const QString& )
- */
- static QList<Token> tokenizeEmoticons( const QString &message, ParseMode mode = \
DefaultParseMode );
-
- /**
- * Tokenizes an message.
- * For example;
- * Assume :], (H), :-x are three emoticons.
- * A text "(H)(H) foo bar john :] :-x" would be tokenized as follows (not strict):
- * 1- /path/to/shades.png
- * 2- /path/to/shades.png
- * 3- " foo bar john "
- * 4- /path/to/bat.png
- * 5- " "
- * 6- /path/to/kiss.png
- *
- * Strict tokenization (require spaces around emoticons):
- * 1- "(H)(H) foo bar john "
- * 2- /path/to/bat.png
- * 3- " "
- * 4- /path/to/kiss.png
- * Note: quotation marks are used to emphasize white spaces.
- * @param message is the message to tokenize
- * @param mode is a bitmask of ParseMode enum
- * @return a QValueList which consiste of ordered tokens of the text.
- * @author Engin AYDOGAN < engin@bzzzt.biz >
- */
- QList<Token> tokenize( const QString &message, ParseMode mode = DefaultParseMode );
-
- /**
- * Return all emoticons and the corresponding icon.
- * (only one emoticon per image)
- */
- QMap<QString, QStringList> emoticonAndPicList();
-
-
private:
/**
* Our instance
**/
- static Emoticons *s_self;
-
- /**
- * add an emoticon to our mapping if
- * an animation/pixmap has been found for it
- **/
- void addIfPossible( const QString& filenameNoExt, const QStringList &emoticons );
-
- /**
- * uses the kopete's emoticons.xml for the theme
- * @see initEmoticons
- */
- void initEmoticon_emoticonsxml( const QString & filename);
-
- /**
- * uses the JEP-0038 xml description for the theme
- * @see initEmoticons
- */
- void initEmoticon_JEP0038( const QString & filename);
-
- /**
- * sorts emoticons for convenient parsing, which yields greedy matching on
- * matchText
- */
- void sortEmoticons();
-
-
- struct Emoticon;
- struct EmoticonNode;
- class Private;
- Private *d;
-private slots:
-
- /**
- * Fills the map with paths and emoticons
- * This needs to be done on every emoticon-theme change
- **/
- void initEmoticons ( const QString &theme = QString() );
+ static KEmoticons *s_self;
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(Emoticons::ParseMode)
-
} //END namespace Kopete
#endif
Index: libkopete/private/kopeteviewmanager.cpp
===================================================================
--- libkopete/private/kopeteviewmanager.cpp (revision 807115)
+++ libkopete/private/kopeteviewmanager.cpp (working copy)
@@ -25,6 +25,7 @@
#include <knotification.h>
#include <kglobal.h>
#include <kwindowsystem.h>
+#include <kemoticons.h>
#include "kopetebehaviorsettings.h"
#include "kopeteaccount.h"
@@ -63,7 +64,7 @@
msgText =msg.plainBody() ;
if( msgText.length() > 30 )
msgText = msgText.left( 30 ) + QString::fromLatin1( " ..." );
- msgText=Kopete::Emoticons::parseEmoticons(Qt::escape(msgText));
+ msgText=Kopete::Emoticons::self()->theme().parseEmoticons(Qt::escape(msgText));
}
else
{
Index: libkopete/kopetecontact.cpp
===================================================================
--- libkopete/kopetecontact.cpp (revision 807115)
+++ libkopete/kopetecontact.cpp (working copy)
@@ -35,6 +35,7 @@
#include <kmenu.h>
#include <kmessagebox.h>
#include <k3listviewsearchline.h>
+#include <kemoticons.h>
#include "kopetecontactlist.h"
#include "kopeteglobal.h"
@@ -580,7 +581,7 @@
"<nobr><b>%4</b> (%3)</nobr><br /><img src=\"%2\"> %1",
Kopete::Message::escape( onlineStatus().description() ), iconName,
Kopete::Message::escape( contactId() ),
- Kopete::Emoticons::parseEmoticons( Kopete::Message::escape( nick ) ) );
+ Kopete::Emoticons::self()->theme().parseEmoticons( Kopete::Message::escape( \
nick ) ) ); }
// --------------------------------------------------------------------------
@@ -623,7 +624,7 @@
if(!statusTitle.isEmpty())
{
tip += i18nc("@label:textbox formatted status title",
- "<br /><b>Status Title:</b> %1", \
Kopete::Emoticons::parseEmoticons( Kopete::Message::escape(statusTitle) ) ); + \
"<br /><b>Status Title:</b> %1", \
Kopete::Emoticons::self()->theme().parseEmoticons( \
Kopete::Message::escape(statusTitle) ) ); }
}
else if ((*it) == Kopete::Global::Properties::self()->statusMessage().key() )
@@ -632,7 +633,7 @@
if(!statusmsg.isEmpty())
{
tip += i18nc("@label:textbox formatted status message",
- "<br /><b>Status Message:</b> %1", \
Kopete::Emoticons::parseEmoticons( Kopete::Message::escape(statusmsg) ) ); \
+ "<br /><b>Status Message:</b> %1", \
Kopete::Emoticons::self()->theme().parseEmoticons( Kopete::Message::escape(statusmsg) \
) ); }
}
else
Index: libkopete/kopeteglobal.h
===================================================================
--- libkopete/kopeteglobal.h (revision 807115)
+++ libkopete/kopeteglobal.h (working copy)
@@ -36,20 +36,6 @@
class PropertiesPrivate;
/**
- * \brief Installs one or more kopete emoticon themes from a tarball
- * (either .kopete-emoticons or .tar.gz or .tar.bz2)
- *
- * @p localPath Full path to a local emoticon archive, use KIO to download
- * files in case their are non-local.
- *
- * @return true in case install was successful, false otherwise. Errors are
- * displayed by either KIO or by using KMessagebox directly.
- *
- * TODO: If possible, port it to KIO instead of using ugly blocking KTar
- **/
- KOPETE_EXPORT void installEmoticonTheme(const QString &localPath);
-
- /**
* \brief Global facility to query/store templates that are needed by \
KopeteProperty
*
* Basically all a plugin author needs to worry about is creating PropertyTmpl
Index: libkopete/CMakeLists.txt
===================================================================
--- libkopete/CMakeLists.txt (revision 807115)
+++ libkopete/CMakeLists.txt (working copy)
@@ -131,7 +131,7 @@
kde4_add_library(kopete SHARED ${kopete_LIB_SRCS})
-target_link_libraries(kopete ${KDE4_KUTILS_LIBS} ${KDE4_KDE3SUPPORT_LIBS} \
${KDE4_KABC_LIBS} ) +target_link_libraries(kopete ${KDE4_KUTILS_LIBS} \
${KDE4_KDE3SUPPORT_LIBS} ${KDE4_KABC_LIBS} -lkemoticons) if(Q_WS_X11 AND \
X11_Xss_FOUND) target_link_libraries(kopete ${X11_Xss_LIB})
endif(Q_WS_X11 AND X11_Xss_FOUND)
Index: libkopete/kopetemimetypehandler.cpp
===================================================================
--- libkopete/kopetemimetypehandler.cpp (revision 807115)
+++ libkopete/kopetemimetypehandler.cpp (working copy)
@@ -27,7 +27,8 @@
#include <kmimetype.h>
#include <kmessagebox.h>
#include <kstandarddirs.h>
-#include <ktar.h>
+#include <kemoticons.h>
+#include <kopeteemoticons.h>
namespace Kopete
{
@@ -205,7 +206,7 @@
void EmoticonMimeTypeHandler::handleURL( const QString &, const KUrl &url ) const
{
- Global::installEmoticonTheme( url.path() );
+ Emoticons::self()->installTheme( url.path() );
}
} // END namespace Kopete
Index: libkopete/ui/kopetelistviewitem.cpp
===================================================================
--- libkopete/ui/kopetelistviewitem.cpp (revision 807115)
+++ libkopete/ui/kopetelistviewitem.cpp (working copy)
@@ -26,6 +26,7 @@
#include <kdebug.h>
#include <kiconloader.h>
#include <kstringhandler.h>
+#include <kemoticons.h>
#include <qapplication.h>
#include <qpixmap.h>
@@ -712,12 +713,12 @@
((TextComponent*)component(n))->color();
}
- QList<Kopete::Emoticons::Token> tokens;
- QList<Kopete::Emoticons::Token>::const_iterator token;
+ QList<KEmoticonsTheme::Token> tokens;
+ QList<KEmoticonsTheme::Token>::const_iterator token;
clear(); // clear childen
- tokens = Kopete::Emoticons::tokenizeEmoticons( d->text );
+ tokens = Kopete::Emoticons::self()->theme().tokenize( d->text );
ImageComponent *ic;
TextComponent *t;
@@ -727,10 +728,10 @@
{
switch ( (*token).type )
{
- case Kopete::Emoticons::Text:
+ case KEmoticonsTheme::Text:
t = new TextComponent( this, d->font, (*token).text );
break;
- case Kopete::Emoticons::Image:
+ case KEmoticonsTheme::Image:
ic = new ImageComponent( this );
ic->setPixmap( QPixmap( (*token).picPath ) );
ic->scale( INT_MAX, fontHeight, Qt::KeepAspectRatio );
_______________________________________________
kopete-devel mailing list
kopete-devel@kde.org
https://mail.kde.org/mailman/listinfo/kopete-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic