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

KUtils

  • sources
  • kde-4.12
  • kdelibs
  • 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 
34 class KEmoticonsTheme::KEmoticonsThemeData : public QSharedData
35 {
36 public:
37  KEmoticonsThemeData();
38  ~KEmoticonsThemeData();
39  KEmoticonsProvider *provider;
40 };
41 
42 
43 KEmoticonsTheme::KEmoticonsThemeData::KEmoticonsThemeData()
44 {
45  provider = 0;
46 }
47 
48 KEmoticonsTheme::KEmoticonsThemeData::~KEmoticonsThemeData()
49 {
50 // delete provider;
51 }
52 
53 KEmoticonsTheme::KEmoticonsTheme()
54 {
55  d = new KEmoticonsThemeData;
56 }
57 
58 KEmoticonsTheme::KEmoticonsTheme(const KEmoticonsTheme &ket)
59 {
60  d = ket.d;
61 }
62 
63 KEmoticonsTheme::KEmoticonsTheme(KEmoticonsProvider *p)
64 {
65  d = new KEmoticonsThemeData;
66  d->provider = p;
67 }
68 
69 KEmoticonsTheme::~KEmoticonsTheme()
70 {
71 }
72 
73 bool KEmoticonsTheme::loadTheme(const QString &path)
74 {
75  if (!d->provider) {
76  return false;
77  }
78 
79  return d->provider->loadTheme(path);
80 }
81 
82 bool KEmoticonsTheme::removeEmoticon(const QString &emo)
83 {
84  if (!d->provider) {
85  return false;
86  }
87 
88  return d->provider->removeEmoticon(emo);
89 }
90 
91 bool 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 
100 void KEmoticonsTheme::save()
101 {
102  if (!d->provider) {
103  return;
104  }
105 
106  d->provider->save();
107 }
108 
109 QString KEmoticonsTheme::themeName() const
110 {
111  if (!d->provider) {
112  return QString();
113  }
114 
115  return d->provider->themeName();
116 }
117 
118 void KEmoticonsTheme::setThemeName(const QString &name)
119 {
120  if (!d->provider) {
121  return;
122  }
123 
124  d->provider->setThemeName(name);
125 }
126 
127 QString KEmoticonsTheme::themePath() const
128 {
129  if (!d->provider) {
130  return QString();
131  }
132 
133  return d->provider->themePath();
134 }
135 
136 QString KEmoticonsTheme::fileName() const
137 {
138  if (!d->provider) {
139  return QString();
140  }
141 
142  return d->provider->fileName();
143 }
144 
145 QHash<QString, QStringList> KEmoticonsTheme::emoticonsMap() const
146 {
147  if (!d->provider) {
148  return QHash<QString, QStringList>();
149  }
150 
151  return d->provider->emoticonsMap();
152 }
153 
154 void KEmoticonsTheme::createNew()
155 {
156  if (!d->provider) {
157  return;
158  }
159 
160  d->provider->createNew();
161 }
162 
163 QString 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 
191 bool EmoticonCompareEscaped( const KEmoticonsProvider::Emoticon &s1, const KEmoticonsProvider::Emoticon &s2)
192 {
193  return s1.matchTextEscaped.length()>s2.matchTextEscaped.length();
194 }
195 bool EmoticonCompare( const KEmoticonsProvider::Emoticon &s1, const KEmoticonsProvider::Emoticon &s2)
196 {
197  return s1.matchText.length()>s2.matchText.length();
198 }
199 
200 
201 QList<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 
362 bool KEmoticonsTheme::isNull() const
363 {
364  return d->provider ? false : true;
365 }
366 
367 KEmoticonsTheme& 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;
kemoticonstheme.h
KEmoticonsTheme
This class contains the emoticons theme.
Definition: kemoticonstheme.h:34
netaccess.h
kdebug.h
KEmoticonsTheme::removeEmoticon
bool removeEmoticon(const QString &emo)
Remove the emoticon emo, this will not delete the image file too.
Definition: kemoticonstheme.cpp:82
KEmoticonsTheme::Token::type
TokenType type
type
Definition: kemoticonstheme.h:76
KEmoticonsTheme::~KEmoticonsTheme
~KEmoticonsTheme()
Destructor.
Definition: kemoticonstheme.cpp:69
KEmoticonsTheme::Image
Token contains a path to an image.
Definition: kemoticonstheme.h:55
KEmoticonsProvider::Emoticon::matchTextEscaped
QString matchTextEscaped
Definition: kemoticonsprovider.h:45
KEmoticonsProvider
This is the base class for the emoticons provider plugins.
Definition: kemoticonsprovider.h:35
QString
QHash< QString, QStringList >
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
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KEmoticons::parseMode
static KEmoticonsTheme::ParseMode parseMode()
Returns the current parse mode.
Definition: kemoticons.cpp:291
KEmoticonsTheme::RelaxedParse
Parse mode where all possible emoticon matches are allowed.
Definition: kemoticonstheme.h:44
EmoticonCompare
bool EmoticonCompare(const KEmoticonsProvider::Emoticon &s1, const KEmoticonsProvider::Emoticon &s2)
Definition: kemoticonstheme.cpp:195
kemoticons.h
KEmoticonsTheme::createNew
void createNew()
Create a new theme.
Definition: kemoticonstheme.cpp:154
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::KEmoticonsTheme
KEmoticonsTheme()
Default constructor, it creates a null emoticons theme you should probably never use this...
Definition: kemoticonstheme.cpp:53
KEmoticonsTheme::Token::picHTMLCode
QString picHTMLCode
html code
Definition: kemoticonstheme.h:79
QStringList
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::tokenize
QList< Token > tokenize(const QString &message, ParseMode mode=DefaultParse) const
Tokenize the message message with ParseMode mode.
Definition: kemoticonstheme.cpp:201
KEmoticonsTheme::setThemeName
void setThemeName(const QString &name)
Set the theme name.
Definition: kemoticonstheme.cpp:118
KEmoticonsTheme::Token::text
QString text
text
Definition: kemoticonstheme.h:77
KEmoticonsTheme::operator=
KEmoticonsTheme & operator=(const KEmoticonsTheme &ket)
Definition: kemoticonstheme.cpp:367
KEmoticonsTheme::SkipHTML
Skip emoticons within HTML.
Definition: kemoticonstheme.h:45
QSharedData
KEmoticonsProvider::Emoticon::matchText
QString matchText
Definition: kemoticonsprovider.h:44
KEmoticonsProvider::Emoticon
Definition: kemoticonsprovider.h:39
KEmoticonsTheme::save
void save()
Save the emoticon theme.
Definition: kemoticonstheme.cpp:100
KEmoticonsTheme::fileName
QString fileName() const
Returns the file name of the theme.
Definition: kemoticonstheme.cpp:136
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::StrictParse
Strict parsing requires a space between each emoticon.
Definition: kemoticonstheme.h:43
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
kstandarddirs.h
EmoticonCompareEscaped
bool EmoticonCompareEscaped(const KEmoticonsProvider::Emoticon &s1, const KEmoticonsProvider::Emoticon &s2)
Definition: kemoticonstheme.cpp:191
KEmoticonsTheme::themeName
QString themeName() const
Returns the theme name.
Definition: kemoticonstheme.cpp:109
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KEmoticonsTheme::themePath
QString themePath() const
Returns the theme path.
Definition: kemoticonstheme.cpp:127
QPair
KEmoticonsProvider::AddEmoticonOption
AddEmoticonOption
Options to pass to addEmoticon.
Definition: kemoticonsprovider.h:53
KEmoticonsTheme::Text
Token contains text.
Definition: kemoticonstheme.h:56
QList
Definition: dialog.h:29
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:50:34 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



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