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

blogilo

  • sources
  • kde-4.14
  • kdepim
  • blogilo
  • src
dbman.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Blogilo, A KDE Blogging Client
3 
4  Copyright (C) 2008-2010 Mehrdad Momeny <mehrdad.momeny@gmail.com>
5  Copyright (C) 2008-2010 Golnaz Nilieh <g382nilieh@gmail.com>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License or (at your option) version 3 or any later version
11  accepted by the membership of KDE e.V. (or its successor approved
12  by the membership of KDE e.V.), which shall act as a proxy
13  defined in Section 14 of version 3 of the license.
14 
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, see http://www.gnu.org/licenses/
23 */
24 //krazy:excludeall=crashy to skip false positives due to QSqlQuery.exec() usage
25 
26 #include "dbman.h"
27 #include "bilboblog.h"
28 #include "bilbopost.h"
29 
30 #include <kdebug.h>
31 #include <KDE/KLocale>
32 #include <kdatetime.h>
33 #include <kurl.h>
34 #include <kwallet.h>
35 #include <kio/deletejob.h>
36 #include <kmessagebox.h>
37 
38 #include <QSqlError>
39 #include <QSqlQuery>
40 #include <QFile>
41 #include <QSqlDatabase>
42 
43 
44 class DBMan::Private
45 {
46 public:
47  Private()
48  : mWallet(0),
49  useWallet(false)
50  {
51  }
52  KWallet::Wallet* mWallet;
53  QString mLastErrorText;
54  bool useWallet;
55  QMap<int, BilboBlog*> mBlogList;
56  QSqlDatabase db;
57 
58  static const int DatabaseSchemaVersion = 1;
59 };
60 
61 DBMan::DBMan()
62  : d(new Private)
63 {
64  d->mWallet = KWallet::Wallet::openWallet( KWallet::Wallet::LocalWallet(), 0 );
65  if ( d->mWallet ) {
66  d->useWallet = true;
67  if ( !d->mWallet->hasFolder( QLatin1String("blogilo") ) ) {
68  d->mWallet->createFolder( QLatin1String("blogilo") );
69  }
70  d->mWallet->setFolder( QLatin1String("blogilo") );
71  kDebug() << "Wallet successfully opened.";
72  } else {
73  d->useWallet = false;
74  kDebug() << "Could not use Wallet service, will use database to store passwords";
75  }
76 
77  if ( !QFile::exists( CONF_DB ) ) {
78  if ( !this->createDB() ) {
79  KMessageBox::detailedError( 0, i18n( "Cannot create database" ),
80  i18n( d->db.lastError().text().toUtf8().data() ) );
81  kDebug() << "Cannot create database, SQL error: " << d->db.lastError().text() << endl;
82  exit ( 1 );
83  }
84  } else if ( !connectDB() ) {
85  kDebug() << d->mLastErrorText;
86  exit( 1 );
87  }
88 
89  if ( !updateDB() ) {
90  kDebug() << d->mLastErrorText;
91  exit( 1 );
92  }
93 
94  reloadBlogList();
95 }
96 
97 DBMan::~DBMan()
98 {
99  kDebug();
100  d->db.close();
101  if(d->useWallet) {
102  d->mWallet->deleteLater();
103  d->mWallet = 0;
104  }
105  delete d;
106  mSelf = 0L;
107 }
108 
109 
110 QString DBMan::lastErrorText() const
111 {
112  return d->mLastErrorText;
113 }
114 
115 DBMan * DBMan::mSelf = 0L;
116 
117 DBMan * DBMan::self()
118 {
119  if ( !mSelf )
120  mSelf = new DBMan;
121  return mSelf;
122 }
123 
124 const QMap<int, BilboBlog*> & DBMan::blogList() const
125 {
126  return d->mBlogList;
127 }
128 
129 void DBMan::reloadBlogList()
130 {
131  d->mBlogList.clear();
132  QList<BilboBlog*> listBlogs = this->listBlogs();
133  const int count = listBlogs.count();
134  for ( int i = 0; i < count; ++i ) {
135  d->mBlogList [ listBlogs.at(i)->id() ] = listBlogs.at(i);
136  }
137 }
138 
139 bool DBMan::connectDB()
140 {
141  kDebug();
142  if( d->db.isOpen() )
143  return true;
144  d->db = QSqlDatabase::addDatabase( QLatin1String("QSQLITE") );
145  d->db.setDatabaseName( QString(CONF_DB) );
146 
147  if ( !d->db.open() ) {
148  KMessageBox::detailedError( 0, i18n( "Cannot connect to database" ),
149  i18n( d->db.lastError().text().toUtf8().data() ) );
150  kDebug() << "Cannot connect to database, SQL error: " << d->db.lastError().text();
151  return false;
152  }
153  return true;
154 }
155 
156 
163 bool DBMan::createDB()
164 {
165  kDebug();
166  bool ret = true;
167  if ( !connectDB() )
168  exit( 1 );
169 
170  QSqlQuery q;
172  if ( !q.exec( QLatin1String("CREATE TABLE blog (id INTEGER PRIMARY KEY, blogid TEXT, blog_url TEXT, username TEXT,\
173  password TEXT, style_url TEXT, api_type TEXT, title TEXT, direction TEXT,\
174  local_directory TEXT, icon_url TEXT)") ) ) {
175  ret = false;
176  d->mLastErrorText = q.lastError().text();
177  }
178 
180  if ( !q.exec( QLatin1String("CREATE TABLE post (id INTEGER PRIMARY KEY, postid TEXT NOT NULL, blog_id NUMERIC NOT NULL,\
181  author TEXT, slug TEXT, post_password TEXT, title TEXT, content TEXT, text_more TEXT,\
182  c_time TEXT, m_time TEXT, is_private NUMERIC, is_comment_allowed NUMERIC,\
183  is_trackback_allowed NUMERIC, link TEXT, perma_link TEXT, summary TEXT, tags TEXT,\
184  status NUMERIC, trackback_urls TEXT, UNIQUE(postid, blog_id));") ) ) {
185  ret = false;
186  d->mLastErrorText = q.lastError().text();
187  }
188 
190  if ( !q.exec( QLatin1String("CREATE TABLE comment (id INTEGER PRIMARY KEY, commentid TEXT NOT NULL, blog_id NUMERIC NOT NULL,\
191  postId TEXT, author_name TEXT, author_url TEXT, author_email TEXT, title TEXT, content TEXT,\
192  c_time TEXT, m_time TEXT, link TEXT, password TEXT,\
193  status NUMERIC, UNIQUE(commentid, blog_id));" ) ) ){
194  ret = false;
195  d->mLastErrorText = q.lastError().text();
196  }
197 
199  if ( !q.exec( QLatin1String("CREATE TABLE category (catid INTEGER PRIMARY KEY, name TEXT NOT NULL,\
200  description TEXT, htmlUrl TEXT, rssUrl TEXT, categoryId TEXT, parentId TEXT,\
201  blog_id NUMERIC NOT NULL, UNIQUE(name,blog_id));" ) ) ) {
202  ret = false;
203  d->mLastErrorText = q.lastError().text();
204  }
205 
207  if( !q.exec( QLatin1String("CREATE TABLE file (fileid INTEGER PRIMARY KEY, name TEXT, blog_id NUMERIC, is_uploaded NUMERIC,\
208  local_url TEXT, remote_url TEXT, mime_type TEXT);" ) ) ) {
209  ret = false;
210  d->mLastErrorText = q.lastError().text();
211  }
212 
214  if ( !q.exec( QLatin1String("CREATE TABLE post_cat (blogId TEXT NOT NULL, postId TEXT NOT NULL,\
215  categoryId TEXT NOT NULL, UNIQUE(blogId,postId,categoryId));" ) ) ) {
216  ret = false;
217  d->mLastErrorText = q.lastError().text();
218  }
219 
221  if ( !q.exec( QLatin1String("CREATE TABLE post_file (post_id INTEGER, file_id INTEGER);" ) ) ) {
222  ret = false;
223  d->mLastErrorText = q.lastError().text();
224  }
225 
227  if( !q.exec( QLatin1String("CREATE TABLE local_post (local_id INTEGER PRIMARY KEY, id INTEGER UNIQUE, postid TEXT, blog_id NUMERIC,\
228  author TEXT, slug TEXT, post_password TEXT, title TEXT, content TEXT, text_more TEXT,\
229  c_time TEXT, m_time TEXT, is_private NUMERIC, is_comment_allowed NUMERIC,\
230  is_trackback_allowed NUMERIC, link TEXT, perma_link TEXT, summary TEXT, tags TEXT,\
231  status NUMERIC);" ) ) ) {
232  ret = false;
233  d->mLastErrorText = q.lastError().text();
234  }
235 
237  if( !q.exec( QLatin1String("CREATE TABLE local_post_cat (local_id INT, categoryId TEXT);" ) ) ) {
238  ret = false;
239  d->mLastErrorText = q.lastError().text();
240  }
241 
243  if( !q.exec( QLatin1String("CREATE TABLE temp_post (local_id INTEGER PRIMARY KEY, id INTEGER UNIQUE, postid TEXT, blog_id NUMERIC,\
244  author TEXT, slug TEXT, post_password TEXT, title TEXT, content TEXT, text_more TEXT,\
245  c_time TEXT, m_time TEXT, is_private NUMERIC, is_comment_allowed NUMERIC,\
246  is_trackback_allowed NUMERIC, link TEXT, perma_link TEXT, summary TEXT, tags TEXT,\
247  status NUMERIC);" ) ) ){
248  ret = false;
249  d->mLastErrorText = q.lastError().text();
250  }
251 
253  if( !q.exec( QLatin1String("CREATE TABLE temp_post_cat (local_id INT, categoryId TEXT);" ) ) ) {
254  ret = false;
255  d->mLastErrorText = q.lastError().text();
256  }
257 
259  if ( !q.exec( QLatin1String("CREATE TABLE auth_data (blog_id INT, key TEXT NOT NULL, value TEXT NOT NULL, UNIQUE(blog_id,key))") ) ) {
260  ret = false;
261  d->mLastErrorText = q.lastError().text();
262  }
263 
264  if ( !q.exec( QLatin1String("CREATE TABLE schema_version (version INT);") ) ) {
265  ret = false;
266  d->mLastErrorText = q.lastError().text();
267  }
268 
269  {
270  QSqlQuery vq;
271  vq.prepare( QLatin1String("INSERT INTO schema_version (version) VALUES (?);") );
272  vq.addBindValue( DBMan::Private::DatabaseSchemaVersion );
273  if ( !vq.exec() ) {
274  ret = false;
275  d->mLastErrorText = q.lastError().text();
276  }
277  }
278 
280  q.exec( QLatin1String("CREATE TRIGGER delete_post AFTER DELETE ON post\
281  BEGIN\
282  DELETE FROM post_cat WHERE post_cat.postId=OLD.postid;\
283  DELETE FROM post_file WHERE post_file.post_id=OLD.id;\
284  DELETE FROM comment WHERE comment.postId=OLD.postid;\
285  END" ) );
286  q.exec( QLatin1String("CREATE TRIGGER delete_blog AFTER DELETE ON blog \
287  BEGIN\
288  DELETE FROM category WHERE category.blog_id=OLD.id;\
289  DELETE FROM file WHERE file.blog_id=OLD.id;\
290  DELETE FROM post WHERE post.blog_id=OLD.id;\
291  DELETE FROM comment WHERE comment.blog_id=OLD.id;\
292  DELETE FROM auth_data WHERE auth_data.blog_id=OLD.id;\
293  END" ) );
294  q.exec( QLatin1String("CREATE TRIGGER delete_temp_post AFTER DELETE ON temp_post \
295  BEGIN\
296  DELETE FROM temp_post_cat WHERE local_id=OLD.local_id;\
297  END" ));
298  q.exec( QLatin1String("CREATE TRIGGER delete_local_post AFTER DELETE ON local_post \
299  BEGIN\
300  DELETE FROM local_post_cat WHERE local_id=OLD.local_id;\
301  END" ));
302 
303  return ret;
304 }
305 
306 bool DBMan::updateDB()
307 {
308  uint dbVersion = 0;
309 
311  if ( !d->db.tables(QSql::Tables).contains( QLatin1String("schema_version") ) ) {
312  QSqlQuery q;
313  if ( !q.exec( QLatin1String("CREATE TABLE schema_version (version INT);") ) ) {
314  d->mLastErrorText = q.lastError().text();
315  return false;
316  }
317  if ( !q.exec( QLatin1String("INSERT INTO schema_version (version) VALUES (0);") ) ) {
318  d->mLastErrorText = q.lastError().text();
319  return false;
320  }
321  }
322 
323  QSqlQuery q;
324  if ( !q.exec( QLatin1String("SELECT version FROM schema_version;") ) ) {
325  d->mLastErrorText = q.lastError().text();
326  return false;
327  }
328  q.next();
329  dbVersion = q.value(0).toUInt();
330 
331  if ( dbVersion < 1 ) {
332  QSqlQuery q;
333  if ( !q.exec( QLatin1String("CREATE TABLE auth_data (blog_id INT, key TEXT NOT NULL, value TEXT NOT NULL, UNIQUE(blog_id, key));") ) ) {
334  d->mLastErrorText = q.lastError().text();
335  return false;
336  }
337 
338  if ( !q.exec( QLatin1String("DROP TRIGGER delete_blog") ) ) {
339  d->mLastErrorText = q.lastError().text();
340  return false;
341  }
342 
343  if ( !q.exec( QLatin1String("CREATE TRIGGER delete_blog AFTER DELETE ON blog \
344  BEGIN\
345  DELETE FROM category WHERE category.blog_id=OLD.id;\
346  DELETE FROM file WHERE file.blog_id=OLD.id;\
347  DELETE FROM post WHERE post.blog_id=OLD.id;\
348  DELETE FROM comment WHERE comment.blog_id=OLD.id;\
349  DELETE FROM auth_data WHERE auth_data.blog_id=OLD.id;\
350  END" ) ) ) {
351  d->mLastErrorText = q.lastError().text();
352  return false;
353  }
354 
355  dbVersion = 1;
356  }
357 
358 
360  {
361  QSqlQuery q;
362  q.prepare( QLatin1String("UPDATE schema_version SET version = ?") );
363  q.addBindValue( dbVersion );
364  if ( !q.exec() ) {
365  d->mLastErrorText = q.lastError().text();
366  return false;
367  }
368  }
369 
370  return true;
371 }
372 
373 int DBMan::addBlog( const BilboBlog & blog )
374 {
375  QSqlQuery q;
376  if( d->useWallet ) {
377  q.prepare( QLatin1String("INSERT INTO blog (blogid, blog_url, username, style_url, api_type, title,\
378  direction, local_directory) VALUES(?, ?, ?, ?, ?, ?, ?, ?)" ) );
379  if ( d->mWallet && d->mWallet->writePassword( blog.url().url() + QLatin1Char('_') + blog.username(), blog.password() ) == 0 )
380  kDebug() << "Password stored to kde wallet";
381  else
382  return -1;
383  } else {
384  q.prepare( QLatin1String("INSERT INTO blog (password, blogid, blog_url, username, style_url, api_type, title,\
385  direction, local_directory) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)" ) );
386  q.addBindValue( blog.password() );
387  }
388  q.addBindValue( blog.blogid() );
389  q.addBindValue( blog.url().url() );
390  q.addBindValue( blog.username() );
391  q.addBindValue( blog.blogUrl() );
392  q.addBindValue( blog.api() );
393  q.addBindValue( blog.title() );
394  q.addBindValue( blog.direction() );
395  q.addBindValue( blog.localDirectory() );
396 
397  if ( q.exec() ) {
398  reloadBlogList();
399  return q.lastInsertId().toInt();
400  } else {
401  d->mLastErrorText = q.lastError().text();
402  return -1;
403  }
404 }
405 
406 bool DBMan::editBlog( const BilboBlog & blog )
407 {
408  QSqlQuery q;
409  if( d->useWallet ) {
410  q.prepare( QLatin1String("UPDATE blog SET blogid=?, blog_url=?, username=? , style_url=? , api_type=?, \
411  title=?, direction=?, local_directory=? WHERE id=?" ) );
412  if ( d->mWallet && d->mWallet->writePassword( blog.url().url() + QLatin1Char('_') + blog.username(), blog.password() ) == 0 )
413  kDebug() << "Password stored to kde wallet";
414  else
415  return false;
416  } else {
417  q.prepare( QLatin1String("UPDATE blog SET password=?, blogid=?, blog_url=?, username=? , style_url=? , api_type=?, \
418  title=?, direction=?, local_directory=? WHERE id=?" ));
419  q.addBindValue( blog.password() );
420  }
421  q.addBindValue( blog.blogid() );
422  q.addBindValue( blog.url().url() );
423  q.addBindValue( blog.username() );
424  q.addBindValue( blog.blogUrl() );
425  q.addBindValue( blog.api() );
426  q.addBindValue( blog.title() );
427  q.addBindValue( blog.direction() );
428  q.addBindValue( blog.localDirectory() );
429  q.addBindValue( blog.id() );
430 
431  bool res = q.exec();
432  if ( !res ) {
433  d->mLastErrorText = q.lastError().text();
434  kDebug() << q.lastError().text();
435  return res;
436  }
437  reloadBlogList();
438  return res;
439 }
440 
441 bool DBMan::removeBlog( int blog_id )
442 {
443  BilboBlog *tmp = d->mBlogList[ blog_id ];
444  if( d->useWallet ) {
445  if ( d->mWallet && d->mWallet->removeEntry( tmp->url().url() + QLatin1Char('_') + tmp->username() ) == 0
446  && d->mWallet->removeEntry( QString::number( blog_id ) ) == 0 )
447  kDebug() << "Password removed to kde wallet";
448  }
449  QSqlQuery q;
450  q.prepare( QLatin1String("DELETE FROM blog WHERE id=?" ));
451  q.addBindValue( blog_id );
452  bool res = q.exec();
453  if ( !res ) {
454  d->mLastErrorText = q.lastError().text();
455  kDebug() << q.lastError().text();
456  return res;
457  }
458  QString path = KStandardDirs::locateLocal( "data", QString::fromLatin1( "blogilo/%1/" ).arg( blog_id ) , false );
459  KIO::del(KUrl(path), KIO::HideProgressInfo);
460  reloadBlogList();
461  return res;
462 }
463 
464 int DBMan::addPost( const BilboPost & post, int blog_id )
465 {
466  kDebug() << "Adding post with title: " << post.title() << " to Blog " << blog_id;
467  QSqlQuery q;
468  q.prepare( QLatin1String("INSERT OR REPLACE INTO post (postid, blog_id, author, title, content, text_more, c_time, m_time,\
469  is_private, is_comment_allowed, is_trackback_allowed, link, perma_link, summary, slug,\
470  tags, status) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ) );
471  q.addBindValue( post.postId() );
472  q.addBindValue( blog_id );
473  q.addBindValue( post.author() );
474  q.addBindValue( post.title() );
475  q.addBindValue( post.content() );
476  q.addBindValue( post.additionalContent() );
477  q.addBindValue( post.creationDateTime().toString( KDateTime::ISODate ) );
478  q.addBindValue( ( post.modificationDateTime().isNull() ? post.creationDateTime().toString( KDateTime::ISODate ) :
479  post.modificationDateTime().toString( KDateTime::ISODate )) );
480  q.addBindValue( post.isPrivate() );
481  q.addBindValue( post.isCommentAllowed() );
482  q.addBindValue( post.isTrackBackAllowed() );
483  q.addBindValue( post.link().url() );
484  q.addBindValue( post.permaLink().url() );
485  q.addBindValue( post.summary() );
486  q.addBindValue( post.slug() );
487  q.addBindValue( post.tags().join(QLatin1String(",")) );
488  q.addBindValue( post.status() );
489 
490  int ret;
491  if ( q.exec() ) {
492  ret = q.lastInsertId().toInt();
493 
495  QSqlQuery qd;
496  qd.prepare( QLatin1String("DELETE FROM post_cat WHERE postId=? AND blogId=(SELECT blogid FROM blog where id=?)" ));
497  qd.addBindValue(post.postId());
498  qd.addBindValue(blog_id);
499  if ( !qd.exec() ) {
500  d->mLastErrorText = qd.lastError().text();
501  kError() << "Cannot delete previous categories.";
502  }
503 
504  int cat_count = post.categories().count();
505  if( cat_count > 0 ) {
506 // kDebug()<< "Adding "<<cat_count<<" category to post.";
507  QSqlQuery q2;
508  q2.prepare( QLatin1String("INSERT OR REPLACE INTO post_cat (blogId, postId, categoryId)\
509  VALUES((SELECT blogid FROM blog where id=?), ?, \
510  (SELECT categoryId FROM category WHERE name = ? AND blog_id= ?))" ) );
511  for ( int i = 0; i < cat_count; ++i ) {
512  q2.addBindValue(blog_id);
513  q2.addBindValue(post.postId());
514  q2.addBindValue(post.categories()[i]);
515  q2.addBindValue(blog_id);
516  if ( !q2.exec() ) {
517  kDebug() << "Cannot add one of categories to Post, SQL Error: " << q2.lastError().text();
518  d->mLastErrorText = q.lastError().text();
519  }
520  }
521  }
522  } else {
523  d->mLastErrorText = q.lastError().text();
524  kDebug() << "Cannot Add post to database!\n\tSQL Error: " << q.lastError().text();
525  ret = -1;
526  }
527 
528  return ret;
529 }
530 
531 bool DBMan::editPost( const BilboPost & post, int blog_id )
532 {
533  kDebug();
534  QSqlQuery q;
535  q.prepare( QLatin1String("UPDATE post SET author=?, title=?, content=?, text_more=?, c_time=?, m_time=?,\
536  is_private=?, is_comment_allowed=?, is_trackback_allowed=?, link=?, perma_link=?, summary=?,\
537  slug=?, tags=?, status=? WHERE postid=? AND blog_id=?" ) );
538  q.addBindValue( post.author() );
539  q.addBindValue( post.title() );
540  q.addBindValue( post.content() );
541  q.addBindValue( post.additionalContent() );
542  q.addBindValue( post.creationDateTime().toString( KDateTime::ISODate ) );
543  q.addBindValue( post.modificationDateTime().toString( KDateTime::ISODate ) );
544  q.addBindValue( post.isPrivate() );
545  q.addBindValue( post.isCommentAllowed() );
546  q.addBindValue( post.isTrackBackAllowed() );
547  q.addBindValue( post.link().url() );
548  q.addBindValue( post.permaLink().url() );
549  q.addBindValue( post.summary() );
550  q.addBindValue( post.slug() );
551  q.addBindValue( post.tags().join(QLatin1String(",")) );
552  q.addBindValue( post.status() );
553 
554  q.addBindValue( post.postId() );
555  q.addBindValue( blog_id );
556 
557  if ( !q.exec() ) {
558  d->mLastErrorText = q.lastError().text();
559  kDebug()<<"Modifying post failed, SQL ERROR: "<< d->mLastErrorText;
560  return false;
561  }
562 
564  QSqlQuery qd;
565  qd.prepare( QLatin1String("DELETE FROM post_cat WHERE postId=? AND blogId=(SELECT blogid FROM blog where id=?)" ));
566  qd.addBindValue(post.postId());
567  qd.addBindValue(blog_id);
568  if ( !qd.exec() ) {
569  d->mLastErrorText = qd.lastError().text();
570  kDebug() << "Cannot delete previous categories.";
571  }
572 
574 
575  int cat_count = post.categories().count();
576  if( cat_count > 0 ) {
577 // kDebug()<< "Adding "<<cat_count<<" category to post.";
578  QSqlQuery q2;
579  q2.prepare( QLatin1String("INSERT OR REPLACE INTO post_cat (blogId, postId, categoryId)\
580  VALUES((SELECT blogid FROM blog where id=?), ?, \
581  (SELECT categoryId FROM category WHERE name = ? AND blog_id= ?))" ) );
582  for ( int i = 0; i < cat_count; ++i ) {
583  q2.addBindValue(blog_id);
584  q2.addBindValue(post.postId());
585  q2.addBindValue(post.categories()[i]);
586  q2.addBindValue(blog_id);
587  if ( !q2.exec() ) {
588  d->mLastErrorText = q2.lastError().text();
589  kDebug() << "Cannot add one of categories to Post, SQL Error: " << q2.lastError().text();
590  }
591  }
592  }
593 
594  return true;
595 }
596 
597 bool DBMan::removePost( int id )
598 {
599  QSqlQuery q;
600  q.prepare( QLatin1String("DELETE FROM post WHERE id=?" ));
601  q.addBindValue( id );
602  bool res = q.exec();
603  if ( !res ) {
604  d->mLastErrorText = q.lastError().text();
605  kDebug() << d->mLastErrorText;
606  }
607  return res;
608 }
609 
610 bool DBMan::removePost( int blog_id, const QString &postId)
611 {
612  QSqlQuery q;
613  q.prepare( QLatin1String("DELETE FROM post WHERE blog_id=? AND postId=?" ));
614  q.addBindValue( blog_id );
615  q.addBindValue( postId );
616  bool res = q.exec();
617  if ( !res ) {
618  d->mLastErrorText = q.lastError().text();
619  kDebug() << d->mLastErrorText;
620  }
621  return res;
622 }
623 
624 bool DBMan::clearPosts( int blog_id )
625 {
626  QSqlQuery q;
627  q.prepare( QLatin1String("DELETE FROM post WHERE blog_id=?") );
628  q.addBindValue( blog_id );
629  bool res = q.exec();
630  if ( !res ) {
631  d->mLastErrorText = q.lastError().text();
632  kDebug() << q.lastError().text();
633  }
634  return res;
635 }
636 
637 int DBMan::addCategory( const QString &name, const QString &description, const QString &htmlUrl,
638  const QString &rssUrl, const QString &categoryId, const QString &parentId, int blog_id )
639 {
640  QSqlQuery q;
641  q.prepare( QLatin1String("INSERT OR REPLACE INTO category (name, description, htmlUrl, rssUrl, categoryId, parentId, blog_id)\
642  VALUES(?, ?, ?, ?, ?, ?, ?)" ) );
643  q.addBindValue( name );
644  q.addBindValue( description );
645  q.addBindValue( htmlUrl );
646  q.addBindValue( rssUrl );
647  q.addBindValue( categoryId );
648  q.addBindValue( parentId );
649  q.addBindValue( blog_id );
650 
651  if ( q.exec() )
652  return q.lastInsertId().toInt();
653  else {
654  d->mLastErrorText = q.lastError().text();
655  return -1;
656  }
657 }
658 
659 bool DBMan::clearCategories( int blog_id )
660 {
661  QSqlQuery q;
662  q.prepare( QLatin1String("DELETE FROM category WHERE blog_id=?") );
663  q.addBindValue( blog_id );
664  bool res = q.exec();
665  if ( !res ) {
666  d->mLastErrorText = q.lastError().text();
667  kDebug() << q.lastError().text();
668  }
669  return res;
670 }
671 
672 int DBMan::addFile( const QString& name, int blog_id, bool isUploaded, const QString& localUrl, const QString& remoteUrl )
673 // int DBMan::addFile( const QString &name, int blog_id, bool isLocal, const QString &localUrl, const QString &remoteUrl )
674 {
675  QSqlQuery q;
676 // q.prepare("INSERT INTO file(name, blog_id, is_uploaded, local_url, remote_url) VALUES(?, ?, ?, ?, ?)");
677  q.prepare( QLatin1String("INSERT INTO file(name, blog_id, is_local, local_url, remote_url) VALUES(?, ?, ?, ?, ?)") );
678  q.addBindValue( name );
679  q.addBindValue( blog_id );
680  q.addBindValue( isUploaded );
681 // q.addBindValue( isLocal );
682  q.addBindValue( localUrl );
683  q.addBindValue( remoteUrl );
684 
685  if ( q.exec() )
686  return q.lastInsertId().toInt();
687  else {
688  d->mLastErrorText = q.lastError().text();
689  return -1;
690  }
691 }
692 
693 int DBMan::addFile(const BilboMedia & file)
694 {
695  QSqlQuery q;
696  q.prepare( QLatin1String("INSERT INTO file(name, blog_id, is_local, local_url, remote_url) VALUES(?, ?, ?, ?, ?)") );
697  q.addBindValue( file.name() );
698  q.addBindValue( file.blogId() );
699  q.addBindValue( file.isUploaded() );
700  q.addBindValue( file.localUrl() );
701  q.addBindValue( file.remoteUrl() );
702 
703  if ( q.exec() )
704  return q.lastInsertId().toInt();
705  else {
706  d->mLastErrorText = q.lastError().text();
707  return -1;
708  }
709 }
710 
711 bool DBMan::removeFile( int fileid )
712 {
713  QSqlQuery q;
714  q.prepare( QLatin1String("DELETE FROM file WHERE fileid=?") );
715  q.addBindValue( fileid );
716  bool res = q.exec();
717  if ( !res ) {
718  d->mLastErrorText = q.lastError().text();
719  kDebug() << q.lastError().text();
720  }
721  return res;
722 }
723 
724 bool DBMan::clearFiles( int blog_id )
725 {
726  QSqlQuery q;
727  q.prepare( QLatin1String("DELETE FROM file WHERE blog_id=?") );
728  q.addBindValue( blog_id );
729  bool res = q.exec();
730  if ( !res ) {
731  d->mLastErrorText = q.lastError().text();
732  kDebug() << q.lastError().text();
733  }
734  return res;
735 }
736 
737 int DBMan::saveLocalEntry( const BilboPost& post, int blog_id )
738 {
739  return saveTemp_LocalEntry(post, blog_id, Local);
740 }
741 
742 int DBMan::saveTempEntry( const BilboPost& post, int blog_id )
743 {
744  return saveTemp_LocalEntry(post, blog_id, Temp);
745 }
746 
747 int DBMan::saveTemp_LocalEntry( const BilboPost& basePost, int blog_id, LocalPostState state )
748 {
749  kDebug();
750  QSqlQuery q;
751  BilboPost post = basePost;
752 // kDebug()<<"postId: "<<post.postId();
753  QString postTable, postCatTable;
754  if(state == Local) {
755  postTable = QLatin1String("local_post");
756  postCatTable = QLatin1String("local_post_cat");
757  } else {
758  postTable = QLatin1String("temp_post");
759  postCatTable = QLatin1String("temp_post_cat");
760  }
761  int localId = post.localId();
762 // if(post.status() == KBlog::BlogPost::New) {///Post is new!
763 // kDebug()<<"Post is new!";
764  if(post.localId() == -1){
766  kDebug()<<"Add new post to temp_post";
767  q.prepare( QLatin1String("INSERT OR REPLACE INTO ")+ postTable +QLatin1String(" (postid, blog_id,\
768  author, title, content, text_more, c_time, m_time, is_private, is_comment_allowed,\
769  is_trackback_allowed, link, perma_link, summary, slug, tags, status)\
770  VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ));
771 // q.addBindValue( post.id() == -1 ? QVariant(QVariant::Int) : post.id() );
772  q.addBindValue( post.postId() );
773  q.addBindValue( blog_id );
774  q.addBindValue( post.author() );
775  q.addBindValue( post.title() );
776  q.addBindValue( post.content() );
777  q.addBindValue( post.additionalContent() );
778  q.addBindValue( post.creationDateTime().toString( KDateTime::ISODate ) );
779  q.addBindValue( post.creationDateTime().toString( KDateTime::ISODate ) );
780  q.addBindValue( post.isPrivate() );
781  q.addBindValue( post.isCommentAllowed() );
782  q.addBindValue( post.isTrackBackAllowed() );
783  q.addBindValue( post.link().url() );
784  q.addBindValue( post.permaLink().url() );
785  q.addBindValue( post.summary() );
786  q.addBindValue( post.slug() );
787  q.addBindValue( post.tags().join(QLatin1String(",")) );
788  q.addBindValue( post.status() );
789 
790  if ( q.exec() ) {
791  localId = q.lastInsertId().toInt();
792  } else {
793  d->mLastErrorText = q.lastError().text();
794  kDebug() << "Cannot Add new local post to database!\n\tSQL Error: " << q.lastError().text();
795  return -1;
796  }
797  } else {
799  kDebug()<<"Update post, with id!";
800  q.prepare( QLatin1String("UPDATE ")+ postTable +QLatin1String(" SET postid=?, blog_id=?,\
801  author=?, title=?, content=?, text_more=?, c_time=?, m_time=?, is_private=?, is_comment_allowed=?,\
802  is_trackback_allowed=?, link=?, perma_link=?, summary=?, slug=?, tags=?, status=?\
803  WHERE local_id=?" ));
804 // q.addBindValue( post.id() == -1 ? QVariant(QVariant::Int) : post.id() );
805  q.addBindValue( post.postId() );
806  q.addBindValue( blog_id );
807  q.addBindValue( post.author() );
808  q.addBindValue( post.title() );
809  q.addBindValue( post.content() );
810  q.addBindValue( post.additionalContent() );
811  q.addBindValue( post.creationDateTime().toString( KDateTime::ISODate ) );
812  q.addBindValue( post.creationDateTime().toString( KDateTime::ISODate ) );
813  q.addBindValue( post.isPrivate() );
814  q.addBindValue( post.isCommentAllowed() );
815  q.addBindValue( post.isTrackBackAllowed() );
816  q.addBindValue( post.link().url() );
817  q.addBindValue( post.permaLink().url() );
818  q.addBindValue( post.summary() );
819  q.addBindValue( post.slug() );
820  q.addBindValue( post.tags().join(QLatin1String(",")) );
821  q.addBindValue( post.status() );
822  q.addBindValue( post.localId() );
823 
824  if ( !q.exec() ) {
825  d->mLastErrorText = q.lastError().text();
826  kDebug() << "Cannot Add new local post to database!\n\tSQL Error: " << q.lastError().text();
827  return -1;
828  }
829  }
830  /*} else {///Post is already created at "Post" table and has a valid id, postId and blog_id. So, local_id is useless here
831  kDebug()<<"Post is already created at \"Post\" table and has a valid id, postId and blog_id. So, local_id is useless here";
832  q.prepare( "INSERT OR REPLACE INTO "+ postTable +" (id, postid, blog_id, author, title,\
833  content, text_more, c_time, m_time, is_private,\
834  is_comment_allowed, is_trackback_allowed, link, perma_link, summary, slug, tags, status)\
835  VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" );
836  q.addBindValue( post.id() );
837  q.addBindValue( post.postId() );
838  q.addBindValue( blog_id );
839  q.addBindValue( post.author() );
840  q.addBindValue( post.title() );
841  q.addBindValue( post.content() );
842  q.addBindValue( post.additionalContent() );
843  q.addBindValue( post.creationDateTime().toString( KDateTime::ISODate ) );
844  q.addBindValue( post.creationDateTime().toString( KDateTime::ISODate ) );
845  q.addBindValue( post.isPrivate() );
846  q.addBindValue( post.isCommentAllowed() );
847  q.addBindValue( post.isTrackBackAllowed() );
848  q.addBindValue( post.link().url() );
849  q.addBindValue( post.permaLink().url() );
850  q.addBindValue( post.summary() );
851  q.addBindValue( post.slug() );
852  q.addBindValue( post.tags().join(QString(',')) );
853  q.addBindValue( post.status() );
854 
855  if ( q.exec() ) {
856  postId = post.id();
857  localId = q.lastInsertId().toInt();
858  } else {
859  d->mLastErrorText = q.lastError().text();
860  kDebug() << "Cannot Add or Edit local post to database!\n\tSQL Error: " << q.lastError().text();
861  return -1;
862  }
863  }*/
864 
866  QSqlQuery qd;
867  qd.prepare( QLatin1String("DELETE FROM ") + postCatTable + QLatin1String(" WHERE local_id=?") );
868  qd.addBindValue( localId );
869  if ( !qd.exec() ) {
870  d->mLastErrorText = q.lastError().text();
871  kDebug() << "Cannot delete previouse categories.";
872  }
873 
876  int cat_count = post.categories().count();
877  if( cat_count > 0 ) {
878  //kDebug()<< "Adding "<<cat_count<<" category to post.";
879  QSqlQuery q2;
880  q2.prepare( QLatin1String("INSERT OR REPLACE INTO ") + postCatTable + QLatin1String(" (local_id, categoryId)\
881  VALUES(?, (SELECT categoryId FROM category WHERE name = ? AND blog_id= ?))" ) );
882  for ( int i = 0; i < cat_count; ++i ) {
883  q2.addBindValue(localId);
884  q2.addBindValue(post.categories()[i]);
885  q2.addBindValue(blog_id);
886  if ( !q2.exec() ) {
887  d->mLastErrorText = q.lastError().text();
888  kDebug() << "Cannot add one of categories to Post, SQL Error: " << q2.lastError().text();
889  }
890 // kDebug()<<"category "<<post.categories()[i] <<" added.";
891  }
892  }
893  return localId;
894 }
895 
896 bool DBMan::removeLocalEntry( const BilboPost &post )
897 {
898  kDebug();
899  QSqlQuery q;
900  q.prepare( QLatin1String("DELETE FROM local_post WHERE local_id=?") );
901  q.addBindValue( post.localId() );
902  bool res = q.exec();
903  if ( !res ) {
904  d->mLastErrorText = q.lastError().text();
905  kDebug() << d->mLastErrorText;
906  }
907  return res;
908 }
909 
910 bool DBMan::removeLocalEntry( int local_id )
911 {
912  kDebug();
913  QSqlQuery q;
914  q.prepare( QLatin1String("DELETE FROM local_post WHERE local_id=?") );
915  q.addBindValue( local_id );
916  bool res = q.exec();
917  if ( !res ) {
918  d->mLastErrorText = q.lastError().text();
919  kDebug() << d->mLastErrorText;
920  }
921  return res;
922 }
923 
924 bool DBMan::removeTempEntry( const BilboPost &post )
925 {
926  kDebug();
927  QSqlQuery q;
928  q.prepare( QLatin1String("DELETE FROM temp_post WHERE local_id=?") );
929  q.addBindValue( post.localId() );
930  bool res = q.exec();
931  if ( !res ) {
932  d->mLastErrorText = q.lastError().text();
933  kDebug() << q.lastError().text();
934  }
935  kDebug()<<"Id: "<<post.id()<<"\tStatus: "<<post.status();
936  return res;
937 }
938 
939 bool DBMan::clearTempEntries()
940 {
941  kDebug();
942  QSqlQuery q;
943  bool res = q.exec( QLatin1String("DELETE FROM temp_post") );
944  if ( !res ) {
945  d->mLastErrorText = q.lastError().text();
946  kDebug() << q.lastError().text();
947  }
948  return res;
949 }
950 
951 QMap<QString, QString> DBMan::getAuthData(int blog_id)
952 {
953  kDebug() << blog_id;
954  QSqlQuery q;
955  q.prepare( QLatin1String("SELECT key, value FROM auth_data WHERE blog_id = ?") );
956  q.addBindValue( blog_id );
957  if ( !q.exec() ) {
958  d->mLastErrorText = q.lastError().text();
959  kDebug() << q.lastError().text();
960  return QMap<QString, QString>();
961  }
962 
963  QMap<QString, QString> result;
964  while ( q.next() ) {
965  result[q.value(0).toString() ] = q.value(1).toString();
966  }
967 
968  kDebug() << blog_id << result;
969  return result;
970 }
971 
972 bool DBMan::saveAuthData( const QMap<QString, QString> &authData, int blog_id )
973 {
974  kDebug() << blog_id;
975  QSqlQuery q;
976  q.prepare( QLatin1String("INSERT OR REPLACE INTO auth_data (blog_id, key, value) VALUES (?, ?, ?)") );
977  QMap<QString, QString>::ConstIterator iter, end = authData.constEnd();
978  QList<QVariant> ids, keys, values;
979  for ( iter = authData.constBegin(); iter != end; ++iter ) {
980  ids << blog_id;
981  keys << iter.key();
982  values << iter.value();
983  }
984  q.addBindValue( ids );
985  q.addBindValue( keys );
986  q.addBindValue( values );
987  const bool res = q.execBatch();
988  if ( !res ) {
989  d->mLastErrorText = q.lastError().text();
990  kDebug() << q.lastError().text();
991  }
992  return res;
993 }
994 
995 bool DBMan::clearAuthData( int blog_id )
996 {
997  kDebug() << blog_id;
998  QSqlQuery q;
999  q.prepare( QLatin1String("DELETE FROM auth_data WHERE blog_id = ?") );
1000  q.addBindValue( blog_id );
1001  const bool res = q.exec();
1002  if ( !res ) {
1003  d->mLastErrorText = q.lastError().text();
1004  kDebug() << q.lastError().text();
1005  }
1006  return res;
1007 }
1008 
1009 
1010 
1011 BilboBlog *DBMan::blog(int blog_id)
1012 {
1013  return blogList().value(blog_id);
1014 }
1015 
1016 QList< BilboBlog *> DBMan::listBlogs()
1017 {
1018  QList<BilboBlog *> list;
1019  QSqlQuery q;
1020  if (q.exec( QLatin1String("SELECT id, blogid, blog_url, username, style_url, api_type, title,\
1021  direction, local_directory, password FROM blog") ) ) {
1022  while ( q.next() ) {
1023  BilboBlog *tmp = new BilboBlog;
1024  tmp->setId( q.value( 0 ).toInt() );
1025  tmp->setBlogId( q.value( 1 ).toString() );
1026  tmp->setUrl( QUrl( q.value( 2 ).toString() ) );
1027  tmp->setUsername( q.value( 3 ).toString() );
1028  tmp->setBlogUrl( q.value( 4 ).toString() );
1029  tmp->setApi(( BilboBlog::ApiType )q.value( 5 ).toInt() );
1030  tmp->setTitle( q.value( 6 ).toString() );
1031  tmp->setDirection(( Qt::LayoutDirection )q.value( 7 ).toInt() );
1032  tmp->setLocalDirectory( q.value( 8 ).toString() );
1033  if( d->useWallet ) {
1034  QString buffer;
1035  if ( d->mWallet && d->mWallet->readPassword( tmp->url().url() + QLatin1Char('_') + tmp->username() , buffer )
1036  == 0 && !buffer.isEmpty() ) {
1037  tmp->setPassword( buffer );
1038  kDebug() << "Password loaded from kde wallet.";
1039  }
1040  } else {
1041  tmp->setPassword( q.value( 9 ).toString() );
1042  }
1043  list.append( tmp );
1044  }
1045  } else {
1046  d->mLastErrorText = q.lastError().text();
1047  }
1048  return list;
1049 }
1050 
1051 QMap< QString, int > DBMan::listBlogsTitle()
1052 {
1053  QMap< QString, int > list;
1054  QSqlQuery q;
1055  if( q.exec( QLatin1String("SELECT title, id FROM blog") ) ) {
1056  while ( q.next() ) {
1057  list[q.value( 0 ).toString()] = q.value( 1 ).toInt();
1058  }
1059  } else {
1060  d->mLastErrorText = q.lastError().text();
1061  }
1062  return list;
1063 }
1064 
1065 QList< BilboPost* > DBMan::listPosts( int blog_id )
1066 {
1067  QList<BilboPost *> list;
1068  QSqlQuery q;
1069  q.prepare( QLatin1String("SELECT id, postid, author, title, content, c_time, m_time, is_private, is_comment_allowed,\
1070  is_trackback_allowed, link, perma_link, summary, tags, status, text_more, slug\
1071  FROM post WHERE blog_id = ? ORDER BY c_time DESC") );
1072  q.addBindValue( blog_id );
1073  if ( q.exec() ) {
1074  while ( q.next() ) {
1075  BilboPost *tmp = new BilboPost();
1076  tmp->setId( q.value( 0 ).toInt() );
1077  tmp->setAuthor( q.value( 2 ).toString() );
1078  tmp->setPostId( q.value( 1 ).toString() );
1079  tmp->setTitle( q.value( 3 ).toString() );
1080  tmp->setContent( q.value( 4 ).toString() );
1081  tmp->setCreationDateTime( KDateTime::fromString( q.value( 5 ).toString(), KDateTime::ISODate ) );
1082  tmp->setModificationDateTime( KDateTime::fromString( q.value( 6 ).toString(), KDateTime::ISODate ) );
1083  tmp->setPrivate( q.value( 7 ).toBool() );
1084  tmp->setCommentAllowed( q.value( 8 ).toBool() );
1085  tmp->setTrackBackAllowed( q.value( 9 ).toBool() );
1086  tmp->setLink( KUrl( q.value( 10 ).toString() ) );
1087  tmp->setPermaLink( KUrl( q.value( 11 ).toString() ) );
1088  tmp->setSummary( q.value( 12 ).toString() );
1089  tmp->setTags( q.value( 13 ).toString().split( QLatin1Char(','), QString::SkipEmptyParts ) );
1090  tmp->setStatus(( KBlog::BlogPost::Status ) q.value( 14 ).toInt() );
1091  tmp->setAdditionalContent( q.value( 15 ).toString() );
1092  tmp->setSlug( q.value( 16 ).toString() );
1093 
1095  QList<Category> catList;
1096  QSqlQuery q2;
1097  q2.prepare( QLatin1String("SELECT category.name, category.description, category.htmlUrl, category.rssUrl,\
1098  category.categoryId, category.parentId\
1099  FROM category JOIN post_cat ON category.categoryId=post_cat.categoryId\
1100  WHERE post_cat.postId = ? AND post_cat.blogId = (SELECT blogid FROM blog where id=?)" ) );
1101  q2.addBindValue( tmp->postId() );
1102  q2.addBindValue( blog_id );
1103  if ( q2.exec() ) {
1104  while ( q2.next() ) {
1105  Category cat;
1106  cat.blog_id = blog_id;
1107  cat.name = q2.value( 0 ).toString();
1108  cat.description = q2.value( 1 ).toString();
1109  cat.htmlUrl = q2.value( 2 ).toString();
1110  cat.rssUrl = q2.value( 3 ).toString();
1111  cat.categoryId = q2.value( 4 ).toString();
1112  cat.parentId = q2.value( 5 ).toString();
1113  catList.append( cat );
1114  }
1115  } else {
1116  d->mLastErrorText = q2.lastError().text();
1117  }
1118  tmp->setCategoryList( catList );
1119  list.append( tmp );
1120  }
1121  } else {
1122  d->mLastErrorText = q.lastError().text();
1123  kDebug() << "Cannot get list of posts for blog with id " << blog_id << "error: "<< d->mLastErrorText;
1124  }
1125  return list;
1126 }
1127 
1128 BilboPost DBMan::getPostInfo( int post_id )
1129 {
1130  QSqlQuery q;
1131  BilboPost tmp;
1132  q.prepare( QLatin1String("SELECT id, postid, author, title, content, c_time, m_time, is_private, is_comment_allowed,\
1133  is_trackback_allowed, link, perma_link, summary, tags, status, blog_id, text_more, slug\
1134  FROM post WHERE id = ?") );
1135  q.addBindValue( post_id );
1136  if ( q.exec() ) {
1137  if ( q.next() ) {
1138  tmp.setId( q.value( 0 ).toInt() );
1139  tmp.setAuthor( q.value( 2 ).toString() );
1140  tmp.setPostId( q.value( 1 ).toString() );
1141  tmp.setTitle( q.value( 3 ).toString() );
1142  tmp.setContent( q.value( 4 ).toString() );
1143  tmp.setCreationDateTime( KDateTime::fromString( q.value( 5 ).toString(), KDateTime::ISODate ) );
1144  tmp.setModificationDateTime( KDateTime::fromString( q.value( 6 ).toString(), KDateTime::ISODate ) );
1145  tmp.setPrivate( q.value( 7 ).toBool() );
1146  tmp.setCommentAllowed( q.value( 8 ).toBool() );
1147  tmp.setTrackBackAllowed( q.value( 9 ).toBool() );
1148  QUrl u( q.value( 10 ).toString() );
1149  tmp.setLink( u );
1150  QUrl pu( q.value( 11 ).toString() );
1151  tmp.setPermaLink( pu );
1152  tmp.setSummary( q.value( 12 ).toString() );
1153  tmp.setTags( q.value( 13 ).toString().split( QLatin1Char(','), QString::SkipEmptyParts ) );
1154  tmp.setStatus(( KBlog::BlogPost::Status ) q.value( 14 ).toInt() );
1155  int blog_id = q.value( 15 ).toInt();
1156  tmp.setAdditionalContent( q.value( 16 ).toString() );
1157  tmp.setSlug( q.value( 17 ).toString() );
1158 
1160  QList<Category> catList;
1161  QSqlQuery q2;
1162  q2.prepare( QLatin1String("SELECT category.name, category.description, category.htmlUrl, category.rssUrl,\
1163  category.categoryId, category.parentId, category.blog_id\
1164  FROM category JOIN post_cat ON category.categoryId=post_cat.categoryId\
1165  WHERE post_cat.postId = ? AND post_cat.blogId = (SELECT blogid FROM blog where id=?)") );
1166  q2.addBindValue( tmp.postId() );
1167  q2.addBindValue( blog_id );
1168  if ( q2.exec() ) {
1169  while ( q2.next() ) {
1170  Category cat;
1171  cat.blog_id = q2.value( 6 ).toInt();
1172  cat.name = q2.value( 0 ).toString();
1173  cat.description = q2.value( 1 ).toString();
1174  cat.htmlUrl = q2.value( 2 ).toString();
1175  cat.rssUrl = q2.value( 3 ).toString();
1176  cat.categoryId = q2.value( 4 ).toString();
1177  cat.parentId = q2.value( 5 ).toString();
1178  catList.append( cat );
1179  }
1180  } else {
1181  d->mLastErrorText = q2.lastError().text();
1182  }
1183  tmp.setCategoryList( catList );
1184  } else {
1185  d->mLastErrorText = i18n( "There is no post with the requested ID" );
1186  kDebug() << "There isn't any post with id: " << post_id;
1187  tmp.setStatus(KBlog::BlogPost::Error);
1188  }
1189  } else {
1190  d->mLastErrorText = q.lastError().text();
1191  kDebug() << "Cannot get post with id " << post_id;
1192  tmp.setStatus(KBlog::BlogPost::Error);
1193  }
1194 
1195  return tmp;
1196 }
1197 
1198 QMap< int, QString > DBMan::listPostsTitle( int blog_id )
1199 {
1200  QMap< int, QString >list;
1201  QSqlQuery q;
1202  q.prepare( QLatin1String("SELECT title, id FROM post WHERE blog_id = ? ORDER BY c_time DESC") );
1203  q.addBindValue( blog_id );
1204  if ( q.exec() ) {
1205  while ( q.next() ) {
1206  list.insert( q.value( 1 ).toInt(), q.value( 0 ).toString() );
1207  }
1208  } else {
1209  d->mLastErrorText = q.lastError().text();
1210  kDebug() << "Cannot get list of posts for blog with id " << blog_id;
1211  }
1212  return list;
1213 }
1214 
1215 QList<QVariantMap> DBMan::listPostsInfo( int blog_id )
1216 {
1217  QList<QVariantMap> list;
1218  QSqlQuery q;
1219  q.prepare( QLatin1String("SELECT title, id, c_time, is_private FROM post WHERE blog_id = ? ORDER BY c_time DESC") );
1220  q.addBindValue( blog_id );
1221  if ( q.exec() ) {
1222  while ( q.next() ) {
1223  QVariantMap entry;
1224  entry[ QLatin1String("title") ] = q.value( 0 ).toString();
1225  entry[ QLatin1String("id") ] = q.value( 1 ).toInt();
1226  entry[ QLatin1String("c_time") ] = KDateTime::fromString( q.value( 2 ).toString() ).dateTime();
1227  entry[ QLatin1String("is_private") ] = q.value( 3 ).toBool();
1228  list.append(entry);
1229  }
1230  } else {
1231  d->mLastErrorText = q.lastError().text();
1232  kDebug() << "Cannot get list of posts for blog with id " << blog_id;
1233  }
1234  return list;
1235 }
1236 
1237 QMap< QString, int > DBMan::listCategoriesName( int blog_id )
1238 {
1239  QMap< QString, int > list;
1240  QSqlQuery q;
1241  q.prepare( QLatin1String("SELECT name, catid FROM category WHERE blog_id = ?") );
1242  q.addBindValue( blog_id );
1243  if ( q.exec() ) {
1244  while ( q.next() ) {
1245  list[q.value( 0 ).toString()] = q.value( 1 ).toInt();
1246  }
1247  } else {
1248  d->mLastErrorText = q.lastError().text();
1249  kDebug() << "Cannot get list of categories for blog with id " << blog_id;
1250  }
1251  return list;
1252 }
1253 
1254 QList< Category > DBMan::listCategories( int blog_id )
1255 {
1256  QList< Category > list;
1257  QSqlQuery q;
1258  q.prepare( QLatin1String("SELECT catid, name, description, htmlUrl, rssUrl, categoryId, parentId FROM category\
1259  WHERE blog_id = ?") );
1260  q.addBindValue( blog_id );
1261  if ( q.exec() ) {
1262  while ( q.next() ) {
1263  Category c;
1264  c.blog_id = blog_id;
1265  c.id = q.value( 0 ).toInt();
1266  c.name = q.value( 1 ).toString();
1267  c.description = q.value( 2 ).toString();
1268  c.htmlUrl = q.value( 3 ).toString();
1269  c.rssUrl = q.value( 4 ).toString();
1270  c.categoryId = q.value( 5 ).toString();
1271  c.parentId = q.value( 6 ).toString();
1272  list.append( c );
1273  }
1274  } else {
1275  d->mLastErrorText = q.lastError().text();
1276  kDebug() << "Cannot get list of categories for blog with id " << blog_id;
1277  }
1278  return list;
1279 }
1280 
1281 QMap< QString, bool > DBMan::listCategoriesId( int blog_id )
1282 {
1283  QMap< QString, bool > list;
1284  QSqlQuery q;
1285  q.prepare( QLatin1String("SELECT categoryId FROM category\
1286  WHERE blog_id = ?") );
1287  q.addBindValue( blog_id );
1288  if ( q.exec() ) {
1289  while ( q.next() ) {
1290  list.insert( q.value( 0 ).toString(), false );
1291  }
1292  } else {
1293  d->mLastErrorText = q.lastError().text();
1294  kDebug() << "Cannot get list of categories for blog with id " << blog_id;
1295  }
1296  return list;
1297 }
1298 
1299 QMap<BilboPost*, int> DBMan::listTempPosts()
1300 {
1301  QMap<BilboPost*, int> list;
1302  QSqlQuery q;
1303  q.prepare( QLatin1String("SELECT local_id, id, postid, blog_id, author, title, content, text_more, c_time,\
1304  m_time, is_private, is_comment_allowed, is_trackback_allowed, link, perma_link, summary, tags, status,\
1305  slug FROM temp_post ORDER BY m_time DESC") );
1306  if ( q.exec() ) {
1307  while ( q.next() ) {
1308  BilboPost *tmp = new BilboPost();
1309  tmp->setLocalId( q.value( 0 ).toInt() );
1310  tmp->setId( q.value( 1 ).toInt() );
1311  tmp->setPostId( q.value( 2 ).toString() );
1312  int blog_id = q.value( 3 ).toInt();
1313  tmp->setAuthor( q.value( 4 ).toString() );
1314  tmp->setTitle( q.value( 5 ).toString() );
1315  tmp->setContent( q.value( 6 ).toString() );
1316  tmp->setCreationDateTime( KDateTime::fromString( q.value( 8 ).toString(), KDateTime::ISODate ) );
1317  tmp->setModificationDateTime( KDateTime::fromString( q.value( 9 ).toString(), KDateTime::ISODate ) );
1318  tmp->setPrivate( q.value( 10 ).toBool() );
1319  tmp->setCommentAllowed( q.value( 11 ).toBool() );
1320  tmp->setTrackBackAllowed( q.value( 12 ).toBool() );
1321  tmp->setLink( KUrl( q.value( 13 ).toString() ) );
1322  tmp->setPermaLink( KUrl( q.value( 14 ).toString() ) );
1323  tmp->setSummary( q.value( 15 ).toString() );
1324  tmp->setTags( q.value( 16 ).toString().split( QLatin1Char(','), QString::SkipEmptyParts ) );
1325  tmp->setStatus(( KBlog::BlogPost::Status ) q.value( 17 ).toInt() );
1326  tmp->setSlug( q.value( 18 ).toString() );
1327 
1329  QList<Category> catList;
1330  QSqlQuery q2;
1331  q2.prepare( QLatin1String("SELECT category.name, category.description, category.htmlUrl, category.rssUrl,\
1332  category.categoryId, category.parentId\
1333  FROM category JOIN temp_post_cat ON category.categoryId=temp_post_cat.categoryId\
1334  WHERE temp_post_cat.local_id = ?") );
1335  q2.addBindValue( tmp->localId() );
1336 // q2.addBindValue( blog_id );
1337  if ( q2.exec() ) {
1338  while ( q2.next() ) {
1339  Category cat;
1340  cat.blog_id = blog_id;
1341  cat.name = q2.value( 0 ).toString();
1342  cat.description = q2.value( 1 ).toString();
1343  cat.htmlUrl = q2.value( 2 ).toString();
1344  cat.rssUrl = q2.value( 3 ).toString();
1345  cat.categoryId = q2.value( 4 ).toString();
1346  cat.parentId = q2.value( 5 ).toString();
1347  catList.append( cat );
1348  }
1349  tmp->setCategoryList( catList );
1350  list.insert( tmp, blog_id);
1351  } else {
1352  d->mLastErrorText = q2.lastError().text();
1353  kDebug()<<"Cannot get categories list of a post. SQL Error: "<< q2.lastError().text();
1354  }
1355  }
1356  } else {
1357  d->mLastErrorText = q.lastError().text();
1358  kDebug() << "Cannot get list of temporary posts, SQL Error: "<< q.lastError().text();
1359  }
1360  return list;
1361 }
1362 
1363 QList<QVariantMap> DBMan::listLocalPosts()
1364 {
1365  kDebug();
1366  QList<QVariantMap> list;
1367  QSqlQuery q;
1368  q.prepare( QLatin1String("SELECT local_post.local_id, local_post.title, local_post.blog_id, blog.title\
1369  FROM local_post LEFT JOIN blog ON local_post.blog_id = blog.id ORDER BY m_time DESC") );
1370  if ( q.exec() ) {
1371  while ( q.next() ) {
1372  QVariantMap entry;
1373  entry[ QLatin1String("local_id") ] = q.value( 0 ).toInt();
1374  entry[ QLatin1String("post_title") ] = q.value( 1 ).toString();
1375  entry[ QLatin1String("blog_id") ] = q.value( 2 ).toInt();
1376  entry[ QLatin1String("blog_title") ] = q.value( 3 ).toString();
1377  list.append(entry);
1378  }
1379  } else {
1380  d->mLastErrorText = q.lastError().text();
1381  kDebug() << "Cannot get list of local posts. SQL Error: "<< q.lastError().text();
1382  }
1383  return list;
1384 }
1385 
1386 BilboPost DBMan::localPost(int local_id)
1387 {
1388  QSqlQuery q;
1389  BilboPost tmp;
1390  q.prepare( QLatin1String("SELECT id, local_id, postid, blog_id, author, title, content, text_more, c_time,\
1391  m_time, is_private, is_comment_allowed, is_trackback_allowed, link, perma_link, summary, tags, status,\
1392  slug FROM local_post WHERE local_id=?") );
1393  q.addBindValue(local_id);
1394  if ( q.exec() ) {
1395  if ( q.next() ) {
1396  tmp.setId( q.value( 0 ).toInt() );
1397  tmp.setLocalId( q.value( 1 ).toInt() );
1398  tmp.setPostId( q.value( 2 ).toString() );
1399  int blog_id = q.value( 3 ).toInt();
1400  tmp.setAuthor( q.value( 4 ).toString() );
1401  tmp.setTitle( q.value( 5 ).toString() );
1402  tmp.setContent( q.value( 6 ).toString() );
1403  tmp.setAdditionalContent( q.value( 7 ).toString() );
1404  tmp.setCreationDateTime( KDateTime::fromString( q.value( 8 ).toString(), KDateTime::ISODate ) );
1405  tmp.setModificationDateTime( KDateTime::fromString( q.value( 9 ).toString(), KDateTime::ISODate ) );
1406  tmp.setPrivate( q.value( 10 ).toBool() );
1407  tmp.setCommentAllowed( q.value( 11 ).toBool() );
1408  tmp.setTrackBackAllowed( q.value( 12 ).toBool() );
1409  tmp.setLink( KUrl( q.value( 13 ).toString() ) );
1410  tmp.setPermaLink( KUrl( q.value( 14 ).toString() ) );
1411  tmp.setSummary( q.value( 15 ).toString() );
1412  tmp.setTags( q.value( 16 ).toString().split( QLatin1Char(','), QString::SkipEmptyParts ) );
1413  tmp.setStatus(( KBlog::BlogPost::Status ) q.value( 17 ).toInt() );
1414  tmp.setSlug( q.value( 18 ).toString() );
1415 
1417  QList<Category> catList;
1418  QSqlQuery q2;
1419  q2.prepare( QLatin1String("SELECT category.name, category.description, category.htmlUrl, category.rssUrl,\
1420  category.categoryId, category.parentId\
1421  FROM category JOIN local_post_cat ON category.categoryId=local_post_cat.categoryId\
1422  WHERE local_post_cat.local_id = ?") );
1423  q2.addBindValue( local_id );
1424  if ( q2.exec() ) {
1425  while ( q2.next() ) {
1426  Category cat;
1427  cat.blog_id = blog_id;
1428  cat.name = q2.value( 0 ).toString();
1429  cat.description = q2.value( 1 ).toString();
1430  cat.htmlUrl = q2.value( 2 ).toString();
1431  cat.rssUrl = q2.value( 3 ).toString();
1432  cat.categoryId = q2.value( 4 ).toString();
1433  cat.parentId = q2.value( 5 ).toString();
1434  catList.append( cat );
1435  }
1436  tmp.setCategoryList( catList );
1437  } else {
1438  d->mLastErrorText = q2.lastError().text();
1439  kDebug()<<"Cannot get categories list of local post. SQL Error: "<< q2.lastError().text();
1440  }
1441  } else {
1442  d->mLastErrorText = i18n( "There is no local post with the requested ID " );
1443  kDebug()<<"there isn't any local post with local_id "<<local_id;
1444  }
1445  } else {
1446  d->mLastErrorText = q.lastError().text();
1447  kDebug() << "Cannot get local post. SQL Error: "<< q.lastError().text();
1448  }
1449  return tmp;
1450 }
DBMan::listPosts
QList< BilboPost * > listPosts(int blog_id)
Definition: dbman.cpp:1065
DBMan::clearCategories
bool clearCategories(int blog_id)
Definition: dbman.cpp:659
BilboPost::localId
int localId() const
Definition: bilbopost.cpp:97
BilboBlog::setApi
void setApi(const ApiType)
Definition: bilboblog.cpp:180
BilboPost::setAuthor
void setAuthor(const QString &)
Definition: bilbopost.cpp:92
BilboBlog::password
QString password() const
Definition: bilboblog.cpp:155
DBMan::removeLocalEntry
bool removeLocalEntry(const BilboPost &post)
Definition: dbman.cpp:896
Category::rssUrl
QString rssUrl
Definition: category.h:38
Category::description
QString description
Definition: category.h:36
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
DBMan::clearTempEntries
bool clearTempEntries()
Definition: dbman.cpp:939
DBMan::listCategoriesId
QMap< QString, bool > listCategoriesId(int blog_id)
Definition: dbman.cpp:1281
DBMan::lastErrorText
QString lastErrorText() const
Definition: dbman.cpp:110
BilboBlog::localDirectory
QString localDirectory() const
Definition: bilboblog.cpp:237
QSqlQuery::exec
bool exec(const QString &query)
BilboPost::setLocalId
void setLocalId(const int)
Definition: bilbopost.cpp:102
QMap::constBegin
const_iterator constBegin() const
BilboBlog::setTitle
void setTitle(const QString &)
Definition: bilboblog.cpp:170
QList::at
const T & at(int i) const
QMap< int, BilboBlog * >
QSqlDatabase::addDatabase
QSqlDatabase addDatabase(const QString &type, const QString &connectionName)
DBMan::saveTempEntry
int saveTempEntry(const BilboPost &post, int blog_id)
Definition: dbman.cpp:742
DBMan::addFile
int addFile()
BilboBlog::title
QString title() const
Definition: bilboblog.cpp:165
DBMan::saveAuthData
bool saveAuthData(const QMap< QString, QString > &authData, int blog_id)
Definition: dbman.cpp:972
DBMan::self
static DBMan * self()
Retrieve the instance of DataBase Manager.
Definition: dbman.cpp:117
QFile::exists
bool exists() const
BilboMedia::name
QString name() const
Definition: bilbomedia.cpp:125
BilboPost
Definition of a blog post! it's implemented to decrease dependency to KBlog :)
Definition: bilbopost.h:41
Category::htmlUrl
QString htmlUrl
Definition: category.h:37
DBMan::listLocalPosts
QList< QVariantMap > listLocalPosts()
Returns list of locally saved posts.
Definition: dbman.cpp:1363
BilboMedia::isUploaded
bool isUploaded() const
Definition: bilbomedia.cpp:85
DBMan::blog
BilboBlog * blog(int blog_id)
QString as Title, and int as blog_id.
Definition: dbman.cpp:1011
QSqlDatabase
bilbopost.h
Category::blog_id
int blog_id
Definition: category.h:42
BilboBlog::blogid
QString blogid() const
Definition: bilboblog.cpp:135
DBMan::saveLocalEntry
int saveLocalEntry(const BilboPost &post, int blog_id)
Definition: dbman.cpp:737
DBMan::listPostsTitle
QMap< int, QString > listPostsTitle(int blog_id)
Definition: dbman.cpp:1198
BilboBlog::setId
void setId(const int)
Definition: bilboblog.cpp:222
QSqlQuery::prepare
bool prepare(const QString &query)
BilboBlog
Blog definition class!
Definition: bilboblog.h:40
QString::number
QString number(int n, int base)
QList::count
int count(const T &value) const
Category::id
int id
Definition: category.h:41
BilboBlog::setDirection
void setDirection(const Qt::LayoutDirection)
Definition: bilboblog.cpp:232
QList::append
void append(const T &value)
DBMan::getAuthData
QMap< QString, QString > getAuthData(int blog_id)
Auth Data:
Definition: dbman.cpp:951
QVariant::toUInt
uint toUInt(bool *ok) const
DBMan::addCategory
int addCategory(const QString &name, const QString &description, const QString &htmlUrl, const QString &rssUrl, const QString &categoryId, const QString &parentId, int blog_id)
Category:
Definition: dbman.cpp:637
BilboBlog::setPassword
void setPassword(const QString &)
Definition: bilboblog.cpp:160
QVariant::toInt
int toInt(bool *ok) const
QSqlQuery::value
QVariant value(int index) const
CONF_DB
#define CONF_DB
Definition: constants.h:39
BilboBlog::setUsername
void setUsername(const QString &)
Definition: bilboblog.cpp:150
BilboBlog::username
QString username() const
Definition: bilboblog.cpp:145
QSqlQuery::execBatch
bool execBatch(BatchExecutionMode mode)
QString::isEmpty
bool isEmpty() const
QMap::constEnd
const_iterator constEnd() const
QSqlQuery
QSqlQuery::next
bool next()
DBMan::DBMan
DBMan()
Definition: dbman.cpp:61
DBMan::listCategories
QList< Category > listCategories(int blog_id)
Definition: dbman.cpp:1254
DBMan::listBlogsTitle
QMap< QString, int > listBlogsTitle()
(BEGIN) Data retrieveing Functions:
Definition: dbman.cpp:1051
DBMan::localPost
BilboPost localPost(int local_id)
Definition: dbman.cpp:1386
QString
QList
DBMan
DataBase Manager class.
Definition: dbman.h:45
DBMan::clearPosts
bool clearPosts(int blog_id)
Definition: dbman.cpp:624
BilboPost::author
QString author() const
Definition: bilbopost.cpp:77
BilboPost::setId
void setId(const int)
Definition: bilbopost.cpp:82
bilboblog.h
BilboMedia::blogId
int blogId() const
Definition: bilbomedia.cpp:64
BilboBlog::setUrl
void setUrl(const KUrl &)
Definition: bilboblog.cpp:130
DBMan::editPost
bool editPost(const BilboPost &post, int blog_id)
Definition: dbman.cpp:531
QUrl
QLatin1Char
DBMan::blogList
const QMap< int, BilboBlog * > & blogList() const
Definition: dbman.cpp:124
BilboMedia::localUrl
KUrl localUrl() const
Definition: bilbomedia.cpp:95
DBMan::removeTempEntry
bool removeTempEntry(const BilboPost &post)
Definition: dbman.cpp:924
Category::categoryId
QString categoryId
Definition: category.h:39
DBMan::listTempPosts
QMap< BilboPost *, int > listTempPosts()
Returns list of temporary posts, e.g.
Definition: dbman.cpp:1299
DBMan::addBlog
int addBlog(const BilboBlog &blog)
END.
Definition: dbman.cpp:373
QMap::key
const Key key(const T &value) const
BilboMedia
Definition: bilbomedia.h:38
DBMan::clearFiles
bool clearFiles(int blog_id)
Definition: dbman.cpp:724
dbman.h
DBMan::addPost
int addPost(const BilboPost &post, int blog_id)
Post:
Definition: dbman.cpp:464
BilboBlog::direction
Qt::LayoutDirection direction() const
Definition: bilboblog.cpp:227
BilboBlog::id
int id() const
Definition: bilboblog.cpp:217
DBMan::listCategoriesName
QMap< QString, int > listCategoriesName(int blog_id)
Definition: dbman.cpp:1237
BilboPost::toString
QString toString() const
Definition: bilbopost.cpp:107
QLatin1String
DBMan::editBlog
bool editBlog(const BilboBlog &blog)
Definition: dbman.cpp:406
DBMan::listPostsInfo
QList< QVariantMap > listPostsInfo(int blog_id)
QString as Title, and int as post_id.
Definition: dbman.cpp:1215
BilboBlog::setLocalDirectory
void setLocalDirectory(const QString &)
Definition: bilboblog.cpp:242
QSqlQuery::lastError
QSqlError lastError() const
QVariant::toBool
bool toBool() const
description
static const char description[]
Definition: main.cpp:33
QString::fromLatin1
QString fromLatin1(const char *str, int size)
QMap::insert
iterator insert(const Key &key, const T &value)
DBMan::getPostInfo
BilboPost getPostInfo(int post_id)
Definition: dbman.cpp:1128
BilboPost::id
int id() const
Definition: bilbopost.cpp:87
QSqlError::text
QString text() const
Category::name
QString name
Definition: category.h:35
QSqlQuery::addBindValue
void addBindValue(const QVariant &val, QFlags< QSql::ParamTypeFlag > paramType)
BilboBlog::ApiType
ApiType
Definition: bilboblog.h:44
DBMan::removeBlog
bool removeBlog(int blog_id)
Definition: dbman.cpp:441
DBMan::removePost
bool removePost(int id)
Definition: dbman.cpp:597
BilboMedia::remoteUrl
KUrl remoteUrl() const
Definition: bilbomedia.cpp:105
QVariant::toString
QString toString() const
BilboBlog::url
KUrl url() const
returns blog xmlrpc Url! For http://bilbo.wordpress.com : it's url() is http://bilbo.wordpress.com/xmlrpc.php and it's blogUrl() is http://bilbo.wordpress.com/
Definition: bilboblog.cpp:125
DBMan::clearAuthData
bool clearAuthData(int blog_id)
Definition: dbman.cpp:995
BilboBlog::blogUrl
QString blogUrl() const
return Blog Actual Url! For http://bilbo.wordpress.com : it's url() is http://bilbo.wordpress.com/xmlrpc.php and it's blogUrl() is http://bilbo.wordpress.com/
Definition: bilboblog.cpp:247
BilboBlog::api
ApiType api() const
Definition: bilboblog.cpp:175
DBMan::~DBMan
~DBMan()
Definition: dbman.cpp:97
QSqlQuery::lastInsertId
QVariant lastInsertId() const
BilboBlog::setBlogId
void setBlogId(const QString &)
Definition: bilboblog.cpp:140
QMap::value
const T value(const Key &key) const
DBMan::removeFile
bool removeFile(int fileid)
Definition: dbman.cpp:711
Category
Blog Category.
Definition: category.h:34
BilboBlog::setBlogUrl
void setBlogUrl(const QString &blogUrl)
Definition: bilboblog.cpp:255
BilboPost::setCategoryList
void setCategoryList(const QList< Category > &list)
Definition: bilbopost.cpp:141
Category::parentId
QString parentId
Definition: category.h:40
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:32:16 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

blogilo

Skip menu "blogilo"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

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