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

KBlog Client Library

  • sources
  • kde-4.12
  • kdepimlibs
  • kblog
wordpressbuggy.cpp
1 /*
2  This file is part of the kblog library.
3 
4  Copyright (c) 2006-2009 Christian Weilbach <christian_weilbach@web.de>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include "wordpressbuggy.h"
23 #include "wordpressbuggy_p.h"
24 
25 #include "blogpost.h"
26 
27 #include <KDebug>
28 #include <KLocalizedString>
29 #include <KDateTime>
30 
31 #include <kio/http.h>
32 #include <kio/job.h>
33 
34 #include <QtCore/QStringList>
35 
36 using namespace KBlog;
37 
38 WordpressBuggy::WordpressBuggy( const KUrl &server, QObject *parent )
39  : MovableType( server, *new WordpressBuggyPrivate, parent )
40 {
41  kDebug();
42 }
43 
44 WordpressBuggy::WordpressBuggy( const KUrl &server, WordpressBuggyPrivate &dd,
45  QObject *parent )
46  : MovableType( server, dd, parent )
47 {
48  kDebug();
49 }
50 
51 WordpressBuggy::~WordpressBuggy()
52 {
53  kDebug();
54 }
55 
56 void WordpressBuggy::createPost( KBlog::BlogPost *post )
57 {
58  // reimplemented because we do this:
59  // http://comox.textdrive.com/pipermail/wp-testers/2005-July/000284.html
60  kDebug();
61  Q_D( WordpressBuggy );
62 
63  // we need mCategoriesList to be loaded first, since we cannot use the post->categories()
64  // names later, but we need to map them to categoryId of the blog
65  d->loadCategories();
66  if ( d->mCategoriesList.isEmpty() ) {
67  kDebug() << "No categories in the cache yet. Have to fetch them first.";
68  d->mCreatePostCache << post;
69  connect( this,SIGNAL(listedCategories(QList<QMap<QString,QString> >)),
70  this,SLOT(slotTriggerCreatePost()) );
71  listCategories();
72  }
73  else {
74  kDebug() << "createPost()";
75  if ( !post ) {
76  kError() << "WordpressBuggy::createPost: post is a null pointer";
77  emit error ( Other, i18n( "Post is a null pointer." ) );
78  return;
79  }
80  kDebug() << "Creating new Post with blogId" << blogId();
81 
82  bool publish = post->isPrivate();
83  // If we do setPostCategories() later than we disable publishing first.
84  if ( !post->categories().isEmpty() ) {
85  post->setPrivate( true );
86  if ( d->mSilentCreationList.contains( post ) ) {
87  kDebug() << "Post already in mSilentCreationList, this *should* never happen!";
88  } else {
89  d->mSilentCreationList << post;
90  }
91  }
92 
93  QString xmlMarkup = QLatin1String("<?xml version=\"1.0\"?>");
94  xmlMarkup += QLatin1String("<methodCall>");
95  xmlMarkup += QLatin1String("<methodName>metaWeblog.newPost</methodName>");
96  xmlMarkup += QLatin1String("<params><param>");
97  xmlMarkup += QLatin1String("<value><string><![CDATA[")+blogId()+QLatin1String("]]></string></value>");
98  xmlMarkup += QLatin1String("</param>");
99  xmlMarkup += QLatin1String("<param>");
100  xmlMarkup += QLatin1String("<value><string><![CDATA[")+username()+QLatin1String("]]></string></value>");
101  xmlMarkup += QLatin1String("</param><param>");
102  xmlMarkup += QLatin1String("<value><string><![CDATA[")+password()+QLatin1String("]]></string></value>");
103  xmlMarkup += QLatin1String("</param>");
104  xmlMarkup += QLatin1String("<param><struct>");
105  xmlMarkup += QLatin1String("<member><name>description</name>");
106  xmlMarkup += QLatin1String("<value><string><![CDATA[")+post->content()+QLatin1String("]]></string></value>");
107  xmlMarkup += QLatin1String("</member><member>");
108  xmlMarkup += QLatin1String("<name>title</name>");
109  xmlMarkup += QLatin1String("<value><string><![CDATA[")+post->title()+QLatin1String("]]></string></value>");
110  xmlMarkup += QLatin1String("</member><member>");
111 
112  xmlMarkup += QLatin1String("<name>dateCreated</name>");
113  xmlMarkup += QLatin1String("<value><dateTime.iso8601>") +
114  post->creationDateTime().dateTime().toUTC().toString( QLatin1String("yyyyMMddThh:mm:ss") ) +
115  QLatin1String("</dateTime.iso8601></value>");
116  xmlMarkup += QLatin1String("</member><member>");
117  xmlMarkup += QLatin1String("<name>mt_allow_comments</name>");
118  xmlMarkup += QString::fromLatin1( "<value><int>%1</int></value>" ).arg( (int)post->isCommentAllowed() );
119  xmlMarkup += QLatin1String("</member><member>");
120  xmlMarkup += QLatin1String("<name>mt_allow_pings</name>");
121  xmlMarkup += QString::fromLatin1( "<value><int>%1</int></value>" ).arg( (int)post->isTrackBackAllowed() );
122  xmlMarkup += QLatin1String("</member><member>");
123  if ( !post->additionalContent().isEmpty() ) {
124  xmlMarkup += QLatin1String("<name>mt_text_more</name>");
125  xmlMarkup += QLatin1String("<value><string><![CDATA[") + post->additionalContent() + QLatin1String("]]></string></value>");
126  xmlMarkup += QLatin1String("</member><member>");
127  }
128  xmlMarkup += QLatin1String("<name>wp_slug</name>");
129  xmlMarkup += QLatin1String("<value><string><![CDATA[") + post->slug() + QLatin1String("]]></string></value>");
130  xmlMarkup += QLatin1String("</member><member>");
131  xmlMarkup += QLatin1String("<name>mt_excerpt</name>");
132  xmlMarkup += QLatin1String("<value><string><![CDATA[") + post->summary() + QLatin1String("]]></string></value>");
133  xmlMarkup += QLatin1String("</member><member>");
134  xmlMarkup += QLatin1String("<name>mt_keywords</name>");
135  xmlMarkup += QLatin1String("<value><string><![CDATA[") + post->tags().join(QLatin1String(",")) + QLatin1String("]]></string></value>");
136  xmlMarkup += QLatin1String("</member></struct></param>");
137  xmlMarkup += QLatin1String("<param><value><boolean>") +
138  QString::fromLatin1( "%1" ).arg( (int)(!post->isPrivate() ) ) +
139  QLatin1String("</boolean></value></param>");
140  xmlMarkup += QLatin1String("</params></methodCall>");
141 
142  QByteArray postData;
143  QDataStream stream( &postData, QIODevice::WriteOnly );
144  stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() );
145 
146  KIO::StoredTransferJob *job = KIO::storedHttpPost( postData, url(), KIO::HideProgressInfo );
147 
148  d->mCreatePostMap[ job ] = post;
149 
150  if ( !job ) {
151  kWarning() << "Failed to create job for: " << url().url();
152  }
153 
154  job->addMetaData(
155  QLatin1String("customHTTPHeader"), QLatin1String("X-hacker: Shame on you Wordpress, ") + QString() +
156  QLatin1String("you took another 4 hours of my life to work around the stupid dateTime bug.") );
157  job->addMetaData( QLatin1String("content-type"), QLatin1String("Content-Type: text/xml; charset=utf-8") );
158  job->addMetaData( QLatin1String("ConnectTimeout"), QLatin1String("50") );
159  job->addMetaData( QLatin1String("UserAgent"), userAgent() );
160 
161  connect( job, SIGNAL(result(KJob*)),
162  this, SLOT(slotCreatePost(KJob*)) );
163  // HACK: uuh this a bit ugly now... reenable the original publish argument,
164  // since createPost should have parsed now
165  post->setPrivate( publish );
166  }
167 }
168 
169 void WordpressBuggy::modifyPost( KBlog::BlogPost *post )
170 {
171  // reimplemented because we do this:
172  // http://comox.textdrive.com/pipermail/wp-testers/2005-July/000284.html
173  kDebug();
174  Q_D( WordpressBuggy );
175 
176  // we need mCategoriesList to be loaded first, since we cannot use the post->categories()
177  // names later, but we need to map them to categoryId of the blog
178  d->loadCategories();
179  if ( d->mCategoriesList.isEmpty() ) {
180  kDebug() << "No categories in the cache yet. Have to fetch them first.";
181  d->mModifyPostCache << post;
182  connect( this,SIGNAL(listedCategories(QList<QMap<QString,QString> >)),
183  this,SLOT(slotTriggerModifyPost()) );
184  listCategories();
185  }
186  else {
187  if ( !post ) {
188  kError() << "WordpressBuggy::modifyPost: post is a null pointer";
189  emit error ( Other, i18n( "Post is a null pointer." ) );
190  return;
191  }
192 
193  kDebug() << "Uploading Post with postId" << post->postId();
194 
195  QString xmlMarkup = QLatin1String("<?xml version=\"1.0\"?>");
196  xmlMarkup += QLatin1String("<methodCall>");
197  xmlMarkup += QLatin1String("<methodName>metaWeblog.editPost</methodName>");
198  xmlMarkup += QLatin1String("<params><param>");
199  xmlMarkup += QLatin1String("<value><string><![CDATA[")+post->postId()+QLatin1String("]]></string></value>");
200  xmlMarkup += QLatin1String("</param>");
201  xmlMarkup += QLatin1String("<param>");
202  xmlMarkup += QLatin1String("<value><string><![CDATA[")+username()+QLatin1String("]]></string></value>");
203  xmlMarkup += QLatin1String("</param><param>");
204  xmlMarkup += QLatin1String("<value><string><![CDATA[")+password()+QLatin1String("]]></string></value>");
205  xmlMarkup += QLatin1String("</param>");
206  xmlMarkup += QLatin1String("<param><struct>");
207  xmlMarkup += QLatin1String("<member><name>description</name>");
208  xmlMarkup += QLatin1String("<value><string><![CDATA[")+post->content()+QLatin1String("]]></string></value>");
209  xmlMarkup += QLatin1String("</member><member>");
210  xmlMarkup += QLatin1String("<name>title</name>");
211  xmlMarkup += QLatin1String("<value><string><![CDATA[")+post->title()+QLatin1String("]]></string></value>");
212  xmlMarkup += QLatin1String("</member><member>");
213 
214  xmlMarkup += QLatin1String("<name>lastModified</name>");
215  xmlMarkup += QLatin1String("<value><dateTime.iso8601>") +
216  post->modificationDateTime().dateTime().toUTC().toString( QLatin1String("yyyyMMddThh:mm:ss") ) +
217  QLatin1String("</dateTime.iso8601></value>");
218  xmlMarkup += QLatin1String("</member><member>");
219  xmlMarkup += QLatin1String("<name>dateCreated</name>");
220  xmlMarkup += QLatin1String("<value><dateTime.iso8601>") +
221  post->creationDateTime().dateTime().toUTC().toString( QLatin1String("yyyyMMddThh:mm:ss") ) +
222  QLatin1String("</dateTime.iso8601></value>");
223  xmlMarkup += QLatin1String("</member><member>");
224  xmlMarkup += QLatin1String("<name>mt_allow_comments</name>");
225  xmlMarkup += QString::fromLatin1( "<value><int>%1</int></value>" ).arg( (int)post->isCommentAllowed() );
226  xmlMarkup += QLatin1String("</member><member>");
227  xmlMarkup += QLatin1String("<name>mt_allow_pings</name>");
228  xmlMarkup += QString::fromLatin1( "<value><int>%1</int></value>" ).arg( (int)post->isTrackBackAllowed() );
229  xmlMarkup += QLatin1String("</member><member>");
230  if ( !post->additionalContent().isEmpty() ) {
231  xmlMarkup += QLatin1String("<name>mt_text_more</name>");
232  xmlMarkup += QLatin1String("<value><string><![CDATA[") + post->additionalContent() + QLatin1String("]]></string></value>");
233  xmlMarkup += QLatin1String("</member><member>");
234  }
235  xmlMarkup += QLatin1String("<name>wp_slug</name>");
236  xmlMarkup += QLatin1String("<value><string><![CDATA[") + post->slug() + QLatin1String("]]></string></value>");
237  xmlMarkup += QLatin1String("</member><member>");
238  xmlMarkup += QLatin1String("<name>mt_excerpt</name>");
239  xmlMarkup += QLatin1String("<value><string><![CDATA[") + post->summary() + QLatin1String("]]></string></value>");
240  xmlMarkup += QLatin1String("</member><member>");
241  xmlMarkup += QLatin1String("<name>mt_keywords</name>");
242  xmlMarkup += QLatin1String("<value><string><![CDATA[") + post->tags().join( QLatin1String(",") ) + QLatin1String("]]></string></value>");
243  xmlMarkup += QLatin1String("</member></struct></param>");
244  xmlMarkup += QLatin1String("<param><value><boolean>") +
245  QString::fromLatin1( "%1" ).arg( (int)( !post->isPrivate() ) ) +
246  QLatin1String("</boolean></value></param>");
247  xmlMarkup += QLatin1String("</params></methodCall>");
248 
249  QByteArray postData;
250  QDataStream stream( &postData, QIODevice::WriteOnly );
251  stream.writeRawData( xmlMarkup.toUtf8(), xmlMarkup.toUtf8().length() );
252 
253  KIO::StoredTransferJob *job = KIO::storedHttpPost( postData, url(), KIO::HideProgressInfo );
254 
255  d->mModifyPostMap[ job ] = post;
256 
257  if ( !job ) {
258  kWarning() << "Failed to create job for: " << url().url();
259  }
260 
261  job->addMetaData(
262  QLatin1String("customHTTPHeader"), QLatin1String("X-hacker: Shame on you Wordpress, ") + QString() +
263  QLatin1String("you took another 4 hours of my life to work around the stupid dateTime bug.") );
264  job->addMetaData( QLatin1String("content-type"), QLatin1String("Content-Type: text/xml; charset=utf-8") );
265  job->addMetaData( QLatin1String("ConnectTimeout"), QLatin1String("50") );
266  job->addMetaData( QLatin1String("UserAgent"), userAgent() );
267 
268  connect( job, SIGNAL(result(KJob*)),
269  this, SLOT(slotModifyPost(KJob*)) );
270  }
271 }
272 
273 QString WordpressBuggy::interfaceName() const
274 {
275  return QLatin1String( "Movable Type" );
276 }
277 
278 WordpressBuggyPrivate::WordpressBuggyPrivate()
279 {
280 }
281 
282 WordpressBuggyPrivate::~WordpressBuggyPrivate()
283 {
284  kDebug();
285 }
286 
287 QList<QVariant> WordpressBuggyPrivate::defaultArgs( const QString &id )
288 {
289  Q_Q( WordpressBuggy );
290  QList<QVariant> args;
291  if ( !id.isEmpty() ) {
292  args << QVariant( id );
293  }
294  args << QVariant( q->username() )
295  << QVariant( q->password() );
296  return args;
297 }
298 
299 void WordpressBuggyPrivate::slotCreatePost( KJob *job )
300 {
301  kDebug();
302 
303  KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>( job );
304  const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
305 
306  Q_Q( WordpressBuggy );
307 
308  KBlog::BlogPost *post = mCreatePostMap[ job ];
309  mCreatePostMap.remove( job );
310 
311  if ( job->error() != 0 ) {
312  kError() << "slotCreatePost error:" << job->errorString();
313  emit q->errorPost( WordpressBuggy::XmlRpc, job->errorString(), post );
314  return;
315  }
316 
317  QRegExp rxError( QLatin1String("faultString") );
318  if ( rxError.indexIn( data ) != -1 ) {
319  rxError = QRegExp( QLatin1String("<string>(.+)</string>") );
320  if ( rxError.indexIn( data ) != -1 ) {
321  kDebug() << "RegExp of faultString failed.";
322  }
323  kDebug() << rxError.cap( 1 );
324  emit q->errorPost( WordpressBuggy::XmlRpc, rxError.cap( 1 ), post );
325  return;
326  }
327 
328  QRegExp rxId( QLatin1String("<string>(.+)</string>") );
329  if ( rxId.indexIn( data ) == -1 ) {
330  kError() << "Could not regexp the id out of the result:" << data;
331  emit q->errorPost( WordpressBuggy::XmlRpc,
332  i18n( "Could not regexp the id out of the result." ), post );
333  return;
334  }
335  kDebug() << "QRegExp rx( \"<string>(.+)</string>\" ) matches" << rxId.cap( 1 );
336 
337  post->setPostId( rxId.cap( 1 ) );
338  if ( mSilentCreationList.contains( post ) )
339  {
340  // set the categories and publish afterwards
341  setPostCategories( post, !post->isPrivate() );
342  } else {
343  kDebug() << "emitting createdPost()"
344  << "for title: \"" << post->title();
345  emit q->createdPost( post );
346  post->setStatus( KBlog::BlogPost::Created );
347  }
348 }
349 
350 void WordpressBuggyPrivate::slotModifyPost( KJob *job )
351 {
352  kDebug();
353 
354  KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob*>( job );
355  const QString data = QString::fromUtf8( stj->data(), stj->data().size() );
356 
357  KBlog::BlogPost *post = mModifyPostMap[ job ];
358  mModifyPostMap.remove( job );
359  Q_Q( WordpressBuggy );
360  if ( job->error() != 0 ) {
361  kError() << "slotModifyPost error:" << job->errorString();
362  emit q->errorPost( WordpressBuggy::XmlRpc, job->errorString(), post );
363  return;
364  }
365 
366  QRegExp rxError( QLatin1String("faultString") );
367  if ( rxError.indexIn( data ) != -1 ) {
368  rxError = QRegExp( QLatin1String("<string>(.+)</string>") );
369  if ( rxError.indexIn( data ) != -1 ) {
370  kDebug() << "RegExp of faultString failed.";
371  }
372  kDebug() << rxError.cap( 1 );
373  emit q->errorPost( WordpressBuggy::XmlRpc, rxError.cap( 1 ), post );
374  return;
375  }
376 
377  QRegExp rxId( QLatin1String("<boolean>(.+)</boolean>") );
378  if ( rxId.indexIn( data ) == -1 ) {
379  kError() << "Could not regexp the id out of the result:" << data;
380  emit q->errorPost( WordpressBuggy::XmlRpc,
381  i18n( "Could not regexp the id out of the result." ), post );
382  return;
383  }
384  kDebug() << "QRegExp rx( \"<boolean>(.+)</boolean>\" ) matches" << rxId.cap( 1 );
385 
386  if ( rxId.cap( 1 ).toInt() == 1 ) {
387  kDebug() << "Post successfully updated.";
388  if ( mSilentCreationList.contains( post ) ) {
389  post->setStatus( KBlog::BlogPost::Created );
390  emit q->createdPost( post );
391  mSilentCreationList.removeOne( post );
392  } else {
393  if ( !post->categories().isEmpty() ) {
394  setPostCategories( post, false );
395  }
396  }
397  }
398 }
399 
400 #include "moc_wordpressbuggy.cpp"
KBlog::BlogPost::title
QString title() const
Returns the title.
Definition: blogpost.cpp:154
KBlog::Blog::error
void error(KBlog::Blog::ErrorType type, const QString &errorMessage)
This signal is emitted when an error occurs with XML parsing or a structural problem.
KBlog::BlogPost::creationDateTime
KDateTime creationDateTime() const
Returns the creation date time.
Definition: blogpost.cpp:308
KBlog::MetaWeblog::listCategories
virtual void listCategories()
List the categories of the blog.
Definition: metaweblog.cpp:62
KBlog::BlogPost::tags
QStringList tags() const
Returns the tags list as a QStringList.
Definition: blogpost.cpp:256
KBlog::BlogPost::Created
Status of a successfully created post.
Definition: blogpost.h:401
KBlog::WordpressBuggy::interfaceName
QString interfaceName() const
Returns the of the inherited object.
Definition: wordpressbuggy.cpp:273
KBlog::BlogPost::isCommentAllowed
bool isCommentAllowed() const
Returns whether comments should be allowed.
Definition: blogpost.cpp:226
KBlog::BlogPost::isTrackBackAllowed
bool isTrackBackAllowed() const
Returns whether track back should be allowed.
Definition: blogpost.cpp:236
KBlog::BlogPost::summary
QString summary() const
Returns the summary.
Definition: blogpost.cpp:246
KBlog::BlogPost::setPostId
void setPostId(const QString &postId)
Sets the post id value.
Definition: blogpost.cpp:149
KBlog::Blog::username
QString username() const
Returns the username used in blog authentication.
Definition: blog.cpp:91
KBlog::BlogPost::additionalContent
QString additionalContent() const
Returns the additional content, (mt_text_more of MovableType API)
Definition: blogpost.cpp:186
KBlog::WordpressBuggy
A class that can be used for access to blogs (Wordpress, Drupal <5.6 and most likely many more) which...
Definition: wordpressbuggy.h:68
wordpressbuggy.h
This file is part of the for accessing Blog Servers and defines the WordpressBuggy class...
KBlog::BlogPost::modificationDateTime
KDateTime modificationDateTime() const
Returns the modification date time.
Definition: blogpost.cpp:318
KBlog::Blog::blogId
QString blogId() const
Returns the unique ID for the specific blog on the server.
Definition: blog.cpp:109
KBlog::BlogPost::setStatus
void setStatus(Status status)
Sets the status.
Definition: blogpost.cpp:333
KBlog::Blog::url
KUrl url() const
Get the URL for the blog's XML-RPC interface.
Definition: blog.cpp:121
KBlog::BlogPost::slug
QString slug() const
Returns the Wordpress posts Slug (or permalink will use for post) Currently just wordpress supports t...
Definition: blogpost.cpp:196
KBlog::MovableType
A class that can be used for access to Movable Type blogs.
Definition: movabletype.h:60
KBlog::BlogPost::setPrivate
void setPrivate(bool privatePost)
Sets the post to private viewings only.
Definition: blogpost.cpp:139
KBlog::WordpressBuggy::createPost
void createPost(KBlog::BlogPost *post)
Create a new post on server.
Definition: wordpressbuggy.cpp:56
KBlog::BlogPost::content
QString content() const
Returns the content.
Definition: blogpost.cpp:164
KBlog::WordpressBuggy::modifyPost
void modifyPost(KBlog::BlogPost *post)
Modify a post on server.
Definition: wordpressbuggy.cpp:169
KBlog::BlogPost
A class that represents a blog post on the server.
Definition: blogpost.h:68
KBlog::WordpressBuggy::~WordpressBuggy
virtual ~WordpressBuggy()
Destroy the object.
Definition: wordpressbuggy.cpp:51
KBlog::BlogPost::categories
QStringList categories() const
Returns the categories.
Definition: blogpost.cpp:298
KBlog::WordpressBuggy::WordpressBuggy
WordpressBuggy(const KUrl &server, QObject *parent=0)
Create an object for WordpressBuggy.
Definition: wordpressbuggy.cpp:38
KBlog::BlogPost::isPrivate
bool isPrivate() const
Returns if the post is published or not.
Definition: blogpost.cpp:134
KBlog::Blog::Other
Any other miscellaneous error.
Definition: blog.h:109
KBlog::MetaWeblog::listedCategories
void listedCategories(const QList< QMap< QString, QString > > &categories)
This signal is emitted when the last category of the listCategories() job has been fetched...
KBlog::BlogPost::postId
QString postId() const
Returns the postId.
Definition: blogpost.cpp:144
KBlog::Blog::userAgent
QString userAgent() const
Returns the HTTP user agent string used to make the HTTP requests.
Definition: blog.cpp:58
KBlog::Blog::password
QString password() const
Returns the password of the blog.
Definition: blog.cpp:85
KBlog::Blog::XmlRpc
An error in the XML-RPC client.
Definition: blog.h:99
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:59:56 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KBlog Client Library

Skip menu "KBlog Client Library"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

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