diff options
50 files changed, 2259 insertions, 1920 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 75ebfc26..5f09f146 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ PROJECT( rekonq ) # Informations to update before to release this package. # rekonq info -SET(REKONQ_VERSION "0.5.55" ) +SET(REKONQ_VERSION "0.5.57" ) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h ) @@ -21,8 +21,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.4) # ================================================================================== -FIND_PACKAGE(Qt4 4.6.0 COMPONENTS QtCore QtGui QtNetwork QtWebKit REQUIRED) -FIND_PACKAGE(KDE4 4.4.0 REQUIRED) +FIND_PACKAGE(Qt4 4.7.0 COMPONENTS QtCore QtGui QtNetwork QtWebKit REQUIRED) +FIND_PACKAGE(KDE4 4.5.0 REQUIRED) INCLUDE(MacroOptionalFindPackage) INCLUDE(FindPackageHandleStandardArgs) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 239f5b3b..cc381c94 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,13 +7,13 @@ ADD_SUBDIRECTORY( tests ) ### ------- SETTING REKONQ FILES.. SET( rekonq_KDEINIT_SRCS - application.cpp + application.cpp clicktoflash.cpp filterurljob.cpp findbar.cpp zoombar.cpp mainview.cpp - mainwindow.cpp + mainwindow.cpp networkaccessmanager.cpp newtabpage.cpp paneltreeview.cpp @@ -30,7 +30,7 @@ SET( rekonq_KDEINIT_SRCS webview.cpp webtab.cpp #---------------------------------------- - history/autosaver.cpp + history/autosaver.cpp history/historymanager.cpp history/historymodels.cpp history/historypanel.cpp @@ -47,11 +47,16 @@ SET( rekonq_KDEINIT_SRCS bookmarks/bookmarkspanel.cpp bookmarks/bookmarkstreemodel.cpp bookmarks/bookmarksproxy.cpp - bookmarks/bookmarkcontextmenu.cpp + bookmarks/bookmarkscontextmenu.cpp + bookmarks/bookmarkstoolbar.cpp + bookmarks/bookmarkowner.cpp #---------------------------------------- + adblock/adblockhostmatcher.cpp adblock/adblockmanager.cpp adblock/adblocknetworkreply.cpp adblock/adblockrule.cpp + adblock/adblockrulefallbackimpl.cpp + adblock/adblockruletextmatchimpl.cpp #---------------------------------------- urlbar/stackedurlbar.cpp urlbar/urlbar.cpp diff --git a/src/adblock/adblockhostmatcher.cpp b/src/adblock/adblockhostmatcher.cpp new file mode 100644 index 00000000..b11dab2c --- /dev/null +++ b/src/adblock/adblockhostmatcher.cpp @@ -0,0 +1,55 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Benjamin Poulain <ikipou at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +// Self Includes +#include "adblockhostmatcher.h" + +// Rekonq Includes +#include "rekonq_defines.h" + +bool AdBlockHostMatcher::tryAddFilter(const QString &filter) +{ + if (filter.startsWith(QL1S("||"))) { + QString domain = filter.mid(2); + + const int indexOfFirstSeparator = domain.indexOf(QL1C('^')); + if (indexOfFirstSeparator < 0) + return false; + + const int indexOfLastDollar = domain.lastIndexOf(QL1C('$')); + if (indexOfLastDollar >= 0 && indexOfLastDollar != indexOfFirstSeparator + 1) + return false; + + domain = domain.left(indexOfFirstSeparator); + if (domain.contains(QL1C('/')) || domain.contains(QL1C('*'))) + return false; + + domain = domain.toLower(); + m_hostList.insert(domain); + m_hostList.insert(QL1S("www.") + domain); + return true; + } + return false; +} diff --git a/src/adblock/adblockhostmatcher.h b/src/adblock/adblockhostmatcher.h new file mode 100644 index 00000000..0a15bd4e --- /dev/null +++ b/src/adblock/adblockhostmatcher.h @@ -0,0 +1,51 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Benjamin Poulain <ikipou at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +#ifndef ADBLOCKHOSTMATCHER_H +#define ADBLOCKHOSTMATCHER_H + +#include <QSet> +#include <QString> + +class AdBlockHostMatcher +{ +public: + // Try to add an adblock filter to this host matcher. + // If the filter is not an hostname, the filter is not added + // and the method return false; + bool tryAddFilter(const QString &filter); + + bool match(const QString &host) const + { + return m_hostList.contains(host.toLower()); + } + + void clear() { m_hostList.clear(); } + +private: + QSet<QString> m_hostList; +}; + +#endif // ADBLOCKHOSTMATCHER_H diff --git a/src/adblock/adblockmanager.cpp b/src/adblock/adblockmanager.cpp index 39432f88..8deb0bcd 100644 --- a/src/adblock/adblockmanager.cpp +++ b/src/adblock/adblockmanager.cpp @@ -67,6 +67,8 @@ void AdBlockManager::loadSettings(bool checkUpdateDate) _index = 0; _buffer.clear(); + _hostWhiteList.clear(); + _hostBlackList.clear(); _whiteList.clear(); _blackList.clear(); _hideList.clear(); @@ -133,7 +135,10 @@ void AdBlockManager::loadRules(const QStringList &rules) // white rules if (stringRule.startsWith(QL1S("@@"))) { - AdBlockRule rule(stringRule.mid(2)); + const QString filter = stringRule.mid(2); + if (_hostWhiteList.tryAddFilter(filter)) + continue; + AdBlockRule rule(filter); _whiteList << rule; continue; } @@ -145,6 +150,12 @@ void AdBlockManager::loadRules(const QStringList &rules) continue; } + // TODO implement domain-specific hiding + if (stringRule.contains(QL1S("##"))) + continue; + + if (_hostBlackList.tryAddFilter(stringRule)) + continue; AdBlockRule rule(stringRule); _blackList << rule; } @@ -161,33 +172,50 @@ QNetworkReply *AdBlockManager::block(const QNetworkRequest &request, WebPage *pa return 0; QString urlString = request.url().toString(); + // We compute a lowercase version of the URL so each rule does not + // have to do it. + const QString urlStringLowerCase = urlString.toLower(); + const QString host = request.url().host(); // check white rules before :) + + if (_hostWhiteList.match(host)) { + kDebug() << "****ADBLOCK: WHITE RULE (@@) Matched by host matcher: ***********"; + kDebug() << "UrlString: " << urlString; + return 0; + } + foreach(const AdBlockRule &filter, _whiteList) { - if (filter.match(urlString)) + if (filter.match(urlString, urlStringLowerCase)) { kDebug() << "****ADBLOCK: WHITE RULE (@@) Matched: ***********"; - kDebug() << "Filter exp: " << filter.pattern(); kDebug() << "UrlString: " << urlString; return 0; } } // then check the black ones :( + if (_hostBlackList.match(host)) { + kDebug() << "****ADBLOCK: BLACK RULE Matched by host matcher: ***********"; + kDebug() << "UrlString: " << urlString; + AdBlockNetworkReply *reply = new AdBlockNetworkReply(request, urlString, this); + return reply; + } + foreach(const AdBlockRule &filter, _blackList) { - if (filter.match(urlString)) + if (filter.match(urlString, urlStringLowerCase)) { kDebug() << "****ADBLOCK: BLACK RULE Matched: ***********"; - kDebug() << "Filter exp: " << filter.pattern(); kDebug() << "UrlString: " << urlString; QWebElement document = page->mainFrame()->documentElement(); QWebElementCollection elements = document.findAll("*"); foreach(QWebElement el, elements) { - if (filter.match(el.attribute("src"))) + const QString srcAttribute = el.attribute("src"); + if (filter.match(srcAttribute, srcAttribute.toLower())) { kDebug() << "MATCHES ATTRIBUTE!!!!!"; el.setStyleProperty(QL1S("visibility"), QL1S("hidden")); diff --git a/src/adblock/adblockmanager.h b/src/adblock/adblockmanager.h index eae761e0..69548994 100644 --- a/src/adblock/adblockmanager.h +++ b/src/adblock/adblockmanager.h @@ -108,6 +108,7 @@ #include "rekonq_defines.h" // Local Includes +#include "adblockhostmatcher.h" #include "adblockrule.h" // KDE Includes @@ -155,6 +156,8 @@ private: bool _isAdblockEnabled; bool _isHideAdsEnabled; + AdBlockHostMatcher _hostBlackList; + AdBlockHostMatcher _hostWhiteList; AdBlockRuleList _blackList; AdBlockRuleList _whiteList; QStringList _hideList; diff --git a/src/adblock/adblockrule.cpp b/src/adblock/adblockrule.cpp index 6ff98f03..1cb6773a 100644 --- a/src/adblock/adblockrule.cpp +++ b/src/adblock/adblockrule.cpp @@ -55,94 +55,13 @@ // Self Includes #include "adblockrule.h" -// Qt Includes -#include <QStringList> -#include <QUrl> - +#include "adblockrulefallbackimpl.h" +#include "adblockruletextmatchimpl.h" AdBlockRule::AdBlockRule(const QString &filter) { - bool isRegExpRule = false; - - QString parsedLine = filter; - - if (parsedLine.startsWith(QL1C('/')) && parsedLine.endsWith(QL1C('/'))) - { - parsedLine = parsedLine.mid(1); - parsedLine = parsedLine.left(parsedLine.size() - 1); - isRegExpRule = true; - } - - int optionsNumber = parsedLine.indexOf(QL1C('$'), 0); - QStringList options; - - if (optionsNumber >= 0) - { - options = parsedLine.mid(optionsNumber + 1).split(QL1C(',')); - parsedLine = parsedLine.left(optionsNumber); - } - - if (!isRegExpRule) - parsedLine = convertPatternToRegExp(parsedLine); - - m_regExp = QRegExp(parsedLine, Qt::CaseInsensitive, QRegExp::RegExp2); - - if (options.contains(QL1S("match-case"))) - { - m_regExp.setCaseSensitivity(Qt::CaseSensitive); - } -} - - -// here return false means that rule doesn't match, -// so that url is allowed -// return true means "matched rule", so stop url! -bool AdBlockRule::match(const QString &encodedUrl) const -{ - return m_regExp.indexIn(encodedUrl) != -1; -} - - -QString AdBlockRule::convertPatternToRegExp(const QString &wildcardPattern) -{ - QString pattern = wildcardPattern; - - // remove multiple wildcards - pattern.replace(QRegExp(QL1S("\\*+")), QL1S("*")); - - // remove anchors following separator placeholder - pattern.replace(QRegExp(QL1S("\\^\\|$")), QL1S("^")); - - // remove leading wildcards - pattern.replace(QRegExp(QL1S("^(\\*)")), QL1S("")); - - // remove trailing wildcards - pattern.replace(QRegExp(QL1S("(\\*)$")), QL1S("")); - - // escape special symbols - pattern.replace(QRegExp(QL1S("(\\W)")), QL1S("\\\\1")); - - // process extended anchor at expression start - pattern.replace(QRegExp(QL1S("^\\\\\\|\\\\\\|")), QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?")); - - // process separator placeholders - pattern.replace(QRegExp(QL1S("\\\\\\^")), QL1S("(?:[^\\w\\d\\-.%]|$)")); - - // process anchor at expression start - pattern.replace(QRegExp(QL1S("^\\\\\\|")), QL1S("^")); - - // process anchor at expression end - pattern.replace(QRegExp(QL1S("\\\\\\|$")), QL1S("$")); - - // replace wildcards by .* - pattern.replace(QRegExp(QL1S("\\\\\\*")), QL1S(".*")); - - // Finally, return... - return pattern; -} - - -QString AdBlockRule::pattern() const -{ - return m_regExp.pattern(); + if (AdBlockRuleTextMatchImpl::isTextMatchFilter(filter)) + m_implementation = QSharedPointer<AdBlockRuleImpl>(new AdBlockRuleTextMatchImpl(filter)); + else + m_implementation = QSharedPointer<AdBlockRuleImpl>(new AdBlockRuleFallbackImpl(filter)); } diff --git a/src/adblock/adblockrule.h b/src/adblock/adblockrule.h index 28084004..ef7b2f5f 100644 --- a/src/adblock/adblockrule.h +++ b/src/adblock/adblockrule.h @@ -58,27 +58,26 @@ // Rekonq Includes #include "rekonq_defines.h" -// Qt Includes -#include <QtCore/QRegExp> -#include <QtCore/QString> +#include "adblockruleimpl.h" -// Forward Includes -class QUrl; +#include <QSharedPointer> +// Forward Includes +class QString; class AdBlockRule { public: AdBlockRule(const QString &filter); - bool match(const QString &encodedUrl) const; - - QString pattern() const; + bool match(const QString &encodedUrl, const QString &encodedUrlLowerCase) const + { + Q_ASSERT(encodedUrl.toLower() == encodedUrlLowerCase); + return m_implementation->match(encodedUrl, encodedUrlLowerCase); + } private: - QString convertPatternToRegExp(const QString &wildcardPattern); - - QRegExp m_regExp; + QSharedPointer<AdBlockRuleImpl> m_implementation; }; diff --git a/src/adblock/adblockrulefallbackimpl.cpp b/src/adblock/adblockrulefallbackimpl.cpp new file mode 100644 index 00000000..988f2895 --- /dev/null +++ b/src/adblock/adblockrulefallbackimpl.cpp @@ -0,0 +1,105 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Benjamin Poulain <ikipou at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +// Self Includes +#include "adblockrulefallbackimpl.h" + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include <QStringList> + +static inline bool isRegExpFilter(const QString &filter) +{ + return filter.startsWith(QL1C('/')) && filter.endsWith(QL1C('/')); +} + +AdBlockRuleFallbackImpl::AdBlockRuleFallbackImpl(const QString &filter) + : AdBlockRuleImpl(filter) +{ + m_regExp.setCaseSensitivity(Qt::CaseInsensitive); + m_regExp.setPatternSyntax(QRegExp::RegExp2); + + QString parsedLine = filter; + + const int optionsNumber = parsedLine.lastIndexOf(QL1C('$')); + if (optionsNumber >= 0 && !isRegExpFilter(parsedLine)) { + const QStringList options(parsedLine.mid(optionsNumber + 1).split(QL1C(','))); + if (options.contains(QL1S("match-case"))) + m_regExp.setCaseSensitivity(Qt::CaseSensitive); + parsedLine = parsedLine.left(optionsNumber); + } + + if (isRegExpFilter(parsedLine)) + parsedLine = parsedLine.mid(1, parsedLine.length() - 2); + else + parsedLine = convertPatternToRegExp(parsedLine); + + m_regExp.setPattern(parsedLine); +} + +bool AdBlockRuleFallbackImpl::match(const QString &encodedUrl, const QString &) const +{ + return m_regExp.indexIn(encodedUrl) != -1; +} + +QString AdBlockRuleFallbackImpl::convertPatternToRegExp(const QString &wildcardPattern) +{ + QString pattern = wildcardPattern; + + // remove multiple wildcards + pattern.replace(QRegExp(QL1S("\\*+")), QL1S("*")); + + // remove anchors following separator placeholder + pattern.replace(QRegExp(QL1S("\\^\\|$")), QL1S("^")); + + // remove leading wildcards + pattern.replace(QRegExp(QL1S("^(\\*)")), QL1S("")); + + // remove trailing wildcards + pattern.replace(QRegExp(QL1S("(\\*)$")), QL1S("")); + + // escape special symbols + pattern.replace(QRegExp(QL1S("(\\W)")), QL1S("\\\\1")); + + // process extended anchor at expression start + pattern.replace(QRegExp(QL1S("^\\\\\\|\\\\\\|")), QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?")); + + // process separator placeholders + pattern.replace(QRegExp(QL1S("\\\\\\^")), QL1S("(?:[^\\w\\d\\-.%]|$)")); + + // process anchor at expression start + pattern.replace(QRegExp(QL1S("^\\\\\\|")), QL1S("^")); + + // process anchor at expression end + pattern.replace(QRegExp(QL1S("\\\\\\|$")), QL1S("$")); + + // replace wildcards by .* + pattern.replace(QRegExp(QL1S("\\\\\\*")), QL1S(".*")); + + // Finally, return... + return pattern; +} diff --git a/src/adblock/adblockrulefallbackimpl.h b/src/adblock/adblockrulefallbackimpl.h new file mode 100644 index 00000000..ed0f6dc6 --- /dev/null +++ b/src/adblock/adblockrulefallbackimpl.h @@ -0,0 +1,47 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Benjamin Poulain <ikipou at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +#ifndef ADBLOCKRULEFALLBACKIMPL_H +#define ADBLOCKRULEFALLBACKIMPL_H + +#include "adblockruleimpl.h" + +// Qt Includes +#include <QRegExp> +#include <QString> + +class AdBlockRuleFallbackImpl : public AdBlockRuleImpl +{ +public: + AdBlockRuleFallbackImpl(const QString &filter); + bool match(const QString &encodedUrl, const QString &encodedUrlLowerCase) const; + +private: + QString convertPatternToRegExp(const QString &wildcardPattern); + + QRegExp m_regExp; +}; + +#endif // ADBLOCKRULEFALLBACKIMPL_H diff --git a/src/adblock/adblockruleimpl.h b/src/adblock/adblockruleimpl.h new file mode 100644 index 00000000..db5cec30 --- /dev/null +++ b/src/adblock/adblockruleimpl.h @@ -0,0 +1,39 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Benjamin Poulain <ikipou at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +#ifndef ADBLOCKRULEIMPL_H +#define ADBLOCKRULEIMPL_H + +class QString; + +class AdBlockRuleImpl +{ +public: + AdBlockRuleImpl(const QString &) {} + virtual ~AdBlockRuleImpl() {} + virtual bool match(const QString &encodedUrl, const QString &encodedUrlLowerCase) const = 0; +}; + +#endif // ADBLOCKRULEIMPL_H diff --git a/src/adblock/adblockruletextmatchimpl.cpp b/src/adblock/adblockruletextmatchimpl.cpp new file mode 100644 index 00000000..892d78e0 --- /dev/null +++ b/src/adblock/adblockruletextmatchimpl.cpp @@ -0,0 +1,73 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Benjamin Poulain <ikipou at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +// Self Includes +#include "adblockruletextmatchimpl.h" + +// Rekonq Includes +#include "rekonq_defines.h" + +AdBlockRuleTextMatchImpl::AdBlockRuleTextMatchImpl(const QString &filter) + : AdBlockRuleImpl(filter) +{ + Q_ASSERT(AdBlockRuleTextMatchImpl::isTextMatchFilter(filter)); + + m_textToMatch = filter.toLower(); + m_textToMatch.remove(QL1C('*')); +} + +bool AdBlockRuleTextMatchImpl::match(const QString &encodedUrl, const QString &encodedUrlLowerCase) const +{ + Q_UNUSED(encodedUrl); + // Case sensitive compare is faster, but would be incorrect with encodedUrl since + // we do want case insensitive. + // What we do is work on a lowercase version of m_textToMatch, and compare to the lowercase + // version of encodedUrl. + return encodedUrlLowerCase.contains(m_textToMatch, Qt::CaseSensitive); +} + +bool AdBlockRuleTextMatchImpl::isTextMatchFilter(const QString &filter) +{ + // We don't deal with options just yet + if (filter.contains(QL1C('$'))) + return false; + + // We don't deal with element matching + if (filter.contains(QL1S("##"))) + return false; + + // We don't deal with the begin-end matching + if (filter.startsWith(QL1C('|')) || filter.endsWith(QL1C('|'))) + return false; + + // We only handle * at the beginning or the end + int starPosition = filter.indexOf(QL1C('*')); + while (starPosition >= 0) { + if (starPosition != 0 && starPosition != (filter.length() - 1)) + return false; + starPosition = filter.indexOf(QL1C('*'), starPosition + 1); + } + return true; +} diff --git a/src/adblock/adblockruletextmatchimpl.h b/src/adblock/adblockruletextmatchimpl.h new file mode 100644 index 00000000..28b0656c --- /dev/null +++ b/src/adblock/adblockruletextmatchimpl.h @@ -0,0 +1,47 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Benjamin Poulain <ikipou at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +#ifndef ADBLOCKRULETEXTMATCHIMPL_H +#define ADBLOCKRULETEXTMATCHIMPL_H + +#include "adblockruleimpl.h" + +// Qt Includes +#include <QString> + +// Simple rule to find a string in the URL +class AdBlockRuleTextMatchImpl : public AdBlockRuleImpl +{ +public: + AdBlockRuleTextMatchImpl(const QString &filter); + bool match(const QString &encodedUrl, const QString &encodedUrlLowerCase) const; + + static bool isTextMatchFilter(const QString &filter); + +private: + QString m_textToMatch; +}; + +#endif // ADBLOCKRULETEXTMATCHIMPL_H diff --git a/src/application.cpp b/src/application.cpp index bfe67f45..065c0ef2 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -467,12 +467,6 @@ void Application::loadResolvedUrl(ThreadWeaver::Job *job) if (view) { view->load(url); - - // we are sure of the url now, let's add it to history - // anyway we store here just http sites because local and ftp ones are - // added trough the protocol handler and the other are ignored - if (url.protocol() == QL1S("http") || url.protocol() == QL1S("https")) - historyManager()->addHistoryEntry(url.prettyUrl()); } } diff --git a/src/bookmarks/bookmarkcontextmenu.cpp b/src/bookmarks/bookmarkcontextmenu.cpp deleted file mode 100644 index 019d9eb9..00000000 --- a/src/bookmarks/bookmarkcontextmenu.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* ============================================================ -* -* This file is a part of the rekonq project -* -* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> -* -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 of -* the License or (at your option) version 3 or any later version -* accepted by the membership of KDE e.V. (or its successor approved -* by the membership of KDE e.V.), which shall act as a proxy -* defined in Section 14 of version 3 of the license. -* -* 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 General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* ============================================================ */ - - -// Self Includes -#include "bookmarkcontextmenu.h" -#include "bookmarkcontextmenu.moc" - -// Local Includes -#include "application.h" -#include "bookmarksmanager.h" - -// KDE Includes -#include <KMessageBox> -#include <KActionCollection> -#include <KBookmarkDialog> - -// Qt Includes -#include <QClipboard> - - -BookmarkContextMenu::BookmarkContextMenu(const KBookmark & bookmark, KBookmarkManager *manager, KBookmarkOwner *owner, QWidget *parent) - : KBookmarkContextMenu(bookmark, manager, owner, parent) - , m_ac(new KActionCollection(this)) -{ - setupActions(); -} - - -BookmarkContextMenu::~BookmarkContextMenu() -{ - delete m_ac; -} - - -void BookmarkContextMenu::setupActions() -{ - KAction* action; - - action = new KAction(KIcon("tab-new"), i18n("Open"), this); - connect(action, SIGNAL(triggered()), this, SLOT(openInCurrentTab())); - m_ac->addAction("open", action); - - action = new KAction(KIcon("tab-new"), i18n("Open in New Tab"), this); - connect(action, SIGNAL(triggered()), this, SLOT(openInNewTab())); - m_ac->addAction("open_tab", action); - - action = new KAction(KIcon("window-new"), i18n("Open in New Window"), this); - connect(action, SIGNAL(triggered()), this, SLOT(openInNewWindow())); - m_ac->addAction("open_window", action); - - action = new KAction(KIcon("bookmark-new"), i18n("Add Bookmark Here"), this); - connect(action, SIGNAL(triggered()), this, SLOT(bookmarkCurrentPage())); - m_ac->addAction("bookmark_page", action); - - action = new KAction(KIcon("folder-new"), i18n("New Bookmark Folder"), this); - connect(action, SIGNAL(triggered()), this, SLOT(newBookmarkGroup())); - m_ac->addAction("folder_new", action); - - action = new KAction(KIcon("edit-clear"), i18n("New Separator"), this); - connect(action, SIGNAL(triggered()), this, SLOT(newSeparator())); - m_ac->addAction("separator_new", action); - - action = new KAction(KIcon("edit-copy"), i18n("Copy Link Address"), this); - connect(action, SIGNAL(triggered()), this, SLOT(copyToClipboard())); - m_ac->addAction("copy", action); - - action = new KAction(KIcon("edit-delete"), i18n("Delete Bookmark"), this); - connect(action, SIGNAL(triggered()), this, SLOT(deleteBookmark())); - m_ac->addAction("delete", action); - - action = new KAction(KIcon("configure"), i18n("Properties"), this); - connect(action, SIGNAL(triggered()), this, SLOT(editBookmark())); - m_ac->addAction("properties", action); - - action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); - connect(action, SIGNAL(triggered()), this, SLOT(openFolderInTabs())); - m_ac->addAction("open_all", action); -} - - -void BookmarkContextMenu::addBookmarkActions() -{ - addAction(m_ac->action("open")); - addAction(m_ac->action("open_tab")); - addAction(m_ac->action("open_window")); - - addSeparator(); - - addAction(m_ac->action("bookmark_page")); - addAction(m_ac->action("folder_new")); - addAction(m_ac->action("separator_new")); - - addSeparator(); - - addAction(m_ac->action("copy")); - - addSeparator(); - - addAction(m_ac->action("delete")); - addAction(m_ac->action("properties")); -} - - -void BookmarkContextMenu::addFolderActions() -{ - if (!bookmark().toGroup().first().isNull()) - { - addAction(m_ac->action("open_all")); - addSeparator(); - } - - addAction(m_ac->action("bookmark_page")); - addAction(m_ac->action("folder_new")); - addAction(m_ac->action("separator_new")); - - addSeparator(); - - addAction(m_ac->action("delete")); - addAction(m_ac->action("properties")); -} - - -void BookmarkContextMenu::addSeparatorActions() -{ - addAction(m_ac->action("bookmark_page")); - addAction(m_ac->action("folder_new")); - addAction(m_ac->action("separator_new")); - - addSeparator(); - - addAction(m_ac->action("delete")); -} - - -void BookmarkContextMenu::addActions() -{ - if (bookmark().isGroup()) - { - addFolderActions(); - } - - else if (bookmark().isSeparator()) - { - addSeparatorActions(); - } - - else if (bookmark().isNull()) - { - addAction(m_ac->action("bookmark_page")); - addAction(m_ac->action("folder_new")); - addAction(m_ac->action("separator_new")); - } - - else - { - addBookmarkActions(); - } -} - - -void BookmarkContextMenu::openInCurrentTab() -{ - Application::instance()->loadUrl(bookmark().url()); -} - - -void BookmarkContextMenu::openInNewTab() -{ - Application::instance()->loadUrl(bookmark().url(), Rekonq::NewTab); -} - - -void BookmarkContextMenu::openInNewWindow() -{ - Application::instance()->loadUrl(bookmark().url(), Rekonq::NewWindow); -} - - -void BookmarkContextMenu::copyToClipboard() -{ - if (bookmark().isNull()) - return; - - QClipboard *cb = QApplication::clipboard(); - cb->setText(bookmark().url().url()); -} - - -void BookmarkContextMenu::deleteBookmark() -{ - KBookmark bm = bookmark(); - KBookmarkGroup bmg = bm.parentGroup(); - bool folder = bm.isGroup(); - QString name = QString(bm.fullText()).replace("&&", "&"); - - if (KMessageBox::warningContinueCancel( - QApplication::activeWindow(), - folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", name) - : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", name), - folder ? i18n("Bookmark Folder Deletion") - : i18n("Bookmark Deletion"), - KStandardGuiItem::del(), - KStandardGuiItem::cancel(), - "bookmarkDeletition_askAgain") - != KMessageBox::Continue - ) - return; - - bmg.deleteBookmark(bm); - manager()->emitChanged(bmg); -} - - -void BookmarkContextMenu::editBookmark() -{ - KBookmark selected = bookmark(); - selected.setFullText(selected.fullText().replace("&&", "&")); - KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow()); - dialog->editBookmark(selected); - selected.setFullText(selected.fullText().replace('&', "&&")); - delete dialog; -} - - -void BookmarkContextMenu::openFolderInTabs() -{ - if (bookmark().isGroup()) - owner()->openFolderinTabs(bookmark().toGroup()); -} - - -void BookmarkContextMenu::newBookmarkGroup() -{ - KBookmark selected = bookmark(); - KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow()); - - if (!selected.isNull()) - { - if (selected.isGroup()) - { - dialog->createNewFolder("New folder", selected); - } - - else - { - KBookmark newBk; - newBk = dialog->createNewFolder("New folder", selected.parentGroup()); - if (!newBk.isNull()) - { - selected.parentGroup().moveBookmark(newBk, selected); - manager()->emitChanged(newBk.parentGroup()); - } - } - } - else - { - dialog->createNewFolder("New folder"); - } - - delete dialog; -} - - -void BookmarkContextMenu::newSeparator() -{ - KBookmark selected = bookmark(); - KBookmark newBk; - - if (!selected.isNull()) - { - if (selected.isGroup()) - newBk = selected.toGroup().createNewSeparator(); - else - newBk = selected.parentGroup().createNewSeparator(); - } - - else - { - newBk = Application::bookmarkProvider()->rootGroup().createNewSeparator(); - } - - KBookmarkGroup parent = newBk.parentGroup(); - newBk.setIcon(("edit-clear")); - parent.addBookmark(newBk); - - if (!selected.isNull()) - parent.moveBookmark(newBk, selected); - - manager()->emitChanged(newBk.parentGroup()); -} - - -void BookmarkContextMenu::bookmarkCurrentPage() -{ - KBookmarkGroup parent = Application::bookmarkProvider()->rootGroup(); - KBookmark selected = bookmark(); - - if (!selected.isNull()) - { - parent = selected.parentGroup(); - - if (selected.isGroup()) - parent = selected.toGroup(); - - KBookmark newBk = parent.addBookmark(owner()->currentTitle().replace('&', "&&"), KUrl(owner()->currentUrl())); - parent.moveBookmark(newBk, selected.parentGroup().previous(selected)); - } - - else - { - parent.addBookmark(owner()->currentTitle(), KUrl(owner()->currentUrl())); - } - - manager()->emitChanged(parent); -} - diff --git a/src/bookmarks/bookmarkowner.cpp b/src/bookmarks/bookmarkowner.cpp new file mode 100644 index 00000000..d9df6e82 --- /dev/null +++ b/src/bookmarks/bookmarkowner.cpp @@ -0,0 +1,359 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkowner.h" + +// Local Includes +#include "application.h" +#include "bookmarksmanager.h" +#include "mainwindow.h" +#include "webtab.h" +#include "mainview.h" + +// KDE Includes +#include <KBookmarkDialog> +#include <KMessageBox> + +// Qt Includes +#include <QtGui/QClipboard> + + +BookmarkOwner::BookmarkOwner(KBookmarkManager *manager, QObject *parent) + : QObject(parent) + , KBookmarkOwner() + , m_manager(manager) + , m_actions(QVector<KAction*>(NUM_ACTIONS)) +{ + setupActions(); +} + + +KAction* BookmarkOwner::action(const BookmarkAction &bmAction) +{ + return static_cast<KAction*>(m_actions.at(bmAction)); +} + + +QString BookmarkOwner::currentTitle() const +{ + return Application::instance()->mainWindow()->currentTab()->view()->title(); +} + + +QString BookmarkOwner::currentUrl() const +{ + return Application::instance()->mainWindow()->currentTab()->url().url(); +} + + +bool BookmarkOwner::supportsTabs() const +{ + return true; +} + + +QList< QPair<QString, QString> > BookmarkOwner::currentBookmarkList() const +{ + QList< QPair<QString, QString> > bkList; + MainView *view = Application::instance()->mainWindow()->mainView(); + int tabNumber = view->count(); + + for (int i = 0; i < tabNumber; ++i) + { + QPair<QString, QString> item; + item.first = view->webTab(i)->view()->title(); + item.second = view->webTab(i)->url().url(); + bkList << item; + } + + return bkList; +} + + +void BookmarkOwner::openBookmark(const KBookmark &bookmark, + Qt::MouseButtons mouseButtons, + Qt::KeyboardModifiers keyboardModifiers) +{ + if (keyboardModifiers & Qt::ControlModifier || mouseButtons & Qt::MidButton) + { + openBookmarkInNewTab(bookmark); + } + else + { + openBookmark(bookmark); + } +} + + +void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bookmark) +{ + openBookmarkFolder(bookmark); +} + + +void BookmarkOwner::setCurrentBookmark(const KBookmark &bookmark) +{ + m_currentBookmark = bookmark; +} + + +void BookmarkOwner::openBookmark(const KBookmark &bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + emit openUrl(selected.url(), Rekonq::CurrentTab); +} + + +void BookmarkOwner::openBookmarkInNewTab(const KBookmark &bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + emit openUrl(selected.url(), Rekonq::NewTab); +} + + +void BookmarkOwner::openBookmarkInNewWindow(const KBookmark &bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + emit openUrl(selected.url(), Rekonq::NewWindow); +} + + +void BookmarkOwner::openBookmarkFolder(const KBookmark &bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + if (!selected.isGroup()) + return; + + QList<KUrl> urlList = selected.toGroup().groupUrlList(); + + if (urlList.length() > 8) + { + if (KMessageBox::warningContinueCancel( + Application::instance()->mainWindow(), + i18n("You are about to open %1 tabs.\nAre you sure?", urlList.length())) + != KMessageBox::Continue + ) + return; + } + + Q_FOREACH(const KUrl &url, urlList) + { + emit openUrl(url, Rekonq::NewFocusedTab); + } +} + + +void BookmarkOwner::bookmarkCurrentPage(const KBookmark &bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + KBookmarkGroup parent; + + if (!selected.isNull()) + { + if (selected.isGroup()) + parent = selected.toGroup(); + else + parent = selected.parentGroup(); + + KBookmark newBk = parent.addBookmark(currentTitle().replace('&', "&&"), KUrl(currentUrl())); + parent.moveBookmark(newBk, selected); + } + else + { + parent = Application::bookmarkProvider()->rootGroup(); + parent.addBookmark(currentTitle(), KUrl(currentUrl())); + } + + m_manager->emitChanged(parent); +} + + +void BookmarkOwner::newBookmarkFolder(const KBookmark &bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + KBookmarkDialog *dialog = bookmarkDialog(m_manager, QApplication::activeWindow()); + QString folderName = i18n("New folder"); + + if (!selected.isNull()) + { + if (selected.isGroup()) + { + dialog->createNewFolder(folderName, selected); + } + else + { + KBookmark newBk = dialog->createNewFolder(folderName, selected.parentGroup()); + if (!newBk.isNull()) + { + KBookmarkGroup parent = newBk.parentGroup(); + parent.moveBookmark(newBk, selected); + m_manager->emitChanged(parent); + } + } + } + else + { + dialog->createNewFolder(folderName); + } + + delete dialog; +} + + +void BookmarkOwner::newSeparator(const KBookmark &bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + KBookmark newBk; + + if (!selected.isNull()) + { + if (selected.isGroup()) + { + newBk = selected.toGroup().createNewSeparator(); + } + else + { + newBk = selected.parentGroup().createNewSeparator(); + newBk.parentGroup().moveBookmark(newBk, selected); + } + } + else + { + newBk = Application::bookmarkProvider()->rootGroup().createNewSeparator(); + } + + newBk.setIcon(("edit-clear")); + + m_manager->emitChanged(newBk.parentGroup()); +} + + +void BookmarkOwner::copyLink(const KBookmark &bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + if (selected.isNull()) + return; + + QApplication::clipboard()->setText(selected.url().url()); +} + + +void BookmarkOwner::editBookmark(KBookmark bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + if (selected.isNull()) + return; + + selected.setFullText(selected.fullText().replace("&&", "&")); + KBookmarkDialog *dialog = bookmarkDialog(m_manager, QApplication::activeWindow()); + + dialog->editBookmark(selected); + selected.setFullText(selected.fullText().replace('&', "&&")); + + delete dialog; +} + + +bool BookmarkOwner::deleteBookmark(KBookmark bookmark) +{ + KBookmark selected = bookmark.isNull() ? m_currentBookmark : bookmark; + if (selected.isNull()) + return false; + + KBookmarkGroup bmg = selected.parentGroup(); + QString name = QString(selected.fullText()).replace("&&", "&"); + QString dialogCaption, dialogText; + + if (selected.isGroup()) + { + dialogCaption = i18n("Bookmark Folder Deletion"); + dialogText = i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", name); + } + else if (selected.isSeparator()) + { + dialogCaption = i18n("Separator Deletion"); + dialogText = i18n("Are you sure you wish to remove this separator?"); + } + else + { + dialogCaption = i18n("Bookmark Deletion"); + dialogText = i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", name); + } + + if (KMessageBox::warningContinueCancel( + QApplication::activeWindow(), + dialogText, + dialogCaption, + KStandardGuiItem::del(), + KStandardGuiItem::cancel(), + "bookmarkDeletition_askAgain") + != KMessageBox::Continue + ) + return false; + + bmg.deleteBookmark(selected); + m_manager->emitChanged(bmg); + return true; +} + + +void BookmarkOwner::setupActions() +{ + createAction(OPEN, i18n("Open"), "tab-new", + i18n("Open bookmark in current tab"), SLOT(openBookmark())); + createAction(OPEN_IN_TAB, i18n("Open in New Tab"), "tab-new", + i18n("Open bookmark in new tab"), SLOT(openBookmarkInNewTab())); + createAction(OPEN_IN_WINDOW, i18n("Open in New Window"), "window-new", + i18n("Open bookmark in new window"), SLOT(openBookmarkInNewWindow())); + createAction(OPEN_FOLDER, i18n("Open Folder in Tabs"), "tab-new", + i18n("Open all the bookmarks in folder in tabs"), SLOT(openBookmarkFolder())); + createAction(BOOKMARK_PAGE, i18n("Add Bookmark"), "bookmark-new", + i18n("Bookmark current page"), SLOT(bookmarkCurrentPage())); + createAction(NEW_FOLDER, i18n("New Folder"), "folder-new", + i18n("Create a new bookmark folder"), SLOT(newBookmarkFolder())); + createAction(NEW_SEPARATOR, i18n("New Separator"), "edit-clear", + i18n("Create a new bookmark separatork"), SLOT(newSeparator())); + createAction(COPY, i18n("Copy Link"), "edit-copy", + i18n("Copy the bookmark's link address"), SLOT(copyLink())); + createAction(EDIT, i18n("Edit"), "configure", + i18n("Edit the bookmark"), SLOT(editBookmark())); + createAction(DELETE, i18n("Delete"), "edit-delete", + i18n("Delete the bookmark"), SLOT(deleteBookmark())); +} + + +void BookmarkOwner::createAction(const BookmarkAction &action, const QString &text, + const QString &icon, const QString &help, const char *slot) +{ + KAction *act = new KAction(KIcon(icon), text, this); + act->setHelpText(help); + m_actions[action] = act; + connect(act, SIGNAL(triggered()), this, slot); +} diff --git a/src/bookmarks/bookmarkowner.h b/src/bookmarks/bookmarkowner.h new file mode 100644 index 00000000..e0c2a8ad --- /dev/null +++ b/src/bookmarks/bookmarkowner.h @@ -0,0 +1,147 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com> +* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef BOOKMARKOWNER_H +#define BOOKMARKOWNER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include <KBookmarkOwner> + +// Forward Declarations +class KAction; + +/** + * Reimplementation of KBookmarkOwner, this class allows to manage + * bookmarks as actions. + */ +class REKONQ_TESTS_EXPORT BookmarkOwner : public QObject, public KBookmarkOwner +{ + Q_OBJECT + +public: + explicit BookmarkOwner(KBookmarkManager *manager, QObject *parent = 0); + virtual ~BookmarkOwner() {} + + enum BookmarkAction + { + OPEN = 0, + OPEN_IN_TAB, + OPEN_IN_WINDOW, + OPEN_FOLDER, + BOOKMARK_PAGE, + NEW_FOLDER, + NEW_SEPARATOR, + COPY, + EDIT, + DELETE, + NUM_ACTIONS + }; + + /** + * @return the action or 0 if it doesn't exist. + */ + KAction* action(const BookmarkAction &bmAction); + + /** + * @return the current page's title. + */ + virtual QString currentTitle() const; + /** + * @return the current page's URL. + */ + virtual QString currentUrl() const; + + /** + * @return whether the owner supports tabs. + */ + virtual bool supportsTabs() const; + + /** + * @return list of title, URL pairs of the open tabs. + */ + virtual QList< QPair<QString, QString> > currentBookmarkList() const; + + /** + * This function is called when a bookmark is selected and belongs to + * the ancestor class. + * This method actually emits signal to load bookmark's url. + * + * @param bookmark the bookmark to open + * @param mouseButtons the mouse buttons clicked to select the bookmark + * @param keyboardModifiers the keyboard modifiers pushed when the bookmark was selected + */ + virtual void openBookmark(const KBookmark &bookmark, + Qt::MouseButtons mouseButtons, + Qt::KeyboardModifiers keyboardModifiers); + + /** + * Called if the user wants to open every bookmark in this folder in a new tab. + * The default implementation does nothing. + * This is only called if supportsTabs() returns true + */ + virtual void openFolderinTabs(const KBookmarkGroup &bookmark); + +signals: + /** + * This signal is emitted when an url has to be loaded + * @param url the URL to load + */ + void openUrl(const KUrl &, const Rekonq::OpenType &); + +public slots: + void setCurrentBookmark(const KBookmark &bookmark); + + void openBookmark(const KBookmark &bookmark = KBookmark()); + void openBookmarkInNewTab(const KBookmark &bookmark = KBookmark()); + void openBookmarkInNewWindow(const KBookmark &bookmark = KBookmark()); + void openBookmarkFolder(const KBookmark &bookmark = KBookmark()); + void bookmarkCurrentPage(const KBookmark &bookmark = KBookmark()); + void newBookmarkFolder(const KBookmark &bookmark = KBookmark()); + void newSeparator(const KBookmark &bookmark = KBookmark()); + void copyLink(const KBookmark &bookmark = KBookmark()); + void editBookmark(KBookmark bookmark = KBookmark()); + bool deleteBookmark(KBookmark bookmark = KBookmark()); + +private: + KBookmarkManager *m_manager; + + QVector<KAction*> m_actions; + KBookmark m_currentBookmark; + + void setupActions(); + void createAction(const BookmarkAction &action, + const QString &text, const QString &icon, + const QString &help, const char *slot); +}; + +#endif // BOOKMARKOWNER_H diff --git a/src/bookmarks/bookmarkscontextmenu.cpp b/src/bookmarks/bookmarkscontextmenu.cpp new file mode 100644 index 00000000..a473966a --- /dev/null +++ b/src/bookmarks/bookmarkscontextmenu.cpp @@ -0,0 +1,127 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkscontextmenu.h" + +// Local Includes +#include "bookmarkowner.h" + + +BookmarksContextMenu::BookmarksContextMenu(const KBookmark &bookmark, KBookmarkManager *manager, BookmarkOwner *owner, QWidget *parent) + : KBookmarkContextMenu(bookmark, manager, owner, parent) + , bmOwner(owner) +{ + bmOwner->setCurrentBookmark(bookmark); +} + + +BookmarksContextMenu::~BookmarksContextMenu() +{ +} + + +void BookmarksContextMenu::addBookmarkActions() +{ + addAction(bmOwner->action(BookmarkOwner::OPEN)); + addAction(bmOwner->action(BookmarkOwner::OPEN_IN_TAB)); + addAction(bmOwner->action(BookmarkOwner::OPEN_IN_WINDOW)); + + addSeparator(); + + addAction(bmOwner->action(BookmarkOwner::BOOKMARK_PAGE)); + addAction(bmOwner->action(BookmarkOwner::NEW_FOLDER)); + addAction(bmOwner->action(BookmarkOwner::NEW_SEPARATOR)); + + addSeparator(); + + addAction(bmOwner->action(BookmarkOwner::COPY)); + + addSeparator(); + + addAction(bmOwner->action(BookmarkOwner::EDIT)); + addAction(bmOwner->action(BookmarkOwner::DELETE)); +} + + +void BookmarksContextMenu::addFolderActions() +{ + if (!bookmark().toGroup().first().isNull()) + { + addAction(bmOwner->action(BookmarkOwner::OPEN_FOLDER)); + addSeparator(); + } + + addAction(bmOwner->action(BookmarkOwner::BOOKMARK_PAGE)); + addAction(bmOwner->action(BookmarkOwner::NEW_FOLDER)); + addAction(bmOwner->action(BookmarkOwner::NEW_SEPARATOR)); + + addSeparator(); + + addAction(bmOwner->action(BookmarkOwner::EDIT)); + addAction(bmOwner->action(BookmarkOwner::DELETE)); +} + + +void BookmarksContextMenu::addSeparatorActions() +{ + addAction(bmOwner->action(BookmarkOwner::BOOKMARK_PAGE)); + addAction(bmOwner->action(BookmarkOwner::NEW_FOLDER)); + addAction(bmOwner->action(BookmarkOwner::NEW_SEPARATOR)); + + addSeparator(); + + addAction(bmOwner->action(BookmarkOwner::DELETE)); +} + + +void BookmarksContextMenu::addNullActions() +{ + addAction(bmOwner->action(BookmarkOwner::BOOKMARK_PAGE)); + addAction(bmOwner->action(BookmarkOwner::NEW_FOLDER)); + addAction(bmOwner->action(BookmarkOwner::NEW_SEPARATOR)); +} + + +void BookmarksContextMenu::addActions() +{ + if (bookmark().isGroup()) + { + addFolderActions(); + } + else if (bookmark().isSeparator()) + { + addSeparatorActions(); + } + else if (bookmark().isNull()) + { + addNullActions(); + } + else + { + addBookmarkActions(); + } +} diff --git a/src/bookmarks/bookmarkcontextmenu.h b/src/bookmarks/bookmarkscontextmenu.h index ebbfd6e8..a6691fdd 100644 --- a/src/bookmarks/bookmarkcontextmenu.h +++ b/src/bookmarks/bookmarkscontextmenu.h @@ -24,45 +24,30 @@ * ============================================================ */ -#ifndef BOOKMARKCONTEXTMENU_H -#define BOOKMARKCONTEXTMENU_H +#ifndef BOOKMARKS_CONTEXT_MENU_H +#define BOOKMARKS_CONTEXT_MENU_H -// Local Includes -#include "application.h" - -// Qt Includes +// KDE Includes #include <KBookmarkMenu> +// Forward Declarations +class BookmarkOwner; -class BookmarkContextMenu : public KBookmarkContextMenu +class BookmarksContextMenu : public KBookmarkContextMenu { - Q_OBJECT - public: - BookmarkContextMenu(const KBookmark & bk, KBookmarkManager * manager, KBookmarkOwner *owner, QWidget * parent = 0); - ~BookmarkContextMenu(); - - virtual void addActions(); + BookmarksContextMenu(const KBookmark &bookmark, KBookmarkManager *manager, BookmarkOwner *owner, QWidget *parent = 0); + virtual ~BookmarksContextMenu(); -private slots: - void openInCurrentTab(); - void openInNewTab(); - void openInNewWindow(); - void copyToClipboard(); - void deleteBookmark(); - void openFolderInTabs(); - void editBookmark(); - void newBookmarkGroup(); - void newSeparator(); - void bookmarkCurrentPage(); + virtual void addActions(); private: - void setupActions(); void addFolderActions(); void addBookmarkActions(); void addSeparatorActions(); + void addNullActions(); - KActionCollection *m_ac; + BookmarkOwner *bmOwner; }; -#endif // BOOKMARKCONTEXTMENU_H +#endif // BOOKMARKS_CONTEXT_MENU_H diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp index bba9dd77..ea7b313d 100644 --- a/src/bookmarks/bookmarksmanager.cpp +++ b/src/bookmarks/bookmarksmanager.cpp @@ -29,313 +29,22 @@ // Self Includes #include "bookmarksmanager.h" -#include "bookmarksmanager.moc" // Local Includes +#include "application.h" #include "mainwindow.h" -#include "webtab.h" -#include "webview.h" -#include "mainview.h" -#include "bookmarkcontextmenu.h" +#include "bookmarkspanel.h" +#include "bookmarkscontextmenu.h" +#include "bookmarkstoolbar.h" +#include "bookmarkowner.h" // KDE Includes -#include <KActionCollection> -#include <KBookmarkAction> -#include <KBookmarkGroup> -#include <KToolBar> -#include <KMenu> #include <KStandardDirs> -#include <KUrl> -#include <KMessageBox> // Qt Includes #include <QtCore/QFile> -#include <QtGui/QActionGroup> -BookmarkOwner::BookmarkOwner(QObject *parent) - : QObject(parent) - , KBookmarkOwner() -{ -} - - -void BookmarkOwner::openBookmark(const KBookmark & bookmark, - Qt::MouseButtons mouseButtons, - Qt::KeyboardModifiers keyboardModifiers) -{ - if (keyboardModifiers & Qt::ControlModifier || mouseButtons == Qt::MidButton) - { - emit openUrl(bookmark.url(), Rekonq::NewTab); - } - else - { - emit openUrl(bookmark.url(), Rekonq::CurrentTab); - } -} - - -bool BookmarkOwner::supportsTabs() const -{ - return true; -} - - -QString BookmarkOwner::currentUrl() const -{ - return Application::instance()->mainWindow()->currentTab()->url().url(); -} - - -QString BookmarkOwner::currentTitle() const -{ - return Application::instance()->mainWindow()->currentTab()->view()->title(); -} - - -void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bookmark) -{ - QList<KUrl> urlList = bookmark.groupUrlList(); - - if (urlList.length() > 8) - { - if ( !(KMessageBox::warningContinueCancel( Application::instance()->mainWindow(), - i18ncp("%1=Number of tabs. Value is always >=8", - "You are about to open %1 tabs.\nAre you sure?", - "You are about to open %1 tabs.\nAre you sure?", - urlList.length()), - "", - KStandardGuiItem::cont(), - KStandardGuiItem::cancel(), - "openFolderInTabs_askAgain" - ) == KMessageBox::Continue) - ) - return; - } - - QList<KUrl>::iterator url; - for (url = urlList.begin(); url != urlList.end(); ++url) - { - emit openUrl(*url, Rekonq::NewFocusedTab); - } -} - - -QList< QPair<QString, QString> > BookmarkOwner::currentBookmarkList() const -{ - QList< QPair<QString, QString> > bkList; - int tabNumber = Application::instance()->mainWindow()->mainView()->count(); - - for (int i = 0; i < tabNumber; i++) - { - QPair<QString, QString> item; - item.first = Application::instance()->mainWindow()->mainView()->webTab(i)->view()->title(); - item.second = Application::instance()->mainWindow()->mainView()->webTab(i)->url().url(); - bkList += item; - } - return bkList; -} - - -// ------------------------------------------------------------------------------------------------------ - - -BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, - KBookmarkOwner *owner, - KMenu *menu, - KActionCollection* actionCollection) - : KBookmarkMenu(manager, owner, menu, actionCollection) -{ -} - - -BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, - KBookmarkOwner *owner, - KMenu *parentMenu, - const QString &parentAddress) - : KBookmarkMenu(manager, owner, parentMenu, parentAddress) -{ -} - - -BookmarkMenu::~BookmarkMenu() -{ -} - - -KMenu * BookmarkMenu::contextMenu(QAction *act) -{ - - KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act); - if (!action) - return 0; - return new BookmarkContextMenu(action->bookmark(), manager(), owner()); -} - - -QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark) -{ - if (bookmark.isGroup()) - { - KBookmarkActionMenu *actionMenu = new KBookmarkActionMenu(bookmark, this); - BookmarkMenu *menu = new BookmarkMenu(manager(), owner(), actionMenu->menu(), bookmark.address()); - connect(actionMenu, SIGNAL(hovered()), menu, SLOT(slotAboutToShow())); - return actionMenu; - } - else if (bookmark.isSeparator()) - { - return KBookmarkMenu::actionForBookmark(bookmark); - } - else - { - KBookmarkAction *action = new KBookmarkAction(bookmark, owner(), this); - connect(action, SIGNAL(hovered()), this, SLOT(actionHovered())); - return action; - } -} - - -void BookmarkMenu::refill() -{ - clear(); - fillBookmarks(); - - if (parentMenu()->actions().count() > 0) - parentMenu()->addSeparator(); - - if (isRoot()) - { - addAddBookmark(); - addAddBookmarksList(); - addNewFolder(); - addEditBookmarks(); - } - else - { - addOpenFolderInTabs(); - addAddBookmark(); - addAddBookmarksList(); - addNewFolder(); - } -} - - -void BookmarkMenu::addOpenFolderInTabs() -{ - KAction *action; - KBookmarkGroup group = manager()->findByAddress(parentAddress()).toGroup(); - - if (!group.first().isNull()) - { - KBookmark bookmark = group.first(); - - while (bookmark.isGroup() || bookmark.isSeparator()) - { - bookmark = group.next(bookmark); - } - - if (!bookmark.isNull()) - { - action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); - action->setHelpText(i18n("Open all bookmarks in this folder as new tabs.")); - connect(action, SIGNAL(triggered(bool)), this, SLOT(slotOpenFolderInTabs())); - parentMenu()->addAction(action); - } - } -} - - -void BookmarkMenu::actionHovered() -{ - KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(sender()); - if (action) - Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url()); -} - - -// ------------------------------------------------------------------------------------------------------ - - -BookmarkToolBar::BookmarkToolBar( const QString &objectName, - QMainWindow *parentWindow, - Qt::ToolBarArea area, - bool newLine, - bool isMainToolBar, - bool readConfig - ) - : KToolBar(objectName, parentWindow, area, newLine, isMainToolBar, readConfig) - , m_filled(false) - , m_currentMenu(0) -{ - connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString,QString)), this, SLOT(hideMenu())); -} - - -BookmarkToolBar::~BookmarkToolBar() -{ -} - - -void BookmarkToolBar::setVisible(bool visible) -{ - if (visible && !m_filled) - { - m_filled = true; - Application::bookmarkProvider()->fillBookmarkBar(this); - } - KToolBar::setVisible(visible); -} - - -void BookmarkToolBar::menuDisplayed() -{ - qApp->installEventFilter(this); - m_currentMenu = qobject_cast<KMenu*>(sender()); -} - - -void BookmarkToolBar::menuHidden() -{ - qApp->removeEventFilter(this); - m_currentMenu = 0; -} - - -void BookmarkToolBar::hideMenu() -{ - if(m_currentMenu) - m_currentMenu->hide(); -} - - -bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event) -{ - // To switch root folders as in a menubar - if (event->type() == QEvent::MouseMove && m_currentMenu) - { - KBookmarkActionMenu* act = dynamic_cast<KBookmarkActionMenu *>(this->actionAt(this->mapFromGlobal(QCursor::pos()))); - if (act && act->menu() != m_currentMenu) - { - m_currentMenu->hide(); - QPoint pos = mapToGlobal(widgetForAction(act)->pos()); - act->menu()->popup(QPoint(pos.x(), pos.y() + widgetForAction(act)->height())); - } - } - return KToolBar::eventFilter(watched, event); -} - - -void BookmarkToolBar::actionHovered() -{ - KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(sender()); - if (action) - Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url()); -} - -// ------------------------------------------------------------------------------------------------------ - - - BookmarkProvider::BookmarkProvider(QObject *parent) : QObject(parent) , m_manager(0) @@ -368,7 +77,7 @@ BookmarkProvider::BookmarkProvider(QObject *parent) this, SLOT(slotBookmarksChanged(const QString &, const QString &))); // setup menu - m_owner = new BookmarkOwner(this); + m_owner = new BookmarkOwner(m_manager, this); connect(m_owner, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)), this, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &))); KAction *a = KStandardAction::addBookmark(this, SLOT(slotAddBookmark()), this); @@ -386,7 +95,7 @@ BookmarkProvider::~BookmarkProvider() } -void BookmarkProvider::setupBookmarkBar(BookmarkToolBar *toolbar) +void BookmarkProvider::registerBookmarkBar(BookmarkToolBar *toolbar) { if (m_bookmarkToolBars.contains(toolbar)) return; @@ -394,9 +103,9 @@ void BookmarkProvider::setupBookmarkBar(BookmarkToolBar *toolbar) kDebug() << "new bookmark bar..."; m_bookmarkToolBars.append(toolbar); - toolbar->setContextMenuPolicy(Qt::CustomContextMenu); - connect(toolbar, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); - + toolbar->toolBar()->setContextMenuPolicy(Qt::CustomContextMenu); + connect(toolbar->toolBar(), SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); + kDebug() << "new bookmark bar... DONE!"; } @@ -416,7 +125,7 @@ void BookmarkProvider::slotBookmarksChanged(const QString &group, const QString { if (bookmarkToolBar) { - bookmarkToolBar->clear(); + bookmarkToolBar->toolBar()->clear(); fillBookmarkBar(bookmarkToolBar); } } @@ -437,7 +146,7 @@ void BookmarkProvider::contextMenu(const QPoint &point) if (m_bookmarkToolBars.isEmpty()) return; - KToolBar *bookmarkToolBar = m_bookmarkToolBars.at(0); + KToolBar *bookmarkToolBar = m_bookmarkToolBars.at(0)->toolBar(); if (!bookmarkToolBar) return; @@ -445,7 +154,7 @@ void BookmarkProvider::contextMenu(const QPoint &point) if (!action) return; - BookmarkContextMenu menu(action->bookmark(), bookmarkManager(), bookmarkOwner()); + BookmarksContextMenu menu(action->bookmark(), bookmarkManager(), bookmarkOwner()); menu.exec(bookmarkToolBar->mapToGlobal(point)); } @@ -453,7 +162,7 @@ void BookmarkProvider::contextMenu(const QPoint &point) KActionMenu* BookmarkProvider::bookmarkActionMenu(QWidget *parent) { kDebug() << "new Bookmarks Menu..."; - + KMenu *menu = new KMenu(parent); _bookmarkActionMenu = new KActionMenu(parent); _bookmarkActionMenu->setMenu(menu); @@ -465,16 +174,6 @@ KActionMenu* BookmarkProvider::bookmarkActionMenu(QWidget *parent) } -KAction* BookmarkProvider::bookmarkToolBarAction(KToolBar *t) -{ - KAction *bookmarkToolBarAction = new KAction(this); - bookmarkToolBarAction->setDefaultWidget(t); // The ownership is transferred to action - bookmarkToolBarAction->setText(i18n("Bookmarks Bar")); - bookmarkToolBarAction->setShortcutConfigurable(false); - return bookmarkToolBarAction; -} - - void BookmarkProvider::fillBookmarkBar(BookmarkToolBar *toolBar) { KBookmarkGroup root = m_manager->toolbar(); @@ -490,12 +189,12 @@ void BookmarkProvider::fillBookmarkBar(BookmarkToolBar *toolBar) new BookmarkMenu(bookmarkManager(), bookmarkOwner(), menuAction->menu(), bookmark.address()); connect(menuAction->menu(), SIGNAL(aboutToShow()), toolBar, SLOT(menuDisplayed())); connect(menuAction->menu(), SIGNAL(aboutToHide()), toolBar, SLOT(menuHidden())); - toolBar->addAction(menuAction); + toolBar->toolBar()->addAction(menuAction); } else if (bookmark.isSeparator()) { - toolBar->addSeparator(); + toolBar->toolBar()->addSeparator(); } else @@ -503,7 +202,8 @@ void BookmarkProvider::fillBookmarkBar(BookmarkToolBar *toolBar) KBookmarkAction* action = new KBookmarkAction(bookmark, m_owner, this); action->setIconText(action->iconText().replace('&', "&&")); connect(action, SIGNAL(hovered()), toolBar, SLOT(actionHovered())); - toolBar->addAction(action); + toolBar->toolBar()->addAction(action); + toolBar->toolBar()->widgetForAction(action)->installEventFilter(toolBar); } } } @@ -524,7 +224,7 @@ QList<KBookmark> BookmarkProvider::find(QString text) return list; } - KBookmark bookmark = bookGroup.first(); + KBookmark bookmark = bookGroup.first(); while (!bookmark.isNull()) { list = find(list, bookmark, text); @@ -597,11 +297,10 @@ void BookmarkProvider::slotPanelChanged() KBookmark BookmarkProvider::bookmarkForUrl(const KUrl &url) { - KBookmark found; - KBookmarkGroup root = rootGroup(); if (root.isNull()) { + KBookmark found; return found; } diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h index eeb5391d..0c2b9ee2 100644 --- a/src/bookmarks/bookmarksmanager.h +++ b/src/bookmarks/bookmarksmanager.h @@ -34,179 +34,16 @@ // Rekonq Includes #include "rekonq_defines.h" -// Local Includes -#include "application.h" -#include "urlresolver.h" -#include "bookmarkspanel.h" - -// Qt Includes -#include <QWidget> - -// KDE Includes -#include <KBookmarkOwner> - -// Forward Declarations -class BookmarkProvider; - -class KAction; -class KActionCollection; -class KActionMenu; -class KUrl; -class KToolBar; -class KBookmarkManager; - - -/** - * Reimplementation of KBookmarkOwner, this class allows to manage - * bookmarks as actions - * - */ -class REKONQ_TESTS_EXPORT BookmarkOwner : public QObject , public KBookmarkOwner -{ - Q_OBJECT - -public: - - /** - * @short The class constructor. - * - * @param parent the pointer parent Bookmark provider. We need it - * to get pointer to MainWindow - */ - BookmarkOwner(QObject *parent = 0); - virtual ~BookmarkOwner() {} - - /** - * This function is called when a bookmark is selected and belongs to - * the ancestor class. - * This method actually emits signal to load bookmark's url. - * - * @param bookmark the bookmark to open - * @param mouseButtons the mouse buttons clicked to select the bookmark - * @param keyboardModifiers the keyboard modifiers pushed when the bookmark was selected - */ - virtual void openBookmark(const KBookmark &bookmark, - Qt::MouseButtons mouseButtons, - Qt::KeyboardModifiers keyboardModifiers); - - - /** - * this method, from KBookmarkOwner interface, allows to add the current page - * to the bookmark list, returning the URL page as QString. - * - * @return the current page's URL - */ - virtual QString currentUrl() const; - - /** - * this method, from KBookmarkOwner interface, allows to add the current page - * to the bookmark list, returning the title's page as QString. - * - * @return the current page's title - */ - virtual QString currentTitle() const; - - /** - * This function returns whether the owner supports tabs. - */ - virtual bool supportsTabs() const; - - /** - * Called if the user wants to open every bookmark in this folder in a new tab. - * The default implementation does nothing. - * This is only called if supportsTabs() returns true - */ - virtual void openFolderinTabs(const KBookmarkGroup &bookmark); - - virtual QList< QPair<QString, QString> > currentBookmarkList() const; - -signals: - /** - * This signal is emitted when an url has to be loaded - * - * @param url the URL to load - * - */ - void openUrl(const KUrl &, const Rekonq::OpenType &); -}; - -// ------------------------------------------------------------------------------ - - // KDE Includes #include <KBookmarkMenu> - -/** - * This class represent the rekonq bookmarks menu. - * It's just a simple class inherited from KBookmarkMenu - * - */ -class BookmarkMenu : public KBookmarkMenu -{ - Q_OBJECT - -public: - BookmarkMenu(KBookmarkManager* manager, - KBookmarkOwner* owner, - KMenu* menu, - KActionCollection* actionCollection); - BookmarkMenu(KBookmarkManager *manager, - KBookmarkOwner *owner, - KMenu *parentMenu, - const QString &parentAddress); - ~BookmarkMenu(); - -protected: - virtual KMenu * contextMenu(QAction * act); - virtual void refill(); - virtual QAction* actionForBookmark(const KBookmark &bookmark); - -private slots: - void actionHovered(); - -private: - void addOpenFolderInTabs(); - -}; - - -// ------------------------------------------------------------------------------ - #include <KToolBar> -class BookmarkToolBar : public KToolBar -{ - Q_OBJECT - -public: -BookmarkToolBar(const QString &objectName, - QMainWindow *parentWindow, - Qt::ToolBarArea area, - bool newLine = false, - bool isMainToolBar = false, - bool readConfig = true); -~BookmarkToolBar(); - -virtual void setVisible(bool visible); - -protected: - bool eventFilter(QObject *watched, QEvent *event); - -private slots: - void actionHovered(); - void menuDisplayed(); - void menuHidden(); - void hideMenu(); - -private: - bool m_filled; - KMenu *m_currentMenu; -}; - +// Forward Declarations +class BookmarksPanel; +class BookmarkToolBar; +class BookmarkOwner; -// ------------------------------------------------------------------------------ - /** * This class represent the interface to rekonq bookmarks system. * All rekonq needs (Bookmarks Menu, Bookmarks Toolbar) is provided @@ -237,12 +74,10 @@ public: */ KActionMenu *bookmarkActionMenu(QWidget *parent); - KAction *bookmarkToolBarAction(KToolBar *t); - /** * @short set the Bookmarks Toolbar Action */ - void setupBookmarkBar(BookmarkToolBar *); + void registerBookmarkBar(BookmarkToolBar *); void removeToolBar(BookmarkToolBar *); @@ -263,7 +98,7 @@ public: KBookmarkGroup rootGroup(); inline KBookmarkManager *bookmarkManager() { return m_manager; } - + inline BookmarkOwner *bookmarkOwner() { return m_owner; } QList<KBookmark> find(QString text); @@ -272,7 +107,7 @@ public: void removeBookmarkPanel(BookmarksPanel *panel); KBookmark bookmarkForUrl(const KUrl &url); - + signals: /** * @short This signal is emitted when an url has to be loaded @@ -299,11 +134,11 @@ public slots: */ void slotBookmarksChanged(const QString &group, const QString &caller); void fillBookmarkBar(BookmarkToolBar *toolBar); - + private slots: void slotAddBookmark(); void slotPanelChanged(); - + private: QList<KBookmark> find(QList<KBookmark> list, const KBookmark &bookmark, QString text); @@ -315,7 +150,7 @@ private: KActionCollection *m_actionCollection; QList<BookmarkToolBar *> m_bookmarkToolBars; QList<BookmarksPanel*> m_bookmarkPanels; - + KActionMenu *_bookmarkActionMenu; }; diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp index 75d8faf3..1b561515 100644 --- a/src/bookmarks/bookmarkspanel.cpp +++ b/src/bookmarks/bookmarkspanel.cpp @@ -27,57 +27,129 @@ // Self Includes #include "bookmarkspanel.h" -#include "bookmarkspanel.moc" // Local Includes +#include "application.h" #include "bookmarksmanager.h" #include "bookmarkstreemodel.h" #include "bookmarksproxy.h" -#include "bookmarkcontextmenu.h" +#include "bookmarkscontextmenu.h" +#include "bookmarkowner.h" +#include "paneltreeview.h" // Auto Includes #include "rekonq.h" // Qt includes -#include <QHBoxLayout> -#include <QLabel> -#include <QHeaderView> +#include <QtGui/QHBoxLayout> +#include <QtGui/QLabel> +#include <QtGui/QHeaderView> // KDE includes #include <KLineEdit> -#include <KLocalizedString> -#include <KMenu> -#include <KMessageBox> - BookmarksPanel::BookmarksPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) : QDockWidget(title, parent, flags) , m_treeView(new PanelTreeView(this)) , m_loadingState(false) - , _loaded(false) + , m_loaded(false) { setObjectName("bookmarksPanel"); setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); connect(this, SIGNAL(visibilityChanged(bool)), this, SLOT(showing(bool))); - setShown(ReKonfig::showBookmarksPanel()); + setVisible(ReKonfig::showBookmarksPanel()); } BookmarksPanel::~BookmarksPanel() { - ReKonfig::setShowBookmarksPanel(!isHidden()); + ReKonfig::setShowBookmarksPanel(false); } void BookmarksPanel::showing(bool b) { - if(b && !_loaded) + if(b && !m_loaded) setup(); } +void BookmarksPanel::startLoadFoldedState() +{ + m_loadingState = true; + loadFoldedState(QModelIndex()); + m_loadingState = false; +} + + +void BookmarksPanel::contextMenu(const QPoint &pos) +{ + if (m_loadingState) + return; + + BookmarksContextMenu menu(bookmarkForIndex( m_treeView->indexAt(pos) ), + Application::bookmarkProvider()->bookmarkManager(), + Application::bookmarkProvider()->bookmarkOwner(), + this + ); + + menu.exec(m_treeView->mapToGlobal(pos)); +} + + +void BookmarksPanel::deleteBookmark() +{ + QModelIndex index = m_treeView->currentIndex(); + if (m_loadingState || !index.isValid()) + return; + + Application::bookmarkProvider()->bookmarkOwner()->deleteBookmark(bookmarkForIndex(index)); +} + + +void BookmarksPanel::onCollapse(const QModelIndex &index) +{ + if (m_loadingState) + return; + + bookmarkForIndex(index).internalElement().setAttribute("folded", "yes"); + emit expansionChanged(); +} + + +void BookmarksPanel::onExpand(const QModelIndex &index) +{ + if (m_loadingState) + return; + + bookmarkForIndex(index).internalElement().setAttribute("folded", "no"); + emit expansionChanged(); +} + + +void BookmarksPanel::loadFoldedState(const QModelIndex &root) +{ + int count = m_treeView->model()->rowCount(root); + QModelIndex index; + + for (int i = 0; i < count; ++i) + { + index = m_treeView->model()->index(i, 0, root); + if (index.isValid()) + { + KBookmark bm = bookmarkForIndex(index); + if (bm.isGroup()) + { + m_treeView->setExpanded(index, bm.toGroup().isOpen()); + loadFoldedState(index); + } + } + } +} + + void BookmarksPanel::setup() { kDebug() << "Loading bookmarks panel setup..."; @@ -96,8 +168,6 @@ void BookmarksPanel::setup() // setup tree view m_treeView->setUniformRowHeights(true); - m_treeView->setTextElideMode(Qt::ElideMiddle); - m_treeView->setAlternatingRowColors(true); m_treeView->header()->hide(); m_treeView->setDragEnabled(true); m_treeView->setAutoExpandDelay(750); @@ -119,16 +189,20 @@ void BookmarksPanel::setup() proxy->setSourceModel(model); m_treeView->setModel(proxy); + connect(search, SIGNAL(textChanged(const QString &)), proxy, SLOT(setFilterFixedString(const QString &))); + + connect(model, SIGNAL(bookmarksUpdated()), this, SLOT(startLoadFoldedState())); + connect(m_treeView, SIGNAL(contextMenuItemRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); connect(m_treeView, SIGNAL(contextMenuGroupRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); connect(m_treeView, SIGNAL(contextMenuEmptyRequested(const QPoint &)), this, SLOT(contextMenu(const QPoint &))); connect(m_treeView, SIGNAL(delKeyPressed()), this, SLOT(deleteBookmark())); connect(m_treeView, SIGNAL(collapsed(const QModelIndex &)), this, SLOT(onCollapse(const QModelIndex &))); connect(m_treeView, SIGNAL(expanded(const QModelIndex &)), this, SLOT(onExpand(const QModelIndex &))); - connect(search, SIGNAL(textChanged(const QString &)), proxy, SLOT(setFilterFixedString(const QString &))); + startLoadFoldedState(); - _loaded = true; + m_loaded = true; } @@ -137,105 +211,9 @@ KBookmark BookmarksPanel::bookmarkForIndex(const QModelIndex &index) if (!index.isValid()) return KBookmark(); - const QAbstractProxyModel* proxyModel = dynamic_cast< const QAbstractProxyModel* >(index.model()); + const BookmarksProxy *proxyModel = static_cast<const BookmarksProxy*>(index.model()); QModelIndex originalIndex = proxyModel->mapToSource(index); - BtmItem *node = static_cast< BtmItem* >(originalIndex.internalPointer()); + BtmItem *node = static_cast<BtmItem*>(originalIndex.internalPointer()); return node->getBkm(); } - - -void BookmarksPanel::onCollapse(const QModelIndex &index) -{ - if (m_loadingState) - return; - - KBookmark bookmark = bookmarkForIndex(index); - bookmark.internalElement().setAttribute("folded", "yes"); - emit expansionChanged(); -} - - -void BookmarksPanel::onExpand(const QModelIndex &index) -{ - if (m_loadingState) - return; - - KBookmark bookmark = bookmarkForIndex(index); - bookmark.internalElement().setAttribute("folded", "no"); - emit expansionChanged(); -} - - -void BookmarksPanel::startLoadFoldedState() -{ - m_loadingState = true; - loadFoldedState(QModelIndex()); - m_loadingState = false; -} - - -void BookmarksPanel::loadFoldedState(const QModelIndex &root) -{ - - int count = m_treeView->model()->rowCount(root); - QModelIndex index; - - for (int i = 0; i < count; i++) - { - index = m_treeView->model()->index(i, 0, root); - if (index.isValid() && bookmarkForIndex(index).isGroup()) - { - m_treeView->setExpanded(index, bookmarkForIndex(index).toGroup().isOpen()); - loadFoldedState(index); - } - } -} - - -void BookmarksPanel::contextMenu(const QPoint &pos) -{ - QModelIndex index = m_treeView->indexAt(pos); - if (m_loadingState) - return; - - KBookmark selected = bookmarkForIndex(index); - - BookmarkContextMenu menu( selected, - Application::bookmarkProvider()->bookmarkManager(), - Application::bookmarkProvider()->bookmarkOwner(), - this - ); - - menu.exec(m_treeView->mapToGlobal(pos)); -} - - -void BookmarksPanel::deleteBookmark() -{ - QModelIndex index = m_treeView->currentIndex(); - if (!index.isValid()) - return; - - KBookmark bm = bookmarkForIndex(index); - KBookmarkGroup bmg = bm.parentGroup(); - bool folder = bm.isGroup(); - QString name = QString(bm.fullText()).replace("&&", "&"); - - if (KMessageBox::warningContinueCancel( - QApplication::activeWindow(), - folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", name) - : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", name), - folder ? i18n("Bookmark Folder Deletion") - : i18n("Bookmark Deletion"), - KStandardGuiItem::del(), - KStandardGuiItem::cancel(), - "bookmarkDeletition_askAgain") - != KMessageBox::Continue - ) - return; - - - bmg.deleteBookmark(bm); - Application::instance()->bookmarkProvider()->bookmarkManager()->emitChanged(bmg); -} diff --git a/src/bookmarks/bookmarkspanel.h b/src/bookmarks/bookmarkspanel.h index d94f2b99..4afa953b 100644 --- a/src/bookmarks/bookmarkspanel.h +++ b/src/bookmarks/bookmarkspanel.h @@ -33,28 +33,21 @@ // Rekonq Includes #include "rekonq_defines.h" -// Local Includes -#include "application.h" -#include "paneltreeview.h" - // Qt Includes #include <QDockWidget> -// KDE Includes -#include <KBookmark> - // Forward Declarations -class KUrl; +class PanelTreeView; +class KBookmark; class QModelIndex; - class REKONQ_TESTS_EXPORT BookmarksPanel : public QDockWidget { Q_OBJECT public: explicit BookmarksPanel(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); - ~BookmarksPanel(); + virtual ~BookmarksPanel(); signals: void openUrl(const KUrl &, const Rekonq::OpenType &); @@ -64,7 +57,7 @@ signals: public slots: void showing(bool); void startLoadFoldedState(); - + private slots: void contextMenu(const QPoint &pos); @@ -78,9 +71,7 @@ private: KBookmark bookmarkForIndex(const QModelIndex &index); PanelTreeView *m_treeView; - bool m_loadingState; - - bool _loaded; + bool m_loadingState, m_loaded; }; #endif // BOOKMARKSPANEL_H diff --git a/src/bookmarks/bookmarksproxy.cpp b/src/bookmarks/bookmarksproxy.cpp index 4e4b4f06..1e4da877 100644 --- a/src/bookmarks/bookmarksproxy.cpp +++ b/src/bookmarks/bookmarksproxy.cpp @@ -27,19 +27,18 @@ // Self Includes #include "bookmarksproxy.h" -#include "bookmarksproxy.moc" BookmarksProxy::BookmarksProxy(QObject *parent) : QSortFilterProxyModel(parent) { + setFilterCaseSensitivity(Qt::CaseInsensitive); } -bool BookmarksProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +bool BookmarksProxy::filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const { - QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); - return recursiveMatch(idx); + return recursiveMatch( sourceModel()->index(source_row, 0, source_parent) ); } @@ -48,10 +47,12 @@ bool BookmarksProxy::recursiveMatch(const QModelIndex &index) const if (index.data().toString().contains(filterRegExp())) return true; - for (int childRow = 0; childRow < sourceModel()->rowCount(index); ++childRow) + int numChildren = sourceModel()->rowCount(index); + for (int childRow = 0; childRow < numChildren; ++childRow) { if (recursiveMatch(sourceModel()->index(childRow, 0, index))) return true; } + return false; } diff --git a/src/bookmarks/bookmarksproxy.h b/src/bookmarks/bookmarksproxy.h index e7b50d8e..b4554d2b 100644 --- a/src/bookmarks/bookmarksproxy.h +++ b/src/bookmarks/bookmarksproxy.h @@ -33,9 +33,13 @@ #include "rekonq_defines.h" // Qt Includes -#include <QSortFilterProxyModel> - +#include <QtGui/QSortFilterProxyModel> +/** + * QSortFilterProxyModel hides all children which parent doesn't + * match the filter. This class is used to change this behavior. + * If a bookmark matches the filter it'll be shown, even if it's parent doesn't match it. + */ class REKONQ_TESTS_EXPORT BookmarksProxy : public QSortFilterProxyModel { Q_OBJECT @@ -45,9 +49,9 @@ public: BookmarksProxy(QObject *parent = 0); protected: - virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + virtual bool filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const; - // returns true if any child(or children-child...) matches filter + // returns true if index or any of his children match the filter bool recursiveMatch(const QModelIndex &index) const; }; diff --git a/src/bookmarks/bookmarkstoolbar.cpp b/src/bookmarks/bookmarkstoolbar.cpp new file mode 100644 index 00000000..bce2bd1e --- /dev/null +++ b/src/bookmarks/bookmarkstoolbar.cpp @@ -0,0 +1,435 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "bookmarkstoolbar.h" +#include "bookmarkstoolbar.moc" + +// Local Includes +#include "bookmarkscontextmenu.h" +#include "mainwindow.h" +#include "application.h" +#include "bookmarksmanager.h" +#include "bookmarkowner.h" + +// Qt Includes +#include <QtGui/QFrame> +#include <QActionEvent> + + +BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *menu, + KActionCollection* actionCollection) + : KBookmarkMenu(manager, owner, menu, actionCollection) +{ +} + + +BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *parentMenu, + const QString &parentAddress) + : KBookmarkMenu(manager, owner, parentMenu, parentAddress) +{ +} + + +BookmarkMenu::~BookmarkMenu() +{ +} + + +KMenu * BookmarkMenu::contextMenu(QAction *act) +{ + + KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act); + if (!action) + return 0; + return new BookmarksContextMenu(action->bookmark(), manager(), static_cast<BookmarkOwner*>(owner())); +} + + +QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark) +{ + if (bookmark.isGroup()) + { + KBookmarkActionMenu *actionMenu = new KBookmarkActionMenu(bookmark, this); + BookmarkMenu *menu = new BookmarkMenu(manager(), owner(), actionMenu->menu(), bookmark.address()); + // An hack to get rid of bug 219274 + connect(actionMenu, SIGNAL(hovered()), menu, SLOT(slotAboutToShow())); + return actionMenu; + } + else if (bookmark.isSeparator()) + { + return KBookmarkMenu::actionForBookmark(bookmark); + } + else + { + KBookmarkAction *action = new KBookmarkAction(bookmark, owner(), this); + connect(action, SIGNAL(hovered()), this, SLOT(actionHovered())); + return action; + } +} + + +void BookmarkMenu::refill() +{ + clear(); + fillBookmarks(); + + if (parentMenu()->actions().count() > 0) + parentMenu()->addSeparator(); + + if (isRoot()) + { + addAddBookmark(); + addAddBookmarksList(); + addNewFolder(); + addEditBookmarks(); + } + else + { + addOpenFolderInTabs(); + addAddBookmark(); + addAddBookmarksList(); + addNewFolder(); + } +} + + +void BookmarkMenu::addOpenFolderInTabs() +{ + KAction *action; + KBookmarkGroup group = manager()->findByAddress(parentAddress()).toGroup(); + + if (!group.first().isNull()) + { + KBookmark bookmark = group.first(); + + while (bookmark.isGroup() || bookmark.isSeparator()) + { + bookmark = group.next(bookmark); + } + + if (!bookmark.isNull()) + { + action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); + action->setHelpText(i18n("Open all bookmarks in this folder as new tabs.")); + connect(action, SIGNAL(triggered(bool)), this, SLOT(slotOpenFolderInTabs())); + parentMenu()->addAction(action); + } + } +} + + +void BookmarkMenu::actionHovered() +{ + KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(sender()); + if (action) + Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url()); +} + + +// ------------------------------------------------------------------------------------------------------ + + +BookmarkToolBar::BookmarkToolBar(KToolBar *toolBar, QObject *parent) + : QObject(parent) + , m_toolBar(toolBar) + , m_currentMenu(0) + , m_dragAction(0) + , m_dropAction(0) + , m_filled(false) +{ + connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(hideMenu())); + toolBar->setAcceptDrops(true); + toolBar->installEventFilter(this); + + if (toolBar->isVisible()) + { + Application::bookmarkProvider()->fillBookmarkBar(this); + m_filled = true; + } +} + + +BookmarkToolBar::~BookmarkToolBar() +{ +} + + +KToolBar* BookmarkToolBar::toolBar() +{ + return m_toolBar; +} + + +void BookmarkToolBar::menuDisplayed() +{ + qApp->installEventFilter(this); + m_currentMenu = qobject_cast<KMenu*>(sender()); +} + + +void BookmarkToolBar::menuHidden() +{ + qApp->removeEventFilter(this); + m_currentMenu = 0; +} + + +void BookmarkToolBar::hideMenu() +{ + if(m_currentMenu) + m_currentMenu->hide(); +} + + +bool BookmarkToolBar::eventFilter(QObject *watched, QEvent *event) +{ + if (m_currentMenu && m_currentMenu->isVisible()) + { + // To switch root folders as in a menubar + KBookmarkActionMenu* act = dynamic_cast<KBookmarkActionMenu *>(toolBar()->actionAt(toolBar()->mapFromGlobal(QCursor::pos()))); + if (event->type() == QEvent::MouseMove && act && m_currentMenu && act->menu() != m_currentMenu) + { + m_currentMenu->hide(); + QPoint pos = toolBar()->mapToGlobal(toolBar()->widgetForAction(act)->pos()); + act->menu()->popup(QPoint(pos.x(), pos.y() + toolBar()->widgetForAction(act)->height())); + } + } + else if (watched == toolBar()) + { + if (event->type() == QEvent::Show) + { + if (!m_filled) + { + Application::bookmarkProvider()->fillBookmarkBar(this); + m_filled = true; + } + } + if (event->type() == QEvent::ActionRemoved) + { + QActionEvent *actionEvent = static_cast<QActionEvent*>(event); + if (actionEvent && actionEvent->action() != m_dropAction) + { + QWidget *widget = toolBar()->widgetForAction(actionEvent->action()); + if (widget) + { + widget->removeEventFilter(this); + } + } + } + else if (event->type() == QEvent::ParentChange) + { + QActionEvent *actionEvent = static_cast<QActionEvent*>(event); + if (actionEvent && actionEvent->action() != m_dropAction) + { + QWidget *widget = toolBar()->widgetForAction(actionEvent->action()); + if (widget) + { + widget->removeEventFilter(this); + } + } + } + else if (event->type() == QEvent::DragEnter) + { + QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent*>(event); + if (dragEvent->mimeData()->hasFormat("application/rekonq-bookmark")) + { + QByteArray addresses = dragEvent->mimeData()->data("application/rekonq-bookmark"); + KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data())); + + if (!bookmark.isNull()) + { + QFrame* dropIndicatorWidget = new QFrame(toolBar()); + dropIndicatorWidget->setFrameShape(QFrame::VLine); + m_dropAction = toolBar()->insertWidget(toolBar()->actionAt(dragEvent->pos()), dropIndicatorWidget); + + dragEvent->accept(); + } + } + } + else if (event->type() == QEvent::DragMove) + { + QDragMoveEvent *dragEvent = static_cast<QDragMoveEvent*>(event); + if (dragEvent->mimeData()->hasFormat("application/rekonq-bookmark")) + { + QByteArray addresses = dragEvent->mimeData()->data("application/rekonq-bookmark"); + KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data())); + QAction *overAction = toolBar()->actionAt(dragEvent->pos()); + KBookmarkActionInterface *overActionBK = dynamic_cast<KBookmarkActionInterface*>(overAction); + QWidget *widgetAction = toolBar()->widgetForAction(overAction); + + if (!bookmark.isNull() && overAction != m_dropAction && overActionBK && widgetAction && m_dropAction) + { + toolBar()->removeAction(m_dropAction); + + if ((dragEvent->pos().x() - widgetAction->pos().x()) > (widgetAction->width() / 2)) + { + if (toolBar()->actions().count() > toolBar()->actions().indexOf(overAction) + 1) + { + toolBar()->insertAction(toolBar()->actions().at(toolBar()->actions().indexOf(overAction) + 1), m_dropAction); + } + else + { + toolBar()->addAction(m_dropAction); + } + } + else + { + toolBar()->insertAction(overAction, m_dropAction); + } + + dragEvent->accept(); + } + } + } + else if (event->type() == QEvent::DragLeave) + { + QDragLeaveEvent *dragEvent = static_cast<QDragLeaveEvent*>(event); + delete m_dropAction; + m_dropAction = 0; + dragEvent->accept(); + } + else if (event->type() == QEvent::Drop) + { + QDropEvent *dropEvent = static_cast<QDropEvent*>(event); + if (dropEvent->mimeData()->hasFormat("application/rekonq-bookmark")) + { + QByteArray addresses = dropEvent->mimeData()->data("application/rekonq-bookmark"); + KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data())); + + QAction *destAction = toolBar()->actionAt(dropEvent->pos()); + if (destAction && destAction == m_dropAction) + { + if (toolBar()->actions().indexOf(m_dropAction) > 0) + { + destAction = toolBar()->actions().at(toolBar()->actions().indexOf(m_dropAction) - 1); + } + else + { + destAction = toolBar()->actions().at(1); + } + } + + KBookmarkActionInterface *destBookmarkAction = dynamic_cast<KBookmarkActionInterface *>(destAction); + QWidget *widgetAction = toolBar()->widgetForAction(destAction); + + if (!bookmark.isNull() && destBookmarkAction && !destBookmarkAction->bookmark().isNull() + && widgetAction && bookmark.address() != destBookmarkAction->bookmark().address()) + { + KBookmarkGroup root = Application::bookmarkProvider()->rootGroup(); + KBookmark destBookmark = destBookmarkAction->bookmark(); + // To fix an issue with panel's drags + root.deleteBookmark(bookmark); + + if ((dropEvent->pos().x() - widgetAction->pos().x()) > (widgetAction->width() / 2)) + { + root.moveBookmark(bookmark, destBookmark); + } + else + { + root.moveBookmark(bookmark, destBookmark.parentGroup().previous(destBookmark)); + } + + Application::bookmarkProvider()->bookmarkManager()->emitChanged(); + dropEvent->accept(); + } + } + } + } + else + { + // Drag handling + if (event->type() == QEvent::MouseButtonPress) + {//QMessageBox::information(NULL, "", ""); + QPoint pos = toolBar()->mapFromGlobal(QCursor::pos()); + KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(toolBar()->actionAt(pos)); + + if (action && !action->bookmark().isGroup()) + { + m_dragAction = toolBar()->actionAt(pos); + m_startDragPos = pos; + } + } + else if (event->type() == QEvent::MouseMove) + { + int distance = (toolBar()->mapFromGlobal(QCursor::pos()) - m_startDragPos).manhattanLength(); + if (distance >= QApplication::startDragDistance()) + { + startDrag(); + } + } + } + + return QObject::eventFilter(watched, event); +} + + +void BookmarkToolBar::actionHovered() +{ + KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(sender()); + if (action) + Application::instance()->mainWindow()->notifyMessage(action->bookmark().url().url()); +} + + +void BookmarkToolBar::startDrag() +{ + KBookmarkActionInterface *action = dynamic_cast<KBookmarkActionInterface *>(m_dragAction); + if (action && !action->bookmark().isGroup()) + { + QMimeData *mimeData = new QMimeData; + + QByteArray address = action->bookmark().address().toLatin1(); + mimeData->setData("application/rekonq-bookmark", address); + action->bookmark().populateMimeData(mimeData); + + QDrag *drag = new QDrag(toolBar()); + drag->setMimeData(mimeData); + drag->setPixmap(KIcon(action->bookmark().icon()).pixmap(24, 24)); + + drag->start(Qt::MoveAction); + connect(drag, SIGNAL(destroyed()), this, SLOT(dragDestroyed())); + } +} + + +void BookmarkToolBar::dragDestroyed() +{ + // A workaround to get rid of the checked state of the dragged action + if (m_dragAction) + { + m_dragAction->setVisible(false); + m_dragAction->setVisible(true); + m_dragAction = 0; + } + delete m_dropAction; + m_dropAction = 0; +} diff --git a/src/bookmarks/bookmarkstoolbar.h b/src/bookmarks/bookmarkstoolbar.h new file mode 100644 index 00000000..54a430e3 --- /dev/null +++ b/src/bookmarks/bookmarkstoolbar.h @@ -0,0 +1,111 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2010 by Yoann Laissus <yoann dot laissus at gmail dot com> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* 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 General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + +#ifndef BOOKMARKSTOOLBAR_H +#define BOOKMARKSTOOLBAR_H + + +// KDE Includes +#include <KBookmarkMenu> + +/** + * This class represent the rekonq bookmarks menu. + * It's just a simple class inherited from KBookmarkMenu + * + */ +class BookmarkMenu : public KBookmarkMenu +{ + Q_OBJECT + +public: + BookmarkMenu(KBookmarkManager* manager, + KBookmarkOwner* owner, + KMenu* menu, + KActionCollection* actionCollection); + BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *parentMenu, + const QString &parentAddress); + ~BookmarkMenu(); + +protected: + virtual KMenu * contextMenu(QAction * act); + virtual void refill(); + virtual QAction* actionForBookmark(const KBookmark &bookmark); + +private slots: + void actionHovered(); + +private: + void addOpenFolderInTabs(); + +}; + + +// ------------------------------------------------------------------------------ + + +// KDE Includes +#include <KToolBar> + + +/** + * This class manage the bookmark toolbar. + * Some events from the toolbar are handled to allow the drag and drop + */ + +class BookmarkToolBar : public QObject +{ + Q_OBJECT + +public: +BookmarkToolBar(KToolBar *toolBar, QObject *parent); +~BookmarkToolBar(); + +KToolBar* toolBar(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private slots: + void actionHovered(); + void menuDisplayed(); + void menuHidden(); + void hideMenu(); + void dragDestroyed(); + +private: + void startDrag(); + + KToolBar *m_toolBar; + KMenu *m_currentMenu; + QPoint m_startDragPos; + QAction *m_dragAction; + QAction *m_dropAction; + bool m_filled; +}; + +#endif // BOOKMARKSTOOLBAR_H diff --git a/src/bookmarks/bookmarkstreemodel.cpp b/src/bookmarks/bookmarkstreemodel.cpp index 299efaf0..7f0bf66f 100644 --- a/src/bookmarks/bookmarkstreemodel.cpp +++ b/src/bookmarks/bookmarkstreemodel.cpp @@ -27,18 +27,13 @@ // Self Includes #include "bookmarkstreemodel.h" -#include "bookmarkstreemodel.moc" // Local Includes #include "application.h" #include "bookmarksmanager.h" // Qt Includes -#include <QMimeData> - -// KDE includes -#include <KBookmarkGroup> -#include <KLocalizedString> +#include <QtCore/QMimeData> BtmItem::BtmItem(const KBookmark &bm) @@ -140,6 +135,7 @@ KBookmark BtmItem::getBkm() const return m_kbm; } + // ------------------------------------------------------------------------------------- @@ -149,7 +145,6 @@ BookmarksTreeModel::BookmarksTreeModel(QObject *parent) { resetModel(); connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(const QString &, const QString &)), this, SLOT(bookmarksChanged(const QString &))); - connect(this, SIGNAL(bookmarksUpdated()), parent, SLOT(startLoadFoldedState())); } @@ -168,33 +163,19 @@ int BookmarksTreeModel::rowCount(const QModelIndex &parent) const } else { - parentItem = static_cast< BtmItem* >(parent.internalPointer()); + parentItem = static_cast<BtmItem*>(parent.internalPointer()); } return parentItem->childCount(); } -int BookmarksTreeModel::columnCount(const QModelIndex &parent) const +int BookmarksTreeModel::columnCount(const QModelIndex& /*parent*/) const { - Q_UNUSED(parent) - // name return 1; } -QVariant BookmarksTreeModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal - && role == Qt::DisplayRole - && section == 0 - ) - return i18n("Bookmark"); - - return QVariant(); -} - - Qt::ItemFlags BookmarksTreeModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); @@ -214,26 +195,18 @@ Qt::ItemFlags BookmarksTreeModel::flags(const QModelIndex &index) const QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) - { return QModelIndex(); - } BtmItem *parentItem; if (!parent.isValid()) - { parentItem = m_root; - } else - { - parentItem = static_cast< BtmItem* >(parent.internalPointer()); - } + parentItem = static_cast<BtmItem*>(parent.internalPointer()); BtmItem *childItem = parentItem->child(row); if (childItem) - { return createIndex(row, column, childItem); - } return QModelIndex(); } @@ -242,17 +215,13 @@ QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &pa QModelIndex BookmarksTreeModel::parent(const QModelIndex &index) const { if (!index.isValid()) - { return QModelIndex(); - } - BtmItem *childItem = static_cast< BtmItem* >(index.internalPointer()); + BtmItem *childItem = static_cast<BtmItem*>(index.internalPointer()); BtmItem *parentItem = childItem->parent(); if (parentItem == m_root) - { return QModelIndex(); - } return createIndex(parentItem->row(), 0, parentItem); } @@ -261,11 +230,9 @@ QModelIndex BookmarksTreeModel::parent(const QModelIndex &index) const QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) - { return QVariant(); - } - BtmItem *node = static_cast< BtmItem* >(index.internalPointer()); + BtmItem *node = static_cast<BtmItem*>(index.internalPointer()); if (node && node == m_root) { if (role == Qt::DisplayRole) @@ -283,12 +250,67 @@ QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const } +QStringList BookmarksTreeModel::mimeTypes() const +{ + return KBookmark::List::mimeDataTypes(); +} + + +bool BookmarksTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + if (action != Qt::MoveAction || !data->hasFormat("application/rekonq-bookmark")) + return false; + + QByteArray addresses = data->data("application/rekonq-bookmark"); + KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data())); + + KBookmarkGroup root; + if (parent.isValid()) + root = bookmarkForIndex(parent).toGroup(); + else + root = Application::bookmarkProvider()->rootGroup(); + + QModelIndex destIndex = index(row, column, parent); + + if (destIndex.isValid() && row != -1) + { + root.moveBookmark(bookmark, root.previous(bookmarkForIndex(destIndex))); + } + else + { + root.deleteBookmark(bookmark); + root.addBookmark(bookmark); + } + + Application::bookmarkProvider()->bookmarkManager()->emitChanged(); + + return true; +} + + +Qt::DropActions BookmarksTreeModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + + +QMimeData* BookmarksTreeModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData; + + QByteArray address = bookmarkForIndex(indexes.first()).address().toLatin1(); + mimeData->setData("application/rekonq-bookmark", address); + bookmarkForIndex(indexes.first()).populateMimeData(mimeData); + + return mimeData; +} + + void BookmarksTreeModel::bookmarksChanged(const QString &groupAddress) { if (groupAddress.isEmpty()) { resetModel(); - emit bookmarksUpdated(); } else { @@ -296,11 +318,12 @@ void BookmarksTreeModel::bookmarksChanged(const QString &groupAddress) BtmItem *node = m_root; QModelIndex nodeIndex; - QStringList indexChain( groupAddress.split( '/', QString::SkipEmptyParts) ); - foreach( const QString &sIndex, indexChain ) + QStringList indexChain( groupAddress.split('/', QString::SkipEmptyParts) ); + bool ok; + int i; + foreach (const QString &sIndex, indexChain) { - bool ok; - int i = sIndex.toInt( &ok ); + i = sIndex.toInt( &ok ); if( !ok ) break; @@ -312,8 +335,9 @@ void BookmarksTreeModel::bookmarksChanged(const QString &groupAddress) } populate(node, Application::bookmarkProvider()->bookmarkManager()->findByAddress(groupAddress).toGroup()); endResetModel(); - emit bookmarksUpdated(); } + + emit bookmarksUpdated(); } @@ -328,10 +352,6 @@ void BookmarksTreeModel::setRoot(KBookmarkGroup bmg) beginResetModel(); delete m_root; m_root = new BtmItem(KBookmark()); - - if (bmg.isNull()) - return; - populate(m_root, bmg); endResetModel(); } @@ -361,64 +381,3 @@ KBookmark BookmarksTreeModel::bookmarkForIndex(const QModelIndex &index) const { return static_cast<BtmItem*>(index.internalPointer())->getBkm(); } - - -Qt::DropActions BookmarksTreeModel::supportedDropActions() const -{ - return Qt::MoveAction; -} - - -QStringList BookmarksTreeModel::mimeTypes() const -{ - return KBookmark::List::mimeDataTypes(); -} - - -QMimeData* BookmarksTreeModel::mimeData(const QModelIndexList & indexes) const -{ - QMimeData *mimeData = new QMimeData; - - QByteArray address = bookmarkForIndex(indexes.first()).address().toLatin1(); - mimeData->setData("application/rekonq-bookmark", address); - bookmarkForIndex(indexes.first()).populateMimeData(mimeData); - - return mimeData; -} - - -bool BookmarksTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex & parent) -{ - if (action == Qt::MoveAction) - { - if (data->hasFormat("application/rekonq-bookmark")) - { - QByteArray addresses = data->data("application/rekonq-bookmark"); - KBookmark bookmark = Application::bookmarkProvider()->bookmarkManager()->findByAddress(QString::fromLatin1(addresses.data())); - - QModelIndex destIndex = index(row, column, parent); - - KBookmark dropDestBookmark; - if (destIndex.isValid()) - dropDestBookmark = bookmarkForIndex(destIndex); - - KBookmarkGroup root = Application::bookmarkProvider()->rootGroup(); - if (parent.isValid()) - root = bookmarkForIndex(parent).toGroup(); - - if (destIndex.isValid() && row != -1) - { - root.moveBookmark(bookmark, root.previous(dropDestBookmark)); - - } - else - { - root.deleteBookmark(bookmark); - root.addBookmark(bookmark); - } - - Application::bookmarkProvider()->bookmarkManager()->emitChanged(); - } - } - return true; -} diff --git a/src/bookmarks/bookmarkstreemodel.h b/src/bookmarks/bookmarkstreemodel.h index c509840b..6b85365b 100644 --- a/src/bookmarks/bookmarkstreemodel.h +++ b/src/bookmarks/bookmarkstreemodel.h @@ -36,13 +36,14 @@ #include <KBookmark> // Qt Includes -#include <QAbstractItemModel> +#include <QtCore/QAbstractItemModel> class BtmItem { public: BtmItem(const KBookmark &bm); ~BtmItem(); + QVariant data(int role = Qt::DisplayRole) const; int row() const; int childCount() const; @@ -66,22 +67,33 @@ class REKONQ_TESTS_EXPORT BookmarksTreeModel : public QAbstractItemModel public: explicit BookmarksTreeModel(QObject *parent = 0); - ~BookmarksTreeModel(); + virtual ~BookmarksTreeModel(); + /** + * @return number of rows under the given parent. + */ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + /** + * @return number of columns (always 1). + */ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual Qt::ItemFlags flags(const QModelIndex &index) const; + /** + * @return index in the model specified by the given row, column and parent. + */ virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + /** + * @return parent of the given index. + */ virtual QModelIndex parent(const QModelIndex &index) const; virtual QVariant data(const QModelIndex &index, int role) const; virtual QStringList mimeTypes() const; - virtual bool dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent); + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); virtual Qt::DropActions supportedDropActions() const; - virtual QMimeData *mimeData(const QModelIndexList & indexes) const; + virtual QMimeData *mimeData(const QModelIndexList &indexes) const; private slots: void bookmarksChanged(const QString &groupAddress); diff --git a/src/data/rekonq.desktop b/src/data/rekonq.desktop index f8a78960..7c45af77 100644 --- a/src/data/rekonq.desktop +++ b/src/data/rekonq.desktop @@ -37,6 +37,7 @@ GenericName[fr]=Navigateur web GenericName[it]=Browser Web GenericName[pt]=Navegador Web GenericName[pt_BR]=Navegador Web +GenericName[ru]=Веб-браузер GenericName[sr]=Веб прегледач GenericName[sr@ijekavian]=Веб прегледач GenericName[sr@ijekavianlatin]=Veb pregledač diff --git a/src/history/historymanager.cpp b/src/history/historymanager.cpp index 966487a9..5cd85cd7 100644 --- a/src/history/historymanager.cpp +++ b/src/history/historymanager.cpp @@ -65,22 +65,18 @@ static const unsigned int HISTORY_VERSION = 23; HistoryManager::HistoryManager(QObject *parent) : QWebHistoryInterface(parent) , m_saveTimer(new AutoSaver(this)) - , m_historyLimit(30) - , m_historyModel(0) - , m_historyFilterModel(0) + , m_historyLimit(0) , m_historyTreeModel(0) { kDebug() << "Loading HistoryManager..."; - m_expiredTimer.setSingleShot(true); - connect(&m_expiredTimer, SIGNAL(timeout()), this, SLOT(checkForExpired())); connect(this, SIGNAL(entryAdded(const HistoryItem &)), m_saveTimer, SLOT(changeOccurred())); connect(this, SIGNAL(entryRemoved(const HistoryItem &)), m_saveTimer, SLOT(changeOccurred())); load(); - m_historyModel = new HistoryModel(this, this); - m_historyFilterModel = new HistoryFilterModel(m_historyModel, this); + HistoryModel *historyModel = new HistoryModel(this, this); + m_historyFilterModel = new HistoryFilterModel(historyModel, this); m_historyTreeModel = new HistoryTreeModel(m_historyFilterModel, this); // QWebHistoryInterface will delete the history manager @@ -92,24 +88,17 @@ HistoryManager::HistoryManager(QObject *parent) HistoryManager::~HistoryManager() { m_saveTimer->saveIfNeccessary(); - - delete m_saveTimer; - - delete m_historyModel; + delete m_historyFilterModel; delete m_historyTreeModel; -} - -QList<HistoryItem> HistoryManager::history() const -{ - return m_history; + delete m_saveTimer; } bool HistoryManager::historyContains(const QString &url) const { - return m_hash.contains(url) && m_hash[url].savedCount>0; + return m_historyFilterModel->historyContains(url); } @@ -130,7 +119,6 @@ void HistoryManager::addHistoryEntry(const QString &url) HistoryItem item(cleanUrl.toString(), QDateTime::currentDateTime()); m_history.prepend(item); - addHistoryHashEntry(item); emit entryAdded(item); if (m_history.count() == 1) @@ -141,14 +129,7 @@ void HistoryManager::addHistoryEntry(const QString &url) void HistoryManager::setHistory(const QList<HistoryItem> &history, bool loadedAndSorted) { m_history = history; - - //TODO: is there a way to really memorize the visitCount instead of recount it at startup ? - m_hash.clear(); - foreach(HistoryItem i, m_history) - { - addHistoryHashEntry(i); - } - + // verify that it is sorted by date if (!loadedAndSorted) qSort(m_history.begin(), m_history.end()); @@ -168,24 +149,6 @@ void HistoryManager::setHistory(const QList<HistoryItem> &history, bool loadedAn } -HistoryModel *HistoryManager::historyModel() const -{ - return m_historyModel; -} - - -HistoryFilterModel *HistoryManager::historyFilterModel() const -{ - return m_historyFilterModel; -} - - -HistoryTreeModel *HistoryManager::historyTreeModel() const -{ - return m_historyTreeModel; -} - - void HistoryManager::checkForExpired() { if (m_historyLimit < 0 || m_history.isEmpty()) @@ -216,44 +179,32 @@ void HistoryManager::checkForExpired() } if (nextTimeout > 0) - m_expiredTimer.start(nextTimeout * 1000); -} - - -void HistoryManager::addHistoryHashEntry(const HistoryItem &item) -{ - if (m_hash.contains(item.url)) - { - m_hash[item.url].visitCount++; - m_hash[item.url].dateTime = item.dateTime; //store last visit date - if (!item.title.isEmpty()) - { - m_hash[item.url].title = item.title; //store last title if not empty - } - } - else - { - m_hash[item.url] = HistoryHashItem(item.url, item.dateTime, item.title); - } - m_hash[item.url].savedCount++; + QTimer::singleShot( nextTimeout * 1000, this, SLOT(checkForExpired()) ); } void HistoryManager::updateHistoryEntry(const KUrl &url, const QString &title) { + QString urlString = url.url(); + urlString.remove(QL1S("www.")); + if(urlString.startsWith(QL1S("http")) && urlString.endsWith(QL1C('/'))) + urlString.remove(urlString.length()-1,1); + for (int i = 0; i < m_history.count(); ++i) { - if (url == m_history.at(i).url) + QString itemUrl = m_history.at(i).url; + itemUrl.remove(QL1S("www.")); + if(itemUrl.startsWith(QL1S("http")) && itemUrl.endsWith(QL1C('/'))) + itemUrl.remove(itemUrl.length()-1,1); + + if (urlString == itemUrl) { m_history[i].title = title; + m_history[i].url = url.url(); m_saveTimer->changeOccurred(); if (m_lastSavedUrl.isEmpty()) m_lastSavedUrl = m_history.at(i).url; - if (m_hash.contains(url.url()) && !title.isEmpty()) - { - m_hash[url.url()].title = title; - } emit entryUpdated(i); break; } @@ -279,45 +230,24 @@ void HistoryManager::removeHistoryEntry(const KUrl &url, const QString &title) } -HistoryHashItem HistoryManager::get(const QString &url) +QList<HistoryItem> HistoryManager::find(const QString &text) { - return m_hash[url]; -} - + QList<HistoryItem> list; -QList<HistoryHashItem> HistoryManager::find(const QString &text) -{ - QList<HistoryHashItem> list; - - QString url; - foreach(url, m_hash.keys()) + QStringList urlKeys = m_historyFilterModel->keys(); + Q_FOREACH(const QString &url, urlKeys) { - if (url.contains(text) || m_hash[url].title.contains(text)) - { - list << m_hash[url]; - } + int index = m_historyFilterModel->historyLocation(url); + HistoryItem item = m_history.at(index); + + if(url.contains(text) || item.title.contains(text)) + list << item; } - + return list; } -int HistoryManager::historyLimit() const -{ - return m_historyLimit; -} - - -void HistoryManager::setHistoryLimit(int limit) -{ - if (m_historyLimit == limit) - return; - m_historyLimit = limit; - checkForExpired(); - m_saveTimer->changeOccurred(); -} - - void HistoryManager::clear() { m_history.clear(); @@ -334,13 +264,27 @@ void HistoryManager::loadSettings() int days; switch (historyExpire) { - case 0: days = 1; break; - case 1: days = 7; break; - case 2: days = 14; break; - case 3: days = 30; break; - case 4: days = 365; break; - case 5: days = -1; break; - default: days = -1; + case 0: + days = 1; + break; + case 1: + days = 7; + break; + case 2: + days = 14; + break; + case 3: + days = 30; + break; + case 4: + days = 365; + break; + case 5: + days = -1; + break; + default: + days = -1; + break; } m_historyLimit = days; } diff --git a/src/history/historymanager.h b/src/history/historymanager.h index 85702b84..1e03fb1c 100644 --- a/src/history/historymanager.h +++ b/src/history/historymanager.h @@ -32,6 +32,8 @@ // Rekonq Includes #include "rekonq_defines.h" + +// Local Includes #include "urlresolver.h" // KDE Includes @@ -84,35 +86,8 @@ public: // --------------------------------------------------------------------------------------------------------------- -class HistoryHashItem : public HistoryItem -{ -public: - HistoryHashItem() {} - explicit HistoryHashItem(const QString &u - ,const QDateTime &d = QDateTime() - ,const QString &t = QString() - ) - : HistoryItem(u, d, t) - ,visitCount(1) - ,savedCount(0) - {} - - inline bool operator <(const HistoryHashItem &other) const - { - return visitCount > other.visitCount; - } - - int visitCount; - int savedCount; -}; - - -// --------------------------------------------------------------------------------------------------------------- - - // Forward Declarations class AutoSaver; -class HistoryModel; class HistoryFilterModel; class HistoryTreeModel; @@ -124,7 +99,6 @@ class HistoryTreeModel; class REKONQ_TESTS_EXPORT HistoryManager : public QWebHistoryInterface { Q_OBJECT - Q_PROPERTY(int historyLimit READ historyLimit WRITE setHistoryLimit) signals: void historyReset(); @@ -141,19 +115,14 @@ public: void updateHistoryEntry(const KUrl &url, const QString &title); void removeHistoryEntry(const KUrl &url, const QString &title = QString()); - HistoryHashItem get(const QString &url); - QList<HistoryHashItem> find(const QString &text); - - int historyLimit() const; - void setHistoryLimit(int limit); + QList<HistoryItem> find(const QString &text); - QList<HistoryItem> history() const; + QList<HistoryItem> history() const { return m_history; }; void setHistory(const QList<HistoryItem> &history, bool loadedAndSorted = false); // History manager keeps around these models for use by the completer and other classes - HistoryModel *historyModel() const; - HistoryFilterModel *historyFilterModel() const; - HistoryTreeModel *historyTreeModel() const; + HistoryFilterModel *historyFilterModel() const { return m_historyFilterModel; }; + HistoryTreeModel *historyTreeModel() const { return m_historyTreeModel; }; public slots: void clear(); @@ -164,17 +133,13 @@ private slots: void checkForExpired(); private: - void addHistoryHashEntry(const HistoryItem &item); void load(); AutoSaver *m_saveTimer; int m_historyLimit; - QTimer m_expiredTimer; QList<HistoryItem> m_history; - QHash<QString, HistoryHashItem> m_hash; QString m_lastSavedUrl; - HistoryModel *m_historyModel; HistoryFilterModel *m_historyFilterModel; HistoryTreeModel *m_historyTreeModel; }; diff --git a/src/history/historymodels.cpp b/src/history/historymodels.cpp index e68eac42..9da755c5 100644 --- a/src/history/historymodels.cpp +++ b/src/history/historymodels.cpp @@ -58,13 +58,13 @@ HistoryModel::HistoryModel(HistoryManager *history, QObject *parent) : QAbstractTableModel(parent) - , m_history(history) + , m_historyManager(history) { - Q_ASSERT(m_history); - connect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); - connect(m_history, SIGNAL(entryRemoved(const HistoryItem &)), this, SLOT(historyReset())); - connect(m_history, SIGNAL(entryAdded(const HistoryItem &)), this, SLOT(entryAdded())); - connect(m_history, SIGNAL(entryUpdated(int)), this, SLOT(entryUpdated(int))); + Q_ASSERT(m_historyManager); + connect(m_historyManager, SIGNAL(historyReset()), this, SLOT(historyReset())); + connect(m_historyManager, SIGNAL(entryRemoved(const HistoryItem &)), this, SLOT(historyReset())); + connect(m_historyManager, SIGNAL(entryAdded(const HistoryItem &)), this, SLOT(entryAdded())); + connect(m_historyManager, SIGNAL(entryUpdated(int)), this, SLOT(entryUpdated(int))); } @@ -105,7 +105,7 @@ QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int QVariant HistoryModel::data(const QModelIndex &index, int role) const { - QList<HistoryItem> lst = m_history->history(); + QList<HistoryItem> lst = m_historyManager->history(); if (index.row() < 0 || index.row() >= lst.size()) return QVariant(); @@ -165,7 +165,7 @@ int HistoryModel::columnCount(const QModelIndex &parent) const int HistoryModel::rowCount(const QModelIndex &parent) const { - return (parent.isValid()) ? 0 : m_history->history().count(); + return (parent.isValid()) ? 0 : m_historyManager->history().count(); } @@ -175,169 +175,18 @@ bool HistoryModel::removeRows(int row, int count, const QModelIndex &parent) return false; int lastRow = row + count - 1; beginRemoveRows(parent, row, lastRow); - QList<HistoryItem> lst = m_history->history(); + QList<HistoryItem> lst = m_historyManager->history(); for (int i = lastRow; i >= row; --i) lst.removeAt(i); - disconnect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); - m_history->setHistory(lst); - connect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); + disconnect(m_historyManager, SIGNAL(historyReset()), this, SLOT(historyReset())); + m_historyManager->setHistory(lst); + connect(m_historyManager, SIGNAL(historyReset()), this, SLOT(historyReset())); endRemoveRows(); return true; } - -// ----------------------------------------------------------------------------------------------- - - -#define MOVEDROWS 20 - - -/* - Maps the first bunch of items of the source model to the root -*/ -HistoryMenuModel::HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent) - : QAbstractProxyModel(parent) - , m_treeModel(sourceModel) -{ - setSourceModel(sourceModel); -} - - -int HistoryMenuModel::bumpedRows() const -{ - QModelIndex first = m_treeModel->index(0, 0); - if (!first.isValid()) - return 0; - return qMin(m_treeModel->rowCount(first), MOVEDROWS); -} - - -int HistoryMenuModel::columnCount(const QModelIndex &parent) const -{ - return m_treeModel->columnCount(mapToSource(parent)); -} - - -int HistoryMenuModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - return 0; - - if (!parent.isValid()) - { - int folders = sourceModel()->rowCount(); - int bumpedItems = bumpedRows(); - if (bumpedItems <= MOVEDROWS - && bumpedItems == sourceModel()->rowCount(sourceModel()->index(0, 0))) - --folders; - return bumpedItems + folders; - } - - if (parent.internalId() == -1) - { - if (parent.row() < bumpedRows()) - return 0; - } - - QModelIndex idx = mapToSource(parent); - int defaultCount = sourceModel()->rowCount(idx); - if (idx == sourceModel()->index(0, 0)) - return defaultCount - bumpedRows(); - return defaultCount; -} - - -QModelIndex HistoryMenuModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - // currently not used or autotested - Q_ASSERT(false); - int sr = m_treeModel->mapToSource(sourceIndex).row(); - return createIndex(sourceIndex.row(), sourceIndex.column(), sr); -} - - -QModelIndex HistoryMenuModel::mapToSource(const QModelIndex &proxyIndex) const -{ - if (!proxyIndex.isValid()) - return QModelIndex(); - - if (proxyIndex.internalId() == -1) - { - int bumpedItems = bumpedRows(); - if (proxyIndex.row() < bumpedItems) - return m_treeModel->index(proxyIndex.row(), proxyIndex.column(), m_treeModel->index(0, 0)); - if (bumpedItems <= MOVEDROWS && bumpedItems == sourceModel()->rowCount(m_treeModel->index(0, 0))) - --bumpedItems; - return m_treeModel->index(proxyIndex.row() - bumpedItems, proxyIndex.column()); - } - - QModelIndex historyIndex = m_treeModel->sourceModel()->index(proxyIndex.internalId(), proxyIndex.column()); - QModelIndex treeIndex = m_treeModel->mapFromSource(historyIndex); - return treeIndex; -} - - -QModelIndex HistoryMenuModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 - || column < 0 || column >= columnCount(parent) - || parent.column() > 0) - return QModelIndex(); - if (!parent.isValid()) - return createIndex(row, column, -1); - - QModelIndex treeIndexParent = mapToSource(parent); - - int bumpedItems = 0; - if (treeIndexParent == m_treeModel->index(0, 0)) - bumpedItems = bumpedRows(); - QModelIndex treeIndex = m_treeModel->index(row + bumpedItems, column, treeIndexParent); - QModelIndex historyIndex = m_treeModel->mapToSource(treeIndex); - int historyRow = historyIndex.row(); - if (historyRow == -1) - historyRow = treeIndex.row(); - return createIndex(row, column, historyRow); -} - - -QModelIndex HistoryMenuModel::parent(const QModelIndex &index) const -{ - int offset = index.internalId(); - if (offset == -1 || !index.isValid()) - return QModelIndex(); - - QModelIndex historyIndex = m_treeModel->sourceModel()->index(index.internalId(), 0); - QModelIndex treeIndex = m_treeModel->mapFromSource(historyIndex); - QModelIndex treeIndexParent = treeIndex.parent(); - - int sr = m_treeModel->mapToSource(treeIndexParent).row(); - int bumpedItems = bumpedRows(); - if (bumpedItems <= MOVEDROWS && bumpedItems == sourceModel()->rowCount(sourceModel()->index(0, 0))) - --bumpedItems; - return createIndex(bumpedItems + treeIndexParent.row(), treeIndexParent.column(), sr); -} - - -// -------------------------------------------------------------------------------------------------------------- - - -TreeProxyModel::TreeProxyModel(QObject *parent) : QSortFilterProxyModel(parent) -{ - setSortRole(HistoryModel::DateTimeRole); - setFilterCaseSensitivity(Qt::CaseInsensitive); -} - - -bool TreeProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - if (!source_parent.isValid()) - return true; - return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); -} - - -// ------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------------------------------------------------------- HistoryFilterModel::HistoryFilterModel(QAbstractItemModel *sourceModel, QObject *parent) @@ -559,114 +408,7 @@ bool HistoryFilterModel::removeRows(int row, int count, const QModelIndex &paren } -// ------------------------------------------------------------------------------------------------------ - - -HistoryCompletionModel::HistoryCompletionModel(QObject *parent) - : QAbstractProxyModel(parent) -{ -} - - -QVariant HistoryCompletionModel::data(const QModelIndex &index, int role) const -{ - if (sourceModel() - && (role == Qt::EditRole || role == Qt::DisplayRole) - && index.isValid()) - { - QModelIndex idx = mapToSource(index); - idx = idx.sibling(idx.row(), 1); - QString urlString = idx.data(HistoryModel::UrlStringRole).toString(); - if (index.row() % 2) - { - QUrl url = urlString; - QString s = url.toString(QUrl::RemoveScheme - | QUrl::RemoveUserInfo - | QUrl::StripTrailingSlash); - return s.mid(2); // strip // from the front - } - return urlString; - } - return QAbstractProxyModel::data(index, role); -} - - -int HistoryCompletionModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !sourceModel()) ? 0 : sourceModel()->rowCount(parent) * 2; -} - - -int HistoryCompletionModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 1; -} - - -QModelIndex HistoryCompletionModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - int row = sourceIndex.row() * 2; - return index(row, sourceIndex.column()); -} - - -QModelIndex HistoryCompletionModel::mapToSource(const QModelIndex &proxyIndex) const -{ - if (!sourceModel()) - return QModelIndex(); - int row = proxyIndex.row() / 2; - return sourceModel()->index(row, proxyIndex.column()); -} - - -QModelIndex HistoryCompletionModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 || row >= rowCount(parent) - || column < 0 || column >= columnCount(parent)) - return QModelIndex(); - return createIndex(row, column, 0); -} - - -QModelIndex HistoryCompletionModel::parent(const QModelIndex &) const -{ - return QModelIndex(); -} - - -void HistoryCompletionModel::setSourceModel(QAbstractItemModel *newSourceModel) -{ - if (sourceModel()) - { - disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - } - - QAbstractProxyModel::setSourceModel(newSourceModel); - - if (newSourceModel) - { - connect(newSourceModel, SIGNAL(modelReset()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - } - - reset(); -} - - -void HistoryCompletionModel::sourceReset() -{ - reset(); -} - - -// ------------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------------------------------------------------- HistoryTreeModel::HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent) @@ -977,3 +719,22 @@ void HistoryTreeModel::sourceRowsRemoved(const QModelIndex &parent, int start, i endRemoveRows(); } } + + +// ------------------------------------------------------------------------------------------------------------------------------------------ + + + +TreeProxyModel::TreeProxyModel(QObject *parent) : QSortFilterProxyModel(parent) +{ + setSortRole(HistoryModel::DateTimeRole); + setFilterCaseSensitivity(Qt::CaseInsensitive); +} + + +bool TreeProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + if (!source_parent.isValid()) + return true; + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); +} diff --git a/src/history/historymodels.h b/src/history/historymodels.h index 78691694..b61e8969 100644 --- a/src/history/historymodels.h +++ b/src/history/historymodels.h @@ -73,19 +73,19 @@ public: bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); private: - HistoryManager *m_history; + HistoryManager *m_historyManager; }; // ---------------------------------------------------------------------------------------------------- + /** * Proxy model that will remove any duplicate entries. * Both m_sourceRow and m_historyHash store their offsets not from * the front of the list, but as offsets from the back. * */ - class REKONQ_TESTS_EXPORT HistoryFilterModel : public QAbstractProxyModel { Q_OBJECT @@ -95,8 +95,16 @@ public: inline bool historyContains(const QString &url) const { - load(); return m_historyHash.contains(url); + load(); + return m_historyHash.contains(url); + } + + inline QList<QString> keys() const + { + load(); + return m_historyHash.keys(); } + int historyLocation(const QString &url) const; QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; @@ -127,72 +135,11 @@ private: // ---------------------------------------------------------------------------------------------------------------------- -/** - * The history menu - * - Removes the first twenty entries and puts them as children of the top level. - * - If there are less then twenty entries then the first folder is also removed. - * - * The mapping is done by knowing that HistoryTreeModel is over a table - * We store that row offset in our index's private data. - * - */ - -class HistoryMenuModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - explicit HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent = 0); - - int columnCount(const QModelIndex &parent) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex & sourceIndex) const; - QModelIndex mapToSource(const QModelIndex & proxyIndex) const; - QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const; - QModelIndex parent(const QModelIndex &index = QModelIndex()) const; - - int bumpedRows() const; - -private: - HistoryTreeModel *m_treeModel; -}; - - -// ---------------------------------------------------------------------------------------- - -/** - * Proxy model for the history model that - * exposes each url http://www.foo.com and - * it url starting at the host www.foo.com - * - */ - -class HistoryCompletionModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryCompletionModel(QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index = QModelIndex()) const; - void setSourceModel(QAbstractItemModel *sourceModel); - -private slots: - void sourceReset(); - -}; - - -// --------------------------------------------------------------------------------------- /** * Proxy model for the history model that converts the list * into a tree, one top level node per day. + * * Used in the HistoryDialog. * */ @@ -232,6 +179,7 @@ private: // ----------------------------------------------------------------------------------------------------------------- + /** * A modified QSortFilterProxyModel that always accepts * the root nodes in the tree diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cbef274a..f0cb5e61 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -38,6 +38,7 @@ #include "settingsdialog.h" #include "historymanager.h" #include "bookmarksmanager.h" +#include "bookmarkstoolbar.h" #include "webtab.h" #include "mainview.h" #include "findbar.h" @@ -57,6 +58,7 @@ #include <KShortcut> #include <KStandardAction> #include <KAction> +#include <KEditToolBar> #include <KToggleFullScreenAction> #include <KActionCollection> #include <KMessageBox> @@ -105,7 +107,7 @@ MainWindow::MainWindow() , m_analyzerPanel(0) , m_historyBackMenu(0) , m_encodingMenu(new KMenu(this)) - , m_bookmarksBar(new BookmarkToolBar(QString("BookmarkToolBar"), this, Qt::TopToolBarArea, true, false, true)) + , m_bookmarksBar(0) , m_popup(new KPassivePopup(this)) , m_hidePopup(new QTimer(this)) { @@ -139,16 +141,16 @@ MainWindow::MainWindow() // setting up rekonq toolbar(s) setupToolbars(); - // a call to KXmlGuiWindow::setupGUI() populates the GUI - // with actions, using KXMLGUI. - // It also applies the saved mainwindow settings, if any, and ask the - // mainwindow to automatically save settings if changed: window size, - // toolbar position, icon size, etc. + // a call to KXmlGuiWindow::setupGUI() populates the GUI + // with actions, using KXMLGUI. + // It also applies the saved mainwindow settings, if any, and ask the + // mainwindow to automatically save settings if changed: window size, + // toolbar position, icon size, etc. setupGUI(); - + // no menu bar in rekonq: we have other plans.. menuBar()->setVisible(false); - + // no more status bar.. setStatusBar(0); @@ -164,7 +166,7 @@ MainWindow::~MainWindow() Application::bookmarkProvider()->removeToolBar(m_bookmarksBar); Application::bookmarkProvider()->removeBookmarkPanel(m_bookmarksPanel); Application::instance()->removeMainWindow(this); - + delete m_view; delete m_findBar; delete m_zoomBar; @@ -187,7 +189,7 @@ MainWindow::~MainWindow() void MainWindow::setupToolbars() { kDebug() << "setup toolbars..."; - + KAction *a; // location bar @@ -197,34 +199,42 @@ void MainWindow::setupToolbars() KToolBar *mainBar = toolBar("mainToolBar"); - // bookmarks bar - KAction *bookmarkBarAction = Application::bookmarkProvider()->bookmarkToolBarAction(m_bookmarksBar); - a = actionCollection()->addAction( QL1S("bookmarks_bar"), bookmarkBarAction); - mainBar->show(); // this just to fix reopening rekonq after fullscreen close - - // =========== Bookmarks ToolBar ================================ - m_bookmarksBar->setAcceptDrops(true); - Application::bookmarkProvider()->setupBookmarkBar(m_bookmarksBar); } -void MainWindow::postLaunch() +void MainWindow::initBookmarkBar() { - KToolBar *mainBar = toolBar("mainToolBar"); - - QToolButton *bookmarksButton = qobject_cast<QToolButton*>(mainBar->widgetForAction(actionByName( QL1S("bookmarksActionMenu") ))); - if(bookmarksButton) - { - connect(actionByName(QL1S("bookmarksActionMenu")), SIGNAL(triggered()), bookmarksButton, SLOT(showMenu())); - } - - QToolButton *toolsButton = qobject_cast<QToolButton*>(mainBar->widgetForAction(actionByName( QL1S("rekonq_tools") ))); - if(toolsButton) + KToolBar *XMLGUIBkBar = toolBar("bookmarkToolBar"); + if (!XMLGUIBkBar) + return; + + if (m_bookmarksBar) { - connect(actionByName(QL1S("rekonq_tools")), SIGNAL(triggered()), toolsButton, SLOT(showMenu())); + Application::bookmarkProvider()->removeToolBar(m_bookmarksBar); + delete m_bookmarksBar; } - + m_bookmarksBar = new BookmarkToolBar(XMLGUIBkBar, this); + Application::bookmarkProvider()->registerBookmarkBar(m_bookmarksBar); +} + + +void MainWindow::configureToolbars() +{ + if (autoSaveSettings()) + saveAutoSaveSettings(); + + KEditToolBar dlg(factory(), this); + // The bookmark bar needs to be refill after the UI changes are finished + connect(&dlg, SIGNAL(newToolBarConfig()), this, SLOT(initBookmarkBar())); + dlg.exec(); +} + + +void MainWindow::postLaunch() +{ + setupBookmarksAndToolsShortcuts(); + // setting popup notification m_popup->setAutoDelete(false); connect(Application::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)), m_popup, SLOT(hide())); @@ -258,12 +268,15 @@ void MainWindow::postLaunch() connect(m_view, SIGNAL(currentChanged(int)), m_zoomBar, SLOT(updateSlider(int))); // Ctrl + wheel handling connect(this->currentTab()->view(), SIGNAL(zoomChanged(int)), m_zoomBar, SLOT(setValue(int))); - + // setting up toolbars to NOT have context menu enabled setContextMenuPolicy(Qt::DefaultContextMenu); // accept d'n'd setAcceptDrops(true); + + // Bookmark ToolBar (needs to be setup after the call to setupGUI()) + initBookmarkBar(); } @@ -278,7 +291,7 @@ QSize MainWindow::sizeHint() const void MainWindow::setupActions() { kDebug() << "setup actions..."; - + // this let shortcuts work.. actionCollection()->addAssociatedWidget(this); @@ -389,7 +402,7 @@ void MainWindow::setupActions() a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabNext() : KStandardShortcut::tabPrev()); actionCollection()->addAction(QL1S("show_prev_tab"), a); connect(a, SIGNAL(triggered(bool)), m_view, SLOT(previousTab())); - + a = new KAction(KIcon("tab-new"), i18n("Open Closed Tabs"), this); a->setShortcut(KShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_T)); actionCollection()->addAction(QL1S("open_closed_tabs"), a); @@ -455,7 +468,7 @@ void MainWindow::setupTools() toolsMenu->setDelayed(false); toolsMenu->setShortcutConfigurable(true); toolsMenu->setShortcut( KShortcut(Qt::ALT + Qt::Key_T) ); - + toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::Open))); toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::SaveAs))); toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::Print))); @@ -547,7 +560,7 @@ void MainWindow::setupPanels() addDockWidget(Qt::BottomDockWidgetArea, m_webInspectorPanel); m_webInspectorPanel->hide(); - + // STEP 4 // Setup Network analyzer panel m_analyzerPanel = new NetworkAnalyzerPanel( i18n("Network Analyzer"), this); @@ -584,7 +597,7 @@ void MainWindow::fileSaveAs() srcUrl = w->url(); } kDebug() << "URL to save: " << srcUrl; - + QString name = srcUrl.fileName(); if (name.isNull()) { @@ -621,7 +634,7 @@ void MainWindow::updateActions() { kDebug() << "updating actions.."; bool rekonqPage = currentTab()->page()->isOnRekonqPage(); - + QAction *historyBackAction = actionByName(KStandardAction::name(KStandardAction::Back)); if( rekonqPage && currentTab()->view()->history()->count() > 0 ) historyBackAction->setEnabled(true); @@ -837,7 +850,7 @@ void MainWindow::setWidgetsVisible(bool makeVisible) KToolBar *mainBar = toolBar("mainToolBar"); KToolBar *bookBar = toolBar("bookmarksToolBar"); - + if (!makeVisible) { // save current state, if in windowed mode @@ -885,10 +898,10 @@ void MainWindow::viewPageSource() void MainWindow::homePage(Qt::MouseButtons mouseButtons, Qt::KeyboardModifiers keyboardModifiers) { - KUrl homeUrl = ReKonfig::useNewTabPage() + KUrl homeUrl = ReKonfig::useNewTabPage() ? KUrl( QL1S("about:home") ) : KUrl( ReKonfig::homePage() ); - + if (mouseButtons == Qt::MidButton || keyboardModifiers == Qt::ControlModifier) Application::instance()->loadUrl( homeUrl, Rekonq::NewTab); else @@ -930,7 +943,7 @@ void MainWindow::openPrevious(Qt::MouseButtons mouseButtons, Qt::KeyboardModifie { QWebHistory *history = currentTab()->view()->history(); QWebHistoryItem *item = 0; - + if (currentTab()->page()->isOnRekonqPage()) { item = new QWebHistoryItem(history->currentItem()); @@ -946,7 +959,7 @@ void MainWindow::openPrevious(Qt::MouseButtons mouseButtons, Qt::KeyboardModifie if(!item) return; - + if (mouseButtons == Qt::MidButton || keyboardModifiers == Qt::ControlModifier) { Application::instance()->loadUrl(item->url(), Rekonq::NewTab); @@ -977,10 +990,10 @@ void MainWindow::openNext(Qt::MouseButtons mouseButtons, Qt::KeyboardModifiers k item = new QWebHistoryItem(history->forwardItem()); } } - + if(!item) return; - + if (mouseButtons == Qt::MidButton || keyboardModifiers == Qt::ControlModifier) { Application::instance()->loadUrl(item->url(), Rekonq::NewTab); @@ -989,7 +1002,7 @@ void MainWindow::openNext(Qt::MouseButtons mouseButtons, Qt::KeyboardModifiers k { history->goToItem(*item); } - + updateActions(); } @@ -1181,7 +1194,7 @@ void MainWindow::aboutToShowBackMenu() offset = pivot - 8; /* - * Need a bug report upstream. + * Need a bug report upstream. * Seems setHtml() do some garbage in history * Here history->currentItem() have backItem url and currentItem (error page) title */ @@ -1195,7 +1208,7 @@ void MainWindow::aboutToShowBackMenu() action->setText(item.title()); m_historyBackMenu->addAction(action); } - + for (int i = listCount - 1; i >= 0; --i) { QWebHistoryItem item = historyList.at(i); @@ -1236,7 +1249,7 @@ void MainWindow::setEncoding(QAction *qa) currentTab()->view()->reload(); return; } - + currentTab()->view()->settings()->setDefaultTextEncoding(currentCodec); currentTab()->view()->reload(); } @@ -1246,7 +1259,7 @@ void MainWindow::populateEncodingMenu() { QStringList codecs; QList<int> mibs = QTextCodec::availableMibs(); - Q_FOREACH (const int &mib, mibs) + Q_FOREACH (const int &mib, mibs) { QString codec = QLatin1String(QTextCodec::codecForMib(mib)->name()); codecs.append(codec); @@ -1261,13 +1274,13 @@ void MainWindow::populateEncodingMenu() KMenu *isciiMenu = new KMenu( QL1S("ISCII"), m_encodingMenu); KMenu *uniMenu = new KMenu( QL1S("Unicode"), m_encodingMenu); KMenu *otherMenu = new KMenu( i18n("Other"), m_encodingMenu); - + QAction *a; bool isDefaultCodecUsed = true; - + Q_FOREACH(const QString &codec, codecs) { - + if( codec.startsWith( QL1S("ISO"), Qt::CaseInsensitive ) ) a = isoMenu->addAction(codec); else if( codec.startsWith( QL1S("win") ) ) @@ -1276,9 +1289,9 @@ void MainWindow::populateEncodingMenu() a = isciiMenu->addAction(codec); else if( codec.startsWith( QL1S("UT") ) ) a = uniMenu->addAction(codec); - else + else a = otherMenu->addAction(codec); - + a->setCheckable(true); if (currentCodec == codec) { @@ -1286,11 +1299,11 @@ void MainWindow::populateEncodingMenu() isDefaultCodecUsed = false; } } - + a = new QAction( i18nc("Default website encoding", "Default"), this); a->setCheckable(true); a->setChecked(isDefaultCodecUsed); - + m_encodingMenu->addAction( a ); m_encodingMenu->addMenu( isoMenu ); m_encodingMenu->addMenu( winMenu ); @@ -1312,34 +1325,59 @@ bool MainWindow::queryClose() // this should fux bug 240432 if(Application::instance()->sessionSaving()) return true; - - if (m_view->count() > 1) + + if (m_view->count() > 1) { - int answer = KMessageBox::questionYesNoCancel( - this, + int answer = KMessageBox::questionYesNoCancel( + this, i18np("Are you sure you want to close the window?\n" "You have 1 tab open.", - "Are you sure you want to close the window?\n" "You have %1 tabs open.", + "Are you sure you want to close the window?\n" "You have %1 tabs open.", m_view->count()), - i18n("Are you sure you want to close the window?"), - KStandardGuiItem::quit(), - KGuiItem(i18n("C&lose Current Tab"), KIcon("tab-close")), - KStandardGuiItem::cancel(), - "confirmClosingMultipleTabs" - ); - - switch (answer) - { - case KMessageBox::Yes: - // Quit - return true; - - case KMessageBox::No: - // Close only the current tab + i18n("Are you sure you want to close the window?"), + KStandardGuiItem::quit(), + KGuiItem(i18n("C&lose Current Tab"), KIcon("tab-close")), + KStandardGuiItem::cancel(), + "confirmClosingMultipleTabs" + ); + + switch (answer) + { + case KMessageBox::Yes: + // Quit + return true; + + case KMessageBox::No: + // Close only the current tab m_view->closeTab(); - - default: - return false; - } - } - return true; + + default: + return false; + } + } + return true; +} + + +void MainWindow::saveNewToolbarConfig() +{ + KXmlGuiWindow::saveNewToolbarConfig(); + setupBookmarksAndToolsShortcuts(); +} + + +void MainWindow::setupBookmarksAndToolsShortcuts() +{ + KToolBar *mainBar = toolBar("mainToolBar"); + + QToolButton *bookmarksButton = qobject_cast<QToolButton*>(mainBar->widgetForAction(actionByName( QL1S("bookmarksActionMenu") ))); + if(bookmarksButton) + { + connect(actionByName(QL1S("bookmarksActionMenu")), SIGNAL(triggered()), bookmarksButton, SLOT(showMenu())); + } + + QToolButton *toolsButton = qobject_cast<QToolButton*>(mainBar->widgetForAction(actionByName( QL1S("rekonq_tools") ))); + if(toolsButton) + { + connect(actionByName(QL1S("rekonq_tools")), SIGNAL(triggered()), toolsButton, SLOT(showMenu())); + } } diff --git a/src/mainwindow.h b/src/mainwindow.h index e5a43649..6ae99b5e 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -81,6 +81,7 @@ public: void setWidgetsVisible(bool makeFullScreen); private: + void setupBookmarksAndToolsShortcuts(); void setupActions(); void setupTools(); void setupToolbars(); @@ -103,11 +104,16 @@ public slots: void updateActions(); + virtual void configureToolbars(); + signals: // switching tabs void ctrlTabPressed(); void shiftCtrlTabPressed(); +protected slots: + void saveNewToolbarConfig(); + protected: /** * Filters (SHIFT + ) CTRL + TAB events and emit (shift)ctrlTabPressed() @@ -159,6 +165,8 @@ private slots: void populateEncodingMenu(); void enableNetworkAnalysis(bool); + + void initBookmarkBar(); private: MainView *m_view; @@ -183,4 +191,3 @@ private: }; #endif // MAINWINDOW_H -
\ No newline at end of file diff --git a/src/rekonqui.rc b/src/rekonqui.rc index e89e3b15..cc2103b4 100644 --- a/src/rekonqui.rc +++ b/src/rekonqui.rc @@ -92,9 +92,8 @@ </ToolBar> <!-- ============ Bookmarks ToolBar =========== --> -<ToolBar name="bookmarksToolBar" fullWidth="true" iconText="icontextright" iconSize="16" newline="true" hidden="true" noEdit="true"> - <text>Bookmark Toolbar</text> - <Action noEdit="true" name="bookmarks_bar" /> +<ToolBar noEdit="true" iconText="icontextright" fullWidth="true" name="bookmarkToolBar" iconSize="16" newline="true"> + <text>Bookmark Toolbar</text> </ToolBar> </gui> diff --git a/src/search/searchengine.cpp b/src/search/searchengine.cpp index 0a66bb64..7065d55f 100644 --- a/src/search/searchengine.cpp +++ b/src/search/searchengine.cpp @@ -36,40 +36,70 @@ #include <KServiceTypeTrader> +bool SearchEngine::m_loaded = false; QString SearchEngine::m_delimiter = ""; +KService::List SearchEngine::m_favorites; +KService::Ptr SearchEngine::m_defaultEngine; -QString SearchEngine::delimiter() -{ - if (m_delimiter == "") loadDelimiter(); - return m_delimiter; -} - - -void SearchEngine::loadDelimiter() +void SearchEngine::reload() { - KConfig config("kuriikwsfilterrc"); //Share with konqueror + KConfig config("kuriikwsfilterrc"); //Shared with konqueror KConfigGroup cg = config.group("General"); + + //load delimiter m_delimiter = cg.readEntry("KeywordDelimiter", ":"); + + //load favorite engines + QStringList favoriteEngines; + favoriteEngines = cg.readEntry("FavoriteSearchEngines", favoriteEngines); + KService::List favorites; + KService::Ptr service; + foreach(const QString &engine, favoriteEngines) + { + service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine)); + if (service) + favorites << service; + } + m_favorites = favorites; + + //load default engine + QString d = cg.readEntry("DefaultSearchEngine"); + m_defaultEngine = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(d)); + if (!m_defaultEngine) + { + d = QL1S("google"); + m_defaultEngine = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(d)); + } + + m_loaded = true; } -KService::Ptr SearchEngine::m_defaultWS; +QString SearchEngine::delimiter() +{ + if (!m_loaded) + reload(); + + return m_delimiter; +} -KService::Ptr SearchEngine::defaultWS() +KService::List SearchEngine::favorites() { - if (!m_defaultWS) loadDefaultWS(); - return m_defaultWS; + if (!m_loaded) + reload(); + + return m_favorites; } -void SearchEngine::loadDefaultWS() +KService::Ptr SearchEngine::defaultEngine() { - KConfig config("kuriikwsfilterrc"); //Share with konqueror - KConfigGroup cg = config.group("General"); - QString d = cg.readEntry("DefaultSearchEngine", "google"); - m_defaultWS = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(d)); + if (!m_loaded) + reload(); + + return m_defaultEngine; } @@ -106,48 +136,4 @@ QString SearchEngine::buildQuery(KService::Ptr engine, QString text) } -KService::List SearchEngine::m_favorites; - - -KService::List SearchEngine::favorites() -{ - if (m_favorites.isEmpty()) loadFavorites(); - return m_favorites; -} - -void SearchEngine::loadFavorites() -{ - KConfig config("kuriikwsfilterrc"); //Share with konqueror - KConfigGroup cg = config.group("General"); - QStringList favoriteEngines; - favoriteEngines << "google"; //defaults - favoriteEngines = cg.readEntry("FavoriteSearchEngines", favoriteEngines); - - KService::List favorites; - KService::Ptr service; - foreach(const QString &engine, favoriteEngines) - { - service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine)); - if (service) - favorites << service; - } - - m_favorites = favorites; -} - -KService::Ptr SearchEngine::defaultEngine() -{ - KConfig config("kuriikwsfilterrc"); //Share with konqueror - KConfigGroup cg = config.group("General"); - QString d = cg.readEntry("DefaultSearchEngine"); - KService::Ptr service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(d)); - if (!service) - { - d = QL1S("google"); - service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(d)); - } - - return service; - -} diff --git a/src/search/searchengine.h b/src/search/searchengine.h index 2e30e056..e57b1a5c 100644 --- a/src/search/searchengine.h +++ b/src/search/searchengine.h @@ -41,22 +41,18 @@ class SearchEngine { public: - + static void reload(); static QString delimiter(); static KService::Ptr defaultEngine(); static KService::List favorites(); static KService::Ptr fromString(QString text); static QString buildQuery(KService::Ptr engine, QString text); - static KService::Ptr defaultWS(); - - static void loadDelimiter(); - static void loadFavorites(); - static void loadDefaultWS(); private: + static bool m_loaded; static QString m_delimiter; static KService::List m_favorites; - static KService::Ptr m_defaultWS; + static KService::Ptr m_defaultEngine; }; #endif diff --git a/src/settings/appearancewidget.cpp b/src/settings/appearancewidget.cpp index 03d81808..c444f724 100644 --- a/src/settings/appearancewidget.cpp +++ b/src/settings/appearancewidget.cpp @@ -87,4 +87,4 @@ bool AppearanceWidget::isDefault() // TODO: implement me!! return def; -}
\ No newline at end of file +} diff --git a/src/settings/generalwidget.cpp b/src/settings/generalwidget.cpp index 09c9e5c7..642813ae 100644 --- a/src/settings/generalwidget.cpp +++ b/src/settings/generalwidget.cpp @@ -36,6 +36,8 @@ #include "mainwindow.h" #include "webtab.h" +//KDE Includes +#include <kstandarddirs.h> GeneralWidget::GeneralWidget(QWidget *parent) : QWidget(parent) @@ -48,6 +50,8 @@ GeneralWidget::GeneralWidget(QWidget *parent) disableHomeSettings(ReKonfig::useNewTabPage()); connect(kcfg_useNewTabPage, SIGNAL(toggled(bool)), this, SLOT(disableHomeSettings(bool))); + + checkKGetPresence(); } @@ -83,3 +87,19 @@ void GeneralWidget::disableHomeSettings(bool b) kcfg_homePage->setEnabled(!b); setHomeToCurrentPageButton->setEnabled(!b); } + +void GeneralWidget::checkKGetPresence() +{ + if (KStandardDirs::findExe("kget").isNull()) + { + kcfg_kgetDownload->setDisabled(true); + kcfg_kgetList->setDisabled(true); + kcfg_kgetDownload->setToolTip(i18n("Install KGet to enable rekonq to use KGet as download manager")); + + } + else + { + kcfg_kgetDownload->setDisabled(false); + kcfg_kgetList->setDisabled(false); + } +} diff --git a/src/settings/generalwidget.h b/src/settings/generalwidget.h index d669fd04..b2cefcfa 100644 --- a/src/settings/generalwidget.h +++ b/src/settings/generalwidget.h @@ -44,6 +44,7 @@ public: void save(); bool changed(); + void checkKGetPresence(); signals: void changed(bool); diff --git a/src/settings/settingsdialog.cpp b/src/settings/settingsdialog.cpp index cd64f434..eee2a4e1 100644 --- a/src/settings/settingsdialog.cpp +++ b/src/settings/settingsdialog.cpp @@ -197,9 +197,7 @@ void SettingsDialog::saveSettings() d->shortcutsEditor->save(); d->ebrowsingModule->save(); - SearchEngine::loadDefaultWS(); - SearchEngine::loadDelimiter(); - SearchEngine::loadFavorites(); + SearchEngine::reload(); updateButtons(); emit settingsChanged("ReKonfig"); diff --git a/src/tabbar.cpp b/src/tabbar.cpp index 2d29032f..98243e71 100644 --- a/src/tabbar.cpp +++ b/src/tabbar.cpp @@ -322,6 +322,12 @@ void TabBar::emptyAreaContextMenu(const QPoint &pos) menu.addSeparator(); menu.addAction(mainWindow->actionByName( QL1S("reload_all_tabs") )); + KToolBar *mainBar = mainWindow->toolBar("mainToolBar"); + if(!mainBar->isVisible()) + { + menu.addAction( mainBar->toggleViewAction() ); + } + menu.exec(pos); } diff --git a/src/urlbar/bookmarkwidget.cpp b/src/urlbar/bookmarkwidget.cpp index 3380ec57..bcf85e1f 100644 --- a/src/urlbar/bookmarkwidget.cpp +++ b/src/urlbar/bookmarkwidget.cpp @@ -31,6 +31,7 @@ // Local includes #include "application.h" #include "bookmarksmanager.h" +#include "bookmarkowner.h" // KDE Includes #include <KLocalizedString> @@ -57,12 +58,12 @@ BookmarkWidget::BookmarkWidget(const KBookmark &bookmark, QWidget *parent) setLayout(layout); QHBoxLayout *hLayout = new QHBoxLayout(); - + QLabel *bookmarkIcon = new QLabel(this); bookmarkIcon->setPixmap(KIcon("bookmarks").pixmap(32, 32)); hLayout->addWidget(bookmarkIcon); hLayout->setSpacing(10); - + QVBoxLayout *vLayout = new QVBoxLayout(); QLabel *bookmarkInfo = new QLabel(this); @@ -70,13 +71,13 @@ BookmarkWidget::BookmarkWidget(const KBookmark &bookmark, QWidget *parent) QFont font; font.setPointSize(font.pointSize() + 2); bookmarkInfo->setFont(font); - + vLayout->addWidget(bookmarkInfo); QPushButton *removeButton = new QPushButton(this); removeButton->setText(i18n("Remove this Bookmark")); connect(removeButton, SIGNAL(clicked()), this, SLOT(removeBookmark())); - + vLayout->addWidget(removeButton); hLayout->addLayout(vLayout); layout->addItem(hLayout); @@ -152,21 +153,6 @@ void BookmarkWidget::showAt(const QPoint &pos) void BookmarkWidget::removeBookmark() { - bool folder = m_bookmark.isGroup(); - - if (KMessageBox::warningContinueCancel( - QApplication::activeWindow(), - folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", m_bookmark.text()) - : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", m_bookmark.text()), - folder ? i18n("Bookmark Folder Deletion") - : i18n("Bookmark Deletion"), - KStandardGuiItem::del()) - == KMessageBox::Continue - ) - { - m_bookmark.parentGroup().deleteBookmark(m_bookmark); - Application::bookmarkProvider()->bookmarkManager()->emitChanged(); - } - + Application::bookmarkProvider()->bookmarkOwner()->deleteBookmark(m_bookmark); reject(); } diff --git a/src/urlbar/bookmarkwidget.h b/src/urlbar/bookmarkwidget.h index cdab328e..c3c15e18 100644 --- a/src/urlbar/bookmarkwidget.h +++ b/src/urlbar/bookmarkwidget.h @@ -44,7 +44,7 @@ class BookmarkWidget : public QFrame Q_OBJECT public: - BookmarkWidget(const KBookmark &bookmark, QWidget *parent = 0); + explicit BookmarkWidget(const KBookmark &bookmark, QWidget *parent = 0); ~BookmarkWidget(); void showAt(const QPoint &pos); diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp index e2033120..e64959bd 100644 --- a/src/urlbar/urlbar.cpp +++ b/src/urlbar/urlbar.cpp @@ -46,6 +46,7 @@ // KDE Includes #include <KCompletionBox> +#include <KStandardDirs> // Qt Includes #include <QtGui/QPainter> @@ -312,14 +313,16 @@ void UrlBar::loadFinished() if (Application::bookmarkProvider()->bookmarkForUrl(_tab->url()).isNull()) { _icon->setIcon(KIcon("bookmarks").pixmap(32,32, QIcon::Disabled)); + _icon->setToolTip(i18n("Bookmark this page")); } else { _icon->setIcon(KIcon("bookmarks")); + _icon->setToolTip(i18n("Edit this bookmark")); } // show KGet downloads?? - if (ReKonfig::kgetList()) + if (!KStandardDirs::findExe("kget").isNull() && ReKonfig::kgetList()) { IconButton *bt = addRightIcon(UrlBar::KGet); connect(bt, SIGNAL(clicked(QPoint)), _tab->page(), SLOT(downloadAllContentsWithKGet(QPoint))); diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp index d6f49923..0505dad1 100644 --- a/src/urlbar/urlresolver.cpp +++ b/src/urlbar/urlresolver.cpp @@ -96,11 +96,13 @@ UrlResolver::UrlResolver(const QString &typedUrl) { QString reg; QString engineUrl; - foreach(KService::Ptr s, SearchEngine::favorites()) + Q_FOREACH(KService::Ptr s, SearchEngine::favorites()) { engineUrl = QRegExp::escape(s->property("Query").toString()).replace("\\\\\\{@\\}","[\\d\\w-.]+"); - if (reg.isEmpty()) reg = "(" + engineUrl + ")"; - else reg = reg + "|(" + engineUrl + ")"; + if (reg.isEmpty()) + reg = '(' + engineUrl + ')'; + else + reg = reg + "|(" + engineUrl + ')'; } _searchEnginesRegexp = QRegExp(reg); } @@ -344,10 +346,10 @@ void UrlResolver::computeWebSearches() //history void UrlResolver::computeHistory() { - QList<HistoryHashItem> found = Application::historyManager()->find(_typedString); + QList<HistoryItem> found = Application::historyManager()->find(_typedString); qSort(found); - foreach (HistoryHashItem i, found) + Q_FOREACH(const HistoryItem &i, found) { if (_searchEnginesRegexp.indexIn(i.url) == -1) //filter all urls that are search engine results { @@ -365,7 +367,7 @@ void UrlResolver::computeBookmarks() { QList<KBookmark> found = Application::bookmarkProvider()->find(_typedString); - foreach (KBookmark b, found) + Q_FOREACH(const KBookmark &b, found) { UrlSearchItem gItem(UrlSearchItem::Bookmark, b.url().url(), b.fullText()); _bookmarks << gItem; diff --git a/src/webpage.cpp b/src/webpage.cpp index ea2add6d..9167c96d 100644 --- a/src/webpage.cpp +++ b/src/webpage.cpp @@ -125,12 +125,20 @@ static bool downloadResource (const KUrl& srcUrl, const KIO::MetaData& metaData if (finfo.exists()) { QDateTime now = QDateTime::currentDateTime(); - KIO::RenameDialog dlg (parent, i18n("Overwrite File?"), srcUrl, destUrl, - KIO::RenameDialog_Mode(KIO::M_OVERWRITE | KIO::M_SKIP), - -1, finfo.size(), - now.toTime_t(), finfo.created().toTime_t(), - now.toTime_t(), finfo.lastModified().toTime_t()); - result = dlg.exec(); + QPointer<KIO::RenameDialog> dlg = new KIO::RenameDialog( parent, + i18n("Overwrite File?"), + srcUrl, + destUrl, + KIO::RenameDialog_Mode(KIO::M_OVERWRITE | KIO::M_SKIP), + -1, + finfo.size(), + now.toTime_t(), + finfo.created().toTime_t(), + now.toTime_t(), + finfo.lastModified().toTime_t() + ); + result = dlg->exec(); + delete dlg; } } } @@ -139,7 +147,7 @@ static bool downloadResource (const KUrl& srcUrl, const KIO::MetaData& metaData // Save download history Application::instance()->addDownload(srcUrl.pathOrUrl() , destUrl.pathOrUrl()); - if (ReKonfig::kgetDownload()) + if (!KStandardDirs::findExe("kget").isNull() && ReKonfig::kgetDownload()) { //KGet integration: if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget")) diff --git a/src/webview.cpp b/src/webview.cpp index 441225af..c15478c2 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -47,6 +47,7 @@ #include <KMenu> #include <KActionMenu> #include <ktoolinvocation.h> +#include <KStandardDirs> // Qt Includes #include <QtCore/QDir> @@ -316,7 +317,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event) menu.addAction(mainwindow->actionByName(KStandardAction::name(KStandardAction::SaveAs))); - if (ReKonfig::kgetList()) + if (!KStandardDirs::findExe("kget").isNull() && ReKonfig::kgetList()) { a = new KAction(KIcon("kget"), i18n("List All Links"), this); connect(a, SIGNAL(triggered(bool)), page(), SLOT(downloadAllContentsWithKGet())); @@ -536,13 +537,11 @@ void WebView::keyPressEvent(QKeyEvent *event) } - - - void WebView::wheelEvent(QWheelEvent *event) { - if (!ReKonfig::smoothScrolling() || page()->currentFrame()->hitTestContent(event->pos()).isContentEditable()) - KWebView::wheelEvent(event); + // To let some websites (eg: google maps) to handle wheel events + int ypos = page()->currentFrame()->scrollPosition().y(); + KWebView::wheelEvent(event); // Sync with the zoom slider if (event->modifiers() == Qt::ControlModifier) @@ -560,8 +559,10 @@ void WebView::wheelEvent(QWheelEvent *event) emit zoomChanged(newFactor); } - else if ( ReKonfig::smoothScrolling() && !page()->currentFrame()->hitTestContent(event->pos()).isContentEditable()) + else if (ReKonfig::smoothScrolling() && ypos != page()->currentFrame()->scrollPosition().y()) { + page()->currentFrame()->setScrollPosition(QPoint(page()->currentFrame()->scrollPosition().x(), ypos)); + int numDegrees = event->delta() / 8; int numSteps = numDegrees / 15; |