diff --git a/runners/bookmarks/browsers/firefox.cpp b/runners/bookmarks/browsers/firefox.cpp index abc0c68f8..65a1ee8e2 100644 --- a/runners/bookmarks/browsers/firefox.cpp +++ b/runners/bookmarks/browsers/firefox.cpp @@ -1,212 +1,217 @@ /* * Copyright 2007 Glenn Ergeerts * Copyright 2012 Glenn Ergeerts * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "firefox.h" #include "bookmarks_debug.h" #include #include #include #include #include #include "bookmarkmatch.h" #include "favicon.h" #include "fetchsqlite.h" #include "faviconfromblob.h" Firefox::Firefox(QObject *parent) : QObject(parent), m_favicon(new FallbackFavicon(this)), m_fetchsqlite(nullptr), m_fetchsqlite_fav(nullptr) { reloadConfiguration(); m_dbCacheFile = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QStringLiteral("/bookmarkrunnerfirefoxdbfile.sqlite"); m_dbCacheFile_fav = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QStringLiteral("/bookmarkrunnerfirefoxfavdbfile.sqlite"); } Firefox::~Firefox() { // Delete the cached databases if (!m_dbFile.isEmpty()) { QFile db_CacheFile(m_dbCacheFile); if (db_CacheFile.exists()) { db_CacheFile.remove(); } } if (!m_dbFile_fav.isEmpty()) { QFile db_CacheFileFav(m_dbCacheFile_fav); if (db_CacheFileFav.exists()) { db_CacheFileFav.remove(); } } } void Firefox::prepare() { if (updateCacheFile(m_dbFile, m_dbCacheFile) != Error) { m_fetchsqlite = new FetchSqlite(m_dbCacheFile); m_fetchsqlite->prepare(); } if (updateCacheFile(m_dbFile_fav, m_dbCacheFile_fav) != Error) { m_fetchsqlite_fav = new FetchSqlite(m_dbCacheFile_fav); m_fetchsqlite_fav->prepare(); delete m_favicon; m_favicon = nullptr; m_favicon = FaviconFromBlob::firefox(m_fetchsqlite_fav, this); } } QList< BookmarkMatch > Firefox::match(const QString& term, bool addEverything) { QList< BookmarkMatch > matches; if (!m_fetchsqlite) { return matches; } QString query; if (addEverything) { query = QStringLiteral("SELECT moz_bookmarks.fk, moz_bookmarks.title, moz_places.url " \ "FROM moz_bookmarks, moz_places WHERE " \ "moz_bookmarks.type = 1 AND moz_bookmarks.fk = moz_places.id"); } else { query = QStringLiteral("SELECT moz_bookmarks.fk, moz_bookmarks.title, moz_places.url " \ "FROM moz_bookmarks, moz_places WHERE " \ "moz_bookmarks.type = 1 AND moz_bookmarks.fk = moz_places.id AND " \ "(moz_bookmarks.title LIKE :term OR moz_places.url LIKE :term)"); } const QMap bindVariables { {QStringLiteral(":term"), QStringLiteral("%%%1%%").arg(term)}, }; const QList results = m_fetchsqlite->query(query, bindVariables); QMultiMap uniqueResults; for (const QVariantMap &result : results) { const QString title = result.value(QStringLiteral("title")).toString(); const QUrl url = result.value(QStringLiteral("url")).toUrl(); if (url.isEmpty() || url.scheme() == QLatin1String("place")) { // Don't use bookmarks with empty url or Firefox's "place:" scheme, // e.g. used for "Most Visited" or "Recent Tags" //qDebug() << "element " << url << " was not added"; continue; } auto urlString = url.toString(); // After joining we may have multiple results for each URL: // 1) one for each bookmark folder (same or different titles) // 2) one for each tag (no title for all but the first entry) auto keyRange = uniqueResults.equal_range(urlString); auto it = keyRange.first; if (!title.isEmpty()) { while (it != keyRange.second) { if (*it == title) { // same URL and title in multiple bookmark folders break; } if (it->isEmpty()) { // add a title if there was none for the URL *it = title; break; } ++it; } } if (it == keyRange.second) { // first or unique entry uniqueResults.insert(urlString, title); } } for (auto result = uniqueResults.constKeyValueBegin(); result != uniqueResults.constKeyValueEnd(); ++result) { const QString url = (*result).first; BookmarkMatch bookmarkMatch(m_favicon->iconFor(url), term, (*result).second, url); bookmarkMatch.addTo(matches, addEverything); } return matches; } void Firefox::teardown() { if (m_fetchsqlite) { m_fetchsqlite->teardown(); delete m_fetchsqlite; m_fetchsqlite = nullptr; } if (m_fetchsqlite_fav) { m_fetchsqlite_fav->teardown(); delete m_fetchsqlite_fav; m_fetchsqlite_fav = nullptr; delete m_favicon; m_favicon = nullptr; } } void Firefox::reloadConfiguration() { if (!QSqlDatabase::isDriverAvailable(QStringLiteral("QSQLITE"))) { qCWarning(RUNNER_BOOKMARKS) << "SQLITE driver isn't available"; return; } - KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), QStringLiteral("General")); - KConfigGroup grp = config; + KConfigGroup grp(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), QStringLiteral("General")); /* This allows the user to specify a profile database */ m_dbFile = grp.readEntry("dbfile", QString()); if (m_dbFile.isEmpty() || !QFile::exists(m_dbFile)) { //Try to get the right database file, the default profile is used KConfig firefoxProfile(QDir::homePath() + "/.mozilla/firefox/profiles.ini", KConfig::SimpleConfig); QStringList profilesList = firefoxProfile.groupList(); profilesList = profilesList.filter(QRegularExpression(QStringLiteral("^Profile\\d+$"))); - int size = profilesList.size(); QString profilePath; - if (size == 1) { + if (profilesList.size() == 1) { // There is only 1 profile so we select it KConfigGroup fGrp = firefoxProfile.group(profilesList.first()); profilePath = fGrp.readEntry("Path"); } else { - // There are multiple profiles, find the default one + const QStringList installConfig = firefoxProfile.groupList().filter(QRegularExpression("^Install.*")); + // The profile with Default=1 is not always the default profile, see BUG: 418526 + // If there is only one Install* group it contains the default profile + if (installConfig.size() == 1) { + profilePath = firefoxProfile.group(installConfig.first()).readEntry("Default"); + } else { + // There are multiple profiles, find the default one for (const QString &profileName: qAsConst(profilesList)) { KConfigGroup fGrp = firefoxProfile.group(profileName); if (fGrp.readEntry("Default", 0)) { profilePath = fGrp.readEntry("Path"); break; } } + } } if (profilePath.isEmpty()) { qCWarning(RUNNER_BOOKMARKS) << "No default firefox profile found"; return; } profilePath.prepend(QStringLiteral("%1/.mozilla/firefox/").arg(QDir::homePath())); m_dbFile = profilePath + "/places.sqlite"; m_dbFile_fav = profilePath + "/favicons.sqlite"; } else { auto dir = QDir(m_dbFile); if (dir.cdUp()) { QString profilePath = dir.absolutePath(); m_dbFile_fav = profilePath + "/favicons.sqlite"; } } }