• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Plasma

bookmarksrunner.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2007 Glenn Ergeerts <glenn.ergeerts@telenet.be>
00003  *
00004  *   This program is free software; you can redistribute it and/or modify
00005  *   it under the terms of the GNU Library General Public License as
00006  *   published by the Free Software Foundation; either version 2, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details
00013  *
00014  *   You should have received a copy of the GNU Library General Public
00015  *   License along with this program; if not, write to the
00016  *   Free Software Foundation, Inc.,
00017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018  */
00019 
00020 #include "bookmarksrunner.h"
00021 
00022 #include <QDBusInterface>
00023 #include <QDBusReply>
00024 #include <QList>
00025 #include <QStack>
00026 #include <QSqlQuery>
00027 #include <QDir>
00028 
00029 #include <KIcon>
00030 #include <KBookmarkManager>
00031 #include <KToolInvocation>
00032 #include <KUrl>
00033 #include <KStandardDirs>
00034 #include <KDebug>
00035 #include <KIO/Job>
00036 
00037 BookmarksRunner::BookmarksRunner( QObject* parent, const QVariantList &args )
00038     : Plasma::AbstractRunner(parent, args)
00039 {
00040     Q_UNUSED(args)
00041     setObjectName("Bookmarks");
00042     m_icon = KIcon("bookmarks");
00043     m_bookmarkManager = KBookmarkManager::userBookmarksManager();
00044     m_browser = whichBrowser();
00045     m_dbCacheFile = KStandardDirs::locateLocal("cache", "") + "bookmarkrunnerfirefoxdbfile.sqlite";
00046     addSyntax(Plasma::RunnerSyntax(":q:", i18n("Finds web browser bookmarks matching :q:.")));
00047     addSyntax(Plasma::RunnerSyntax(i18nc("list of all web browser bookmarks", "bookmarks"),
00048                                    i18n("List all web browser bookmarks")));
00049 
00050     connect(this, SIGNAL(prepare()), this, SLOT(prep()));
00051     connect(this, SIGNAL(teardown()), this, SLOT(down()));
00052 
00053     reloadConfiguration();
00054 }
00055 
00056 BookmarksRunner::~BookmarksRunner()
00057 {
00058 }
00059 
00060 void BookmarksRunner::reloadConfiguration()
00061 {
00062     if (QSqlDatabase::isDriverAvailable("QSQLITE")) {
00063         KConfigGroup grp = config();
00064         /* This allows the user to specify a profile database */
00065         m_dbFile = grp.readEntry<QString>("dbfile", "");
00066         if (m_dbFile.isEmpty()) {//Try to get the right database file, the default profile is used
00067             KConfig firefoxProfile(QDir::homePath() + "/.mozilla/firefox/profiles.ini",
00068                                    KConfig::SimpleConfig);
00069             QStringList profilesList = firefoxProfile.groupList();
00070             profilesList = profilesList.filter(QRegExp("^Profile\\d+$"));
00071             int size = profilesList.size();
00072 
00073             QString profilePath;
00074             if (size == 1) {
00075                 // There is only 1 profile so we select it
00076                 KConfigGroup fGrp = firefoxProfile.group(profilesList.first());
00077                 profilePath = fGrp.readEntry("Path", "");
00078             } else {
00079                 // There are multiple profiles, find the default one
00080                 foreach(const QString & profileName, profilesList) {
00081                     KConfigGroup fGrp = firefoxProfile.group(profileName);
00082                     if (fGrp.readEntry<int>("Default", 0)) {
00083                         profilePath = fGrp.readEntry("Path", "");
00084                         break;
00085                     }
00086                 }
00087             }
00088 
00089             if (profilePath.isEmpty()) {
00090               kDebug() << "No default firefox profile found";
00091               m_db = QSqlDatabase();
00092               return;
00093             }
00094 
00095             profilePath.prepend(QString("%1/.mozilla/firefox/").arg(QDir::homePath()));
00096             m_dbFile = profilePath + "/places.sqlite";
00097             grp.writeEntry("dbfile", m_dbFile);
00098         }
00099         m_db = QSqlDatabase::addDatabase("QSQLITE");
00100         m_db.setHostName("localhost");
00101     } else {
00102         kDebug() << "SQLITE driver isn't available";
00103         m_db = QSqlDatabase();
00104     }
00105 }
00106 
00107 void BookmarksRunner::prep()
00108 {
00109     m_browser = whichBrowser();
00110     if (m_browser == Firefox) {
00111         if (m_db.isValid()) {
00112             kDebug() << "Cache file was removed: " << QFile(m_dbCacheFile).remove();
00113             kDebug() << "Database was copyed: " << QFile(m_dbFile).copy(m_dbCacheFile);
00114             m_db.setDatabaseName(m_dbCacheFile);
00115             m_dbOK = m_db.open();
00116             kDebug() << "Database was opened: " << m_dbOK;
00117         }
00118     }
00119 }
00120 
00121 void BookmarksRunner::down()
00122 {
00123     if (m_db.isOpen()) {
00124         m_db.close();
00125         m_dbOK = false;
00126         QFile db_CacheFile(m_dbCacheFile);
00127         if (db_CacheFile.exists()) {
00128             kDebug() << "Cache file was removed: " << db_CacheFile.remove();
00129         }
00130     }
00131 }
00132 
00133 void BookmarksRunner::match(Plasma::RunnerContext &context)
00134 {
00135     const QString term = context.query();
00136     if (term.length() < 3) {
00137         return;
00138     }
00139     bool allBookmarks = term.compare(i18nc("list of all konqueror bookmarks", "bookmarks"),
00140                                      Qt::CaseInsensitive) == 0;
00141     if (m_browser == Konqueror) {
00142         matchKonquerorBookmarks(context, allBookmarks, term);
00143     } else if (m_browser == Firefox) {
00144         matchFirefoxBookmarks(context, allBookmarks, term);
00145     }
00146 }
00147 
00148 KIcon BookmarksRunner::favicon(const KUrl &url)
00149 {
00150     // query the favicons module
00151     QDBusInterface favicon("org.kde.kded", "/modules/favicons", "org.kde.FavIcon");
00152     QDBusReply<QString> reply = favicon.call("iconForUrl", url.url());
00153 
00154     if (!reply.isValid()) {
00155         return KIcon();
00156     }
00157 
00158     // locate the favicon
00159     const QString iconFile = KGlobal::dirs()->findResource("cache",reply.value()+".png");
00160     if(iconFile.isNull()) {
00161         return KIcon();
00162     }
00163 
00164     KIcon icon = KIcon(iconFile);
00165 
00166     return icon;
00167 }
00168 
00169 void BookmarksRunner::matchKonquerorBookmarks(Plasma::RunnerContext& context, bool allBookmarks,
00170                                               const QString& term)
00171 {
00172     KBookmarkGroup bookmarkGroup = m_bookmarkManager->root();
00173 
00174     QList<Plasma::QueryMatch> matches;
00175     QStack<KBookmarkGroup> groups;
00176 
00177     KBookmark bookmark = bookmarkGroup.first();
00178     while (!bookmark.isNull()) {
00179         if (!context.isValid()) {
00180             return;
00181         }
00182 
00183         if (bookmark.isGroup()) { // descend
00184             //kDebug () << "descending into" << bookmark.text();
00185             groups.push(bookmarkGroup);
00186             bookmarkGroup = bookmark.toGroup();
00187             bookmark = bookmarkGroup.first();
00188 
00189             while (bookmark.isNull() && !groups.isEmpty()) {
00190                 if (!context.isValid()) {
00191                     return;
00192                 }
00193 
00194                 bookmark = bookmarkGroup;
00195                 bookmarkGroup = groups.pop();
00196                 bookmark = bookmarkGroup.next(bookmark);
00197             }
00198 
00199             continue;
00200         }
00201 
00202         Plasma::QueryMatch::Type type = Plasma::QueryMatch::NoMatch;
00203         qreal relevance = 0;
00204 
00205         const QString text = bookmark.text();
00206         const QString url = bookmark.url().prettyUrl();
00207         if (text.compare(term, Qt::CaseInsensitive) == 0) {
00208             type = Plasma::QueryMatch::ExactMatch;
00209             relevance = 1.0;
00210         } else if (text.contains(term, Qt::CaseInsensitive)) {
00211             type = Plasma::QueryMatch::PossibleMatch;
00212             relevance = 0.45;
00213         } else if (url.contains(term, Qt::CaseInsensitive)) {
00214             type = Plasma::QueryMatch::PossibleMatch;
00215             relevance = 0.2;
00216         } else if (allBookmarks) {
00217             type = Plasma::QueryMatch::PossibleMatch;
00218             relevance = 0.18;
00219         }
00220 
00221         if (type != Plasma::QueryMatch::NoMatch) {
00222             //kDebug() << "Found bookmark: " << bookmark.text() << " (" << bookmark.url().prettyUrl() << ")";
00223             // getting the favicon is too slow and can easily lead to starving the thread pool out
00224             /*
00225             QIcon icon = getFavicon(bookmark.url());
00226             if (icon.isNull()) {
00227                 match->setIcon(m_icon);
00228             }
00229             else {
00230                 match->setIcon(icon);
00231             }
00232             */
00233             Plasma::QueryMatch match(this);
00234             match.setType(type);
00235             match.setRelevance(relevance);
00236             match.setIcon(m_icon);
00237             match.setText(bookmark.text());
00238             match.setData(bookmark.url().url());
00239             matches << match;
00240         }
00241 
00242         bookmark = bookmarkGroup.next(bookmark);
00243         while (bookmark.isNull() && !groups.isEmpty()) {
00244             if (!context.isValid()) {
00245                 return;
00246             }
00247 
00248             bookmark = bookmarkGroup;
00249             bookmarkGroup = groups.pop();
00250             //kDebug() << "ascending from" << bookmark.text() << "to" << bookmarkGroup.text();
00251             bookmark = bookmarkGroup.next(bookmark);
00252         }
00253     }
00254     context.addMatches(term, matches);
00255 }
00256 
00257 void BookmarksRunner::matchFirefoxBookmarks(Plasma::RunnerContext& context, bool allBookmarks, const QString& term)
00258 {
00259     if (!m_dbOK) {
00260         return;
00261     }
00262 
00263     QList<int> fks;
00264     QHash<int, QString> titles; //index (fk), title
00265     QHash<int, QUrl> urls; //index, url (QUrl in order to go with QVariant)
00266     QHash<int, KIcon> icons; //index, icon
00267     QString tmpTerm = term;
00268     QSqlQuery query;
00269     if (allBookmarks) {
00270         query = QSqlQuery("SELECT moz_bookmarks.fk, moz_bookmarks.title, moz_places.url," \
00271                     "moz_places.favicon_id FROM moz_bookmarks, moz_places WHERE " \
00272                     "moz_bookmarks.type = 1 AND moz_bookmarks.fk = moz_places.id");
00273     } else {
00274         const QString escapedTerm = tmpTerm.replace("'", "\\'");
00275         query = QSqlQuery("SELECT moz_bookmarks.fk, moz_bookmarks.title, moz_places.url," \
00276                         "moz_places.favicon_id FROM moz_bookmarks, moz_places WHERE " \
00277                         "moz_bookmarks.type = 1 AND moz_bookmarks.fk = moz_places.id AND " \
00278                         "(moz_bookmarks.title LIKE  '%" + escapedTerm + "%' or moz_places.url LIKE '%"
00279                         + escapedTerm + "%')");
00280     }
00281     while (query.next()) {
00282         const QString title = query.value(1).toString();
00283         const QUrl url = query.value(2).toString();
00284         //const int favicon_id = query.value(3).toInt();
00285 
00286         int fk = query.value(0).toInt();
00287         fks << fk;
00288         titles.insert(fk, title);
00289         urls.insert(fk, url);
00290         icons.insert(fk, m_icon); //could be changed to use favicon
00291     }
00292 
00293     if (!context.isValid()) {
00294         return;
00295     }
00296 
00297     QList<Plasma::QueryMatch> matches;
00298     foreach (const int& fk, fks) {
00299         Plasma::QueryMatch match(this);
00300         match.setIcon(icons[fk]);
00301         match.setText(titles[fk]);
00302         match.setData(urls[fk]);
00303         matches << match;
00304     }
00305     context.addMatches(term, matches);
00306 }
00307 
00308 BookmarksRunner::Browser BookmarksRunner::whichBrowser()
00309 {
00310     KConfigGroup config(KSharedConfig::openConfig("kdeglobals"), QLatin1String("General") );
00311     QString exec = config.readPathEntry( QLatin1String("BrowserApplication"), QString("") );
00312     kDebug() << exec;
00313     if (exec.contains("firefox", Qt::CaseInsensitive)) {
00314         return Firefox;
00315     } else if (exec.contains("konqueror", Qt::CaseInsensitive)) {
00316         return Konqueror;
00317     } else {
00318         return Default;
00319     }
00320 }
00321 
00322 void BookmarksRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &action)
00323 {
00324     Q_UNUSED(context);
00325     KUrl url = (KUrl)action.data().toString();
00326     //kDebug() << "BookmarksRunner::run opening: " << url.url();
00327     KToolInvocation::invokeBrowser(url.url());
00328 }
00329 
00330 #include "bookmarksrunner.moc"

Plasma

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

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •     Animators
  •     Applets
  •     Engines
  • Solid Modules
  • System Settings
  •   SystemSettingsView
Generated for API Reference by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal