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

mailcommon

  • sources
  • kde-4.14
  • kdepim
  • mailcommon
  • search
  • searchrule
searchrulestring.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2015 Montel Laurent <montel@kde.org>
3 
4  This program is free software; you can redistribute it and/or modify it
5  under the terms of the GNU General Public License, version 2, as
6  published by the Free Software Foundation.
7 
8  This program is distributed in the hope that it will be useful, but
9  WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License along
14  with this program; if not, write to the Free Software Foundation, Inc.,
15  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include "searchrulestring.h"
19 #include "filterlog.h"
20 using MailCommon::FilterLog;
21 
22 #include <Akonadi/Contact/ContactSearchJob>
23 
24 #include <Akonadi/SearchQuery>
25 
26 #include <KMime/KMimeMessage>
27 
28 #include <KPIMUtils/Email>
29 
30 //note: lowercase include for compatibility
31 #include <kascii.h>
32 #include <KDebug>
33 #include <KLocale>
34 #include <KGlobal>
35 
36 #include <QRegExp>
37 
38 #include <algorithm>
39 #ifndef Q_MOC_RUN
40 #include <boost/bind.hpp>
41 #endif
42 
43 
44 using namespace MailCommon;
45 SearchRuleString::SearchRuleString( const QByteArray &field,
46  Function func,
47  const QString &contents )
48  : SearchRule( field, func, contents )
49 {
50 }
51 
52 SearchRuleString::SearchRuleString( const SearchRuleString &other )
53  : SearchRule( other )
54 {
55 }
56 
57 const SearchRuleString &SearchRuleString::operator=( const SearchRuleString &other )
58 {
59  if ( this == &other ) {
60  return *this;
61  }
62 
63  setField( other.field() );
64  setFunction( other.function() );
65  setContents( other.contents() );
66 
67  return *this;
68 }
69 
70 SearchRuleString::~SearchRuleString()
71 {
72 }
73 
74 bool SearchRuleString::isEmpty() const
75 {
76  return field().trimmed().isEmpty() || contents().isEmpty();
77 }
78 
79 SearchRule::RequiredPart SearchRuleString::requiredPart() const
80 {
81  const QByteArray f = field();
82  SearchRule::RequiredPart part = Header;
83  if ( kasciistricmp( f, "<recipients>" ) == 0 ||
84  kasciistricmp( f, "<status>" ) == 0 ||
85  kasciistricmp( f, "<tag>" ) == 0 ||
86  kasciistricmp( f, "subject" ) == 0 ||
87  kasciistricmp( f, "from" ) == 0 ||
88  kasciistricmp( f, "sender" ) == 0 ||
89  kasciistricmp( f, "reply-to" ) == 0 ||
90  kasciistricmp( f, "to" ) == 0 ||
91  kasciistricmp( f, "cc" ) == 0 ||
92  kasciistricmp( f, "bcc" ) == 0 ||
93  kasciistricmp( f, "in-reply-to" ) == 0 ||
94  kasciistricmp( f, "message-id" ) == 0 ||
95  kasciistricmp( f, "references" ) == 0) {
96  // these fields are directly provided by KMime::Message, no need to fetch the whole Header part
97  part = Envelope;
98  } else if ( kasciistricmp( f, "<message>" ) == 0 ||
99  kasciistricmp( f, "<body>" ) == 0) {
100  part = CompleteMessage;
101  } else {
102  //qDebug()<< "VERIFY IT: SearchRule::RequiredPart SearchRuleString::requiredPart() const use default \"Header\" for field :"<<f;
103  }
104 
105 
106  return part;
107 }
108 
109 
110 bool SearchRuleString::matches( const Akonadi::Item &item ) const
111 {
112  if ( isEmpty() ) {
113  return false;
114  }
115  const KMime::Message::Ptr msg = item.payload<KMime::Message::Ptr>();
116  Q_ASSERT( msg.get() );
117 
118  if ( !msg->hasHeader( "From" ) ) {
119  msg->parse(); // probably not parsed yet: make sure we can access all headers
120  }
121 
122  QString msgContents;
123  // Show the value used to compare the rules against in the log.
124  // Overwrite the value for complete messages and all headers!
125  bool logContents = true;
126 
127  if ( kasciistricmp( field(), "<message>" ) == 0 ) {
128  msgContents = msg->encodedContent();
129  logContents = false;
130  } else if ( kasciistricmp( field(), "<body>" ) == 0 ) {
131  msgContents = msg->body();
132  logContents = false;
133  } else if ( kasciistricmp( field(), "<any header>" ) == 0 ) {
134  msgContents = msg->head();
135  logContents = false;
136  } else if ( kasciistricmp( field(), "<recipients>" ) == 0 ) {
137  // (mmutz 2001-11-05) hack to fix "<recipients> !contains foo" to
138  // meet user's expectations. See FAQ entry in KDE 2.2.2's KMail
139  // handbook
140  if ( function() == FuncEquals || function() == FuncNotEqual ) {
141  // do we need to treat this case specially? Ie.: What shall
142  // "equality" mean for recipients.
143  return
144  matchesInternal( msg->to()->asUnicodeString() ) ||
145  matchesInternal( msg->cc()->asUnicodeString() ) ||
146  matchesInternal( msg->bcc()->asUnicodeString() ) ;
147  }
148  msgContents = msg->to()->asUnicodeString();
149  msgContents += ", " + msg->cc()->asUnicodeString();
150  msgContents += ", " + msg->bcc()->asUnicodeString();
151  } else if ( kasciistricmp( field(), "<tag>" ) == 0 ) {
152  //port?
153  // const Nepomuk2::Resource res( item.url() );
154  // foreach ( const Nepomuk2::Tag &tag, res.tags() ) {
155  // msgContents += tag.label();
156  // }
157  logContents = false;
158  } else {
159  // make sure to treat messages with multiple header lines for
160  // the same header correctly
161  msgContents = msg->headerByType( field() ) ?
162  msg->headerByType( field() )->asUnicodeString() :
163  "";
164  }
165 
166  if ( function() == FuncIsInAddressbook ||
167  function() == FuncIsNotInAddressbook ) {
168  // I think only the "from"-field makes sense.
169  msgContents = msg->headerByType( field() ) ?
170  msg->headerByType( field() )->asUnicodeString() :
171  "";
172 
173  if ( msgContents.isEmpty() ) {
174  return ( function() == FuncIsInAddressbook ) ? false : true;
175  }
176  }
177 
178  // these two functions need the kmmessage therefore they don't call matchesInternal
179  if ( function() == FuncHasAttachment ) {
180  return ( !msg->attachments().isEmpty() );
181  }
182  else if ( function() == FuncHasNoAttachment ) {
183  return ( msg->attachments().isEmpty() );
184  }
185 
186  bool rc = matchesInternal( msgContents );
187  if ( FilterLog::instance()->isLogging() ) {
188  QString msg = ( rc ? "<font color=#00FF00>1 = </font>" : "<font color=#FF0000>0 = </font>" );
189  msg += FilterLog::recode( asString() );
190  // only log headers bcause messages and bodies can be pretty large
191  if ( logContents ) {
192  msg += " (<i>" + FilterLog::recode( msgContents ) + "</i>)";
193  }
194  FilterLog::instance()->add( msg, FilterLog::RuleResult );
195  }
196  return rc;
197 }
198 
199 void SearchRuleString::addQueryTerms(Akonadi::SearchTerm &groupTerm , bool &emptyIsNotAnError) const
200 {
201  using namespace Akonadi;
202  emptyIsNotAnError = false;
203  SearchTerm termGroup(SearchTerm::RelOr);
204  if ( kasciistricmp( field(), "subject" ) == 0 ) {
205  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::Subject, contents(), akonadiComparator()) );
206  } else if ( kasciistricmp( field(), "reply-to" ) == 0 ) {
207  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderReplyTo, contents(), akonadiComparator()) );
208  } else if ( kasciistricmp( field(), "<message>" ) == 0 ) {
209  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::Message, contents(), akonadiComparator()) );
210  } else if ( field() == "<body>" ) {
211  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::Body, contents(), akonadiComparator()) );
212  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::Attachment, contents(), akonadiComparator()) );
213  } else if ( kasciistricmp( field(), "<recipients>" ) == 0 ) {
214  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderTo, contents(), akonadiComparator()) );
215  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderCC, contents(), akonadiComparator()) );
216  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderBCC, contents(), akonadiComparator()) );
217  } else if ( kasciistricmp( field(), "<any header>" ) == 0 ) {
218  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::Headers, contents(), akonadiComparator()) );
219  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::Subject, contents(), akonadiComparator()) );
220  } else if ( kasciistricmp( field(), "to" ) == 0 ) {
221  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderTo, contents(), akonadiComparator()) );
222  } else if ( kasciistricmp( field(), "cc" ) == 0 ) {
223  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderCC, contents(), akonadiComparator()) );
224  } else if ( kasciistricmp( field(), "bcc" ) == 0 ) {
225  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderBCC, contents(), akonadiComparator()) );
226  } else if ( kasciistricmp( field(), "from" ) == 0 ) {
227  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderFrom, contents(), akonadiComparator()) );
228  } else if ( kasciistricmp( field(), "list-id" ) == 0 ) {
229  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderListId, contents(), akonadiComparator()) );
230  } else if ( kasciistricmp( field(), "resent-from" ) == 0 ) {
231  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderResentFrom, contents(), akonadiComparator()) );
232  } else if ( kasciistricmp( field(), "x-loop" ) == 0 ) {
233  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderXLoop, contents(), akonadiComparator()) );
234  } else if ( kasciistricmp( field(), "x-mailing-list" ) == 0 ) {
235  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderXMailingList, contents(), akonadiComparator()) );
236  } else if ( kasciistricmp( field(), "x-spam-flag" ) == 0 ) {
237  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderXSpamFlag, contents(), akonadiComparator()) );
238  } else if ( kasciistricmp( field(), "organization" ) == 0 ) {
239  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::HeaderOrganization, contents(), akonadiComparator()) );
240  } else if ( kasciistricmp( field(), "<tag>" ) == 0 ) {
241  termGroup.addSubTerm(EmailSearchTerm(EmailSearchTerm::MessageTag, contents(), akonadiComparator()) );
242  }
243 
244  // TODO complete for other headers, generic headers
245 
246  if ( !termGroup.subTerms().isEmpty() ) {
247  termGroup.setIsNegated( isNegated() );
248  groupTerm.addSubTerm( termGroup );
249  }
250 }
251 
252 QString SearchRuleString::informationAboutNotValidRules() const
253 {
254  //KF5 add i18n
255  return QLatin1String("String is empty.");
256 }
257 
258 // helper, does the actual comparing
259 bool SearchRuleString::matchesInternal( const QString &msgContents ) const
260 {
261  if( msgContents.isEmpty()) {
262  return false;
263  }
264 
265  switch ( function() ) {
266  case SearchRule::FuncEquals:
267  return ( QString::compare( msgContents.toLower(), contents().toLower() ) == 0 );
268 
269  case SearchRule::FuncNotEqual:
270  return ( QString::compare( msgContents.toLower(), contents().toLower() ) != 0 );
271 
272  case SearchRule::FuncContains:
273  return ( msgContents.contains( contents(), Qt::CaseInsensitive ) );
274 
275  case SearchRule::FuncContainsNot:
276  return ( !msgContents.contains( contents(), Qt::CaseInsensitive ) );
277 
278  case SearchRule::FuncRegExp:
279  {
280  QRegExp regexp( contents(), Qt::CaseInsensitive );
281  return ( regexp.indexIn( msgContents ) >= 0 );
282  }
283 
284  case SearchRule::FuncNotRegExp:
285  {
286  QRegExp regexp( contents(), Qt::CaseInsensitive );
287  return ( regexp.indexIn( msgContents ) < 0 );
288  }
289 
290  case SearchRule::FuncStartWith:
291  {
292  return msgContents.startsWith( contents() );
293  }
294 
295  case SearchRule::FuncNotStartWith:
296  {
297  return !msgContents.startsWith( contents() );
298  }
299 
300  case SearchRule::FuncEndWith:
301  {
302  return msgContents.endsWith( contents() );
303  }
304 
305  case SearchRule::FuncNotEndWith:
306  {
307  return !msgContents.endsWith( contents() );
308  }
309 
310  case FuncIsGreater:
311  return ( QString::compare( msgContents.toLower(), contents().toLower() ) > 0 );
312 
313  case FuncIsLessOrEqual:
314  return ( QString::compare( msgContents.toLower(), contents().toLower() ) <= 0 );
315 
316  case FuncIsLess:
317  return ( QString::compare( msgContents.toLower(), contents().toLower() ) < 0 );
318 
319  case FuncIsGreaterOrEqual:
320  return ( QString::compare( msgContents.toLower(), contents().toLower() ) >= 0 );
321 
322  case FuncIsInAddressbook:
323  {
324  const QStringList addressList = KPIMUtils::splitAddressList( msgContents.toLower() );
325  QStringList::ConstIterator end( addressList.constEnd() );
326  for ( QStringList::ConstIterator it = addressList.constBegin(); ( it != end ); ++it ) {
327  const QString email(KPIMUtils::extractEmailAddress( *it ).toLower());
328  if (!email.isEmpty()) {
329  Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob();
330  job->setLimit( 1 );
331  job->setQuery( Akonadi::ContactSearchJob::Email, email );
332  job->exec();
333 
334  if ( !job->contacts().isEmpty() ) {
335  return true;
336  }
337  }
338  }
339  return false;
340  }
341 
342  case FuncIsNotInAddressbook:
343  {
344  const QStringList addressList = KPIMUtils::splitAddressList( msgContents.toLower() );
345  QStringList::ConstIterator end( addressList.constEnd() );
346 
347  for ( QStringList::ConstIterator it = addressList.constBegin(); ( it != end ); ++it ) {
348  const QString email(KPIMUtils::extractEmailAddress( *it ).toLower());
349  if (!email.isEmpty()) {
350  Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob();
351  job->setLimit( 1 );
352  job->setQuery( Akonadi::ContactSearchJob::Email, email );
353  job->exec();
354 
355  if ( job->contacts().isEmpty() ) {
356  return true;
357  }
358  }
359  }
360  return false;
361  }
362 
363  case FuncIsInCategory:
364  {
365  QString category = contents();
366  const QStringList addressList = KPIMUtils::splitAddressList( msgContents.toLower() );
367 
368  QStringList::ConstIterator end( addressList.constEnd() );
369  for ( QStringList::ConstIterator it = addressList.constBegin(); it != end; ++it ) {
370  const QString email(KPIMUtils::extractEmailAddress( *it ).toLower());
371  if (!email.isEmpty()) {
372  Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob();
373  job->setQuery( Akonadi::ContactSearchJob::Email, email );
374  job->exec();
375 
376  const KABC::Addressee::List contacts = job->contacts();
377 
378  foreach ( const KABC::Addressee &contact, contacts ) {
379  if ( contact.hasCategory( category ) ) {
380  return true;
381  }
382  }
383  }
384  }
385  return false;
386  }
387 
388  case FuncIsNotInCategory:
389  {
390  QString category = contents();
391  const QStringList addressList = KPIMUtils::splitAddressList( msgContents.toLower() );
392 
393  QStringList::ConstIterator end( addressList.constEnd() );
394  for ( QStringList::ConstIterator it = addressList.constBegin(); it != end; ++it ) {
395  const QString email(KPIMUtils::extractEmailAddress( *it ).toLower());
396  if (!email.isEmpty()) {
397  Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob();
398  job->setQuery( Akonadi::ContactSearchJob::Email, email );
399  job->exec();
400 
401  const KABC::Addressee::List contacts = job->contacts();
402 
403  foreach ( const KABC::Addressee &contact, contacts ) {
404  if ( contact.hasCategory( category ) ) {
405  return false;
406  }
407  }
408  }
409 
410  }
411  return true;
412  }
413  default:
414  ;
415  }
416 
417  return false;
418 }
MailCommon::SearchRule::FuncIsInAddressbook
Definition: searchrule.h:67
MailCommon::SearchRule::FuncEndWith
Definition: searchrule.h:75
MailCommon::SearchRuleString::matchesInternal
bool matchesInternal(const QString &contents) const
A helper method for the main matches() method.
Definition: searchrulestring.cpp:259
MailCommon::SearchRule::FuncIsGreaterOrEqual
Definition: searchrule.h:66
MailCommon::SearchRule::FuncNotEndWith
Definition: searchrule.h:76
MailCommon::FilterLog::recode
static QString recode(const QString &plain)
Returns an escaped version of the log which can be used in a HTML document.
Definition: filterlog.cpp:228
QByteArray::trimmed
QByteArray trimmed() const
QByteArray
MailCommon::SearchRule::FuncContainsNot
Definition: searchrule.h:58
MailCommon::SearchRule::FuncIsNotInAddressbook
Definition: searchrule.h:68
MailCommon::SearchRule::setField
void setField(const QByteArray &name)
Sets the message header field name.
Definition: searchrule.cpp:496
MailCommon::SearchRule::FuncIsInCategory
Definition: searchrule.h:69
MailCommon::SearchRule::FuncNotStartWith
Definition: searchrule.h:74
MailCommon::SearchRule::akonadiComparator
Akonadi::SearchTerm::Condition akonadiComparator() const
Converts the rule function into the corresponding Akonadi query operator.
Definition: searchrule.cpp:526
QByteArray::isEmpty
bool isEmpty() const
MailCommon::SearchRule::FuncHasAttachment
Definition: searchrule.h:71
MailCommon::SearchRule::CompleteMessage
Definition: searchrule.h:82
MailCommon::SearchRule::setContents
void setContents(const QString &contents)
Set the contents of the rule.
Definition: searchrule.cpp:506
MailCommon::SearchRule::setFunction
void setFunction(Function function)
Sets the filter function of the rule.
Definition: searchrule.cpp:486
MailCommon::FilterLog::instance
static FilterLog * instance()
Returns the single global instance of the filter log.
Definition: filterlog.cpp:107
MailCommon::FilterLog
KMail Filter Log Collector.
Definition: filterlog.h:55
filterlog.h
MailCommon::SearchRule::FuncStartWith
Definition: searchrule.h:73
MailCommon::SearchRule::FuncNotRegExp
Definition: searchrule.h:62
QRegExp::indexIn
int indexIn(const QString &str, int offset, CaretMode caretMode) const
QRegExp
MailCommon::SearchRule::Function
Function
Describes operators for comparison of field and contents.
Definition: searchrule.h:55
MailCommon::SearchRule::FuncNotEqual
Definition: searchrule.h:60
MailCommon::SearchRuleString::isEmpty
virtual bool isEmpty() const
Determines whether the rule is worth considering.
Definition: searchrulestring.cpp:74
MailCommon::SearchRule::asString
const QString asString() const
Returns the rule as string for debugging purpose.
Definition: searchrule.cpp:516
MailCommon::SearchRule::contents
QString contents() const
Returns the contents of the rule.
Definition: searchrule.cpp:511
QString::isEmpty
bool isEmpty() const
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
MailCommon::SearchRuleString::informationAboutNotValidRules
virtual QString informationAboutNotValidRules() const
Definition: searchrulestring.cpp:252
MailCommon::SearchRule::RequiredPart
RequiredPart
Definition: searchrule.h:79
QString
MailCommon::SearchRule::FuncHasNoAttachment
Definition: searchrule.h:72
MailCommon::SearchRule::field
QByteArray field() const
Returns the message header field name (without the trailing ':').
Definition: searchrule.cpp:501
QStringList
MailCommon::SearchRule::FuncRegExp
Definition: searchrule.h:61
MailCommon::SearchRule::isNegated
bool isNegated() const
Helper that returns whether the rule has a negated function.
Definition: searchrule.cpp:567
MailCommon::SearchRuleString::requiredPart
virtual RequiredPart requiredPart() const
Returns the required part from the item that is needed for the search to operate. ...
Definition: searchrulestring.cpp:79
QString::toLower
QString toLower() const
QString::contains
bool contains(QChar ch, Qt::CaseSensitivity cs) const
MailCommon::SearchRule
This class represents one search pattern rule.
Definition: searchrule.h:38
MailCommon::SearchRule::FuncIsNotInCategory
Definition: searchrule.h:70
MailCommon::SearchRule::Envelope
Definition: searchrule.h:80
MailCommon::SearchRule::FuncContains
Definition: searchrule.h:57
MailCommon::SearchRule::function
Function function() const
Returns the filter function of the rule.
Definition: searchrule.cpp:491
MailCommon::SearchRule::FuncIsGreater
Definition: searchrule.h:63
MailCommon::SearchRuleString
Definition: searchrulestring.h:32
MailCommon::SearchRuleString::operator=
const SearchRuleString & operator=(const SearchRuleString &other)
Initializes this rule with an other rule.
Definition: searchrulestring.cpp:57
MailCommon::SearchRule::FuncIsLessOrEqual
Definition: searchrule.h:64
MailCommon::SearchRuleString::addQueryTerms
virtual void addQueryTerms(Akonadi::SearchTerm &groupTerm, bool &emptyIsNotAnError) const
Adds query terms to the given term group.
Definition: searchrulestring.cpp:199
MailCommon::SearchRuleString::matches
virtual bool matches(const Akonadi::Item &item) const
Tries to match the rule against the KMime::Message in the given item.
Definition: searchrulestring.cpp:110
QLatin1String
QList::ConstIterator
typedef ConstIterator
MailCommon::SearchRuleString::SearchRuleString
SearchRuleString(const QByteArray &field=QByteArray(), Function function=FuncContains, const QString &contents=QString())
Creates new new string search rule.
Definition: searchrulestring.cpp:45
searchrulestring.h
MailCommon::FilterLog::add
void add(const QString &entry, ContentType type)
Adds the given log entry under the given content type to the log.
Definition: filterlog.cpp:164
MailCommon::SearchRuleString::~SearchRuleString
virtual ~SearchRuleString()
Destroys the string search rule.
Definition: searchrulestring.cpp:70
MailCommon::SearchRule::Header
Definition: searchrule.h:81
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
QString::compare
int compare(const QString &other) const
MailCommon::SearchRule::FuncIsLess
Definition: searchrule.h:65
MailCommon::SearchRule::FuncEquals
Definition: searchrule.h:59
MailCommon::FilterLog::RuleResult
Log all rule matching results.
Definition: filterlog.h:76
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:31:41 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

mailcommon

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

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

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