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; | 
