• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KUtils

  • kutils
  • kemoticons
kemoticonstheme.cpp
Go to the documentation of this file.
1/**********************************************************************************
2 * Copyright (C) 2008 by Carlo Segato <brandon.ml@gmail.com> *
3 * Copyright (c) 2002-2003 by Stefan Gehn <metz@gehn.net> *
4 * Kopete (c) 2002-2008 by the Kopete developers <kopete-devel@kde.org> *
5 * Copyright (c) 2005 by Engin AYDOGAN <engin@bzzzt.biz> *
6 * *
7 * This library is free software; you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public *
9 * License as published by the Free Software Foundation; either *
10 * version 2.1 of the License, or (at your option) any later version. *
11 * *
12 * This library is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15 * Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with this library. If not, see <http://www.gnu.org/licenses/>.*
19 * *
20 **********************************************************************************/
21
22#include "kemoticonstheme.h"
23#include "kemoticons.h"
24
25#include <QtCore/QFileInfo>
26#include <QtCore/QDir>
27#include <QtGui/QTextDocument>
28#include <QtCore/QtAlgorithms>
29
30#include <kio/netaccess.h>
31#include <kstandarddirs.h>
32#include <kdebug.h>
33
34class KEmoticonsTheme::KEmoticonsThemeData : public QSharedData
35{
36public:
37 KEmoticonsThemeData();
38 ~KEmoticonsThemeData();
39 KEmoticonsProvider *provider;
40};
41
42
43KEmoticonsTheme::KEmoticonsThemeData::KEmoticonsThemeData()
44{
45 provider = 0;
46}
47
48KEmoticonsTheme::KEmoticonsThemeData::~KEmoticonsThemeData()
49{
50// delete provider;
51}
52
53KEmoticonsTheme::KEmoticonsTheme()
54{
55 d = new KEmoticonsThemeData;
56}
57
58KEmoticonsTheme::KEmoticonsTheme(const KEmoticonsTheme &ket)
59{
60 d = ket.d;
61}
62
63KEmoticonsTheme::KEmoticonsTheme(KEmoticonsProvider *p)
64{
65 d = new KEmoticonsThemeData;
66 d->provider = p;
67}
68
69KEmoticonsTheme::~KEmoticonsTheme()
70{
71}
72
73bool KEmoticonsTheme::loadTheme(const QString &path)
74{
75 if (!d->provider) {
76 return false;
77 }
78
79 return d->provider->loadTheme(path);
80}
81
82bool KEmoticonsTheme::removeEmoticon(const QString &emo)
83{
84 if (!d->provider) {
85 return false;
86 }
87
88 return d->provider->removeEmoticon(emo);
89}
90
91bool KEmoticonsTheme::addEmoticon(const QString &emo, const QString &text, KEmoticonsProvider::AddEmoticonOption option)
92{
93 if (!d->provider) {
94 return false;
95 }
96
97 return d->provider->addEmoticon(emo, text, option);
98}
99
100void KEmoticonsTheme::save()
101{
102 if (!d->provider) {
103 return;
104 }
105
106 d->provider->save();
107}
108
109QString KEmoticonsTheme::themeName() const
110{
111 if (!d->provider) {
112 return QString();
113 }
114
115 return d->provider->themeName();
116}
117
118void KEmoticonsTheme::setThemeName(const QString &name)
119{
120 if (!d->provider) {
121 return;
122 }
123
124 d->provider->setThemeName(name);
125}
126
127QString KEmoticonsTheme::themePath() const
128{
129 if (!d->provider) {
130 return QString();
131 }
132
133 return d->provider->themePath();
134}
135
136QString KEmoticonsTheme::fileName() const
137{
138 if (!d->provider) {
139 return QString();
140 }
141
142 return d->provider->fileName();
143}
144
145QHash<QString, QStringList> KEmoticonsTheme::emoticonsMap() const
146{
147 if (!d->provider) {
148 return QHash<QString, QStringList>();
149 }
150
151 return d->provider->emoticonsMap();
152}
153
154void KEmoticonsTheme::createNew()
155{
156 if (!d->provider) {
157 return;
158 }
159
160 d->provider->createNew();
161}
162
163QString KEmoticonsTheme::parseEmoticons(const QString &text, ParseMode mode, const QStringList &exclude) const
164{
165 QList<Token> tokens = tokenize(text, mode | SkipHTML);
166 if (tokens.isEmpty() && !text.isEmpty())
167 return text;
168
169 QString result;
170
171 foreach(const Token &token , tokens) {
172 switch (token.type) {
173 case Text:
174 result += token.text;
175 break;
176 case Image:
177 if (!exclude.contains(token.text)) {
178 result += token.picHTMLCode;
179 } else {
180 result += token.text;
181 }
182 break;
183 default:
184 kWarning() << "Unknown token type. Something's broken.";
185 break;
186 }
187 }
188 return result;
189}
190
191bool EmoticonCompareEscaped( const KEmoticonsProvider::Emoticon &s1, const KEmoticonsProvider::Emoticon &s2)
192{
193 return s1.matchTextEscaped.length()>s2.matchTextEscaped.length();
194}
195bool EmoticonCompare( const KEmoticonsProvider::Emoticon &s1, const KEmoticonsProvider::Emoticon &s2)
196{
197 return s1.matchText.length()>s2.matchText.length();
198}
199
200
201QList<KEmoticonsTheme::Token> KEmoticonsTheme::tokenize(const QString &message, ParseMode mode) const
202{
203 if (!d->provider) {
204 return QList<KEmoticonsTheme::Token>();
205 }
206
207 if (!(mode & (StrictParse | RelaxedParse))) {
208 //if none of theses two mode are selected, use the mode from the config
209 mode |= KEmoticons::parseMode();
210 }
211
212 QList<Token> result;
213
214 /* previous char, in the firs iteration assume that it is space since we want
215 * to let emoticons at the beginning, the very first previous QChar must be a space. */
216 QChar p = ' ';
217 QChar c; /* current char */
218 QChar n;
219
220 /* This is the EmoticonNode container, it will represent each matched emoticon */
221 typedef QPair<KEmoticonsProvider::Emoticon, int> EmoticonNode;
222 QList<EmoticonNode> foundEmoticons;
223 /* First-pass, store the matched emoticon locations in foundEmoticons */
224 QList<KEmoticonsProvider::Emoticon> emoticonList;
225 QList<KEmoticonsProvider::Emoticon>::const_iterator it;
226 int pos;
227
228 bool inHTMLTag = false;
229 bool inHTMLLink = false;
230 bool inHTMLEntity = false;
231 QString needle; // search for this
232
233 for (pos = 0; pos < message.length(); ++pos) {
234 c = message[pos];
235
236 if (mode & SkipHTML) { // Shall we skip HTML ?
237 if (!inHTMLTag) { // Are we already in an HTML tag ?
238 if (c == '<') { // If not check if are going into one
239 inHTMLTag = true; // If we are, change the state to inHTML
240 p = c;
241 continue;
242 }
243 } else { // We are already in a HTML tag
244 if (c == '>') { // Check if it ends
245 inHTMLTag = false; // If so, change the state
246
247 if (p == 'a') {
248 inHTMLLink = false;
249 }
250 } else if (c == 'a' && p == '<') { // check if we just entered an achor tag
251 inHTMLLink = true; // don't put smileys in urls
252 }
253 p = c;
254 continue;
255 }
256
257 if (!inHTMLEntity) { // are we
258 if (c == '&') {
259 inHTMLEntity = true;
260 }
261 }
262 }
263
264 if (inHTMLLink) { // i can't think of any situation where a link address might need emoticons
265 p = c;
266 continue;
267 }
268
269 if ((mode & StrictParse) && !p.isSpace() && p != '>') { // '>' may mark the end of an html tag
270 p = c;
271 continue;
272 } /* strict requires space before the emoticon */
273
274 if (d->provider->emoticonsIndex().contains(c)) {
275 emoticonList = d->provider->emoticonsIndex().value(c);
276 if (mode & SkipHTML)
277 qSort(emoticonList.begin(),emoticonList.end(),EmoticonCompareEscaped);
278 else
279 qSort(emoticonList.begin(),emoticonList.end(),EmoticonCompare);
280 bool found = false;
281 for (it = emoticonList.constBegin(); it != emoticonList.constEnd(); ++it) {
282 // If this is an HTML, then search for the HTML form of the emoticon.
283 // For instance <o) => &gt;o)
284 needle = (mode & SkipHTML) ? (*it).matchTextEscaped : (*it).matchText;
285 if (pos == message.indexOf(needle, pos)) {
286 if (mode & StrictParse) {
287 /* check if the character after this match is space or end of string*/
288 if (message.length() > pos + needle.length()) {
289 n = message[pos + needle.length()];
290 //<br/> marks the end of a line
291 if (n != '<' && !n.isSpace() && !n.isNull() && n != '&') {
292 break;
293 }
294 }
295 }
296 /* Perfect match */
297 foundEmoticons.append(EmoticonNode((*it), pos));
298 found = true;
299 /* Skip the matched emoticon's matchText */
300 pos += needle.length() - 1;
301 break;
302 }
303
304 if (found) {
305 break;
306 }
307 }
308
309 if (!found) {
310 if (inHTMLEntity) {
311 // If we are in an HTML entitiy such as &gt;
312 int htmlEnd = message.indexOf(';', pos);
313 // Search for where it ends
314 if (htmlEnd == -1) {
315 // Apparently this HTML entity isn't ended, something is wrong, try skip the '&'
316 // and continue
317 kDebug() << "Broken HTML entity, trying to recover.";
318 inHTMLEntity = false;
319 pos++;
320 } else {
321 pos = htmlEnd;
322 inHTMLEntity = false;
323 }
324 }
325 }
326 } /* else no emoticons begin with this character, so don't do anything */
327 p = c;
328 }
329
330 /* if no emoticons found just return the text */
331 if (foundEmoticons.isEmpty()) {
332 result.append(Token(Text, message));
333 return result;
334 }
335
336 /* Second-pass, generate tokens based on the matches */
337
338 pos = 0;
339 int length;
340
341 for (int i = 0; i < foundEmoticons.size(); ++i) {
342 EmoticonNode itFound = foundEmoticons.at(i);
343 needle = (mode & SkipHTML) ? itFound.first.matchTextEscaped : itFound.first.matchText;
344
345 if ((length = (itFound.second - pos))) {
346 result.append(Token(Text, message.mid(pos, length)));
347 result.append(Token(Image, itFound.first.matchTextEscaped, itFound.first.picPath, itFound.first.picHTMLCode));
348 pos += length + needle.length();
349 } else {
350 result.append(Token(Image, itFound.first.matchTextEscaped, itFound.first.picPath, itFound.first.picHTMLCode));
351 pos += needle.length();
352 }
353 }
354
355 if (message.length() - pos) { // if there is remaining regular text
356 result.append(Token(Text, message.mid(pos)));
357 }
358
359 return result;
360}
361
362bool KEmoticonsTheme::isNull() const
363{
364 return d->provider ? false : true;
365}
366
367KEmoticonsTheme& KEmoticonsTheme::operator=(const KEmoticonsTheme &ket)
368{
369 if (d == ket.d) {
370 return *this;
371 }
372
373 d = ket.d;
374 return *this;
375}
376
377// kate: space-indent on; indent-width 4; replace-tabs on;
KEmoticonsProvider
This is the base class for the emoticons provider plugins.
Definition: kemoticonsprovider.h:36
KEmoticonsProvider::AddEmoticonOption
AddEmoticonOption
Options to pass to addEmoticon.
Definition: kemoticonsprovider.h:53
KEmoticonsTheme
This class contains the emoticons theme.
Definition: kemoticonstheme.h:35
KEmoticonsTheme::setThemeName
void setThemeName(const QString &name)
Set the theme name.
Definition: kemoticonstheme.cpp:118
KEmoticonsTheme::fileName
QString fileName() const
Returns the file name of the theme.
Definition: kemoticonstheme.cpp:136
KEmoticonsTheme::removeEmoticon
bool removeEmoticon(const QString &emo)
Remove the emoticon emo, this will not delete the image file too.
Definition: kemoticonstheme.cpp:82
KEmoticonsTheme::emoticonsMap
QHash< QString, QStringList > emoticonsMap() const
Returns a QHash that contains the emoticons path as keys and the text as values.
Definition: kemoticonstheme.cpp:145
KEmoticonsTheme::SkipHTML
@ SkipHTML
Skip emoticons within HTML.
Definition: kemoticonstheme.h:45
KEmoticonsTheme::StrictParse
@ StrictParse
Strict parsing requires a space between each emoticon.
Definition: kemoticonstheme.h:43
KEmoticonsTheme::RelaxedParse
@ RelaxedParse
Parse mode where all possible emoticon matches are allowed.
Definition: kemoticonstheme.h:44
KEmoticonsTheme::themeName
QString themeName() const
Returns the theme name.
Definition: kemoticonstheme.cpp:109
KEmoticonsTheme::tokenize
QList< Token > tokenize(const QString &message, ParseMode mode=DefaultParse) const
Tokenize the message message with ParseMode mode.
Definition: kemoticonstheme.cpp:201
KEmoticonsTheme::themePath
QString themePath() const
Returns the theme path.
Definition: kemoticonstheme.cpp:127
KEmoticonsTheme::Text
@ Text
Token contains text.
Definition: kemoticonstheme.h:56
KEmoticonsTheme::Image
@ Image
Token contains a path to an image.
Definition: kemoticonstheme.h:55
KEmoticonsTheme::addEmoticon
bool addEmoticon(const QString &emo, const QString &text, KEmoticonsProvider::AddEmoticonOption option=KEmoticonsProvider::DoNotCopy)
Add the emoticon emo with text text.
Definition: kemoticonstheme.cpp:91
KEmoticonsTheme::parseEmoticons
QString parseEmoticons(const QString &text, ParseMode mode=DefaultParse, const QStringList &exclude=QStringList()) const
Parse emoticons in text text with ParseMode mode and optionally excluding emoticons from exclude.
Definition: kemoticonstheme.cpp:163
KEmoticonsTheme::loadTheme
bool loadTheme(const QString &path)
Load the theme inside the directory path.
Definition: kemoticonstheme.cpp:73
KEmoticonsTheme::~KEmoticonsTheme
~KEmoticonsTheme()
Destructor.
Definition: kemoticonstheme.cpp:69
KEmoticonsTheme::isNull
bool isNull() const
Check if the theme has a valid provider and it returns true if it can't find it.
Definition: kemoticonstheme.cpp:362
KEmoticonsTheme::save
void save()
Save the emoticon theme.
Definition: kemoticonstheme.cpp:100
KEmoticonsTheme::createNew
void createNew()
Create a new theme.
Definition: kemoticonstheme.cpp:154
KEmoticonsTheme::KEmoticonsTheme
KEmoticonsTheme()
Default constructor, it creates a null emoticons theme you should probably never use this,...
Definition: kemoticonstheme.cpp:53
KEmoticonsTheme::operator=
KEmoticonsTheme & operator=(const KEmoticonsTheme &ket)
Definition: kemoticonstheme.cpp:367
KEmoticons::parseMode
static KEmoticonsTheme::ParseMode parseMode()
Returns the current parse mode.
Definition: kemoticons.cpp:291
QHash
QList
QPair
kDebug
#define kDebug
kWarning
#define kWarning
kdebug.h
kemoticons.h
EmoticonCompare
bool EmoticonCompare(const KEmoticonsProvider::Emoticon &s1, const KEmoticonsProvider::Emoticon &s2)
Definition: kemoticonstheme.cpp:195
EmoticonCompareEscaped
bool EmoticonCompareEscaped(const KEmoticonsProvider::Emoticon &s1, const KEmoticonsProvider::Emoticon &s2)
Definition: kemoticonstheme.cpp:191
kemoticonstheme.h
kstandarddirs.h
message
void message(KMessage::MessageType messageType, const QString &text, const QString &caption=QString())
name
const char * name(StandardAction id)
netaccess.h
KEmoticonsProvider::Emoticon
Definition: kemoticonsprovider.h:40
KEmoticonsProvider::Emoticon::matchTextEscaped
QString matchTextEscaped
Definition: kemoticonsprovider.h:45
KEmoticonsProvider::Emoticon::matchText
QString matchText
Definition: kemoticonsprovider.h:44
KEmoticonsTheme::Token
A token consists of a QString text which is either a regular text or a path to image depending on the...
Definition: kemoticonstheme.h:65
KEmoticonsTheme::Token::text
QString text
text
Definition: kemoticonstheme.h:77
KEmoticonsTheme::Token::picHTMLCode
QString picHTMLCode
<img> html code
Definition: kemoticonstheme.h:79
KEmoticonsTheme::Token::type
TokenType type
type
Definition: kemoticonstheme.h:76
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KUtils

Skip menu "KUtils"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal