summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS3
-rw-r--r--CMakeLists.txt21
-rw-r--r--ChangeLog25
-rw-r--r--docs/index.docbook4
-rw-r--r--scripts/RELEASE_HOWTO2
-rw-r--r--[-rwxr-xr-x]scripts/codingstyle.sh4
-rw-r--r--scripts/cppcheck.sh39
-rw-r--r--scripts/download_i18n.sh83
-rw-r--r--[-rwxr-xr-x]scripts/i18n.sh0
-rw-r--r--src/CMakeLists.txt29
-rw-r--r--src/Messages.sh2
-rw-r--r--src/adblock/adblockmanager.cpp298
-rw-r--r--src/adblock/adblockmanager.h98
-rw-r--r--src/adblock/adblocknetworkreply.cpp16
-rw-r--r--src/adblock/adblocknetworkreply.h13
-rw-r--r--src/adblock/adblockrule.cpp86
-rw-r--r--src/adblock/adblockrule.h22
-rw-r--r--src/application.cpp366
-rw-r--r--src/application.h80
-rw-r--r--src/bookmarks/bookmarkcontextmenu.cpp325
-rw-r--r--src/bookmarks/bookmarkcontextmenu.h65
-rw-r--r--src/bookmarks/bookmarksmanager.cpp293
-rw-r--r--src/bookmarks/bookmarksmanager.h54
-rw-r--r--src/bookmarks/bookmarkspanel.cpp154
-rw-r--r--src/bookmarks/bookmarkspanel.h32
-rw-r--r--src/bookmarks/bookmarksproxy.cpp19
-rw-r--r--src/bookmarks/bookmarksproxy.h16
-rw-r--r--src/bookmarks/bookmarkstreemodel.cpp364
-rw-r--r--src/bookmarks/bookmarkstreemodel.h64
-rw-r--r--src/cleardata.ui48
-rw-r--r--src/clicktoflash.cpp159
-rw-r--r--src/clicktoflash.h94
-rw-r--r--src/data/CMakeLists.txt13
-rw-r--r--src/data/bot.gifbin644 -> 0 bytes
-rw-r--r--src/data/closed.pngbin118 -> 0 bytes
-rw-r--r--src/data/default.css10
-rw-r--r--src/data/home.html239
-rw-r--r--src/data/open.pngbin120 -> 0 bytes
-rw-r--r--src/data/rekonq.desktop36
-rw-r--r--src/data/top.pngbin786 -> 0 bytes
-rw-r--r--src/data/webkit-icon.pngbin25694 -> 8121 bytes
-rw-r--r--src/filterurljob.cpp24
-rw-r--r--src/filterurljob.h13
-rw-r--r--src/findbar.cpp87
-rw-r--r--src/findbar.h30
-rw-r--r--src/history/autosaver.cpp13
-rw-r--r--src/history/autosaver.h11
-rw-r--r--src/history/historymanager.cpp125
-rw-r--r--src/history/historymanager.h47
-rw-r--r--src/history/historymodels.cpp16
-rw-r--r--src/history/historymodels.h15
-rw-r--r--src/history/historypanel.cpp106
-rw-r--r--src/history/historypanel.h25
-rw-r--r--src/main.cpp30
-rw-r--r--src/mainview.cpp342
-rw-r--r--src/mainview.h40
-rw-r--r--src/mainwindow.cpp634
-rw-r--r--src/mainwindow.h61
-rw-r--r--src/networkaccessmanager.cpp62
-rw-r--r--src/networkaccessmanager.h22
-rw-r--r--src/newtabpage.cpp597
-rw-r--r--src/newtabpage.h122
-rw-r--r--src/paneltreeview.cpp200
-rw-r--r--src/paneltreeview.h72
-rw-r--r--src/previewimage.cpp430
-rw-r--r--src/previewimage.h101
-rw-r--r--src/previewselectorbar.cpp157
-rw-r--r--src/previewselectorbar.h (renamed from src/urlbar/lineedit.cpp)64
-rw-r--r--src/protocolhandler.cpp273
-rw-r--r--src/protocolhandler.h27
-rw-r--r--src/rekonq.kcfg72
-rw-r--r--src/rekonq_defines.h98
-rw-r--r--src/rekonqpage/newtabpage.cpp280
-rw-r--r--src/rekonqpage/newtabpage.h86
-rw-r--r--src/searchengine.cpp167
-rw-r--r--src/searchengine.h62
-rw-r--r--src/sessionmanager.cpp35
-rw-r--r--src/sessionmanager.h11
-rw-r--r--src/settings/adblockwidget.cpp192
-rw-r--r--src/settings/adblockwidget.h (renamed from src/rekonqprivate_export.h)57
-rw-r--r--src/settings/networkwidget.cpp100
-rw-r--r--src/settings/networkwidget.h (renamed from src/urlbar/lineedit.h)46
-rw-r--r--src/settings/settings_adblock.ui167
-rw-r--r--src/settings/settings_general.ui93
-rw-r--r--src/settings/settings_tabs.ui138
-rw-r--r--src/settings/settings_webkit.ui98
-rw-r--r--src/settings/settingsdialog.cpp120
-rw-r--r--src/settings/settingsdialog.h16
-rw-r--r--src/sslinfodialog_p.h107
-rw-r--r--src/tabbar.cpp163
-rw-r--r--src/tabbar.h30
-rw-r--r--src/tests/CMakeLists.txt144
-rw-r--r--src/tests/HTTP_tests.html601
-rw-r--r--src/tests/findbar_test.cpp76
-rw-r--r--src/tests/link_test.html7
-rw-r--r--src/tests/mainview_test.cpp239
-rw-r--r--src/tests/mainwindow_test.cpp65
-rw-r--r--src/tests/networkaccessmanager_test.cpp67
-rw-r--r--src/tests/protocolhandler_test.cpp130
-rw-r--r--src/tests/sessionmanager_test.cpp69
-rw-r--r--src/tests/tabbar_test.cpp141
-rw-r--r--src/tests/urlbar_test.cpp74
-rw-r--r--src/tests/walletbar_test.cpp69
-rw-r--r--src/tests/webpage_test.cpp112
-rw-r--r--src/tests/websnap_test.cpp69
-rw-r--r--src/tests/webtab_test.cpp68
-rw-r--r--src/tests/webview_test.cpp71
-rw-r--r--src/urlbar/completionwidget.cpp282
-rw-r--r--src/urlbar/completionwidget.h89
-rw-r--r--src/urlbar/listitem.cpp427
-rw-r--r--src/urlbar/listitem.h220
-rw-r--r--src/urlbar/rsswidget.cpp154
-rw-r--r--src/urlbar/rsswidget.h66
-rw-r--r--src/urlbar/urlbar.cpp436
-rw-r--r--src/urlbar/urlbar.h104
-rw-r--r--src/urlbar/urlresolver.cpp217
-rw-r--r--src/urlbar/urlresolver.h88
-rw-r--r--src/walletbar.cpp35
-rw-r--r--src/walletbar.h19
-rw-r--r--src/webinspectorpanel.cpp21
-rw-r--r--src/webinspectorpanel.h21
-rw-r--r--src/webpage.cpp501
-rw-r--r--src/webpage.h38
-rw-r--r--src/webpluginfactory.cpp104
-rw-r--r--src/webpluginfactory.h24
-rw-r--r--src/websnap.cpp141
-rw-r--r--src/websnap.h93
-rw-r--r--src/websslinfo.cpp214
-rw-r--r--src/websslinfo.h73
-rw-r--r--src/webtab.cpp179
-rw-r--r--src/webtab.h30
-rw-r--r--src/webview.cpp302
-rw-r--r--src/webview.h35
133 files changed, 11098 insertions, 3877 deletions
diff --git a/AUTHORS b/AUTHORS
index 1f8f8043..a1e08493 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -5,4 +5,5 @@ Lionel Chauvin megabigbug@yahoo.fr
Johannes Zellner webmaster@nebulon.de
Matthieu Gicquel matgic78@gmail.com
Ronny Scholz ronny_scholz@web.de
-Jonas Gastal jgastal@gmail.com
+Jonas Gastal jgastal@gmail.com
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 661cc6e3..d52e8b4a 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.3.33" )
+SET(REKONQ_VERSION "0.4.66" )
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/version.h )
@@ -21,10 +21,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.2)
# ==================================================================================
-SET(QT_MIN_VERSION 4.6.0)
-FIND_PACKAGE(Qt4 REQUIRED)
-SET(KDE_MIN_VERSION 4.3.80)
-FIND_PACKAGE(KDE4 REQUIRED)
+FIND_PACKAGE(Qt4 4.6.0 COMPONENTS QtCore QtGui QtNetwork QtWebKit REQUIRED)
+FIND_PACKAGE(KDE4 4.4.0 REQUIRED)
INCLUDE(MacroOptionalFindPackage)
INCLUDE(FindPackageHandleStandardArgs)
@@ -46,16 +44,16 @@ SET(QT_VERS_STR
"${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}"
)
-IF(QT_FOUND)
+IF(QT4_FOUND)
MESSAGE(STATUS " Qt library found...................... YES")
MESSAGE(STATUS " Qt version ${QT_VERS_STR} found! ")
-ELSE(QT_FOUND)
+ELSE(QT4_FOUND)
MESSAGE(STATUS " Qt library found...................... NO")
MESSAGE(STATUS "")
MESSAGE(SEND_ERROR " rekonq needs at least Qt ${QT_MIN_VERSION}. Please install it and try compiling again.")
MESSAGE(STATUS " Qt website is at http://qt.nokia.com")
MESSAGE(STATUS "")
-ENDIF(QT_FOUND)
+ENDIF(QT4_FOUND)
MESSAGE(STATUS "")
@@ -78,13 +76,13 @@ ENDIF(KDE4_FOUND)
##### FINAL RESULTS #####
-IF(QT_FOUND AND KDE4_FOUND)
+IF(QT4_FOUND AND KDE4_FOUND)
MESSAGE(STATUS " rekonq will be compiled............... YES")
SET(REKONQ_CAN_BE_COMPILED true)
-ELSE(QT_FOUND AND KDE4_FOUND)
+ELSE(QT4_FOUND AND KDE4_FOUND)
MESSAGE(FATAL_ERROR " rekonq will NOT be compiled!")
SET(REKONQ_CAN_BE_COMPILED false)
-ENDIF(QT_FOUND AND KDE4_FOUND)
+ENDIF(QT4_FOUND AND KDE4_FOUND)
MESSAGE(STATUS "")
MESSAGE(STATUS "-----------------------------------------------------------------------")
@@ -97,6 +95,7 @@ IF(REKONQ_CAN_BE_COMPILED)
ADD_SUBDIRECTORY( src )
ADD_SUBDIRECTORY( icons )
ADD_SUBDIRECTORY( docs )
+# ADD_SUBDIRECTORY( i18n )
ENDIF(REKONQ_CAN_BE_COMPILED)
diff --git a/ChangeLog b/ChangeLog
index cee60742..b165b547 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+0.4
+- moved to kdewebkit (this means based on kde 4.4)
+- kwallet support
+- KIO full support (cookies, cache, proxy, network)
+- file:// && ftp:// protocol easy handling
+- improved rekonq pages (in the about: protocol)
+- multithreaded url resolver (hopefully, no more UI freezes)
+- adblock support, first part (load manually links, for now...)
+- improved fullscreen mode
+- embedded inspector (A-LA firebug)
+- first kget integration
+- optional "clickToFlash" feature
+- tons of bugs fixed
+
+0.3
+- Simpler UI
+- new icon
+- multi windows support
+- KDE proxy setting support
+- "new tab home page" (tech preview)
+- Initial handbook added
+- tab previews
+- save & restore session support
+- Compiles on Windows, too
+
0.2
- simpler and better UI
- unique urlbar (integrated google search)
diff --git a/docs/index.docbook b/docs/index.docbook
index 2b210f6c..fde284a3 100644
--- a/docs/index.docbook
+++ b/docs/index.docbook
@@ -60,7 +60,7 @@
<abstract>
<para>
-&rekonq; is a lightweight web browser for &kde; based on WebKit.
+&rekonq; is a lightweight web browser for &kde; based on QtWebKit.
</para>
</abstract>
@@ -465,7 +465,7 @@ Documentation copyright 2010 &Jonathan.Kolberg; &Jonathan.Kolberg.mail;
<!--TRANS:CREDIT_FOR_TRANSLATORS-->
&underFDL; <!-- FDL: do not remove -->
-&underBSDLicense; <!-- BSD License -->
+&underGPL; <!-- GPL License -->
</chapter>
diff --git a/scripts/RELEASE_HOWTO b/scripts/RELEASE_HOWTO
index c0ae221e..eb3c3665 100644
--- a/scripts/RELEASE_HOWTO
+++ b/scripts/RELEASE_HOWTO
@@ -8,7 +8,7 @@ SECTION 0: A few days in advance
SECTION 1: Preparation
-* Check the README file is still relevant
+* Update CHANGELOG file
* Bump Version Number (in the CMakeLists.txt file)
* Commit the source to GIT
diff --git a/scripts/codingstyle.sh b/scripts/codingstyle.sh
index bb3add49..d13e84c0 100755..100644
--- a/scripts/codingstyle.sh
+++ b/scripts/codingstyle.sh
@@ -18,7 +18,7 @@
# ...
# }
#
-# I like this way, for me more readable.
+# I like this way, for me more readable. :)
#
# Kdelibs coding style is defined in http://techbase.kde.org/Policies/Kdelibs_Coding_Style
@@ -42,7 +42,7 @@ astyle \
`find -type f -name '*.cpp'` `find -type f -name '*.h'`
echo "Removing .orig files..."
-rm *.orig
+rm *.orig */*.orig
echo "Done!"
diff --git a/scripts/cppcheck.sh b/scripts/cppcheck.sh
new file mode 100644
index 00000000..be081040
--- /dev/null
+++ b/scripts/cppcheck.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+#
+# apply rekonq coding style to all cpp and header files in src directory
+#
+# requirements: installed astyle
+#
+# rekonq use kdelibs coding style, except for brackets, so while kdelibs coding style
+# is
+#
+# void foo() {
+# ...
+# }
+#
+# rekonq uses
+#
+# void foo()
+# {
+# ...
+# }
+#
+# I like this way, for me more readable. :)
+#
+# Kdelibs coding style is defined in http://techbase.kde.org/Policies/Kdelibs_Coding_Style
+
+
+PWD=$(pwd)
+
+cd $PWD
+cd ..
+cd src
+
+echo "cppcheck(ing)..."
+cppcheck \
+--enable=all \
+--force \
+--verbose \
+. 2>/tmp/cppcheck.out
+
+echo "DONE. read output in /tmp/cppcheck.out"
diff --git a/scripts/download_i18n.sh b/scripts/download_i18n.sh
new file mode 100644
index 00000000..a70c11d8
--- /dev/null
+++ b/scripts/download_i18n.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+# use this stupid script to just prepare rekonq
+# dir with translations.
+#
+# 1. Update the lists of the ready (about 80%) translations
+# check the situation here: http://l10n.kde.org/stats/gui/trunk-kde4/po/rekonq.po/
+LIST="pt_BR en_GB ca zh_CN cs da nl fr gl de hu it nds pl pt ru sr es sv tr uk"
+
+# 2. run this script. It will create an i18n dir in rekonq sources ($RK_SRCS variable, set it to your source path)
+# dir with all the listed translations (eg: italian translation = rekonq_it.po file)
+# plus the CMakeLists.txt file needed to compile them.
+RK_SRCS=/DATI/KDE/SRC/rekonq
+
+# 3. Uncomment the "ADD_SUBDIRECTORY( i18n )" line in main CMakeLists.txt file.
+
+# 4. test a package creation (to see the translations installed)
+
+# THAT's ALL!!
+
+########################################################################################################
+
+# exit on most errors
+set -e
+
+# current dir
+CWD=$(pwd)
+
+# create the i18n dir
+cd $RK_SRCS
+mkdir -p i18n
+cd i18n
+
+# download the po files
+for lang in $LIST
+do
+ wget http://websvn.kde.org/*checkout*/trunk/l10n-kde4/$lang/messages/playground-network/rekonq.po;
+ mv rekonq.po rekonq_$lang.po;
+done
+
+# create the CMakeLists.txt file for the translations
+
+
+echo '
+
+FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt)
+
+IF(NOT GETTEXT_MSGFMT_EXECUTABLE)
+ MESSAGE(
+"------
+ NOTE: msgfmt not found. Translations will *not* be installed
+------")
+ELSE(NOT GETTEXT_MSGFMT_EXECUTABLE)
+
+ SET(catalogname rekonq)
+
+ ADD_CUSTOM_TARGET(translations ALL)
+
+ FILE(GLOB PO_FILES ${catalogname}*.po)
+
+ FOREACH(_poFile ${PO_FILES})
+ GET_FILENAME_COMPONENT(_poFileName ${_poFile} NAME)
+ STRING(REGEX REPLACE "^${catalogname}_?" "" _langCode ${_poFileName} )
+ STRING(REGEX REPLACE "\\.po$" "" _langCode ${_langCode} )
+
+ IF( _langCode )
+ GET_FILENAME_COMPONENT(_lang ${_poFile} NAME_WE)
+ SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo)
+
+ ADD_CUSTOM_COMMAND(TARGET translations
+ COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check -o ${_gmoFile} ${_poFile}
+ DEPENDS ${_poFile})
+ INSTALL(FILES ${_gmoFile} DESTINATION ${LOCALE_INSTALL_DIR}/${_langCode}/LC_MESSAGES/ RENAME ${catalogname}.mo)
+ ENDIF( _langCode )
+
+ ENDFOREACH(_poFile ${PO_FILES})
+
+ENDIF(NOT GETTEXT_MSGFMT_EXECUTABLE)
+
+' > CMakeLists.txt
+
+# done :)
+cd $CWD
+echo "Done. Yuppy!"
diff --git a/scripts/i18n.sh b/scripts/i18n.sh
index e9b5444d..e9b5444d 100755..100644
--- a/scripts/i18n.sh
+++ b/scripts/i18n.sh
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b0a3fbd8..a6055ce7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,44 +8,52 @@ ADD_SUBDIRECTORY( tests )
SET( rekonq_KDEINIT_SRCS
application.cpp
+ clicktoflash.cpp
+ filterurljob.cpp
findbar.cpp
mainview.cpp
mainwindow.cpp
- previewimage.cpp
+ networkaccessmanager.cpp
+ newtabpage.cpp
+ paneltreeview.cpp
+ previewselectorbar.cpp
+ protocolhandler.cpp
sessionmanager.cpp
tabbar.cpp
+ walletbar.cpp
+ webinspectorpanel.cpp
webpage.cpp
webpluginfactory.cpp
+ websslinfo.cpp
websnap.cpp
webview.cpp
webtab.cpp
- clicktoflash.cpp
- networkaccessmanager.cpp
- webinspectorpanel.cpp
- walletbar.cpp
- protocolhandler.cpp
- filterurljob.cpp
+ searchengine.cpp
#----------------------------------------
history/autosaver.cpp
history/historymanager.cpp
history/historymodels.cpp
history/historypanel.cpp
#----------------------------------------
- rekonqpage/newtabpage.cpp
- #----------------------------------------
settings/settingsdialog.cpp
+ settings/adblockwidget.cpp
+ settings/networkwidget.cpp
#----------------------------------------
bookmarks/bookmarksmanager.cpp
bookmarks/bookmarkspanel.cpp
bookmarks/bookmarkstreemodel.cpp
bookmarks/bookmarksproxy.cpp
+ bookmarks/bookmarkcontextmenu.cpp
#----------------------------------------
adblock/adblockmanager.cpp
adblock/adblocknetworkreply.cpp
adblock/adblockrule.cpp
#----------------------------------------
urlbar/urlbar.cpp
- urlbar/lineedit.cpp
+ urlbar/completionwidget.cpp
+ urlbar/urlresolver.cpp
+ urlbar/listitem.cpp
+ urlbar/rsswidget.cpp
)
@@ -54,6 +62,7 @@ KDE4_ADD_UI_FILES( rekonq_KDEINIT_SRCS
settings/settings_tabs.ui
settings/settings_fonts.ui
settings/settings_webkit.ui
+ settings/settings_adblock.ui
cleardata.ui
)
diff --git a/src/Messages.sh b/src/Messages.sh
index b22743a6..efa6adff 100644
--- a/src/Messages.sh
+++ b/src/Messages.sh
@@ -1,2 +1,2 @@
#! /bin/sh
-$XGETTEXT *.cpp -o $podir/rekonq.pot
+$XGETTEXT *.cpp */*.cpp -o $podir/rekonq.pot
diff --git a/src/adblock/adblockmanager.cpp b/src/adblock/adblockmanager.cpp
index c2a42f0b..e195c705 100644
--- a/src/adblock/adblockmanager.cpp
+++ b/src/adblock/adblockmanager.cpp
@@ -2,7 +2,7 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -10,9 +10,9 @@
* 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
+* 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
@@ -28,6 +28,9 @@
#include "adblockmanager.h"
#include "adblockmanager.moc"
+// Auto Includes
+#include "rekonq.h"
+
// Local Includes
#include "adblocknetworkreply.h"
#include "webpage.h"
@@ -35,7 +38,7 @@
// KDE Includes
#include <KSharedConfig>
#include <KConfigGroup>
-#include <KDebug>
+#include <KIO/TransferJob>
// Qt Includes
#include <QUrl>
@@ -43,11 +46,11 @@
AdBlockManager::AdBlockManager(QObject *parent)
- : QObject(parent)
- , _isAdblockEnabled(false)
- , _isHideAdsEnabled(false)
+ : QObject(parent)
+ , _isAdblockEnabled(false)
+ , _isHideAdsEnabled(false)
+ , _index(0)
{
- loadSettings();
}
@@ -56,91 +59,144 @@ AdBlockManager::~AdBlockManager()
}
-void AdBlockManager::loadSettings()
+void AdBlockManager::loadSettings(bool checkUpdateDate)
{
- KSharedConfig::Ptr config = KSharedConfig::openConfig("khtmlrc", KConfig::NoGlobals);
- KConfigGroup cg( config, "Filter Settings" );
+ _index = 0;
+ _buffer.clear();
+
+ _whiteList.clear();
+ _blackList.clear();
+ _hideList.clear();
+
+ _isAdblockEnabled = ReKonfig::adBlockEnabled();
+ kDebug() << "ADBLOCK ENABLED = " << _isAdblockEnabled;
+
+ // no need to load filters if adblock is not enabled :)
+ if (!_isAdblockEnabled)
+ return;
+
+ // just to be sure..
+ _isHideAdsEnabled = ReKonfig::hideAdsEnabled();
+
+ // local settings
+ KSharedConfig::Ptr config = KGlobal::config();
+ KConfigGroup rulesGroup(config, "rules");
+ QStringList rules;
+ rules = rulesGroup.readEntry("local-rules" , QStringList());
+ loadRules(rules);
- if ( cg.exists() )
+ // ----------------------------------------------------------
+
+ QDateTime today = QDateTime::currentDateTime();
+ QDateTime lastUpdate = ReKonfig::lastUpdate(); // the day of the implementation.. :)
+ int days = ReKonfig::updateInterval();
+
+ if (!checkUpdateDate || today > lastUpdate.addDays(days))
{
- _isAdblockEnabled = cg.readEntry("Enabled", false);
- _isHideAdsEnabled = cg.readEntry("Shrink", false);
-
- // no need to load filters if adblock is not enabled :)
- if(!_isAdblockEnabled)
- return;
-
- _whiteList.clear();
- _blackList.clear();
- _hideList.clear();
-
- QMap<QString,QString> entryMap = cg.entryMap();
- QMap<QString,QString>::ConstIterator it;
- for( it = entryMap.constBegin(); it != entryMap.constEnd(); ++it )
+ ReKonfig::setLastUpdate(today);
+
+ updateNextSubscription();
+ return;
+ }
+
+ // else
+ QStringList titles = ReKonfig::subscriptionTitles();
+ foreach(const QString &title, titles)
+ {
+ rules = rulesGroup.readEntry(title + "-rules" , QStringList());
+ loadRules(rules);
+ }
+}
+
+
+void AdBlockManager::loadRules(const QStringList &rules)
+{
+ foreach(const QString &stringRule, rules)
+ {
+ // ! rules are comments
+ if (stringRule.startsWith('!'))
+ continue;
+
+ // [ rules are ABP info
+ if (stringRule.startsWith('['))
+ continue;
+
+ // empty rules are just dangerous..
+ // (an empty rule in whitelist allows all, in blacklist blocks all..)
+ if (stringRule.isEmpty())
+ continue;
+
+ // white rules
+ if (stringRule.startsWith(QL1S("@@")))
{
- QString name = it.key();
- QString url = it.value();
+ AdBlockRule rule(stringRule.mid(2));
+ _whiteList << rule;
+ continue;
+ }
- if (name.startsWith(QLatin1String("Filter")))
- {
- if(!url.startsWith("!"))
- {
- // white rules
- if(url.startsWith("@@"))
- {
- AdBlockRule rule( url.mid(2) );
- _whiteList << rule;
- continue;
- }
-
- // hide (CSS) rules
- if(url.startsWith("##"))
- {
- _hideList << url.mid(2);
- continue;
- }
-
- AdBlockRule rule( url );
- _blackList << rule;
- }
- }
+ // hide (CSS) rules
+ if (stringRule.startsWith(QL1S("##")))
+ {
+ _hideList << stringRule.mid(2);
+ continue;
}
+
+ AdBlockRule rule(stringRule);
+ _blackList << rule;
}
}
-QNetworkReply *AdBlockManager::block(const QNetworkRequest &request)
+QNetworkReply *AdBlockManager::block(const QNetworkRequest &request, WebPage *page)
{
if (!_isAdblockEnabled)
return 0;
-
+
// we (ad)block just http traffic
- if(request.url().scheme() != QLatin1String("http"))
+ if (request.url().scheme() != QL1S("http"))
return 0;
-
+
QString urlString = request.url().toString();
// check white rules before :)
foreach(const AdBlockRule &filter, _whiteList)
{
- if(filter.match(urlString))
+ if (filter.match(urlString))
{
- kDebug() << "****ADBLOCK: WHITE RULE (@@) Matched: ***********" << urlString;
- return 0;
+ kDebug() << "****ADBLOCK: WHITE RULE (@@) Matched: ***********";
+ kDebug() << "Filter exp: " << filter.pattern();
+ kDebug() << "UrlString: " << urlString;
+ return 0;
}
}
-
+
// then check the black ones :(
foreach(const AdBlockRule &filter, _blackList)
{
- if(filter.match(urlString))
+ if (filter.match(urlString))
{
- kDebug() << "****ADBLOCK: BLACK RULE Matched: ***********" << urlString;
+ 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")))
+ {
+ kDebug() << "MATCHES ATTRIBUTE!!!!!";
+ el.setStyleProperty(QL1S("visibility"), QL1S("hidden"));
+ el.setStyleProperty(QL1S("width"), QL1S("0"));
+ el.setStyleProperty(QL1S("height"), QL1S("0"));
+ }
+ }
+
AdBlockNetworkReply *reply = new AdBlockNetworkReply(request, urlString, this);
- return reply;
+ return reply;
}
}
-
+
// no match
return 0;
}
@@ -148,24 +204,124 @@ QNetworkReply *AdBlockManager::block(const QNetworkRequest &request)
void AdBlockManager::applyHidingRules(WebPage *page)
{
- if(!page || !page->mainFrame())
+ if (!page)
return;
-
+
if (!_isAdblockEnabled)
return;
-
+
if (!_isHideAdsEnabled)
return;
-
+
+ QWebElement document = page->mainFrame()->documentElement();
+
+ // HIDE RULES
foreach(const QString &filter, _hideList)
{
- QWebElement document = page->mainFrame()->documentElement();
QWebElementCollection elements = document.findAll(filter);
- foreach (QWebElement element, elements)
+ foreach(QWebElement el, elements)
{
- element.setStyleProperty(QLatin1String("visibility"), QLatin1String("hidden"));
- element.removeFromDocument();
+ if (el.isNull())
+ continue;
+ kDebug() << "Hide element: " << el.localName();
+ el.setStyleProperty(QL1S("visibility"), QL1S("hidden"));
+ el.removeFromDocument();
}
}
}
+
+
+void AdBlockManager::updateNextSubscription()
+{
+ QStringList locations = ReKonfig::subscriptionLocations();
+
+ if (_index < locations.size())
+ {
+ QString urlString = locations.at(_index);
+ kDebug() << "DOWNLOADING FROM " << urlString;
+ KUrl subUrl = KUrl(urlString);
+
+ KIO::TransferJob* job = KIO::get(subUrl , KIO::Reload , KIO::HideProgressInfo);
+ connect(job, SIGNAL(data(KIO::Job*, const QByteArray&)), this, SLOT(subscriptionData(KIO::Job*, const QByteArray&)));
+ connect(job, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*)));
+
+ return;
+ }
+
+ _index = 0;
+ _buffer.clear();
+}
+
+
+void AdBlockManager::slotResult(KJob *job)
+{
+ kDebug() << "SLOTRESULT";
+ if (job->error())
+ return;
+
+ QList<QByteArray> list = _buffer.split('\n');
+ QStringList ruleList;
+ foreach(const QByteArray &ba, list)
+ {
+ kDebug() << ba;
+ ruleList << QString(ba);
+ }
+ loadRules(ruleList);
+ saveRules(ruleList);
+
+ _index++;
+
+ // last..
+ updateNextSubscription();
+}
+
+
+void AdBlockManager::subscriptionData(KIO::Job* job, const QByteArray& data)
+{
+ kDebug() << "subscriptionData";
+ Q_UNUSED(job)
+
+ if (data.isEmpty())
+ return;
+
+ int oldSize = _buffer.size();
+ _buffer.resize(_buffer.size() + data.size());
+ memcpy(_buffer.data() + oldSize, data.data(), data.size());
+}
+
+
+void AdBlockManager::saveRules(const QStringList &rules)
+{
+ QStringList cleanedRules;
+ foreach(const QString &r, rules)
+ {
+ if (!r.startsWith('!') && !r.startsWith('[') && !r.isEmpty())
+ cleanedRules << r;
+ }
+
+ QStringList titles = ReKonfig::subscriptionTitles();
+ QString title = titles.at(_index) + "-rules";
+
+ KSharedConfig::Ptr config = KGlobal::config();
+ KConfigGroup cg(config , "rules");
+ cg.writeEntry(title, cleanedRules);
+}
+
+
+void AdBlockManager::addSubscription(const QString &title, const QString &location)
+{
+ QStringList titles = ReKonfig::subscriptionTitles();
+ if (titles.contains(title))
+ return;
+
+ QStringList locations = ReKonfig::subscriptionLocations();
+ if (locations.contains(location))
+ return;
+
+ titles << title;
+ locations << location;
+
+ ReKonfig::setSubscriptionTitles(titles);
+ ReKonfig::setSubscriptionLocations(locations);
+}
diff --git a/src/adblock/adblockmanager.h b/src/adblock/adblockmanager.h
index f01aaca0..eae761e0 100644
--- a/src/adblock/adblockmanager.h
+++ b/src/adblock/adblockmanager.h
@@ -2,7 +2,7 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -10,9 +10,9 @@
* 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
+* 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
@@ -30,42 +30,42 @@
// NOTE: AdBlockPlus Filters (fast) summary
-//
+//
// ### Basic Filter rules
-//
-// RULE = http://example.com/ads/*
+//
+// RULE = http://example.com/ads/*
// this should block every link containing all things from that link
-//
+//
// ### Exception rules (@@)
-//
+//
// RULE = @@advice*
-//
+//
// this will save every site, also that matched by other rules, cointaining words
// that starts with "advice". Wildcards && regular expression allowed here.
-//
+//
// ### Beginning/end matching rules (||)
-//
+//
// RULE=||http://badsite.com
-//
+//
// will stop all links starting with http://badsite.com
-//
+//
// RULE=*swf||
-//
+//
// will stop all links to direct flash contents
-//
+//
// ### Comments (!)
-//
+//
// RULE=!azz..
-//
+//
// Every rule starting with a ! is commented out and should not be checked
-//
+//
// ### Filter Options
-//
-// You can also specify a number of options to modify the behavior of a filter.
+//
+// You can also specify a number of options to modify the behavior of a filter.
// You list these options separated with commas after a dollar sign ($) at the end of the filter
-//
+//
// RULE=*/ads/*$element,match-case
-//
+//
// where $element can be one of the following:
// $script external scripts loaded via HTML script tag
// $image regular images, typically loaded via HTML img tag
@@ -80,37 +80,44 @@
// $subdocument embedded pages, usually included via HTML frames
// $document the page itself (only exception rules can be applied to the page)
// $other types of requests not covered in the list above
-//
+//
// Inverse type options are allowed through the ~ sign, for example:
-//
+//
// RULE=*/ads/*~$script,match-case
-//
+//
// ### Regular expressions
-//
+//
// They usually allow to check for (a lot of) sites, using just one rule, but be careful:
// BASIC FILTERS ARE PROCESSED FASTER THAN REGULAR EXPRESSIONS (In ADP! In rekonq, I don't know...)
-//
-//
+//
+//
// ### ELEMENT HIDING (##)
-//
-// This is quite different from usual adblock (but, for me, more powerful!). Sometimes you will find advertisements
+//
+// This is quite different from usual adblock (but, for me, more powerful!). Sometimes you will find advertisements
// that can’t be blocked because they are embedded as text in the web page itself.
// All you can do there is HIDE the element :)
-//
+//
// RULE=##div.advise
-//
+//
// The previous rule will hide every div whose class is named "advise". Usual CSS selectors apply here :)
//
// END NOTE ----------------------------------------------------------------------------------------------------------
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Local Includes
#include "adblockrule.h"
+// KDE Includes
+#include <KIO/Job>
+
// Qt Includes
#include <QObject>
#include <QNetworkReply>
#include <QStringList>
+#include <QByteArray>
// Forward Includes
class QNetworkRequest;
@@ -120,18 +127,30 @@ class WebPage;
typedef QList<AdBlockRule> AdBlockRuleList;
-class AdBlockManager : public QObject
+class REKONQ_TESTS_EXPORT AdBlockManager : public QObject
{
-Q_OBJECT
-
+ Q_OBJECT
+
public:
AdBlockManager(QObject *parent = 0);
~AdBlockManager();
- void loadSettings();
- QNetworkReply *block(const QNetworkRequest &request);
+ QNetworkReply *block(const QNetworkRequest &request, WebPage *page);
void applyHidingRules(WebPage *page);
-
+ void addSubscription(const QString &title, const QString &location);
+
+public slots:
+ void loadSettings(bool checkUpdateDate = true);
+
+private:
+ void updateNextSubscription();
+ void saveRules(const QStringList &);
+ void loadRules(const QStringList &);
+
+private slots:
+ void slotResult(KJob *);
+ void subscriptionData(KIO::Job*, const QByteArray&);
+
private:
bool _isAdblockEnabled;
bool _isHideAdsEnabled;
@@ -139,6 +158,9 @@ private:
AdBlockRuleList _blackList;
AdBlockRuleList _whiteList;
QStringList _hideList;
+
+ int _index;
+ QByteArray _buffer;
};
#endif
diff --git a/src/adblock/adblocknetworkreply.cpp b/src/adblock/adblocknetworkreply.cpp
index 1ccca96d..13677daa 100644
--- a/src/adblock/adblocknetworkreply.cpp
+++ b/src/adblock/adblocknetworkreply.cpp
@@ -28,7 +28,7 @@
*
* This file is a part of the rekonq project
*
- * Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+ * Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -36,9 +36,9 @@
* 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
+ * 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
@@ -58,17 +58,19 @@
#include <klocalizedstring.h>
// Qt Includes
-#include <QNetworkRequest>
-#include <QTimer>
+#include <QtCore/QTimer>
+#include <QtCore/QString>
+
+#include <QtNetwork/QNetworkRequest>
AdBlockNetworkReply::AdBlockNetworkReply(const QNetworkRequest &request, const QString &urlString, QObject *parent)
- : QNetworkReply(parent)
+ : QNetworkReply(parent)
{
setOperation(QNetworkAccessManager::GetOperation);
setRequest(request);
setUrl(request.url());
- setError(QNetworkReply::ContentAccessDenied, i18n("Blocked by AdBlockRule: %1").arg(urlString));
+ setError(QNetworkReply::ContentAccessDenied, i18n("Blocked by AdBlockRule: %1", urlString));
QTimer::singleShot(0, this, SLOT(delayedFinished()));
}
diff --git a/src/adblock/adblocknetworkreply.h b/src/adblock/adblocknetworkreply.h
index b5bb8300..14a0672c 100644
--- a/src/adblock/adblocknetworkreply.h
+++ b/src/adblock/adblocknetworkreply.h
@@ -28,7 +28,7 @@
*
* This file is a part of the rekonq project
*
- * Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+ * Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -36,9 +36,9 @@
* 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
+ * 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
@@ -54,15 +54,18 @@
#define ADBLOCK_NETWORK_REPLY_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Qt Includes
#include <QNetworkReply>
-#include <QString>
// Forward Declarations
class AdBlockRule;
+class QString;
-class AdBlockNetworkReply : public QNetworkReply
+class REKONQ_TESTS_EXPORT AdBlockNetworkReply : public QNetworkReply
{
Q_OBJECT
diff --git a/src/adblock/adblockrule.cpp b/src/adblock/adblockrule.cpp
index 9f86ffee..7c91a692 100644
--- a/src/adblock/adblockrule.cpp
+++ b/src/adblock/adblockrule.cpp
@@ -30,7 +30,7 @@
*
* This file is a part of the rekonq project
*
- * Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+ * Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -38,9 +38,9 @@
* 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
+ * 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
@@ -57,44 +57,38 @@
// Qt Includes
#include <QStringList>
-#include <QDebug>
-#include <QRegExp>
#include <QUrl>
-// Defines
-#define QL1S(x) QLatin1String(x)
-#define QL1C(x) QLatin1Char(x)
-
AdBlockRule::AdBlockRule(const QString &filter)
- : m_optionMatchRule(false)
+ : m_optionMatchRule(false)
{
bool isRegExpRule = false;
QString parsedLine = filter;
-
- if ( parsedLine.startsWith( QL1C('/') ) && parsedLine.endsWith( QL1C('/') ) )
+
+ 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);
+
+ int optionsNumber = parsedLine.indexOf(QL1C('$'), 0);
QStringList options;
-
- if (optionsNumber >= 0)
+
+ if (optionsNumber >= 0)
{
options = parsedLine.mid(optionsNumber + 1).split(QL1C(','));
parsedLine = parsedLine.left(optionsNumber);
}
- if(!isRegExpRule)
+ if (!isRegExpRule)
parsedLine = convertPatternToRegExp(parsedLine);
-
+
m_regExp = QRegExp(parsedLine, Qt::CaseInsensitive, QRegExp::RegExp2);
- if ( options.contains( QL1S("match-case") ))
+ if (options.contains(QL1S("match-case")))
{
m_regExp.setCaseSensitivity(Qt::CaseSensitive);
m_optionMatchRule = true;
@@ -111,19 +105,19 @@ bool AdBlockRule::match(const QString &encodedUrl) const
// TODO: Reimplement this in rekonq 0.5 :)
//
-// if (matched && !m_options.isEmpty())
+// if (matched && !m_options.isEmpty())
// {
// // we only support domain right now
// if (m_options.count() == 1)
// {
-// foreach (const QString &option, m_options)
+// foreach (const QString &option, m_options)
// {
-// if (option.startsWith( QL1S("domain=") ))
+// if (option.startsWith( QL1S("domain=") ))
// {
// QUrl url = QUrl::fromEncoded(encodedUrl.toUtf8());
// QString host = url.host();
// QStringList domainOptions = option.mid(7).split( QL1C('|') );
-// foreach (QString domainOption, domainOptions)
+// foreach (QString domainOption, domainOptions)
// {
// bool negate = domainOption.at(0) == QL1C('~');
// if (negate)
@@ -147,37 +141,43 @@ bool AdBlockRule::match(const QString &encodedUrl) const
QString AdBlockRule::convertPatternToRegExp(const QString &wildcardPattern)
{
QString pattern = wildcardPattern;
-
+
// remove multiple wildcards
- pattern.replace(QRegExp( QL1S("\\*+") ), QL1S("*") );
-
+ pattern.replace(QRegExp(QL1S("\\*+")), QL1S("*"));
+
// remove anchors following separator placeholder
- pattern.replace(QRegExp( QL1S("\\^\\|$") ), QL1S("^") );
-
+ pattern.replace(QRegExp(QL1S("\\^\\|$")), QL1S("^"));
+
// remove leading wildcards
- pattern.replace(QRegExp( QL1S("^(\\*)") ), QL1S("") );
-
+ pattern.replace(QRegExp(QL1S("^(\\*)")), QL1S(""));
+
// remove trailing wildcards
- pattern.replace(QRegExp( QL1S("(\\*)$") ), QL1S("") );
-
+ pattern.replace(QRegExp(QL1S("(\\*)$")), QL1S(""));
+
// escape special symbols
- pattern.replace(QRegExp( QL1S("(\\W)") ), QL1S("\\\\1") );
-
+ pattern.replace(QRegExp(QL1S("(\\W)")), QL1S("\\\\1"));
+
// process extended anchor at expression start
- pattern.replace(QRegExp( QL1S("^\\\\\\|\\\\\\|") ), QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?") );
-
+ pattern.replace(QRegExp(QL1S("^\\\\\\|\\\\\\|")), QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?"));
+
// process separator placeholders
- pattern.replace(QRegExp( QL1S("\\\\\\^") ), QL1S("(?:[^\\w\\d\\-.%]|$)") );
-
+ pattern.replace(QRegExp(QL1S("\\\\\\^")), QL1S("(?:[^\\w\\d\\-.%]|$)"));
+
// process anchor at expression start
- pattern.replace(QRegExp( QL1S("^\\\\\\|") ), QL1S("^") );
-
+ pattern.replace(QRegExp(QL1S("^\\\\\\|")), QL1S("^"));
+
// process anchor at expression end
- pattern.replace(QRegExp( QL1S("\\\\\\|$") ), QL1S("$") );
-
+ pattern.replace(QRegExp(QL1S("\\\\\\|$")), QL1S("$"));
+
// replace wildcards by .*
- pattern.replace(QRegExp( QL1S("\\\\\\*") ), QL1S(".*") );
+ pattern.replace(QRegExp(QL1S("\\\\\\*")), QL1S(".*"));
// Finally, return...
return pattern;
}
+
+
+QString AdBlockRule::pattern() const
+{
+ return m_regExp.pattern();
+}
diff --git a/src/adblock/adblockrule.h b/src/adblock/adblockrule.h
index 35715051..6f042fe2 100644
--- a/src/adblock/adblockrule.h
+++ b/src/adblock/adblockrule.h
@@ -29,7 +29,7 @@
*
* This file is a part of the rekonq project
*
- * Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+ * Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -37,9 +37,9 @@
* 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
+ * 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
@@ -54,9 +54,13 @@
#ifndef ADBLOCKRULE_H
#define ADBLOCKRULE_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Qt Includes
-#include <QRegExp>
-#include <QString>
+#include <QtCore/QRegExp>
+#include <QtCore/QString>
// Forward Includes
class QUrl;
@@ -69,11 +73,13 @@ public:
bool match(const QString &encodedUrl) const;
-private:
+ QString pattern() const;
+
+private:
QString convertPatternToRegExp(const QString &wildcardPattern);
-
+
QRegExp m_regExp;
-
+
// Rule Options
bool m_optionMatchRule;
};
diff --git a/src/application.cpp b/src/application.cpp
index 05004f30..b1419d00 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -2,9 +2,9 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +12,9 @@
* 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
+* 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
@@ -44,48 +44,60 @@
#include "adblockmanager.h"
#include "webview.h"
#include "filterurljob.h"
+#include "tabbar.h"
// KDE Includes
#include <KCmdLineArgs>
#include <KStandardDirs>
#include <kio/job.h>
#include <kio/jobclasses.h>
-#include <KToolInvocation>
#include <KUriFilter>
#include <KMessageBox>
-#include <KWindowInfo>
#include <KUrl>
#include <ThreadWeaver/Weaver>
// Qt Includes
-#include <QRegExp>
-#include <QFile>
-#include <QFileInfo>
#include <QtCore/QTimer>
-QPointer<HistoryManager> Application::s_historyManager;
-QPointer<BookmarkProvider> Application::s_bookmarkProvider;
-QPointer<SessionManager> Application::s_sessionManager;
-QPointer<AdBlockManager> Application::s_adblockManager;
+QWeakPointer<HistoryManager> Application::s_historyManager;
+QWeakPointer<BookmarkProvider> Application::s_bookmarkProvider;
+QWeakPointer<SessionManager> Application::s_sessionManager;
+QWeakPointer<AdBlockManager> Application::s_adblockManager;
Application::Application()
- : KUniqueApplication()
+ : KUniqueApplication()
{
- connect(Weaver::instance(), SIGNAL( jobDone(ThreadWeaver::Job*) ),
- this, SLOT( loadResolvedUrl(ThreadWeaver::Job*) ) );
+ connect(Weaver::instance(), SIGNAL(jobDone(ThreadWeaver::Job*)),
+ this, SLOT(loadResolvedUrl(ThreadWeaver::Job*)));
}
Application::~Application()
{
- qDeleteAll(m_mainWindows);
+ // ok, we are closing well.
+ // Don't recover on next load..
+ ReKonfig::setRecoverOnCrash(0);
+ saveConfiguration();
+
+ foreach(QWeakPointer<MainWindow> window, m_mainWindows)
+ {
+ delete window.data();
+ window.clear();
+ }
+
+ delete s_bookmarkProvider.data();
+ s_bookmarkProvider.clear();
- delete s_bookmarkProvider;
- delete s_historyManager;
- delete s_sessionManager;
- delete s_adblockManager;
+ delete s_historyManager.data();
+ s_historyManager.clear();
+
+ delete s_sessionManager.data();
+ s_sessionManager.clear();
+
+ delete s_adblockManager.data();
+ s_adblockManager.clear();
}
@@ -93,81 +105,69 @@ int Application::newInstance()
{
KCmdLineArgs::setCwd(QDir::currentPath().toUtf8());
KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
-
- // we share one process for several mainwindows,
- // so initialize only once
- static bool first = true;
-
- if(args->count() == 0)
+
+ bool isFirstLoad = m_mainWindows.isEmpty();
+
+ // is your app session restored? restore session...
+ // this mechanism also falls back to load usual plain rekonq
+ // if something goes wrong...
+ if (isFirstLoad && ReKonfig::recoverOnCrash() == 1 && sessionManager()->restoreSession())
+ {
+ QTimer::singleShot(0, this, SLOT(postLaunch()));
+ kDebug() << "session restored";
+ return 1;
+ }
+
+ if (args->count() == 0)
{
- if(first) // we are starting rekonq, for the first time with no args: use startup behaviour
+ if (isFirstLoad) // we are starting rekonq, for the first time with no args: use startup behaviour
{
- switch(ReKonfig::startupBehaviour())
+ switch (ReKonfig::startupBehaviour())
{
- case 0: // open home page
- mainWindow()->homePage();
- break;
- case 1: // open new tab page
- loadUrl( KUrl("about:home") );
- break;
- case 2: // restore session
- if(sessionManager()->restoreSession())
- break;
- default:
- mainWindow()->homePage();
+ case 0: // open home page
+ mainWindow()->homePage();
+ break;
+ case 1: // open new tab page
+ loadUrl(KUrl("about:home"));
+ break;
+ case 2: // restore session
+ if (sessionManager()->restoreSession())
break;
- }
+ default:
+ mainWindow()->homePage();
+ break;
+ }
}
else // rekonq has just been started. Just open a new window
{
- newMainWindow();
+ loadUrl(KUrl("about:home") , Rekonq::NewWindow);
}
}
-
- if (first)
- {
- QTimer::singleShot(0, this, SLOT(postLaunch()));
- first = false;
- }
-
- // is your app session restored? restore session...
- // this mechanism also falls back to load usual plain rekonq
- // if something goes wrong...
- if (isSessionRestored() && sessionManager()->restoreSession())
+ else
{
- kDebug() << "session restored";
- return 1;
- }
-
- // are there args? load them..
- if (args->count() > 0)
- {
- // is there a window open on the current desktop ? use it!
- for (int i = 0; i < m_mainWindows.size(); ++i)
+ if (isFirstLoad)
{
- MainWindow *m = m_mainWindows.at(i);
- KWindowInfo w = KWindowInfo(m->winId(), NET::WMDesktop);
- if(w.isOnCurrentDesktop())
+ // No windows in the current desktop? No windows at all?
+ // Create a new one and load there sites...
+ loadUrl(args->arg(0), Rekonq::CurrentTab);
+ for (int i = 1; i < args->count(); ++i)
+ loadUrl(KUrl(args->arg(i)), Rekonq::SettingOpenTab);
+ }
+ else
+ {
+ // are there any windows there? use it
+ int index = m_mainWindows.size();
+ if (index > 0)
{
+ MainWindow *m = m_mainWindows.at(index - 1).data();
m->activateWindow();
- m->raise();
-
for (int i = 0; i < args->count(); ++i)
- loadUrl(args->arg(i), Rekonq::NewCurrentTab);
-
- return 2;
+ loadUrl(KUrl(args->arg(i)), Rekonq::NewCurrentTab);
}
}
-
- // No windows in the current desktop? No windows at all?
- // Create a new one and load there sites...
- loadUrl(args->arg(0), Rekonq::CurrentTab);
- for (int i = 1; i < args->count(); ++i)
- loadUrl(args->arg(i), Rekonq::SettingOpenTab);
-
- return 3;
}
-
+
+ QTimer::singleShot(0, this, SLOT(postLaunch()));
return 0;
}
@@ -180,18 +180,26 @@ Application *Application::instance()
void Application::postLaunch()
{
+ // updating rekonq configuration
+ updateConfiguration();
+
setWindowIcon(KIcon("rekonq"));
-
+
// set Icon Database Path to store "favicons" associated with web sites
QString directory = KStandardDirs::locateLocal("cache" , "" , true);
QWebSettings::setIconDatabasePath(directory);
Application::historyManager();
Application::sessionManager();
-
+
// bookmarks loading
connect(Application::bookmarkProvider(), SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType&)),
Application::instance(), SLOT(loadUrl(const KUrl&, const Rekonq::OpenType&)));
+
+ // crash recovering
+ int n = ReKonfig::recoverOnCrash();
+ ReKonfig::setRecoverOnCrash(++n);
+ saveConfiguration();
}
@@ -203,14 +211,14 @@ void Application::saveConfiguration() const
MainWindow *Application::mainWindow()
{
- if(m_mainWindows.isEmpty())
+ if (m_mainWindows.isEmpty())
return newMainWindow();
-
+
MainWindow *active = qobject_cast<MainWindow*>(QApplication::activeWindow());
-
- if(!active)
+
+ if (!active)
{
- return m_mainWindows.at(0);
+ return m_mainWindows.at(0).data();
}
return active;
}
@@ -218,53 +226,55 @@ MainWindow *Application::mainWindow()
HistoryManager *Application::historyManager()
{
- if (!s_historyManager)
+ if (s_historyManager.isNull())
{
s_historyManager = new HistoryManager();
- QWebHistoryInterface::setDefaultInterface(s_historyManager);
+ QWebHistoryInterface::setDefaultInterface(s_historyManager.data());
}
- return s_historyManager;
+ return s_historyManager.data();
}
BookmarkProvider *Application::bookmarkProvider()
{
- if (!s_bookmarkProvider)
+ if (s_bookmarkProvider.isNull())
{
s_bookmarkProvider = new BookmarkProvider(instance());
}
- return s_bookmarkProvider;
+ return s_bookmarkProvider.data();
}
SessionManager *Application::sessionManager()
{
- if(!s_sessionManager)
+ if (s_sessionManager.isNull())
{
s_sessionManager = new SessionManager(instance());
}
- return s_sessionManager;
+ return s_sessionManager.data();
}
KIcon Application::icon(const KUrl &url)
{
- if(!Application::instance()->mainWindowList().isEmpty()) // avoid infinite loop at startup
- {
+ // avoid infinite loop at startup
+ if (Application::instance()->mainWindowList().isEmpty())
+ return KIcon("text-html");
- if(url == KUrl("about:closedTabs"))
- return KIcon("tab-close");
- if(url == KUrl("about:history"))
- return KIcon("view-history");
- if(url == KUrl("about:bookmarks"))
- return KIcon("bookmarks");
- if(url == KUrl("about:favorites"))
- return KIcon("emblem-favorite");
- }
-
- if(url.isEmpty())
+ // first things first..
+ if (url.isEmpty())
return KIcon("text-html");
-
+
+ // rekonq icons..
+ if (url == KUrl("about:closedTabs"))
+ return KIcon("tab-close");
+ if (url == KUrl("about:history"))
+ return KIcon("view-history");
+ if (url == KUrl("about:bookmarks"))
+ return KIcon("bookmarks");
+ if (url == KUrl("about:favorites"))
+ return KIcon("emblem-favorite");
+
KIcon icon = KIcon(QWebSettings::iconForUrl(url));
if (icon.isNull())
{
@@ -279,23 +289,20 @@ void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type)
if (url.isEmpty())
return;
- // sanitization
- KUrl loadingUrl( url.toEncoded() );
-
- if ( !loadingUrl.isValid() )
+ if (!url.isValid())
{
- KMessageBox::error(0, i18n("Malformed URL:\n%1", loadingUrl.url(KUrl::RemoveTrailingSlash)));
+ KMessageBox::error(0, i18n("Malformed URL:\n%1", url.url(KUrl::RemoveTrailingSlash)));
return;
}
// first, create the webview(s) to not let hangs UI..
WebTab *tab = 0;
MainWindow *w = 0;
- w = (type == Rekonq::NewWindow)
+ w = (type == Rekonq::NewWindow)
? newMainWindow()
: mainWindow();
-
- switch(type)
+
+ switch (type)
{
case Rekonq::SettingOpenTab:
tab = w->mainView()->newWebTab(!ReKonfig::openTabsBack(), ReKonfig::openTabsNearCurrent());
@@ -311,39 +318,34 @@ void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type)
tab = w->mainView()->currentWebTab();
break;
};
-
+
WebView *view = tab->view();
-
+
if (view)
{
- FilterUrlJob *job = new FilterUrlJob(view, loadingUrl.pathOrUrl(), this);
+ FilterUrlJob *job = new FilterUrlJob(view, url.pathOrUrl(), this);
Weaver::instance()->enqueue(job);
}
}
-
-void Application::loadUrl(const QString& urlString, const Rekonq::OpenType& type)
-{
- return loadUrl( QUrl::fromUserInput(urlString), type );
-}
-
-
-MainWindow *Application::newMainWindow()
+MainWindow *Application::newMainWindow(bool withTab)
{
MainWindow *w = new MainWindow();
- w->mainView()->newWebTab(); // remember using newWebTab and NOT newTab here!!
-
+
+ if (withTab)
+ w->mainView()->newWebTab(); // remember using newWebTab and NOT newTab here!!
+
m_mainWindows.prepend(w);
w->show();
-
+
return w;
}
void Application::removeMainWindow(MainWindow *window)
{
- m_mainWindows.removeAt(m_mainWindows.indexOf(window, 0));
+ m_mainWindows.removeOne(window);
}
@@ -355,11 +357,11 @@ MainWindowList Application::mainWindowList()
AdBlockManager *Application::adblockManager()
{
- if(!s_adblockManager)
+ if (s_adblockManager.isNull())
{
s_adblockManager = new AdBlockManager(instance());
}
- return s_adblockManager;
+ return s_adblockManager.data();
}
@@ -368,19 +370,101 @@ void Application::loadResolvedUrl(ThreadWeaver::Job *job)
FilterUrlJob *threadedJob = static_cast<FilterUrlJob *>(job);
KUrl url = threadedJob->url();
WebView *view = threadedJob->view();
-
+
+ // Bye and thanks :)
+ delete threadedJob;
+
if (view)
{
- view->setFocus();
- view->load(url);
-
+ 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() == QLatin1String("http") || url.protocol() == QLatin1String("https") )
- historyManager()->addHistoryEntry( url.prettyUrl() );
+ if (url.protocol() == QL1S("http") || url.protocol() == QL1S("https"))
+ historyManager()->addHistoryEntry(url.prettyUrl());
}
-
- // Bye and thanks :)
- delete threadedJob;
+}
+
+
+void Application::newWindow()
+{
+ loadUrl(KUrl("about:home"), Rekonq::NewWindow);
+ mainWindow()->mainView()->urlBarWidget()->setFocus();
+}
+
+
+void Application::updateConfiguration()
+{
+ // FIXME:
+ // all things related to mainview can be
+ // improved/moved/replicated in all the mainwindows
+ MainView *view = mainWindow()->mainView();
+
+ // ============== General ==================
+ view->updateTabBar();
+
+ // ============== Tabs ==================
+ if (ReKonfig::closeTabSelectPrevious())
+ view->tabBar()->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
+ else
+ view->tabBar()->setSelectionBehaviorOnRemove(QTabBar::SelectRightTab);
+
+ // =========== Encodings & Fonts ==============
+ QWebSettings *defaultSettings = QWebSettings::globalSettings();
+
+ defaultSettings->setDefaultTextEncoding(ReKonfig::defaultEncoding());
+
+ int fnSize = ReKonfig::fontSize();
+ int minFnSize = ReKonfig::minFontSize();
+
+ QFont standardFont = ReKonfig::standardFont();
+ defaultSettings->setFontFamily(QWebSettings::StandardFont, standardFont.family());
+ defaultSettings->setFontSize(QWebSettings::DefaultFontSize, fnSize);
+ defaultSettings->setFontSize(QWebSettings::MinimumFontSize, minFnSize);
+
+ QFont fixedFont = ReKonfig::fixedFont();
+ defaultSettings->setFontFamily(QWebSettings::FixedFont, fixedFont.family());
+ defaultSettings->setFontSize(QWebSettings::DefaultFixedFontSize, fnSize);
+
+ // ================ WebKit ============================
+ defaultSettings->setAttribute(QWebSettings::AutoLoadImages, ReKonfig::autoLoadImages());
+ defaultSettings->setAttribute(QWebSettings::DnsPrefetchEnabled, ReKonfig::dnsPrefetch());
+ defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, ReKonfig::javascriptEnabled());
+ defaultSettings->setAttribute(QWebSettings::JavaEnabled, ReKonfig::javaEnabled());
+ defaultSettings->setAttribute(QWebSettings::JavascriptCanOpenWindows, ReKonfig::javascriptCanOpenWindows());
+ defaultSettings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, ReKonfig::javascriptCanAccessClipboard());
+ defaultSettings->setAttribute(QWebSettings::LinksIncludedInFocusChain, ReKonfig::linksIncludedInFocusChain());
+ defaultSettings->setAttribute(QWebSettings::ZoomTextOnly, ReKonfig::zoomTextOnly());
+ defaultSettings->setAttribute(QWebSettings::PrintElementBackgrounds, ReKonfig::printElementBackgrounds());
+
+ if (ReKonfig::pluginsEnabled() == 2)
+ defaultSettings->setAttribute(QWebSettings::PluginsEnabled, false);
+ else
+ defaultSettings->setAttribute(QWebSettings::PluginsEnabled, true);
+
+ // ===== HTML 5 features WebKit support ======
+ defaultSettings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, ReKonfig::offlineStorageDatabaseEnabled());
+ defaultSettings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, ReKonfig::offlineWebApplicationCacheEnabled());
+ defaultSettings->setAttribute(QWebSettings::LocalStorageEnabled, ReKonfig::localStorageEnabled());
+ if (ReKonfig::localStorageEnabled())
+ {
+ QString path = KStandardDirs::locateLocal("cache", QString("WebkitLocalStorage/rekonq"), true);
+ path.remove("rekonq");
+ QWebSettings::setOfflineStoragePath(path);
+ QWebSettings::setOfflineStorageDefaultQuota(50000);
+ }
+
+ // Applies user defined CSS to all open webpages. If there no longer is a
+ // user defined CSS removes it from all open webpages.
+ if (ReKonfig::userCSS().isEmpty())
+ defaultSettings->setUserStyleSheetUrl(KUrl(KStandardDirs::locate("appdata" , "default.css")));
+ else
+ defaultSettings->setUserStyleSheetUrl(ReKonfig::userCSS());
+
+ // ====== load Settings on main classes
+ Application::historyManager()->loadSettings();
+ Application::adblockManager()->loadSettings();
+
+ defaultSettings = 0;
}
diff --git a/src/application.h b/src/application.h
index 4b951ded..7b58ab18 100644
--- a/src/application.h
+++ b/src/application.h
@@ -2,9 +2,9 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +12,9 @@
* 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
+* 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
@@ -30,15 +30,16 @@
#define APPLICATION_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// KDE Includes
#include <KUniqueApplication>
#include <KIcon>
-#include <kio/job.h>
-#include <kio/jobclasses.h>
#include <ThreadWeaver/Job>
// Qt Includes
-#include <QPointer>
+#include <QWeakPointer>
#include <QList>
// Forward Declarations
@@ -52,44 +53,13 @@ class AdBlockManager;
class WebView;
-typedef QList< QPointer<MainWindow> > MainWindowList;
-
-
-namespace Rekonq
-{
- /**
- * @short notifying message status
- * Different message status
- */
-
- enum Notify
- {
- Success, ///< url successfully (down)loaded
- Error, ///< url failed to (down)load
- Download, ///< downloading url
- Info ///< information, (default)
- };
-
- /**
- * @short Open link options
- * Different modes of opening new tab
- */
- enum OpenType
- {
- CurrentTab, ///< open url in current tab
- SettingOpenTab, ///< open url according to users settings
- NewCurrentTab, ///< open url in new tab and make it current
- NewBackTab, ///< open url in new tab in background
- NewWindow ///< open url in new window
- };
-
-}
+typedef QList< QWeakPointer<MainWindow> > MainWindowList;
/**
*
*/
-class Application : public KUniqueApplication
+class REKONQ_TESTS_EXPORT Application : public KUniqueApplication
{
Q_OBJECT
@@ -100,15 +70,16 @@ public:
static Application *instance();
MainWindow *mainWindow();
+ MainWindow *newMainWindow(bool withTab = true);
MainWindowList mainWindowList();
-
+
static KIcon icon(const KUrl &url);
static HistoryManager *historyManager();
static BookmarkProvider *bookmarkProvider();
static SessionManager *sessionManager();
static AdBlockManager *adblockManager();
-
+
public slots:
/**
* Save application's configuration
@@ -117,16 +88,11 @@ public slots:
*/
void saveConfiguration() const;
- MainWindow *newMainWindow();
-
- void loadUrl( const KUrl& url,
- const Rekonq::OpenType& type = Rekonq::CurrentTab
+ void loadUrl(const KUrl& url,
+ const Rekonq::OpenType& type = Rekonq::CurrentTab
);
-
- void loadUrl( const QString& urlString,
- const Rekonq::OpenType& type = Rekonq::CurrentTab
- );
+ void newWindow();
void removeMainWindow(MainWindow *window);
private slots:
@@ -137,13 +103,15 @@ private slots:
void postLaunch();
void loadResolvedUrl(ThreadWeaver::Job *);
-
+
+ void updateConfiguration();
+
private:
- static QPointer<HistoryManager> s_historyManager;
- static QPointer<BookmarkProvider> s_bookmarkProvider;
- static QPointer<SessionManager> s_sessionManager;
- static QPointer<AdBlockManager> s_adblockManager;
-
+ static QWeakPointer<HistoryManager> s_historyManager;
+ static QWeakPointer<BookmarkProvider> s_bookmarkProvider;
+ static QWeakPointer<SessionManager> s_sessionManager;
+ static QWeakPointer<AdBlockManager> s_adblockManager;
+
MainWindowList m_mainWindows;
};
diff --git a/src/bookmarks/bookmarkcontextmenu.cpp b/src/bookmarks/bookmarkcontextmenu.cpp
new file mode 100644
index 00000000..df8bf5e0
--- /dev/null
+++ b/src/bookmarks/bookmarkcontextmenu.cpp
@@ -0,0 +1,325 @@
+/* ============================================================
+*
+* 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();
+}
+
+
+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::SettingOpenTab);
+}
+
+
+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();
+ bool folder = bm.isGroup();
+
+ if (KMessageBox::warningContinueCancel(
+ QApplication::activeWindow(),
+ folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", bm.text())
+ : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", bm.text()),
+ folder ? i18n("Bookmark Folder Deletion")
+ : i18n("Bookmark Deletion"),
+ KStandardGuiItem::del())
+ != KMessageBox::Continue
+ )
+ return;
+
+ bm.parentGroup().deleteBookmark(bm);
+ manager()->emitChanged();
+}
+
+
+void BookmarkContextMenu::editBookmark()
+{
+ KBookmark selected = bookmark();
+
+ KBookmarkDialog *dialog = owner()->bookmarkDialog(manager(), QApplication::activeWindow());
+ dialog->editBookmark(selected);
+ 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());
+ selected.parentGroup().moveBookmark(newBk, selected);
+ manager()->emitChanged();
+ }
+ }
+ 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();
+}
+
+
+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(), KUrl(owner()->currentUrl()), "text-html");
+ parent.moveBookmark(newBk, selected.parentGroup().previous(selected));
+ }
+
+ else
+ {
+ parent.addBookmark(owner()->currentTitle(), KUrl(owner()->currentUrl()), "text-html");
+ }
+
+ manager()->emitChanged();
+}
+
diff --git a/src/bookmarks/bookmarkcontextmenu.h b/src/bookmarks/bookmarkcontextmenu.h
new file mode 100644
index 00000000..c8c903d8
--- /dev/null
+++ b/src/bookmarks/bookmarkcontextmenu.h
@@ -0,0 +1,65 @@
+/* ============================================================
+*
+* 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/>.
+*
+* ============================================================ */
+
+
+#ifndef BOOKMARKCONTEXTMENU_H
+#define BOOKMARKCONTEXTMENU_H
+
+// Local Includes
+#include "application.h"
+
+// Qt Includes
+#include <KBookmarkMenu>
+
+
+class BookmarkContextMenu : public KBookmarkContextMenu
+{
+ Q_OBJECT
+
+public:
+ BookmarkContextMenu(const KBookmark & bk, KBookmarkManager * manager, KBookmarkOwner *owner, QWidget * parent = 0);
+ virtual void addActions();
+
+private slots:
+ void openInCurrentTab();
+ void openInNewTab();
+ void openInNewWindow();
+ void copyToClipboard();
+ void deleteBookmark();
+ void openFolderInTabs();
+ void editBookmark();
+ void newBookmarkGroup();
+ void newSeparator();
+ void bookmarkCurrentPage();
+
+private:
+ void setupActions();
+ void addFolderActions();
+ void addBookmarkActions();
+ void addSeparatorActions();
+ KActionCollection *m_ac;
+};
+
+#endif // BOOKMARKCONTEXTMENU_H
diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp
index 6442192a..73127257 100644
--- a/src/bookmarks/bookmarksmanager.cpp
+++ b/src/bookmarks/bookmarksmanager.cpp
@@ -2,9 +2,10 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* 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
@@ -12,9 +13,9 @@
* 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
+* 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
@@ -34,25 +35,24 @@
#include "mainwindow.h"
#include "webtab.h"
#include "webview.h"
+#include "mainview.h"
+#include "bookmarkcontextmenu.h"
// KDE Includes
#include <KActionCollection>
-#include <KBookmark>
#include <KBookmarkAction>
#include <KBookmarkGroup>
-#include <KBookmarkMenu>
#include <KToolBar>
-#include <KDebug>
#include <KMenu>
#include <KStandardDirs>
#include <KUrl>
+#include <KMessageBox>
// Qt Includes
#include <QtCore/QFile>
#include <QtGui/QActionGroup>
-
BookmarkOwner::BookmarkOwner(QObject *parent)
: QObject(parent)
, KBookmarkOwner()
@@ -66,7 +66,7 @@ void BookmarkOwner::openBookmark(const KBookmark & bookmark,
{
if (keyboardModifiers & Qt::ControlModifier || mouseButtons == Qt::MidButton)
{
- emit openUrl(bookmark.url(), Rekonq::NewCurrentTab);
+ emit openUrl(bookmark.url(), Rekonq::SettingOpenTab);
}
else
{
@@ -93,17 +93,40 @@ QString BookmarkOwner::currentTitle() const
}
-void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bm)
+void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bookmark)
{
- QList<KUrl> urlList = bm.groupUrlList();
+ QList<KUrl> urlList = bookmark.groupUrlList();
+
+ if (urlList.length() > 8)
+ {
+ if (!(KMessageBox::warningContinueCancel(Application::instance()->mainWindow(), i18n("You are about to open %1 tabs.\nAre you sure ?", QString::number(urlList.length()))) == KMessageBox::Continue))
+ return;
+ }
+
QList<KUrl>::iterator url;
for (url = urlList.begin(); url != urlList.end(); ++url)
{
- Application::instance()->loadUrl(*url, Rekonq::NewCurrentTab);
+ emit openUrl(*url, Rekonq::NewCurrentTab);
}
}
+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;
+}
+
+
// ------------------------------------------------------------------------------------------------------
@@ -112,26 +135,35 @@ BookmarkMenu::BookmarkMenu(KBookmarkManager *manager,
KMenu *menu,
KActionCollection* actionCollection)
: KBookmarkMenu(manager, owner, menu, actionCollection)
-
{
KAction *a = KStandardAction::addBookmark(this, SLOT(slotAddBookmark()), this);
-// a->setText(i18n("Bookmark this Page"));
- actionCollection->addAction(QLatin1String("rekonq_add_bookmark"),a);
+ actionCollection->addAction(QL1S("rekonq_add_bookmark"), a);
+ refill();
+}
+
+
+BookmarkMenu::BookmarkMenu(KBookmarkManager *manager,
+ KBookmarkOwner *owner,
+ KMenu *parentMenu,
+ const QString &parentAddress)
+ : KBookmarkMenu(manager, owner, parentMenu, parentAddress)
+{
+ refill();
}
+
BookmarkMenu::~BookmarkMenu()
{
}
-KMenu *BookmarkMenu::viewContextMenu(QAction *action)
+KMenu * BookmarkMenu::contextMenu(QAction *act)
{
- // contextMenu() returns an invalid KMenu (seg fault) for the folders in the toolbar
- KMenu *menu = contextMenu(action);
- if(menu)
- return menu;
- return 0; // new KMenu();
+ KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(act);
+ if (!action)
+ return 0;
+ return new BookmarkContextMenu(action->bookmark(), manager(), owner());
}
@@ -151,6 +183,76 @@ void BookmarkMenu::slotAddBookmark()
}
+QAction * BookmarkMenu::actionForBookmark(const KBookmark &bookmark)
+{
+ if (bookmark.isGroup())
+ {
+ KBookmarkActionMenu *actionMenu = new KBookmarkActionMenu(bookmark, this);
+ new BookmarkMenu(manager(), owner(), actionMenu->menu(), bookmark.address());
+ return actionMenu;
+ }
+ else if (bookmark.isSeparator())
+ {
+ return KBookmarkMenu::actionForBookmark(bookmark);
+ }
+ else
+ {
+ Application::bookmarkProvider()->completionObject()->addItem(bookmark.url().url());
+ return new KBookmarkAction(bookmark, owner(), this);
+ }
+}
+
+
+void BookmarkMenu::refill()
+{
+ 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 a new tab."));
+ connect(action, SIGNAL(triggered(bool)), this, SLOT(slotOpenFolderInTabs()));
+ parentMenu()->addAction(action);
+ }
+ }
+}
+
+
// ------------------------------------------------------------------------------------------------------
@@ -160,8 +262,12 @@ BookmarkProvider::BookmarkProvider(QObject *parent)
, m_owner(0)
, m_actionCollection(new KActionCollection(this))
, m_bookmarkMenu(0)
- , m_bookmarkToolBar(0)
+ , m_completion(0)
{
+ // take care of the completion object
+ m_completion = new KCompletion;
+ m_completion->setOrder(KCompletion::Weighted);
+
KUrl bookfile = KUrl("~/.kde/share/apps/konqueror/bookmarks.xml"); // share konqueror bookmarks
if (!QFile::exists(bookfile.path()))
@@ -178,7 +284,9 @@ BookmarkProvider::BookmarkProvider(QObject *parent)
bookfile = KUrl(bookmarksPath);
}
}
- m_manager = KBookmarkManager::managerForExternalFile(bookfile.path());
+
+ m_manager = KBookmarkManager::managerForFile(bookfile.path(), "rekonq");
+
connect(m_manager, SIGNAL(changed(const QString &, const QString &)),
this, SLOT(slotBookmarksChanged(const QString &, const QString &)));
@@ -197,37 +305,37 @@ BookmarkProvider::~BookmarkProvider()
}
-void BookmarkProvider::setupBookmarkBar(KToolBar *t)
+void BookmarkProvider::setupBookmarkBar(KToolBar *toolbar)
{
- m_bookmarkToolBar = t;
- connect(m_bookmarkToolBar, SIGNAL(customContextMenuRequested(const QPoint &)),
+ KToolBar *bookmarkToolBar = toolbar;
+ m_bookmarkToolBars.append(bookmarkToolBar);
+ bookmarkToolBar->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(bookmarkToolBar, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(contextMenu(const QPoint &)));
slotBookmarksChanged("", "");
}
+void BookmarkProvider::removeToolBar(KToolBar *toolbar)
+{
+ m_bookmarkToolBars.removeOne(toolbar);
+}
+
+
void BookmarkProvider::slotBookmarksChanged(const QString &group, const QString &caller)
{
Q_UNUSED(group)
Q_UNUSED(caller)
- if (!m_bookmarkToolBar)
- return;
-
- KBookmarkGroup toolBarGroup = m_manager->toolbar();
- if (toolBarGroup.isNull())
- return;
+ m_completion->clear();
- if(m_bookmarkToolBar)
+ foreach(KToolBar *bookmarkToolBar, m_bookmarkToolBars)
{
- m_bookmarkToolBar->clear(); // FIXME CRASH
-
- KBookmark bookmark = toolBarGroup.first();
- while (!bookmark.isNull())
+ if (bookmarkToolBar)
{
- m_bookmarkToolBar->addAction(fillBookmarkBar(bookmark));
- bookmark = toolBarGroup.next(bookmark);
+ bookmarkToolBar->clear();
+ fillBookmarkBar(bookmarkToolBar);
}
}
}
@@ -244,13 +352,22 @@ QAction *BookmarkProvider::actionByName(const QString &name)
void BookmarkProvider::contextMenu(const QPoint &point)
{
- KAction* action = dynamic_cast<KAction*>(m_bookmarkToolBar->actionAt(point));
+ if (m_bookmarkToolBars.isEmpty())
+ return;
+
+ KToolBar *bookmarkToolBar = m_bookmarkToolBars.at(0);
+ if (!bookmarkToolBar)
+ return;
+
+ KBookmarkActionInterface* action = dynamic_cast<KBookmarkActionInterface *>(bookmarkToolBar->actionAt(point));
if (!action)
return;
- KMenu *menu = m_bookmarkMenu->viewContextMenu(action);
+
+ KMenu *menu = new BookmarkContextMenu(action->bookmark(), bookmarkManager(), bookmarkOwner());
if (!menu)
return;
- menu->popup(m_bookmarkToolBar->mapToGlobal(point));
+
+ menu->popup(bookmarkToolBar->mapToGlobal(point));
}
@@ -265,36 +382,90 @@ KActionMenu* BookmarkProvider::bookmarkActionMenu(QWidget *parent)
}
-KAction *BookmarkProvider::fillBookmarkBar(const KBookmark &bookmark)
+void BookmarkProvider::fillBookmarkBar(KToolBar *toolBar)
{
- if (bookmark.isGroup())
+ KBookmarkGroup root = m_manager->toolbar();
+ if (root.isNull())
+ return;
+
+ for (KBookmark bookmark = root.first(); !bookmark.isNull(); bookmark = root.next(bookmark))
{
- KBookmarkGroup group = bookmark.toGroup();
- KBookmark bm = group.first();
- KActionMenu *menuAction = new KActionMenu(KIcon(bookmark.icon()), bookmark.text(), this);
- menuAction->setDelayed(false);
- while (!bm.isNull())
+ if (bookmark.isGroup())
{
- menuAction->addAction(fillBookmarkBar(bm));
- bm = group.next(bm);
+ KBookmarkActionMenu *menuAction = new KBookmarkActionMenu(bookmark.toGroup(), this);
+ menuAction->setDelayed(false);
+ new BookmarkMenu(bookmarkManager(), bookmarkOwner(), menuAction->menu(), bookmark.address());
+
+ toolBar->addAction(menuAction);
}
- return menuAction;
+
+ else if (bookmark.isSeparator())
+ {
+ toolBar->addSeparator();
+ }
+
+ else
+ {
+ toolBar->addAction(new KBookmarkAction(bookmark, m_owner, this));
+ }
+ }
+}
+
+
+KBookmarkGroup BookmarkProvider::rootGroup()
+{
+ return m_manager->root();
+}
+
+
+KCompletion *BookmarkProvider::completionObject() const
+{
+ return m_completion;
+}
+
+
+QString BookmarkProvider::titleForBookmarkUrl(QString url)
+{
+ QString title = "";
+ KBookmarkGroup bookGroup = Application::bookmarkProvider()->rootGroup();
+ if (bookGroup.isNull())
+ {
+ return title;
}
-
- if(bookmark.isSeparator())
+
+ KBookmark bookmark = bookGroup.first();
+ while (!bookmark.isNull() && title.isEmpty())
{
- KAction *a = new KAction(this);
- a->setSeparator(true);
- return a;
+ title = titleForBookmarkUrl(bookmark, url);
+ bookmark = bookGroup.next(bookmark);
}
- else
+
+ if (title.isEmpty())
{
- return new KBookmarkAction(bookmark, m_owner, this);
+ title = url;
}
+
+ return title;
}
-KBookmarkGroup BookmarkProvider::rootGroup()
+QString BookmarkProvider::titleForBookmarkUrl(const KBookmark &bookmark, QString url)
{
- return m_manager->root();
+ QString title = "";
+ if (bookmark.isGroup())
+ {
+ KBookmarkGroup group = bookmark.toGroup();
+ KBookmark bm = group.first();
+ while (!bm.isNull() && title.isEmpty())
+ {
+ title = titleForBookmarkUrl(bm, url); // it is .bookfolder
+ bm = group.next(bm);
+ }
+ }
+ else if (!bookmark.isSeparator() && bookmark.url() == url)
+ {
+ title = bookmark.fullText();
+ }
+
+ return title;
}
diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h
index febac234..ae12280b 100644
--- a/src/bookmarks/bookmarksmanager.h
+++ b/src/bookmarks/bookmarksmanager.h
@@ -2,9 +2,10 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* 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
@@ -30,6 +31,9 @@
#define BOOKMARKS_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Local Includes
#include "application.h"
@@ -38,6 +42,7 @@
// KDE Includes
#include <KBookmarkOwner>
+#include <KCompletion>
// Forward Declarations
class BookmarkProvider;
@@ -55,7 +60,7 @@ class KBookmarkManager;
* bookmarks as actions
*
*/
-class BookmarkOwner : public QObject , public KBookmarkOwner
+class REKONQ_TESTS_EXPORT BookmarkOwner : public QObject , public KBookmarkOwner
{
Q_OBJECT
@@ -110,7 +115,9 @@ public:
* The default implementation does nothing.
* This is only called if supportsTabs() returns true
*/
- virtual void openFolderinTabs(const KBookmarkGroup &bm);
+ virtual void openFolderinTabs(const KBookmarkGroup &bookmark);
+
+ virtual QList< QPair<QString, QString> > currentBookmarkList() const;
signals:
/**
@@ -128,7 +135,6 @@ signals:
// KDE Includes
#include <KBookmarkMenu>
-
/**
* This class represent the rekonq bookmarks menu.
* It's just a simple class inherited from KBookmarkMenu
@@ -143,13 +149,23 @@ public:
KBookmarkOwner* owner,
KMenu* menu,
KActionCollection* actionCollection);
+ BookmarkMenu(KBookmarkManager *manager,
+ KBookmarkOwner *owner,
+ KMenu *parentMenu,
+ const QString &parentAddress);
~BookmarkMenu();
- virtual KMenu *viewContextMenu(QAction* action);
+protected:
+ virtual KMenu * contextMenu(QAction * act);
+ virtual void refill();
+ virtual QAction* actionForBookmark(const KBookmark &bookmark);
protected slots:
void slotAddBookmark();
+private:
+ void addOpenFolderInTabs();
+
};
@@ -192,6 +208,7 @@ public:
*/
void setupBookmarkBar(KToolBar *);
+ void removeToolBar(KToolBar*);
/**
* @short Get action by name
@@ -209,7 +226,22 @@ public:
*/
KBookmarkGroup rootGroup();
- KBookmarkManager *bookmarkManager() { return m_manager; }
+ KBookmarkManager *bookmarkManager()
+ {
+ return m_manager;
+ }
+ BookmarkOwner *bookmarkOwner()
+ {
+ return m_owner;
+ }
+
+ /**
+ * @returns the KCompletion object.
+ */
+ KCompletion *completionObject() const;
+
+ QString titleForBookmarkUrl(QString url);
+
signals:
/**
* @short This signal is emitted when an url has to be loaded
@@ -236,14 +268,18 @@ public slots:
*/
void slotBookmarksChanged(const QString &group, const QString &caller);
+
private:
- KAction *fillBookmarkBar(const KBookmark &bookmark);
+ void fillBookmarkBar(KToolBar *toolBar);
+ QString titleForBookmarkUrl(const KBookmark &bookmark, QString url);
KBookmarkManager *m_manager;
BookmarkOwner *m_owner;
KActionCollection *m_actionCollection;
BookmarkMenu *m_bookmarkMenu;
- KToolBar *m_bookmarkToolBar;
+ QList<KToolBar*> m_bookmarkToolBars;
+ KCompletion *m_completion;
};
+
#endif
diff --git a/src/bookmarks/bookmarkspanel.cpp b/src/bookmarks/bookmarkspanel.cpp
index 9164dbb6..0f4e64b8 100644
--- a/src/bookmarks/bookmarkspanel.cpp
+++ b/src/bookmarks/bookmarkspanel.cpp
@@ -3,7 +3,8 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com>
-*
+* Copyright (C) 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
@@ -29,8 +30,10 @@
#include "bookmarkspanel.moc"
// Local Includes
+#include "bookmarksmanager.h"
#include "bookmarkstreemodel.h"
#include "bookmarksproxy.h"
+#include "bookmarkcontextmenu.h"
// Auto Includes
#include "rekonq.h"
@@ -38,16 +41,19 @@
// Qt includes
#include <QHBoxLayout>
#include <QLabel>
-#include <QTreeView>
#include <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)
+ : QDockWidget(title, parent, flags)
+ , m_treeView(new PanelTreeView(this))
+ , m_loadingState(false)
{
setup();
setShown(ReKonfig::showBookmarksPanel());
@@ -60,13 +66,6 @@ BookmarksPanel::~BookmarksPanel()
}
-void BookmarksPanel::bookmarkActivated( const QModelIndex &index )
-{
- if( index.isValid() )
- emit openUrl( qVariantValue< KUrl >( index.data( Qt::UserRole ) ) );
-}
-
-
void BookmarksPanel::setup()
{
setObjectName("bookmarksPanel");
@@ -82,32 +81,139 @@ void BookmarksPanel::setup()
KLineEdit *search = new KLineEdit;
search->setClearButtonShown(true);
searchLayout->addWidget(search);
- searchLabel->setBuddy( search );
+ searchLabel->setBuddy(search);
// setup tree view
- QTreeView *treeView = new QTreeView(ui);
- treeView->setUniformRowHeights(true);
- treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
- treeView->setTextElideMode(Qt::ElideMiddle);
- treeView->setAlternatingRowColors(true);
- treeView->header()->hide();
- treeView->setRootIsDecorated( false );
+ 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);
+ m_treeView->setDefaultDropAction(Qt::MoveAction);
+ m_treeView->viewport()->setAcceptDrops(true);
// put everything together
QVBoxLayout *vBoxLayout = new QVBoxLayout;
vBoxLayout->setContentsMargins(0, 0, 0, 0);
vBoxLayout->addLayout(searchLayout);
- vBoxLayout->addWidget(treeView);
+ vBoxLayout->addWidget(m_treeView);
// add it to the UI
ui->setLayout(vBoxLayout);
setWidget(ui);
- BookmarksTreeModel *model = new BookmarksTreeModel( this );
+ BookmarksTreeModel *model = new BookmarksTreeModel(this);
BookmarksProxy *proxy = new BookmarksProxy(ui);
- proxy->setSourceModel( model );
- treeView->setModel( proxy );
+ proxy->setSourceModel(model);
+ m_treeView->setModel(proxy);
+
+ 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 &)));
+ loadFoldedState();
+}
+
+
+KBookmark BookmarksPanel::bookmarkForIndex(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return KBookmark();
+
+ const QAbstractProxyModel* proxyModel = dynamic_cast< const QAbstractProxyModel* >(index.model());
+ QModelIndex originalIndex = proxyModel->mapToSource(index);
+
+ 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 saveOnlyRequested();
+}
+
+
+void BookmarksPanel::onExpand(const QModelIndex &index)
+{
+ if (m_loadingState)
+ return;
- connect(search, SIGNAL(textChanged(QString)), proxy, SLOT(setFilterFixedString(QString)));
- connect(treeView, SIGNAL( activated(QModelIndex) ), this, SLOT( bookmarkActivated(QModelIndex) ) );
+ KBookmark bookmark = bookmarkForIndex(index);
+ bookmark.internalElement().setAttribute("folded", "no");
+ emit saveOnlyRequested();
+}
+
+
+void BookmarksPanel::loadFoldedState()
+{
+ 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 = new BookmarkContextMenu(selected, Application::bookmarkProvider()->bookmarkManager(), Application::bookmarkProvider()->bookmarkOwner(), this);
+ menu->popup(m_treeView->mapToGlobal(pos));
+}
+
+
+void BookmarksPanel::deleteBookmark()
+{
+ QModelIndex index = m_treeView->currentIndex();
+ if (!index.isValid())
+ return;
+
+ KBookmark bm = bookmarkForIndex(index);
+ bool folder = bm.isGroup();
+
+ if (KMessageBox::warningContinueCancel(
+ QApplication::activeWindow(),
+ folder ? i18n("Are you sure you wish to remove the bookmark folder\n\"%1\"?", bm.text())
+ : i18n("Are you sure you wish to remove the bookmark\n\"%1\"?", bm.text()),
+ folder ? i18n("Bookmark Folder Deletion")
+ : i18n("Bookmark Deletion"),
+ KStandardGuiItem::del())
+ != KMessageBox::Continue
+ )
+ return;
+
+
+ bm.parentGroup().deleteBookmark(bm);
+ Application::instance()->bookmarkProvider()->bookmarkManager()->emitChanged();
}
diff --git a/src/bookmarks/bookmarkspanel.h b/src/bookmarks/bookmarkspanel.h
index 6c0e153f..b2a9f264 100644
--- a/src/bookmarks/bookmarkspanel.h
+++ b/src/bookmarks/bookmarkspanel.h
@@ -3,6 +3,8 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com>
+* Copyright (C) 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
@@ -27,15 +29,26 @@
#ifndef BOOKMARKSPANEL_H
#define BOOKMARKSPANEL_H
+
+// 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 QModelIndex;
-class BookmarksPanel : public QDockWidget
+class REKONQ_TESTS_EXPORT BookmarksPanel : public QDockWidget
{
Q_OBJECT
@@ -44,13 +57,26 @@ public:
~BookmarksPanel();
signals:
- void openUrl(const KUrl &);
+ void openUrl(const KUrl &, const Rekonq::OpenType &);
+ void itemHovered(const QString &);
+ void saveOnlyRequested();
private slots:
- void bookmarkActivated( const QModelIndex &index );
+ void contextMenu(const QPoint &pos);
+
+ void deleteBookmark();
+ void onCollapse(const QModelIndex &index);
+ void onExpand(const QModelIndex &index);
+ void loadFoldedState(const QModelIndex &root);
+ void loadFoldedState();
+
private:
void setup();
+ KBookmark bookmarkForIndex(const QModelIndex &index);
+
+ PanelTreeView *m_treeView;
+ bool m_loadingState;
};
#endif // BOOKMARKSPANEL_H
diff --git a/src/bookmarks/bookmarksproxy.cpp b/src/bookmarks/bookmarksproxy.cpp
index e94fbeff..4e4b4f06 100644
--- a/src/bookmarks/bookmarksproxy.cpp
+++ b/src/bookmarks/bookmarksproxy.cpp
@@ -3,6 +3,7 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -29,27 +30,27 @@
#include "bookmarksproxy.moc"
-BookmarksProxy::BookmarksProxy( QObject *parent )
- : QSortFilterProxyModel( parent )
+BookmarksProxy::BookmarksProxy(QObject *parent)
+ : QSortFilterProxyModel(parent)
{
}
-bool BookmarksProxy::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
+bool BookmarksProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
- QModelIndex idx = sourceModel()->index( source_row, 0, source_parent );
- return recursiveMatch( idx );
+ QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
+ return recursiveMatch(idx);
}
-bool BookmarksProxy::recursiveMatch( const QModelIndex &index ) const
+bool BookmarksProxy::recursiveMatch(const QModelIndex &index) const
{
- if( index.data().toString().contains( filterRegExp() ) )
+ if (index.data().toString().contains(filterRegExp()))
return true;
- for( int childRow = 0; childRow < sourceModel()->rowCount( index ); ++childRow )
+ for (int childRow = 0; childRow < sourceModel()->rowCount(index); ++childRow)
{
- if( recursiveMatch( sourceModel()->index( childRow, 0, index ) ) )
+ if (recursiveMatch(sourceModel()->index(childRow, 0, index)))
return true;
}
return false;
diff --git a/src/bookmarks/bookmarksproxy.h b/src/bookmarks/bookmarksproxy.h
index 99483331..e7b50d8e 100644
--- a/src/bookmarks/bookmarksproxy.h
+++ b/src/bookmarks/bookmarksproxy.h
@@ -3,6 +3,7 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -27,22 +28,27 @@
#ifndef BOOKMARKSPROXY_H
#define BOOKMARKSPROXY_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Qt Includes
#include <QSortFilterProxyModel>
-class BookmarksProxy : public QSortFilterProxyModel
+
+class REKONQ_TESTS_EXPORT BookmarksProxy : public QSortFilterProxyModel
{
Q_OBJECT
Q_DISABLE_COPY(BookmarksProxy)
public:
- BookmarksProxy( QObject *parent = 0 );
+ BookmarksProxy(QObject *parent = 0);
protected:
- virtual bool filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const;
+ virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
- // returns true if any child(or childs-child...) matches filter
- bool recursiveMatch( const QModelIndex &index ) const;
+ // returns true if any child(or children-child...) matches filter
+ bool recursiveMatch(const QModelIndex &index) const;
};
#endif // BOOKMARKSPROXY_H
diff --git a/src/bookmarks/bookmarkstreemodel.cpp b/src/bookmarks/bookmarkstreemodel.cpp
index 140fa9c8..654069c2 100644
--- a/src/bookmarks/bookmarkstreemodel.cpp
+++ b/src/bookmarks/bookmarkstreemodel.cpp
@@ -3,6 +3,7 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -32,105 +33,124 @@
#include "application.h"
#include "bookmarksmanager.h"
+// Qt Includes
+#include <QMimeData>
+
// KDE includes
#include <KBookmarkGroup>
#include <KLocalizedString>
-class BookmarksTreeModel::BtmItem
-{
-public:
- BtmItem(const KBookmark &bm)
+BtmItem::BtmItem(const KBookmark &bm)
: m_parent(0)
, m_kbm(bm)
- {
- }
-
-
- ~BtmItem()
- {
- qDeleteAll(m_children);
- }
+{
+}
- QVariant data( int role = Qt::DisplayRole ) const
- {
- if( m_kbm.isNull() )
- return QVariant(); // should only happen for root item
+BtmItem::~BtmItem()
+{
+ qDeleteAll(m_children);
+}
- if( role == Qt::DisplayRole )
- return m_kbm.text();
- if( role == Qt::DecorationRole )
- return KIcon( m_kbm.icon() );
- if( role == Qt::UserRole )
- return m_kbm.url();
- return QVariant();
+QVariant BtmItem::data(int role) const
+{
+ if (m_kbm.isNull())
+ return QVariant(); // should only happen for root item
+
+ if (role == Qt::DisplayRole)
+ return m_kbm.text();
+ if (role == Qt::DecorationRole)
+ return KIcon(m_kbm.icon());
+ if (role == Qt::UserRole)
+ return m_kbm.url();
+ if (role == Qt::ToolTipRole)
+ {
+ QString tooltip = "";
+
+ if (!m_kbm.text().isEmpty())
+ {
+ tooltip += m_kbm.text();
+ }
+ if (m_kbm.isGroup())
+ {
+ tooltip += " [" + QString::number(childCount()) + ' ' + i18n("Items") + ']';
+ }
+ if (!m_kbm.url().url().isEmpty())
+ {
+ if (!tooltip.isEmpty())
+ tooltip += '\n';
+ tooltip += m_kbm.url().url();
+ }
+ return tooltip;
}
+ return QVariant();
+}
- int row() const
- {
- if(m_parent)
- return m_parent->m_children.indexOf( const_cast< BtmItem* >( this ) );
- return 0;
- }
+int BtmItem::row() const
+{
+ if (m_parent)
+ return m_parent->m_children.indexOf(const_cast< BtmItem* >(this));
+ return 0;
+}
- int childCount() const
- {
- return m_children.count();
- }
+int BtmItem::childCount() const
+{
+ return m_children.count();
+}
- BtmItem* child( int n )
- {
- Q_ASSERT(n>=0);
- Q_ASSERT(n<childCount());
- return m_children.at(n);
- }
+BtmItem* BtmItem::child(int n)
+{
+ Q_ASSERT(n >= 0);
+ Q_ASSERT(n < childCount());
+ return m_children.at(n);
+}
- BtmItem* parent() const
- {
- return m_parent;
- }
+BtmItem* BtmItem::parent() const
+{
+ return m_parent;
+}
- void appendChild(BtmItem *child)
- {
- if( !child )
- return;
- child->m_parent = this;
- m_children << child;
- }
+void BtmItem::appendChild(BtmItem *child)
+{
+ if (!child)
+ return;
+ child->m_parent = this;
+ m_children << child;
+}
- void clear()
- {
- qDeleteAll(m_children);
- m_children.clear();
- }
-private:
- BtmItem *m_parent;
- QList< BtmItem* > m_children;
- KBookmark m_kbm;
-};
+void BtmItem::clear()
+{
+ qDeleteAll(m_children);
+ m_children.clear();
+}
+KBookmark BtmItem::getBkm() const
+{
+ return m_kbm;
+}
// -------------------------------------------------------------------------------------
BookmarksTreeModel::BookmarksTreeModel(QObject *parent)
- : QAbstractItemModel(parent)
- , m_root(0)
+ : QAbstractItemModel(parent)
+ , m_root(0)
{
resetModel();
- connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( changed(QString,QString) ), this, SLOT( bookmarksChanged(QString) ) );
- connect( Application::bookmarkProvider()->bookmarkManager(), SIGNAL( bookmarksChanged(QString) ), this, SLOT( bookmarksChanged(QString) ) );
+ connect(this, SIGNAL(bookmarksUpdated()), parent, SLOT(loadFoldedState()));
+ connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(bookmarksChanged()));
+ connect(parent, SIGNAL(saveOnlyRequested()), this, SLOT(saveOnly()));
}
@@ -143,13 +163,13 @@ BookmarksTreeModel::~BookmarksTreeModel()
int BookmarksTreeModel::rowCount(const QModelIndex &parent) const
{
BtmItem *parentItem = 0;
- if( !parent.isValid() )
+ if (!parent.isValid())
{
parentItem = m_root;
}
- else
+ else
{
- parentItem = static_cast< BtmItem* >( parent.internalPointer() );
+ parentItem = static_cast< BtmItem* >(parent.internalPointer());
}
return parentItem->childCount();
@@ -166,11 +186,11 @@ int BookmarksTreeModel::columnCount(const QModelIndex &parent) const
QVariant BookmarksTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
{
- if( orientation == Qt::Horizontal
- && role == Qt::DisplayRole
- && section == 0
- )
- return i18n( "Bookmark" );
+ if (orientation == Qt::Horizontal
+ && role == Qt::DisplayRole
+ && section == 0
+ )
+ return i18n("Bookmark");
return QVariant();
}
@@ -178,33 +198,42 @@ QVariant BookmarksTreeModel::headerData(int section, Qt::Orientation orientation
Qt::ItemFlags BookmarksTreeModel::flags(const QModelIndex &index) const
{
- Q_UNUSED(index)
- return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ Qt::ItemFlags flags = QAbstractItemModel::flags(index);
+
+ if (!index.isValid())
+ return flags | Qt::ItemIsDropEnabled;
+
+ flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
+
+ if (bookmarkForIndex(index).isGroup())
+ flags |= Qt::ItemIsDropEnabled;
+
+ return flags;
}
QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &parent) const
{
- if( !hasIndex( row, column, parent ) )
+ if (!hasIndex(row, column, parent))
{
return QModelIndex();
}
BtmItem *parentItem;
- if( !parent.isValid() )
+ if (!parent.isValid())
{
parentItem = m_root;
}
- else
+ else
{
- parentItem = static_cast< BtmItem* >( parent.internalPointer() );
+ parentItem = static_cast< BtmItem* >(parent.internalPointer());
}
- BtmItem *childItem = parentItem->child( row );
- if( childItem )
+ BtmItem *childItem = parentItem->child(row);
+ if (childItem)
{
- return createIndex( row, column, childItem );
+ return createIndex(row, column, childItem);
}
return QModelIndex();
@@ -213,74 +242,52 @@ QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &pa
QModelIndex BookmarksTreeModel::parent(const QModelIndex &index) const
{
- if( !index.isValid() )
+ 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 )
+ if (parentItem == m_root)
{
return QModelIndex();
}
- return createIndex( parentItem->row(), 0, parentItem );
+ return createIndex(parentItem->row(), 0, parentItem);
}
QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const
{
- if( !index.isValid() )
+ if (!index.isValid())
{
return QVariant();
}
- BtmItem *node = static_cast< BtmItem* >( index.internalPointer() );
- if( node && node == m_root )
+ BtmItem *node = static_cast< BtmItem* >(index.internalPointer());
+ if (node && node == m_root)
{
- if( role == Qt::DisplayRole )
- return i18n( "Bookmarks" );
- if( role == Qt::DecorationRole )
- return KIcon( "bookmarks" );
+ if (role == Qt::DisplayRole)
+ return i18n("Bookmarks");
+ if (role == Qt::DecorationRole)
+ return KIcon("bookmarks");
}
- else
+ else
{
- if( node )
- return node->data( role );
+ if (node)
+ return node->data(role);
}
return QVariant();
}
-void BookmarksTreeModel::bookmarksChanged( const QString &groupAddress )
+void BookmarksTreeModel::bookmarksChanged()
{
- if( groupAddress.isEmpty() )
- {
- resetModel();
- return;
- }
-
- BtmItem *node = m_root;
- QModelIndex nodeIndex;
-
- QStringList indexChain( groupAddress.split( '/', QString::SkipEmptyParts) );
- foreach( QString sIndex, indexChain )
- {
- bool ok;
- int i = sIndex.toInt( &ok );
- if( !ok )
- break;
-
- if( i < 0 || i >= node->childCount() )
- break;
-
- node = node->child( i );
- nodeIndex = index( i, 0, nodeIndex );
- }
- emit dataChanged( index( 0, 0, nodeIndex ), index( node->childCount(), 0, nodeIndex ) );
+ resetModel();
+ emit bookmarksUpdated();
}
@@ -295,29 +302,126 @@ void BookmarksTreeModel::setRoot(KBookmarkGroup bmg)
delete m_root;
m_root = new BtmItem(KBookmark());
- if( bmg.isNull() )
+ if (bmg.isNull())
return;
- populate( m_root, bmg );
+ populate(m_root, bmg);
reset();
}
-void BookmarksTreeModel::populate( BtmItem *node, KBookmarkGroup bmg)
+void BookmarksTreeModel::populate(BtmItem *node, KBookmarkGroup bmg)
{
node->clear();
- if( bmg.isNull() )
+ if (bmg.isNull())
return;
KBookmark bm = bmg.first();
- while( !bm.isNull() )
+ while (!bm.isNull())
{
- BtmItem *newChild = new BtmItem( bm );
- if( bm.isGroup() )
- populate( newChild, bm.toGroup() );
+ BtmItem *newChild = new BtmItem(bm);
+ if (bm.isGroup())
+ populate(newChild, bm.toGroup());
+
+ node->appendChild(newChild);
+ bm = bmg.next(bm);
+ }
+}
+
+
+KBookmark BookmarksTreeModel::bookmarkForIndex(const QModelIndex index) const
+{
+ return static_cast<BtmItem*>(index.internalPointer())->getBkm();
+}
+
+
+void BookmarksTreeModel::saveOnly()
+{
+ disconnect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(bookmarksChanged()));
+ connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(reconnectManager()));
+ Application::bookmarkProvider()->bookmarkManager()->emitChanged();
+}
+
+
+void BookmarksTreeModel::reconnectManager()
+{
+ connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(QString, QString)), this, SLOT(bookmarksChanged()));
+}
+
+
+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 addresse = bookmarkForIndex(indexes.first()).address().toLatin1();
+ mimeData->setData("application/rekonq-bookmark", addresse);
+ bookmarkForIndex(indexes.first()).populateMimeData(mimeData);
- node->appendChild( newChild );
- bm = bmg.next( bm );
+ 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())
+ {
+ if (!parent.isValid()) // Drop into a blank area
+ {
+ Application::bookmarkProvider()->rootGroup().deleteBookmark(bookmark);
+ Application::bookmarkProvider()->rootGroup().addBookmark(bookmark);
+ }
+ else // Drop at the last item of the group or directly on the main item of the group
+ {
+ root.deleteBookmark(bookmark);
+ root.addBookmark(bookmark);
+ }
+ }
+
+ else
+ {
+ if (row == -1)
+ {
+ root.deleteBookmark(bookmark);
+ root.addBookmark(bookmark);
+ }
+ else // A classic drop
+ {
+ root.moveBookmark(bookmark, root.previous(dropDestBookmark));
+ }
+ }
+
+ Application::bookmarkProvider()->bookmarkManager()->emitChanged(root);
+ }
}
+ return true;
}
diff --git a/src/bookmarks/bookmarkstreemodel.h b/src/bookmarks/bookmarkstreemodel.h
index 9753999c..d066e137 100644
--- a/src/bookmarks/bookmarkstreemodel.h
+++ b/src/bookmarks/bookmarkstreemodel.h
@@ -3,6 +3,7 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2009 by Nils Weigel <nehlsen at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -27,13 +28,38 @@
#ifndef BOOKMARKSTREEMODEL_H
#define BOOKMARKSTREEMODEL_H
-// Qt Includes
-#include <QAbstractItemModel>
+
+// Rekonq Includes
+#include "rekonq_defines.h"
// KDE includes
#include <KBookmark>
-class BookmarksTreeModel : public QAbstractItemModel
+// Qt Includes
+#include <QAbstractItemModel>
+
+class BtmItem
+{
+public:
+ BtmItem(const KBookmark &bm);
+ ~BtmItem();
+ QVariant data(int role = Qt::DisplayRole) const;
+ int row() const;
+ int childCount() const;
+ BtmItem* child(int n);
+ BtmItem* parent() const;
+ void appendChild(BtmItem *child);
+ void clear();
+ KBookmark getBkm() const;
+
+private:
+ BtmItem *m_parent;
+ QList< BtmItem* > m_children;
+ KBookmark m_kbm;
+};
+
+
+class REKONQ_TESTS_EXPORT BookmarksTreeModel : public QAbstractItemModel
{
Q_OBJECT
Q_DISABLE_COPY(BookmarksTreeModel)
@@ -42,28 +68,36 @@ public:
explicit BookmarksTreeModel(QObject *parent = 0);
~BookmarksTreeModel();
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
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;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const;
- virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
virtual QModelIndex parent(const QModelIndex &index) const;
- virtual QVariant data(const QModelIndex &index, int role) const;
-// virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
+ 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 Qt::DropActions supportedDropActions() const;
+ virtual QMimeData *mimeData(const QModelIndexList & indexes) const;
private slots:
- void bookmarksChanged( const QString &groupAddress );
+ void bookmarksChanged();
+ void saveOnly();
+ void reconnectManager();
-private:
- class BtmItem;
- BtmItem *m_root;
+signals:
+ void bookmarksUpdated();
- void resetModel();
+private:
+ BtmItem *m_root;
+ void resetModel();
void setRoot(KBookmarkGroup bmg);
- void populate( BtmItem *node, KBookmarkGroup bmg);
+ void populate(BtmItem *node, KBookmarkGroup bmg);
+ KBookmark bookmarkForIndex(const QModelIndex index) const;
};
#endif // BOOKMARKSTREEMODEL_H
diff --git a/src/cleardata.ui b/src/cleardata.ui
index b70d3b5a..effb2d7e 100644
--- a/src/cleardata.ui
+++ b/src/cleardata.ui
@@ -2,12 +2,15 @@
<ui version="4.0">
<class>ClearDataWidget</class>
<widget class="QWidget" name="ClearDataWidget">
+ <property name="windowModality">
+ <enum>Qt::WindowModal</enum>
+ </property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>260</width>
- <height>208</height>
+ <width>245</width>
+ <height>226</height>
</rect>
</property>
<property name="windowTitle">
@@ -16,15 +19,47 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
- <string>Clear the following items:</string>
+ <string>&lt;h3&gt;Clear the following items:&lt;/h3&gt;</string>
</property>
</widget>
</item>
<item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
<widget class="QCheckBox" name="clearHistory">
<property name="text">
- <string>History</string>
+ <string>Visited pages history</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="clearDownloads">
+ <property name="text">
+ <string>Downloads history</string>
</property>
<property name="checked">
<bool>true</bool>
@@ -76,10 +111,13 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
- <height>40</height>
+ <height>15</height>
</size>
</property>
</spacer>
diff --git a/src/clicktoflash.cpp b/src/clicktoflash.cpp
index b6e1df34..e9174470 100644
--- a/src/clicktoflash.cpp
+++ b/src/clicktoflash.cpp
@@ -1,53 +1,28 @@
-/*
- * Copyright (c) 2009, Benjamin C. Meyer
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Benjamin Meyer nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ============================================================
- *
- * This file is a part of the rekonq project
- *
- * Copyright (C) 2009 by Matthieu Gicquel <matgic78@gmail.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/>.
- *
- * ============================================================ */
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Benjamin C. Meyer <ben@meyerhome.net>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78@gmail.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
@@ -66,13 +41,13 @@
-ClickToFlash::ClickToFlash(QUrl pluginUrl, QWidget *parent)
- : QWidget(parent)
- , m_url(pluginUrl)
+ClickToFlash::ClickToFlash(const QUrl &pluginUrl, QWidget *parent)
+ : QWidget(parent)
+ , m_url(pluginUrl)
{
QHBoxLayout *l = new QHBoxLayout(this);
setLayout(l);
-
+
QToolButton *button = new QToolButton(this);
button->setPopupMode(QToolButton::InstantPopup);
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -84,12 +59,12 @@ ClickToFlash::ClickToFlash(QUrl pluginUrl, QWidget *parent)
void ClickToFlash::load()
-{
+{
QWidget *parent = parentWidget();
QWebView *view = 0;
- while (parent)
+ while (parent)
{
- if (QWebView *aView = qobject_cast<QWebView*>(parent))
+ if (QWebView *aView = qobject_cast<QWebView*>(parent))
{
view = aView;
break;
@@ -99,54 +74,66 @@ void ClickToFlash::load()
if (!view)
return;
- const QString selector = QLatin1String("%1[type=\"application/x-shockwave-flash\"]");
+ const QString selector = QL1S("%1[type=\"application/x-shockwave-flash\"]");
hide();
-
+
QList<QWebFrame*> frames;
frames.append(view->page()->mainFrame());
- while (!frames.isEmpty())
+ while (!frames.isEmpty())
{
QWebFrame *frame = frames.takeFirst();
QWebElement docElement = frame->documentElement();
QWebElementCollection elements;
- elements.append(docElement.findAll(selector.arg(QLatin1String("object"))));
- elements.append(docElement.findAll(selector.arg(QLatin1String("embed"))));
-
- bool isRightElement = false;
- foreach (QWebElement element, elements)
+ elements.append(docElement.findAll(selector.arg(QL1S("object"))));
+ elements.append(docElement.findAll(selector.arg(QL1S("embed"))));
+
+ foreach(QWebElement element, elements)
{
- // TODO : find a proper solution to compare a QWebElement with a plugin
- // With this "manual" test, it's probably not working everywhere
- if(QUrl(element.attribute("data")) == m_url
- || QUrl(element.attribute("src")) == m_url)
- isRightElement = true;
- else
- {
- QWebElementCollection collec = element.findAll("param");
- int i = 0;
- while(i < collec.count() && isRightElement == false)
- {
- if(QUrl(collec.at(i).attribute("value")) == m_url)
- isRightElement = true;
- i++;
- }
- }
-
- if(isRightElement)
+ if (checkElement(element))
{
+ kDebug() << "RETURNED TRUE ...........................";
QWebElement substitute = element.clone();
emit signalLoadClickToFlash(true);
element.replace(substitute);
+ deleteLater();
return;
}
}
-
frames += frame->childFrames();
}
-
- deleteLater();
}
+bool ClickToFlash::checkElement(QWebElement el)
+{
+ kDebug() << "src: " << QUrl(el.attribute("src"));
+ kDebug() << "url: " << m_url;
+
+ QString checkString;
+ QString urlString;
+
+ checkString = QUrl(el.attribute("src")).toString(QUrl::RemoveQuery);
+ urlString = m_url.toString(QUrl::RemoveQuery);
+
+ if (urlString.contains(checkString))
+ return true;
+
+ QWebElementCollection collec = el.findAll("*");
+ int i = 0;
+ while (i < collec.count())
+ {
+ QWebElement el = collec.at(i);
+
+ checkString = QUrl(el.attribute("src")).toString(QUrl::RemoveQuery);
+ urlString = m_url.toString(QUrl::RemoveQuery);
+
+ if (urlString.contains(checkString))
+ return true;
+
+ i++;
+ }
+
+ return false;
+}
diff --git a/src/clicktoflash.h b/src/clicktoflash.h
index 01bba257..87c53587 100644
--- a/src/clicktoflash.h
+++ b/src/clicktoflash.h
@@ -1,77 +1,61 @@
-/*
- * Copyright (c) 2009, Benjamin C. Meyer
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Benjamin Meyer nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ============================================================
- *
- * This file is a part of the rekonq project
- *
- * Copyright (C) 2009 by Matthieu Gicquel <matgic78@gmail.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/>.
- *
- * ============================================================ */
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Benjamin C. Meyer <ben@meyerhome.net>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78@gmail.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 CLICKTOFLASH_H
#define CLICKTOFLASH_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Qt Includes
#include <QWidget>
#include <QUrl>
+// Forward Declarations
+class QWebElement;
-class WebPluginFactory;
-class ClickToFlash : public QWidget
+class REKONQ_TESTS_EXPORT ClickToFlash : public QWidget
{
Q_OBJECT
+
public:
- ClickToFlash(QUrl pluginUrl, QWidget *parent = 0);
+ explicit ClickToFlash(const QUrl &pluginUrl, QWidget *parent = 0);
signals:
void signalLoadClickToFlash(bool);
-
+
private slots:
void load();
-
+
private:
+ bool checkElement(QWebElement el);
+
/**
used to find the right QWebElement between the ones of the different plugins
*/
diff --git a/src/data/CMakeLists.txt b/src/data/CMakeLists.txt
index 0af92f5e..ef777c9c 100644
--- a/src/data/CMakeLists.txt
+++ b/src/data/CMakeLists.txt
@@ -1,10 +1,15 @@
INSTALL(
- FILES bg2.png bg.png bot.gif busywidget.gif closed.png loading.mng open.png tile.gif top.png webkit-icon.png category.png button.png
+ FILES
+ bg2.png bg.png tile.gif category.png button.png
+ busywidget.gif loading.mng
+ webkit-icon.png
DESTINATION ${DATA_INSTALL_DIR}/rekonq/pics
)
INSTALL(
- FILES defaultbookmarks.xbel
+ FILES
+ defaultbookmarks.xbel
+ default.css
DESTINATION ${DATA_INSTALL_DIR}/rekonq
)
@@ -14,6 +19,8 @@ INSTALL(
)
INSTALL(
- FILES rekonqinfo.html home.html
+ FILES
+ rekonqinfo.html
+ home.html
DESTINATION ${DATA_INSTALL_DIR}/rekonq/htmls
)
diff --git a/src/data/bot.gif b/src/data/bot.gif
deleted file mode 100644
index 2f9abde4..00000000
--- a/src/data/bot.gif
+++ /dev/null
Binary files differ
diff --git a/src/data/closed.png b/src/data/closed.png
deleted file mode 100644
index 2b1bf01e..00000000
--- a/src/data/closed.png
+++ /dev/null
Binary files differ
diff --git a/src/data/default.css b/src/data/default.css
new file mode 100644
index 00000000..3ddd3026
--- /dev/null
+++ b/src/data/default.css
@@ -0,0 +1,10 @@
+/*
+rekonq default css properties
+this file will not be considered
+setting a local stylesheet in rekonq config
+*/
+
+/* Set background color to white for sites forgetting this */
+body{
+background-color:#FFFFFF;
+} \ No newline at end of file
diff --git a/src/data/home.html b/src/data/home.html
index 9d8f390f..25236743 100644
--- a/src/data/home.html
+++ b/src/data/home.html
@@ -6,134 +6,170 @@
<style type="text/css">
-/* ------------------------------------------------------- */
-/* generic styles */
-
-html, body, div, h1, h2, h3, h4, a, p{
-margin:0;
-padding:0;
-border:0;
+/* -------------------------------------------------------- */
+/* css reset */
+* {
+border: 0; padding: 0; margin: 0;
}
-body{
+/* -------------------------------------------------------- */
+/* generic styles */
+
+body {
background: url(%2/tile.gif) repeat-x #fff;
-font-family: sans-serif;
-font-size: 0.8em;
-text-align: center;
+font-family: sans-serif; font-size: 0.8em;
}
-h1{
-font: normal bold 2em sans-serif;
-text-align:right;
-color: #3F7AB7;
-margin-right:3%;
-margin-top: 0.5%;
-float:right;
+#rekonq-newtabpage {
+width: 100%;
+text-align: center; /* center #navigation */
}
-h2{
-font: normal bold 1.2em sans-serif;
-color: #3F7AB7;
-margin-top: 2em;
+#content {
+text-align: left;
+margin: 0 1% 2% 1%;
}
-h3{
+h3 {
border-bottom-width: 1px;
-webkit-border-image: url(%2/category.png) 1 1 1 1 stretch stretch;
-padding: 0.2em;
-margin-top: 0.5em;
-margin-bottom: 0.5em;
-font: normal bold 1em sans-serif;
+padding: 0.2em; margin: 0.5em 0;
+font: normal bold 1em;
}
-h4{
-font-size: 1em;
-margin-top: 0.5em;
-}
-
-a{
+a {
color: #3F7AB7;
text-decoration: none;
+-webkit-transition-property: color;
+-webkit-transition-duration: 0.5s;
+-webkit-transition-timing-function: ease;
}
-a:hover{
+a:hover {
color: black;
}
-/* ------------------------------------------------------- */
-/* page sections */
+/* -------------------------------------------------------- */
+/* Top bar */
-#container {
-width: 100%;
+#top {
+margin: 20px;
}
-#navigation {
+.topBar {
display: inline-block;
-margin-top: 2%;
-margin-bottom: 2%;
-text-align: center;
border-width: 5px;
--webkit-border-image: url(%2/bg2.png) 12 12 12 12 stretch stretch;
}
-#content {
-text-align: left;
-margin: 2%;
+#navigation {
+-webkit-border-image: url(%2/bg2.png) 12 12 12 12 stretch stretch;
+max-width: 55%;
}
-/* -------------------------------------------------------- */
-/* div navigations styles */
+#actions, #balance {
+margin-top: 12px;
+width: 20%;
+}
-.link{
-display: inline-block;
+#actions {
+float: right;
}
-.link img{
-vertical-align: middle;
-margin-right: 5px;
+#balance {
+display: hidden; float: left;
+height: 16px;
}
-.link a{
+.link {
+display: inline-block;
+}
+.link img, .link span {
+vertical-align: middle; display: inline-block;
+}
+.link a, .link span {
color: black;
-text-decoration:none;
-font: normal 1em sans-serif;
+}
+
+#actions .link {
+-webkit-transition-property: opacity;
+-webkit-transition-duration: 0.8s;
+-webkit-transition-timing-function: ease;
+opacity: 0.2;
+}
+#actions .link:hover {
+opacity: 1;
+}
+#actions .link img {
+margin-right: 3px; width: 16px;
}
.current{
border-width: 6px;
-webkit-border-image: url(%2/button.png) 6 stretch stretch;
}
-
-#navigation .link:not(.current){
-margin-right: 10px;
-margin-left: 10px;
+.link:not(.current){
+margin: 0 10px;
}
+/* -------------------------------------------------------- */
+/* Previews */
-.favorites{
+#content.favorites, #content.closedTabs {
text-align: center;
-margin-top: -5%;
}
-/* -------------------------------------------------------- */
-/* Thumbnail class */
-
.thumbnail {
-text-align: center;
display: inline-block;
-width:25%;
-margin-top: 7%;
-min-width:250px;
-min-height:192px;
+width: 25%; min-width: 240px;
+height: 170px;
+margin: 3% 0 3% 0;
}
-.thumbnail object{
-text-align: center;
-width:228px;
-height:192px;
+.thumb-inner {
+width: 232px; /* 200 + 16*2 */
+margin: auto;
+}
+
+.preview {
+display: table-cell; vertical-align: middle;
+width: 200px; height: 150px;
+padding: 14px 16px 12px;
+background: url(%2/bg.png) no-repeat;
+-webkit-background-size: 100% 100%;
+}
+
+.title {
+padding: 0 12px;
+}
+
+.thumbnail:hover .preview ,
+.thumbnail:hover .button img {
+opacity: 0.8;
+}
+.button img, .preview {
+-webkit-transition-property: opacity;
+-webkit-transition-duration: 0.8s;
+-webkit-transition-timing-function: ease-in-out;
+}
+
+.button img {
+display: inline-block;
+width: 16px;
+height: 16px;
+opacity: 0;
+}
+.remove {
+float: right;
+}
+.modify {
+float: left;
+}
+
+.thumbnail a:hover, .thumbnail span {
+color:#3F7AB7;
}
/* -------------------------------------------------------- */
-/* Bookmarks page*/
+/* Bookmarks page */
.bookfolder{
margin-left: 2em;
@@ -141,39 +177,68 @@ margin-bottom: 0.5em;
}
/* -------------------------------------------------------- */
+/* Downloads page */
+
+.download{
+margin: 1.5em 0;
+}
+
+.download img{
+float: left;
+margin-right: 5px;
+}
+
+/* -------------------------------------------------------- */
+/* Empty pages : in the end : need to overwrite */
+#content.empty {
+margin-top: 10%;
+text-align: center;
+}
+
+
</style>
</head>
<body>
-<div id="container">
- <div id="navigation">
+<div id="rekonq-newtabpage">
+ <div id="top">
+ <div class="topBar" id="balance"></div> <!-- This # is the same size as #actions to center #navigation -->
+ <div class="topBar" id="navigation"></div>
+ <div class="topBar" id="actions"></div>
</div>
-
<div id="content">
-
</div>
</div>
<div id="models" style="display:none">
+ <div></div>
<div class="link">
<a href="">
<img src="" />
+ <span></span>
</a>
</div>
<div class="thumbnail">
- <object type="application/image-preview" data="">
- <param name="title" />
- <param name="index" />
- <param name="isFavorite" />
- </object>
+ <div class ="thumb-inner">
+ <a>
+ <div class ="preview">
+ <img />
+ </div>
+ </a>
+ <div class="title">
+ <a class="button modify"><img /></a>
+ <span><a></a></span>
+ <a class="button remove"><img /></a>
+ </div>
+ </div>
</div>
<h3></h3>
<a></a>
- </br>
- <p class="bookfolder"></h3>
+ <br />
+ <img />
+ <p class="bookfolder"></p>
</div>
-
</body>
</html>
diff --git a/src/data/open.png b/src/data/open.png
deleted file mode 100644
index fee6f3fb..00000000
--- a/src/data/open.png
+++ /dev/null
Binary files differ
diff --git a/src/data/rekonq.desktop b/src/data/rekonq.desktop
index 62998336..bff4ccb0 100644
--- a/src/data/rekonq.desktop
+++ b/src/data/rekonq.desktop
@@ -1,18 +1,40 @@
[Desktop Entry]
Name=rekonq
+Name[cs]=rekonq
+Name[da]=rekonq
+Name[de]=rekonq
+Name[en_GB]=rekonq
+Name[es]=rekonq
+Name[fr]=rekonq
+Name[ga]=rekonq
+Name[lt]=rekonq
+Name[nds]=Rekonq
+Name[nl]=rekonq
+Name[pl]=rekonq
+Name[pt]=rekonq
+Name[pt_BR]=rekonq
Name[sv]=Rekonq
-Name[tr]=Rekonq
+Name[uk]=rekonq
Name[x-test]=xxrekonqxx
+Name[zh_TW]=rekonq
GenericName=Webkit KDE Browser
-GenericName[de]=Webkit-Browser für KDE
-GenericName[et]=KDE Webkiti veebibrauser
-GenericName[km]=កម្មវិធី​រុករក​ Webkit KDE
-GenericName[pt]=Navegador Web com WebKit
+GenericName[cs]=Prohlížeč pro KDE založený na Webkitu
+GenericName[da]=KDE-browser baseret på Webkit
+GenericName[de]=WebKit-basierter Webbrowser für KDE
+GenericName[en_GB]=Webkit KDE Browser
+GenericName[es]=Navegador Webkit para KDE
+GenericName[fr]=Navigateur Webkit pour KDE
+GenericName[ga]=Brabhsálaí Webkit KDE
+GenericName[lt]=Webkit KDE naršyklė
+GenericName[nds]=Webkit-KDE-Kieker
+GenericName[nl]=Webkit KDE Browser
+GenericName[pl]=Przeglądarka Webkit dla KDE
+GenericName[pt]=Navegador do KDE usando o WebKit
GenericName[pt_BR]=Navegador Webkit do KDE
GenericName[sv]=Webkit webbläsare för KDE
-GenericName[tr]=Webkit KDE Tarayıcı
-GenericName[uk]=Переглядач мережі на WebKit для KDE
+GenericName[uk]=Переглядач інтернету на WebKit для KDE
GenericName[x-test]=xxWebkit KDE Browserxx
+GenericName[zh_TW]=Webkit KDE 瀏覽器
Icon=rekonq
Type=Application
Exec=rekonq %u
diff --git a/src/data/top.png b/src/data/top.png
deleted file mode 100644
index 9ebf0234..00000000
--- a/src/data/top.png
+++ /dev/null
Binary files differ
diff --git a/src/data/webkit-icon.png b/src/data/webkit-icon.png
index b3ec677a..780b0b16 100644
--- a/src/data/webkit-icon.png
+++ b/src/data/webkit-icon.png
Binary files differ
diff --git a/src/filterurljob.cpp b/src/filterurljob.cpp
index 00bdee36..bc6118d7 100644
--- a/src/filterurljob.cpp
+++ b/src/filterurljob.cpp
@@ -10,9 +10,9 @@
* 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
+* 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
@@ -31,14 +31,11 @@
#include <KUriFilter>
#include <KUriFilterData>
-// Qt Includes
-#include <QUrl>
-
FilterUrlJob::FilterUrlJob(WebView *view, const QString &urlString, QObject *parent)
- : Job(parent)
- , _view(view)
- , _urlString(urlString)
+ : Job(parent)
+ , _view(view)
+ , _urlString(urlString)
{
}
@@ -61,7 +58,12 @@ void FilterUrlJob::run()
// the beautiful KDE web browsing shortcuts
KUriFilterData data(_urlString);
data.setCheckForExecutables(false); // if true, queries like "rekonq" or "dolphin" are considered as executables
- _url = KUriFilter::self()->filterUri(data)
- ? data.uri().pathOrUrl()
- : QUrl::fromUserInput( _urlString );
+
+ if (KUriFilter::self()->filterUri(data) && data.uriType() != KUriFilterData::Error)
+ {
+ QString tempUrlString = data.uri().url();
+ _url = KUrl(tempUrlString);
+ }
+ else
+ _url = QUrl::fromUserInput(_urlString);
}
diff --git a/src/filterurljob.h b/src/filterurljob.h
index 3a9511ea..6ab10695 100644
--- a/src/filterurljob.h
+++ b/src/filterurljob.h
@@ -10,9 +10,9 @@
* 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
+* 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
@@ -27,6 +27,9 @@
#ifndef FILTER_URL_JOB_H
#define FILTER_URL_JOB_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Local Includes
#include "webview.h"
@@ -41,17 +44,17 @@
using namespace ThreadWeaver;
-class FilterUrlJob : public Job
+class REKONQ_TESTS_EXPORT FilterUrlJob : public Job
{
public:
FilterUrlJob(WebView *view, const QString &urlString, QObject *parent = 0);
WebView *view();
KUrl url();
-
+
protected:
void run();
-
+
private:
WebView *_view;
QString _urlString;
diff --git a/src/findbar.cpp b/src/findbar.cpp
index bd1a5137..db97f87d 100644
--- a/src/findbar.cpp
+++ b/src/findbar.cpp
@@ -2,8 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -29,12 +29,14 @@
#include "findbar.h"
#include "findbar.moc"
+// Local Includes
+#include "mainwindow.h"
+
// KDE Includes
#include <KLineEdit>
#include <KIcon>
#include <KPushButton>
#include <klocalizedstring.h>
-#include <KMainWindow>
#include <KApplication>
// Qt Includes
@@ -43,17 +45,20 @@
#include <QtGui/QToolButton>
#include <QtGui/QLabel>
#include <QtGui/QColor>
-#include <QtGui/QKeyEvent>
#include <QtCore/QString>
#include <QtCore/QTimer>
-FindBar::FindBar(KMainWindow *mainwindow)
- : QWidget(mainwindow)
+FindBar::FindBar(QWidget *parent)
+ : QWidget(parent)
, m_lineEdit(new KLineEdit(this))
- , m_matchCase(new QCheckBox(i18n("&Match case"), this))
, m_hideTimer(new QTimer(this))
+ , m_matchCase(new QCheckBox(i18n("&Match case"), this))
+ , m_highlightAll(new QCheckBox(i18n("&Highlight all"), this))
{
+ // mainwindow pointer
+ MainWindow *window = qobject_cast<MainWindow *>(parent);
+
QHBoxLayout *layout = new QHBoxLayout;
// cosmetic
@@ -64,10 +69,11 @@ FindBar::FindBar(KMainWindow *mainwindow)
hideButton->setAutoRaise(true);
hideButton->setIcon(KIcon("dialog-close"));
connect(hideButton, SIGNAL(clicked()), this, SLOT(hide()));
+ connect(hideButton, SIGNAL(clicked()), window, SLOT(highlightAll()));
layout->addWidget(hideButton);
layout->setAlignment(hideButton, Qt::AlignLeft | Qt::AlignTop);
- // hide timer
+ // hide timer
connect(m_hideTimer, SIGNAL(timeout()), this, SLOT(hide()));
// label
@@ -77,27 +83,35 @@ FindBar::FindBar(KMainWindow *mainwindow)
// lineEdit, focusProxy
setFocusProxy(m_lineEdit);
m_lineEdit->setMaximumWidth(250);
- connect(m_lineEdit, SIGNAL(textChanged(const QString &)), mainwindow, SLOT(find(const QString &)));
+ connect(m_lineEdit, SIGNAL(textChanged(const QString &)), window, SLOT(find(const QString &)));
+ connect(m_lineEdit, SIGNAL(returnPressed()), window, SLOT(findNext()));
layout->addWidget(m_lineEdit);
// buttons
KPushButton *findNext = new KPushButton(KIcon("go-down"), i18n("&Next"), this);
KPushButton *findPrev = new KPushButton(KIcon("go-up"), i18n("&Previous"), this);
- connect(findNext, SIGNAL(clicked()), mainwindow, SLOT(findNext()));
- connect(findPrev, SIGNAL(clicked()), mainwindow, SLOT(findPrevious()));
+ connect(findNext, SIGNAL(clicked()), window, SLOT(findNext()));
+ connect(findPrev, SIGNAL(clicked()), window, SLOT(findPrevious()));
layout->addWidget(findNext);
layout->addWidget(findPrev);
// Case sensitivity. Deliberately set so this is off by default.
m_matchCase->setCheckState(Qt::Unchecked);
m_matchCase->setTristate(false);
+ connect(m_matchCase, SIGNAL(toggled(bool)), window, SLOT(matchCaseUpdate()));
layout->addWidget(m_matchCase);
+ // Hightlight All. On by default
+ m_highlightAll->setCheckState(Qt::Checked);
+ m_highlightAll->setTristate(false);
+ connect(m_highlightAll, SIGNAL(toggled(bool)), window, SLOT(highlightAll()));
+ layout->addWidget(m_highlightAll);
+
// stretching widget on the left
layout->addStretch();
setLayout(layout);
-
+
// we start off hidden
hide();
}
@@ -120,44 +134,29 @@ bool FindBar::matchCase() const
}
-void FindBar::clear()
+bool FindBar::highlightAllState() const
{
- m_lineEdit->setText(QString());
+ return m_highlightAll->isChecked();
}
void FindBar::show()
{
- // set focus to findbar if user select showFindBar shortcut
- m_lineEdit->setFocus();
- m_lineEdit->selectAll();
-
// show findbar if not visible
- if (isVisible())
- return;
-
- QWidget::show();
- m_hideTimer->start(60000);
-}
-
-
-void FindBar::keyPressEvent(QKeyEvent* event)
-{
- if (event->key() == Qt::Key_Escape)
- {
- hide();
- m_hideTimer->stop();
- return;
- }
- if (event->key() == Qt::Key_Return && !m_lineEdit->text().isEmpty())
+ if (isHidden())
{
+ QWidget::show();
emit searchString(m_lineEdit->text());
- return;
}
- QWidget::keyPressEvent(event);
+ m_hideTimer->start(60000);
+
+ // set focus to findbar if user select showFindBar shortcut
+ m_lineEdit->setFocus();
+ m_lineEdit->selectAll();
}
+
void FindBar::notifyMatch(bool match)
{
QPalette p = m_lineEdit->palette();
@@ -166,7 +165,7 @@ void FindBar::notifyMatch(bool match)
{
p.setColor(QPalette::Base, QColor(KApplication::palette().color(QPalette::Active, QPalette::Base)));
}
- else
+ else
{
if (match)
{
@@ -180,3 +179,11 @@ void FindBar::notifyMatch(bool match)
m_lineEdit->setPalette(p);
m_hideTimer->start(60000);
}
+
+
+void FindBar::hide()
+{
+ m_hideTimer->stop();
+ QWidget::hide();
+ emit(searchString(m_lineEdit->text()));
+}
diff --git a/src/findbar.h b/src/findbar.h
index fa369f66..39bb28c9 100644
--- a/src/findbar.h
+++ b/src/findbar.h
@@ -2,8 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -29,46 +29,44 @@
#define FINDBAR_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// KDE Includes
#include <KLineEdit>
// Qt Includes
#include <QtGui/QWidget>
#include <QtGui/QCheckBox>
-#include <QtGui/QKeyEvent>
// Forward Declarations
-class KMainWindow;
-class QKeyEvent;
class QString;
-class FindBar : public QWidget
+class REKONQ_TESTS_EXPORT FindBar : public QWidget
{
Q_OBJECT
public:
- FindBar(KMainWindow *mainwindow);
+ FindBar(QWidget *parent);
~FindBar();
KLineEdit *lineEdit() const;
bool matchCase() const;
+ void notifyMatch(bool match);
+ bool highlightAllState() const;
public slots:
- void clear();
void show();
- void notifyMatch(bool match);
-
-protected Q_SLOTS:
- void keyPressEvent(QKeyEvent* event);
+ void hide();
signals:
void searchString(const QString &);
private:
KLineEdit *m_lineEdit;
- QCheckBox *m_matchCase;
QTimer *m_hideTimer;
-
+ QCheckBox *m_matchCase;
+ QCheckBox *m_highlightAll;
};
#endif
diff --git a/src/history/autosaver.cpp b/src/history/autosaver.cpp
index 236922b5..83b3f6b0 100644
--- a/src/history/autosaver.cpp
+++ b/src/history/autosaver.cpp
@@ -3,7 +3,7 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -31,9 +31,6 @@
#include "autosaver.h"
#include "autosaver.moc"
-// KDE Includes
-#include <KDebug>
-
// Qt Includes
#include <QtCore/QMetaObject>
@@ -52,7 +49,7 @@ AutoSaver::~AutoSaver()
{
if (m_timer.isActive())
{
- kWarning() << "AutoSaver: still active when destroyed, changes not saved.";
+ kDebug() << "AutoSaver: still active when destroyed, changes not saved.";
}
}
@@ -94,7 +91,7 @@ void AutoSaver::saveIfNeccessary()
m_firstChange = QTime();
if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection))
{
- kWarning() << "AutoSaver: error invoking slot save() on parent";
+ kDebug() << "AutoSaver: error invoking slot save() on parent";
}
}
diff --git a/src/history/autosaver.h b/src/history/autosaver.h
index 80583f9c..6927dbe8 100644
--- a/src/history/autosaver.h
+++ b/src/history/autosaver.h
@@ -3,7 +3,7 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -29,6 +29,9 @@
#define AUTOSAVER_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Qt Includes
#include <QtCore/QObject>
#include <QtCore/QBasicTimer>
@@ -43,7 +46,7 @@
*
*/
-class AutoSaver : public QObject
+class REKONQ_TESTS_EXPORT AutoSaver : public QObject
{
Q_OBJECT
diff --git a/src/history/historymanager.cpp b/src/history/historymanager.cpp
index 29bdb45b..8dc7e049 100644
--- a/src/history/historymanager.cpp
+++ b/src/history/historymanager.cpp
@@ -4,7 +4,7 @@
*
* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
* Copyright (C) 2008 Benjamin C. Meyer <ben@meyerhome.net>
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +12,9 @@
* 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
+* 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
@@ -63,18 +63,17 @@ 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_historyTreeModel(0)
- , m_completion(0)
+ : QWebHistoryInterface(parent)
+ , m_saveTimer(new AutoSaver(this))
+ , m_historyLimit(30)
+ , m_historyModel(0)
+ , m_historyFilterModel(0)
+ , m_historyTreeModel(0)
+ , m_completion(new KCompletion)
{
// take care of the completion object
- m_completion = new KCompletion;
- m_completion->setOrder( KCompletion::Weighted );
-
+ m_completion->setOrder(KCompletion::Weighted);
+
m_expiredTimer.setSingleShot(true);
connect(&m_expiredTimer, SIGNAL(timeout()), this, SLOT(checkForExpired()));
connect(this, SIGNAL(entryAdded(const HistoryItem &)), m_saveTimer, SLOT(changeOccurred()));
@@ -113,11 +112,11 @@ bool HistoryManager::historyContains(const QString &url) const
void HistoryManager::addHistoryEntry(const QString &url)
{
QUrl cleanUrl(url);
-
+
// don't store about: urls (home page related)
- if(cleanUrl.scheme() == QString("about"))
+ if (cleanUrl.scheme() == QString("about"))
return;
-
+
cleanUrl.setPassword(QString());
cleanUrl.setHost(cleanUrl.host().toLower());
HistoryItem item(cleanUrl.toString(), QDateTime::currentDateTime());
@@ -213,7 +212,7 @@ void HistoryManager::addHistoryEntry(const HistoryItem &item)
m_history.prepend(item);
emit entryAdded(item);
-
+
if (m_history.count() == 1)
checkForExpired();
}
@@ -255,7 +254,7 @@ void HistoryManager::removeHistoryEntry(const KUrl &url, const QString &title)
break;
}
}
-
+
// Remove item from completion object
QString _url = url.path();
_url.remove(QRegExp("^http://|/$"));
@@ -317,7 +316,7 @@ void HistoryManager::load()
return;
if (!historyFile.open(QFile::ReadOnly))
{
- kWarning() << "Unable to open history file" << historyFile.fileName();
+ kDebug() << "Unable to open history file" << historyFile.fileName();
return;
}
@@ -363,7 +362,7 @@ void HistoryManager::load()
// Add item to completion object
QString _url = item.url;
- _url.remove(QRegExp("^http://|/$"));
+ //_url.remove(QRegExp("^http://|/$"));
m_completion->addItem(_url);
}
if (needToSort)
@@ -417,7 +416,7 @@ void HistoryManager::save()
if (!open)
{
- kWarning() << "Unable to open history file for saving"
+ kDebug() << "Unable to open history file for saving"
<< (saveAll ? tempFile.fileName() : historyFile.fileName());
return;
}
@@ -437,11 +436,11 @@ void HistoryManager::save()
{
if (historyFile.exists() && !historyFile.remove())
{
- kWarning() << "History: error removing old history." << historyFile.errorString();
+ kDebug() << "History: error removing old history." << historyFile.errorString();
}
if (!tempFile.rename(historyFile.fileName()))
{
- kWarning() << "History: error moving new history over old." << tempFile.errorString() << historyFile.fileName();
+ kDebug() << "History: error moving new history over old." << tempFile.errorString() << historyFile.fileName();
}
}
m_lastSavedUrl = m_history.value(0).url;
@@ -452,3 +451,83 @@ KCompletion * HistoryManager::completionObject() const
{
return m_completion;
}
+
+
+void HistoryManager::addDownload(const QString &srcUrl, const QString &destUrl)
+{
+ QWebSettings *globalSettings = QWebSettings::globalSettings();
+ if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled))
+ return;
+ QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads");
+ QFile downloadFile(downloadFilePath);
+ if (!downloadFile.open(QFile::WriteOnly | QFile::Append))
+ {
+ kDebug() << "azz...";
+ return;
+ }
+ QDataStream out(&downloadFile);
+ out << srcUrl;
+ out << destUrl;
+ out << QDateTime::currentDateTime();
+ downloadFile.close();
+}
+
+
+DownloadList HistoryManager::downloads()
+{
+ DownloadList list;
+
+ QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads");
+ QFile downloadFile(downloadFilePath);
+ if (!downloadFile.open(QFile::ReadOnly))
+ {
+ kDebug() << "azz...";
+ return list;
+ }
+
+ QDataStream in(&downloadFile);
+ while (!in.atEnd())
+ {
+ QString srcUrl;
+ in >> srcUrl;
+ QString destUrl;
+ in >> destUrl;
+ QDateTime dt;
+ in >> dt;
+ DownloadItem item(srcUrl, destUrl, dt);
+ list << item;
+ }
+ return list;
+}
+
+
+bool HistoryManager::clearDownloadsHistory()
+{
+ QString downloadFilePath = KStandardDirs::locateLocal("appdata" , "downloads");
+ QFile downloadFile(downloadFilePath);
+ return downloadFile.remove();
+}
+
+
+QString HistoryManager::titleForHistoryUrl(QString url)
+{
+ QString title = "";
+
+ int i = 0;
+ while (i < history().count() && title.isEmpty())
+ {
+ if (history().at(i).url == url)
+ {
+ title = history().at(i).title;
+ }
+ i++;
+ }
+
+ if (title.isEmpty())
+ {
+ title = url;
+ }
+
+ return title;
+}
+
diff --git a/src/history/historymanager.h b/src/history/historymanager.h
index ff3b4381..0f131782 100644
--- a/src/history/historymanager.h
+++ b/src/history/historymanager.h
@@ -4,7 +4,7 @@
*
* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
* Copyright (C) 2008 Benjamin C. Meyer <ben@meyerhome.net>
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +12,9 @@
* 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
+* 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
@@ -30,6 +30,9 @@
#define HISTORY_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// KDE Includes
#include <KUrl>
@@ -51,10 +54,13 @@ class HistoryItem
public:
HistoryItem() {}
explicit HistoryItem(const QString &u,
- const QDateTime &d = QDateTime(),
+ const QDateTime &d = QDateTime(),
const QString &t = QString()
)
- : title(t), url(u), dateTime(d) {}
+ : title(t)
+ , url(u),
+ dateTime(d)
+ {}
inline bool operator==(const HistoryItem &other) const
{
@@ -74,6 +80,29 @@ public:
};
+// ---------------------------------------------------------------------------------------------------------------
+
+
+class DownloadItem
+{
+public:
+ DownloadItem() {}
+ explicit DownloadItem(const QString &srcUrl,
+ const QString &destUrl,
+ const QDateTime &d
+ )
+ : srcUrlString(srcUrl)
+ , destUrlString(destUrl)
+ , dateTime(d)
+ {}
+
+ QString srcUrlString;
+ QString destUrlString;
+ QDateTime dateTime;
+};
+
+
+typedef QList<DownloadItem> DownloadList;
// ---------------------------------------------------------------------------------------------------------------
@@ -92,7 +121,7 @@ class KCompletion;
* It manages rekonq history
*
*/
-class HistoryManager : public QWebHistoryInterface
+class REKONQ_TESTS_EXPORT HistoryManager : public QWebHistoryInterface
{
Q_OBJECT
Q_PROPERTY(int historyLimit READ historyLimit WRITE setHistoryLimit)
@@ -112,6 +141,8 @@ public:
void updateHistoryEntry(const KUrl &url, const QString &title);
void removeHistoryEntry(const KUrl &url, const QString &title = QString());
+ QString titleForHistoryUrl(QString url);
+
int historyLimit() const;
void setHistoryLimit(int limit);
@@ -128,6 +159,10 @@ public:
*/
KCompletion *completionObject() const;
+ void addDownload(const QString &srcUrl, const QString &destUrl);
+ DownloadList downloads();
+ bool clearDownloadsHistory();
+
public slots:
void clear();
void loadSettings();
diff --git a/src/history/historymodels.cpp b/src/history/historymodels.cpp
index cf8d1aed..e68eac42 100644
--- a/src/history/historymodels.cpp
+++ b/src/history/historymodels.cpp
@@ -4,7 +4,7 @@
*
* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
* Copyright (C) 2008 Benjamin C. Meyer <ben@meyerhome.net>
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +12,9 @@
* 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
+* 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
@@ -118,6 +118,8 @@ QVariant HistoryModel::data(const QModelIndex &index, int role) const
return item.dateTime.date();
case UrlRole:
return QUrl(item.url);
+ case Qt::UserRole:
+ return KUrl(item.url);
case UrlStringRole:
return item.url;
case Qt::DisplayRole:
@@ -144,6 +146,12 @@ QVariant HistoryModel::data(const QModelIndex &index, int role) const
{
return Application::icon(item.url);
}
+ case Qt::ToolTipRole:
+ QString tooltip = "";
+ if (!item.title.isEmpty())
+ tooltip = item.title + '\n';
+ tooltip += item.dateTime.toString(Qt::SystemLocaleShortDate) + '\n' + item.url;
+ return tooltip;
}
return QVariant();
}
@@ -688,7 +696,7 @@ QVariant HistoryTreeModel::data(const QModelIndex &index, int role) const
QDate date = idx.data(HistoryModel::DateRole).toDate();
if (date == QDate::currentDate())
return i18n("Earlier Today");
- return date.toString(QLatin1String("dddd, MMMM d, yyyy"));
+ return date.toString(QL1S("dddd, MMMM d, yyyy"));
}
if (index.column() == 1)
{
diff --git a/src/history/historymodels.h b/src/history/historymodels.h
index 08f3f63e..78691694 100644
--- a/src/history/historymodels.h
+++ b/src/history/historymodels.h
@@ -4,7 +4,7 @@
*
* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
* Copyright (C) 2008 Benjamin C. Meyer <ben@meyerhome.net>
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +12,9 @@
* 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
+* 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
@@ -30,6 +30,9 @@
#define HISTORYMODELS_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Local Includes
#include "historymanager.h"
@@ -37,15 +40,13 @@
#include <KUrl>
// Qt Includes
-#include <QDateTime>
#include <QHash>
#include <QObject>
-#include <QTimer>
#include <QSortFilterProxyModel>
#include <QWebHistoryInterface>
-class HistoryModel : public QAbstractTableModel
+class REKONQ_TESTS_EXPORT HistoryModel : public QAbstractTableModel
{
Q_OBJECT
@@ -85,7 +86,7 @@ private:
*
*/
-class HistoryFilterModel : public QAbstractProxyModel
+class REKONQ_TESTS_EXPORT HistoryFilterModel : public QAbstractProxyModel
{
Q_OBJECT
diff --git a/src/history/historypanel.cpp b/src/history/historypanel.cpp
index 08dc3800..4c4982e9 100644
--- a/src/history/historypanel.cpp
+++ b/src/history/historypanel.cpp
@@ -2,8 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>*
* Copyright (C) 2009 by Domrachev Alexandr <alexandr.domrachev@gmail.com>
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -46,10 +46,14 @@
// KDE Includes
#include <KLineEdit>
#include <KLocalizedString>
+#include <KMenu>
+#include <KAction>
+#include <KMessageBox>
HistoryPanel::HistoryPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags)
- : QDockWidget(title, parent, flags)
+ : QDockWidget(title, parent, flags)
+ , m_treeView(new PanelTreeView(this))
{
setup();
setShown(ReKonfig::showHistoryPanel());
@@ -67,14 +71,14 @@ void HistoryPanel::setup()
{
setObjectName("historyPanel");
setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
-
+
QWidget *ui = new QWidget(this);
- QTreeView *historyTreeView = new QTreeView(this);
- historyTreeView->setUniformRowHeights(true);
- historyTreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
- historyTreeView->setTextElideMode(Qt::ElideMiddle);
- historyTreeView->setAlternatingRowColors(true);
+ m_treeView->setUniformRowHeights(true);
+ m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows);
+ m_treeView->setTextElideMode(Qt::ElideMiddle);
+ m_treeView->setAlternatingRowColors(true);
+ m_treeView->header()->hide();
// add search bar
QHBoxLayout *hBoxLayout = new QHBoxLayout;
@@ -91,7 +95,7 @@ void HistoryPanel::setup()
QVBoxLayout *vBoxLayout = new QVBoxLayout;
vBoxLayout->setContentsMargins(0, 0, 0, 0);
vBoxLayout->addWidget(searchBar);
- vBoxLayout->addWidget(historyTreeView);
+ vBoxLayout->addWidget(m_treeView);
// add it to the UI
ui->setLayout(vBoxLayout);
@@ -103,19 +107,83 @@ void HistoryPanel::setup()
TreeProxyModel *treeProxyModel = new TreeProxyModel(this);
treeProxyModel->setSourceModel(model);
- historyTreeView->setModel(treeProxyModel);
- historyTreeView->setExpanded(treeProxyModel->index(0, 0), true);
- historyTreeView->header()->hideSection(1);
+ m_treeView->setModel(treeProxyModel);
+ m_treeView->setExpanded(treeProxyModel->index(0, 0), true);
+ m_treeView->header()->hideSection(1);
QFontMetrics fm(font());
- int header = fm.width(QLatin1Char('m')) * 40;
- historyTreeView->header()->resizeSection(0, header);
+ int header = fm.width( QL1C('m') ) * 40;
+ m_treeView->header()->resizeSection(0, header);
connect(search, SIGNAL(textChanged(QString)), treeProxyModel, SLOT(setFilterFixedString(QString)));
- connect(historyTreeView, SIGNAL(activated(const QModelIndex &)), this, SLOT(itemActivated(const QModelIndex &)));
+ connect(m_treeView, SIGNAL(contextMenuItemRequested(const QPoint &)), this, SLOT(contextMenuItem(const QPoint &)));
+ connect(m_treeView, SIGNAL(contextMenuGroupRequested(const QPoint &)), this, SLOT(contextMenuGroup(const QPoint &)));
}
-void HistoryPanel::itemActivated(const QModelIndex &item)
+void HistoryPanel::contextMenuItem(const QPoint &pos)
{
- emit openUrl( item.data(HistoryModel::UrlRole).toUrl() );
+ KMenu *menu = new KMenu(this);
+ KAction* action;
+
+ action = new KAction(KIcon("tab-new"), i18n("Open"), this);
+ connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInCurrentTab()));
+ menu->addAction(action);
+
+ action = new KAction(KIcon("tab-new"), i18n("Open in New Tab"), this);
+ connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewTab()));
+ menu->addAction(action);
+
+ action = new KAction(KIcon("window-new"), i18n("Open in New Window"), this);
+ connect(action, SIGNAL(triggered()), m_treeView, SLOT(openInNewWindow()));
+ menu->addAction(action);
+
+ action = new KAction(KIcon("edit-copy"), i18n("Copy Link Address"), this);
+ connect(action, SIGNAL(triggered()), m_treeView, SLOT(copyToClipboard()));
+ menu->addAction(action);
+
+ if (!menu)
+ return;
+ menu->popup(m_treeView->mapToGlobal(pos));
}
+
+
+void HistoryPanel::contextMenuGroup(const QPoint &pos)
+{
+ KMenu *menu = new KMenu(this);
+ KAction* action;
+
+ action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this);
+ connect(action, SIGNAL(triggered()), this, SLOT(openAll()));
+
+ menu->addAction(action);
+
+ if (!menu)
+ return;
+ menu->popup(m_treeView->mapToGlobal(pos));
+}
+
+
+void HistoryPanel::openAll()
+{
+ QModelIndex index = m_treeView->currentIndex();
+ if (!index.isValid())
+ return;
+
+ QList<KUrl> allChild;
+
+ for (int i = 0; i < index.model()->rowCount(index); i++)
+ allChild << qVariantValue<KUrl>(index.child(i, 0).data(Qt::UserRole));
+
+ if (allChild.length() > 8)
+ {
+ if (!(KMessageBox::warningContinueCancel(this,
+ i18n("You are about to open %1 tabs.\nAre you sure ?",
+ QString::number(allChild.length()))) == KMessageBox::Continue)
+ )
+ return;
+ }
+
+ for (int i = 0; i < allChild.length(); i++)
+ emit openUrl(allChild.at(i).url(), Rekonq::SettingOpenTab);
+}
+
diff --git a/src/history/historypanel.h b/src/history/historypanel.h
index e07e2190..1c86cfee 100644
--- a/src/history/historypanel.h
+++ b/src/history/historypanel.h
@@ -2,8 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>*
* Copyright (C) 2009 by Domrachev Alexandr <alexandr.domrachev@gmail.com>
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -29,6 +29,13 @@
#define HISTORYPANEL_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Local Includes
+#include "application.h"
+#include "paneltreeview.h"
+
// Qt Includes
#include <QDockWidget>
@@ -38,22 +45,26 @@ class QWidget;
class QModelIndex;
-class HistoryPanel : public QDockWidget
+class REKONQ_TESTS_EXPORT HistoryPanel : public QDockWidget
{
-Q_OBJECT
+ Q_OBJECT
public:
explicit HistoryPanel(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0);
~HistoryPanel();
signals:
- void openUrl(const KUrl &);
+ void openUrl(const KUrl &, const Rekonq::OpenType &);
+ void itemHovered(const QString &);
private slots:
- void itemActivated(const QModelIndex &);
+ void contextMenuItem(const QPoint &pos);
+ void contextMenuGroup(const QPoint &pos);
+ void openAll();
private:
void setup();
+ PanelTreeView *m_treeView;
};
#endif // HISTORYPANEL_H
diff --git a/src/main.cpp b/src/main.cpp
index 030b8476..5551c55a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2,7 +2,7 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -10,9 +10,9 @@
* 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
+* 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
@@ -41,7 +41,7 @@ static const char description[] =
I18N_NOOP("A lightweight Web Browser for KDE based on WebKit");
-extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
+extern "C" KDE_EXPORT int kdemain(int argc, char **argv)
{
KAboutData about("rekonq",
0,
@@ -49,22 +49,17 @@ extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
REKONQ_VERSION,
ki18n(description),
KAboutData::License_GPL_V3,
- ki18n("(C) 2008-2009 Andrea Diamantini"),
+ ki18n("(C) 2008-2010 Andrea Diamantini"),
KLocalizedString(),
"http://rekonq.sourceforge.net"
);
// --------------- about authors -----------------------------
about.addAuthor(ki18n("Andrea Diamantini"),
- ki18n("Project Lead, Developer"),
+ ki18n("Project Lead, Developer, Maintainer"),
"adjam7@gmail.com",
"http://www.adjam.org");
- about.addAuthor(ki18n("Domrachev Alexandr"),
- ki18n("Developer"),
- "alexandr.domrachev@gmail.com",
- "");
-
about.addAuthor(ki18n("Panagiotis Papadopoulos"),
ki18n("Quite everything but code"),
"pano_90@gmx.net",
@@ -89,8 +84,13 @@ extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
ki18n("(Tons of ) patches, testing, bugfixing"),
"ronny_scholz@web.de",
"");
-
- // --------------- about credits -----------------------------
+
+ // --------------- about credits -----------------------------
+ about.addCredit(ki18n("Domrachev Alexandr"),
+ ki18n("Developer"),
+ "alexandr.domrachev@gmail.com",
+ "");
+
about.addCredit(ki18n("Henry de Valence"),
ki18n("Promised help on multitask rekonq"),
"hdevalence@gmail.com",
@@ -120,7 +120,7 @@ extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
ki18n("Handbook"),
"rohan16garg@gmail.com",
"");
-
+
about.addCredit(ki18n("Dario Freddi"),
ki18n("Patches, hints, first KWallet support implementation (not yet included)"),
"drf@kde.org",
@@ -130,7 +130,7 @@ extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
ki18n("first awesome bar implementation (wait next version and you'll see..)"),
"jondeandres@gmail.com",
"");
-
+
// Initialize command line args
KCmdLineArgs::init(argc, argv, &about);
diff --git a/src/mainview.cpp b/src/mainview.cpp
index b26e7466..4dc95b26 100644
--- a/src/mainview.cpp
+++ b/src/mainview.cpp
@@ -2,9 +2,10 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +13,9 @@
* 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
+* 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
@@ -45,7 +46,6 @@
#include <KShortcut>
#include <KStandardShortcut>
#include <KMessageBox>
-#include <KDebug>
#include <KStandardDirs>
#include <KPassivePopup>
#include <KLocalizedString>
@@ -63,37 +63,39 @@
MainView::MainView(MainWindow *parent)
: KTabWidget(parent)
- , m_urlBar(new UrlBar(this))
- , m_tabBar(new TabBar(this))
- , m_addTabButton(new QToolButton(this))
+ , _bars(new QStackedWidget(this))
+ , m_addTabButton(0)
, m_currentTabIndex(0)
, m_parentWindow(parent)
{
// setting tabbar
- setTabBar(m_tabBar);
+ TabBar *tabBar = new TabBar(this);
+ m_addTabButton = new QToolButton(this);
+ setTabBar(tabBar);
// set mouse tracking for tab previews
setMouseTracking(true);
-
+
// loading pixmap path
m_loadingGitPath = KStandardDirs::locate("appdata" , "pics/loading.mng");
// connecting tabbar signals
- connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int)));
- connect(m_tabBar, SIGNAL(mouseMiddleClick(int)), this, SLOT(closeTab(int)));
- connect(m_tabBar, SIGNAL(newTabRequest()), this, SLOT(newTab()));
-
- connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int)));
- connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int)));
- connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int)));
- connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs()));
- connect(m_tabBar, SIGNAL(detachTab(int)), this, SLOT(detachTab(int)));
-
- connect(m_tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
-
+ connect(tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int)));
+ connect(tabBar, SIGNAL(mouseMiddleClick(int)), this, SLOT(closeTab(int)));
+ connect(tabBar, SIGNAL(newTabRequest()), this, SLOT(newTab()));
+
+ connect(tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int)));
+ connect(tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int)));
+ connect(tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int)));
+ connect(tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs()));
+ connect(tabBar, SIGNAL(detachTab(int)), this, SLOT(detachTab(int)));
+
+ connect(tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));
+ connect(tabBar, SIGNAL(tabMoved(int, int)), this, SLOT(movedTab(int, int)));
+
// current page index changing
connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int)));
-
+
QTimer::singleShot(0, this, SLOT(postLaunch()));
}
@@ -106,8 +108,8 @@ MainView::~MainView()
void MainView::postLaunch()
{
// Session Manager
- connect (this, SIGNAL(tabsChanged()), Application::sessionManager(), SLOT(saveSession()));
-
+ connect(this, SIGNAL(tabsChanged()), Application::sessionManager(), SLOT(saveSession()));
+
m_addTabButton->setDefaultAction(m_parentWindow->actionByName("new_tab"));
m_addTabButton->setAutoRaise(true);
@@ -117,23 +119,21 @@ void MainView::postLaunch()
void MainView::updateTabButtonPosition()
{
- kDebug() << "updating new tab button position..";
-
static bool ButtonInCorner = false;
int tabWidgetWidth = frameSize().width();
- int tabBarWidth = m_tabBar->tabSizeHint(0).width()*m_tabBar->count();
+ int tabBarWidth = tabBar()->tabSizeHint(0).width() * tabBar()->count();
if (tabBarWidth + m_addTabButton->width() > tabWidgetWidth)
{
- if(ButtonInCorner)
+ if (ButtonInCorner)
return;
setCornerWidget(m_addTabButton);
ButtonInCorner = true;
}
else
{
- if(ButtonInCorner)
+ if (ButtonInCorner)
{
setCornerWidget(0);
m_addTabButton->show();
@@ -141,16 +141,12 @@ void MainView::updateTabButtonPosition()
}
// detecting X position
- int newPosX = tabBarWidth;
- int tabWidthHint = m_tabBar->tabSizeHint(0).width();
- if (tabWidthHint < sizeHint().width()/4)
+ int newPosX = tabBarWidth;
+ int tabWidthHint = tabBar()->tabSizeHint(0).width();
+ if (tabWidthHint < sizeHint().width() / 4)
newPosX = tabWidgetWidth - m_addTabButton->width();
- // Y position is fixed
- // Here I noticed with some emphiric valutations ( :D )
- // that 2 look better than 0, just that..
-
- m_addTabButton->move(newPosX, 2);
+ m_addTabButton->move(newPosX, 0);
}
}
@@ -163,13 +159,20 @@ QToolButton *MainView::addTabButton() const
TabBar *MainView::tabBar() const
{
- return m_tabBar;
+ TabBar *tabBar = qobject_cast<TabBar *>(KTabWidget::tabBar());
+ return tabBar;
+}
+
+
+UrlBar *MainView::urlBar() const
+{
+ return qobject_cast<UrlBar *>(_bars->widget(m_currentTabIndex));
}
-UrlBar *MainView::urlBar() const
-{
- return m_urlBar;
+QWidget *MainView::urlBarWidget() const
+{
+ return _bars;
}
@@ -185,9 +188,9 @@ void MainView::updateTabBar()
{
if (!isTabBarHidden())
{
- if (m_tabBar->isHidden())
+ if (tabBar()->isHidden())
{
- m_tabBar->show();
+ tabBar()->show();
m_addTabButton->show();
}
updateTabButtonPosition();
@@ -195,16 +198,16 @@ void MainView::updateTabBar()
return;
}
- if (m_tabBar->count() == 1)
+ if (tabBar()->count() == 1)
{
- m_tabBar->hide();
+ tabBar()->hide();
m_addTabButton->hide();
}
else if (!isTabBarHidden())
{
- if (m_tabBar->isHidden())
+ if (tabBar()->isHidden())
{
- m_tabBar->show();
+ tabBar()->show();
m_addTabButton->show();
}
updateTabButtonPosition();
@@ -235,17 +238,6 @@ void MainView::webStop()
}
-void MainView::clear()
-{
- // FIXME (the programmer, not the code)
- // What exactly do we need to clear here?
- m_urlBar->clearHistory();
- m_urlBar->clear();
-
- m_recentlyClosedTabs.clear();
-}
-
-
// When index is -1 index chooses the current tab
void MainView::reloadTab(int index)
{
@@ -268,17 +260,12 @@ void MainView::currentChanged(int index)
// retrieve the old webview (that where we move from)
WebTab *oldTab = this->webTab(m_currentTabIndex);
-
+
// set current index
m_currentTabIndex = index;
if (oldTab)
- {
- // disconnecting webview from urlbar
- disconnect(oldTab->view(), SIGNAL(loadProgress(int)), urlBar(), SLOT(updateProgress(int)));
- disconnect(oldTab->view(), SIGNAL(loadFinished(bool)), urlBar(), SLOT(loadFinished(bool)));
- disconnect(oldTab->view(), SIGNAL(urlChanged(const QUrl &)), urlBar(), SLOT(setUrl(const QUrl &)));
-
+ {
// disconnecting webpage from mainview
disconnect(oldTab->page(), SIGNAL(statusBarMessage(const QString&)),
this, SIGNAL(showStatusBarMessage(const QString&)));
@@ -286,36 +273,40 @@ void MainView::currentChanged(int index)
this, SIGNAL(linkHovered(const QString&)));
}
- // connecting webview with urlbar
- connect(tab->view(), SIGNAL(loadProgress(int)), urlBar(), SLOT(updateProgress(int)));
- connect(tab->view(), SIGNAL(loadFinished(bool)), urlBar(), SLOT(loadFinished(bool)));
- connect(tab->view(), SIGNAL(urlChanged(const QUrl &)), urlBar(), SLOT(setUrl(const QUrl &)));
-
- connect(tab->view()->page(), SIGNAL(statusBarMessage(const QString&)),
+ connect(tab->page(), SIGNAL(statusBarMessage(const QString&)),
this, SIGNAL(showStatusBarMessage(const QString&)));
- connect(tab->view()->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)),
+ connect(tab->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)),
this, SIGNAL(linkHovered(const QString&)));
- emit setCurrentTitle(tab->view()->title());
- urlBar()->setUrl(tab->view()->url());
- urlBar()->setProgress(tab->progress());
- emit showStatusBarMessage(tab->lastStatusBarText());
+ emit currentTitle(tab->view()->title());
+ _bars->setCurrentIndex(index);
+
+ // clean up "status bar"
+ emit showStatusBarMessage(QString());
// notify UI to eventually switch stop/reload button
- if(urlBar()->isLoading())
- emit browserTabLoading(true);
- else
+ int progr = tab->progress();
+ if (progr == 0)
emit browserTabLoading(false);
+ else
+ emit browserTabLoading(true);
+
+ // update zoom slider
+ if (!Application::instance()->mainWindowList().isEmpty())
+ Application::instance()->mainWindow()->setZoomSliderFactor(tab->view()->zoomFactor());
// set focus to the current webview
- tab->setFocus();
+ if (tab->url().scheme() == QL1S("about"))
+ _bars->currentWidget()->setFocus();
+ else
+ tab->view()->setFocus();
}
WebTab *MainView::webTab(int index) const
{
- WebTab *tab = qobject_cast<WebTab *>( this->widget(index) );
- if(tab)
+ WebTab *tab = qobject_cast<WebTab *>(this->widget(index));
+ if (tab)
{
return tab;
}
@@ -328,6 +319,7 @@ WebTab *MainView::webTab(int index) const
WebTab *MainView::newWebTab(bool focused, bool nearParent)
{
WebTab* tab = new WebTab(this);
+ UrlBar *bar = new UrlBar(tab);
// connecting webview with mainview
connect(tab->view(), SIGNAL(loadStarted()), this, SLOT(webViewLoadStarted()));
@@ -339,21 +331,26 @@ WebTab *MainView::newWebTab(bool focused, bool nearParent)
// connecting webPage signals with mainview
connect(tab->view()->page(), SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested()));
connect(tab->view()->page(), SIGNAL(printRequested(QWebFrame *)), this, SIGNAL(printRequested(QWebFrame *)));
-
+
if (nearParent)
+ {
insertTab(currentIndex() + 1, tab, i18n("(Untitled)"));
+ _bars->insertWidget(currentIndex() + 1, bar);
+ }
else
+ {
addTab(tab, i18n("(Untitled)"));
-
+ _bars->addWidget(bar);
+ }
updateTabBar();
-
+
if (focused)
{
setCurrentWidget(tab);
}
emit tabsChanged();
-
+
return tab;
}
@@ -362,21 +359,21 @@ void MainView::newTab()
{
WebView *w = newWebTab()->view();
- switch(ReKonfig::newTabsBehaviour())
+ switch (ReKonfig::newTabsBehaviour())
{
case 0: // new tab page
- w->load( KUrl("about:home") );
+ w->load(KUrl("about:home"));
break;
case 1: // blank page
- urlBar()->setUrl(KUrl(""));
+ urlBar()->clear();
break;
case 2: // homepage
- w->load( KUrl(ReKonfig::homePage()) );
+ w->load(KUrl(ReKonfig::homePage()));
break;
default:
break;
}
- urlBar()->setFocus();
+ _bars->currentWidget()->setFocus();
}
@@ -391,9 +388,9 @@ void MainView::reloadAllTabs()
void MainView::windowCloseRequested()
{
- WebPage *page = qobject_cast<WebPage *>( sender() );
- WebView *view = qobject_cast<WebView *>( page->view() );
- int index = indexOf( view->parentWidget() );
+ WebPage *page = qobject_cast<WebPage *>(sender());
+ WebView *view = qobject_cast<WebView *>(page->view());
+ int index = indexOf(view->parentWidget());
if (index >= 0)
{
@@ -437,10 +434,10 @@ void MainView::cloneTab(int index)
index = currentIndex();
if (index < 0 || index >= count())
return;
-
+
WebTab *tab = newWebTab();
KUrl url = webTab(index)->url();
-
+
// workaround against bug in webkit:
// only set url if it is not empty
// otherwise the current working directory will be used
@@ -452,26 +449,25 @@ void MainView::cloneTab(int index)
// When index is -1 index chooses the current tab
-void MainView::closeTab(int index)
+void MainView::closeTab(int index, bool del)
{
// open default homePage if just one tab is opened
if (count() == 1)
{
WebView *w = currentWebTab()->view();
- urlBar()->setUrl(KUrl(""));
- switch(ReKonfig::newTabsBehaviour())
+ switch (ReKonfig::newTabsBehaviour())
{
case 0: // new tab page
case 1: // blank page
- w->load( KUrl("about:home") );
+ w->load(KUrl("about:home"));
+ urlBar()->setFocus();
break;
case 2: // homepage
- w->load( KUrl(ReKonfig::homePage()) );
+ w->load(KUrl(ReKonfig::homePage()));
break;
default:
break;
}
- urlBar()->setFocus();
return;
}
@@ -480,50 +476,51 @@ void MainView::closeTab(int index)
if (index < 0 || index >= count())
return;
- bool hasFocus = false;
WebTab *tab = webTab(index);
- if (tab)
+ if (!tab)
+ return;
+
+ if (tab->view()->isModified())
{
- if (tab->view()->isModified())
- {
- int risp = KMessageBox::questionYesNo(this,
- i18n("This tab contains changes that have not been submitted.\n"
- "Closing the tab will discard these changes.\n"
- "Do you really want to close this tab?\n"),
- i18n("Closing Modified Tab"));
- if (risp == KMessageBox::No)
- return;
- }
- hasFocus = tab->hasFocus();
+ int risp = KMessageBox::warningContinueCancel(this,
+ i18n("This tab contains changes that have not been submitted.\n"
+ "Closing the tab will discard these changes.\n"
+ "Do you really want to close this tab?\n"),
+ i18n("Closing Modified Tab"), KGuiItem(i18n("Close &Tab"), "tab-close"), KStandardGuiItem::cancel());
+ if (risp != KMessageBox::Continue)
+ return;
+ }
- //store close tab except homepage
- if (!tab->url().prettyUrl().startsWith( QLatin1String("about:") ) && !tab->url().isEmpty())
- {
- QString title = tab->view()->title();
- QString url = tab->url().prettyUrl();
- HistoryItem item(url, QDateTime::currentDateTime(), title);
- m_recentlyClosedTabs.removeAll(item);
- m_recentlyClosedTabs.prepend(item);
- }
+ // store close tab except homepage
+ if (!tab->url().prettyUrl().startsWith(QL1S("about:")) && !tab->url().isEmpty())
+ {
+ QString title = tab->view()->title();
+ QString url = tab->url().prettyUrl();
+ HistoryItem item(url, QDateTime::currentDateTime(), title);
+ m_recentlyClosedTabs.removeAll(item);
+ m_recentlyClosedTabs.prepend(item);
+ }
- removeTab(index);
- updateTabBar(); // UI operation: do it ASAP!!
- tab->deleteLater(); // webView is scheduled for deletion.
-
- emit tabsChanged();
+ removeTab(index);
+ updateTabBar(); // UI operation: do it ASAP!!
- if (hasFocus && count() > 0)
- {
- currentWebTab()->setFocus();
- }
+ QWidget *urlbar = _bars->widget(index);
+ _bars->removeWidget(urlbar);
+
+ if (del)
+ {
+ tab->deleteLater(); // tab is scheduled for deletion.
+ urlbar->deleteLater();
}
+
+ emit tabsChanged();
}
void MainView::webViewLoadStarted()
{
- WebView *view = qobject_cast<WebView *>( sender() );
- int index = indexOf( view->parentWidget() );
+ WebView *view = qobject_cast<WebView *>(sender());
+ int index = indexOf(view->parentWidget());
if (-1 != index)
{
QLabel *label = animatedLoading(index, true);
@@ -533,21 +530,20 @@ void MainView::webViewLoadStarted()
}
}
- emit browserTabLoading(true);
-
if (index != currentIndex())
return;
+ emit browserTabLoading(true);
emit showStatusBarMessage(i18n("Loading..."));
}
void MainView::webViewLoadFinished(bool ok)
{
- WebView *view = qobject_cast<WebView *>( sender() );
+ WebView *view = qobject_cast<WebView *>(sender());
int index = -1;
- if(view)
- index = indexOf( view->parentWidget() );
+ if (view)
+ index = indexOf(view->parentWidget());
if (-1 != index)
{
@@ -565,28 +561,26 @@ void MainView::webViewLoadFinished(bool ok)
{
return;
}
-
+
if (ok)
emit showStatusBarMessage(i18n("Done"), Rekonq::Success);
- else
- emit showStatusBarMessage(i18n("Failed to load"), Rekonq::Error);
+// else
+// emit showStatusBarMessage(i18n("Failed to load"), Rekonq::Error);
}
void MainView::webViewIconChanged()
{
- WebView *view = qobject_cast<WebView *>( sender() );
- int index = indexOf( view->parentWidget() );
+ WebView *view = qobject_cast<WebView *>(sender());
+ int index = indexOf(view->parentWidget());
if (-1 != index)
{
- QIcon icon = Application::icon(view->url());
+ KIcon icon = Application::icon(view->url());
QLabel *label = animatedLoading(index, false);
QMovie *movie = label->movie();
delete movie;
label->setMovie(0);
label->setPixmap(icon.pixmap(16, 16));
-
- urlBar()->updateUrl();
}
}
@@ -598,15 +592,15 @@ void MainView::webViewTitleChanged(const QString &title)
{
tabTitle = i18n("(Untitled)");
}
- WebView *view = qobject_cast<WebView *>( sender() );
- int index = indexOf( view->parentWidget() );
+ WebView *view = qobject_cast<WebView *>(sender());
+ int index = indexOf(view->parentWidget());
if (-1 != index)
{
setTabText(index, tabTitle);
}
if (currentIndex() == index)
{
- emit setCurrentTitle(tabTitle);
+ emit currentTitle(tabTitle);
}
Application::historyManager()->updateHistoryEntry(view->url(), tabTitle);
}
@@ -614,11 +608,11 @@ void MainView::webViewTitleChanged(const QString &title)
void MainView::webViewUrlChanged(const QUrl &url)
{
- WebView *view = qobject_cast<WebView *>( sender() );
- int index = indexOf( view->parentWidget() );
+ WebView *view = qobject_cast<WebView *>(sender());
+ int index = indexOf(view->parentWidget());
if (-1 != index)
{
- m_tabBar->setTabData(index, url);
+ tabBar()->setTabData(index, url);
}
emit tabsChanged();
}
@@ -647,7 +641,7 @@ QLabel *MainView::animatedLoading(int index, bool addMovie)
if (index == -1)
return 0;
- QLabel *label = qobject_cast<QLabel*>(m_tabBar->tabButton(index, QTabBar::LeftSide));
+ QLabel *label = qobject_cast<QLabel* >(tabBar()->tabButton(index, QTabBar::LeftSide));
if (!label)
{
label = new QLabel(this);
@@ -659,8 +653,8 @@ QLabel *MainView::animatedLoading(int index, bool addMovie)
label->setMovie(movie);
movie->start();
}
- m_tabBar->setTabButton(index, QTabBar::LeftSide, 0);
- m_tabBar->setTabButton(index, QTabBar::LeftSide, label);
+ tabBar()->setTabButton(index, QTabBar::LeftSide, 0);
+ tabBar()->setTabButton(index, QTabBar::LeftSide, label);
return label;
}
@@ -685,8 +679,32 @@ void MainView::detachTab(int index)
if (index < 0 || index >= count())
return;
- KUrl url = webTab(index)->view()->url();
- closeTab(index);
-
- Application::instance()->loadUrl(url, Rekonq::NewWindow);
+ WebTab *tab = webTab(index);
+ KUrl u = tab->url();
+ kDebug() << u;
+ if (u.scheme() == QL1S("about"))
+ {
+ closeTab(index);
+ Application::instance()->loadUrl(u, Rekonq::NewWindow);
+ }
+ else
+ {
+ QString label = tab->view()->title();
+ QWidget *bar = _bars->widget(index);
+ closeTab(index, false);
+
+ MainWindow *w = Application::instance()->newMainWindow(false);
+ w->mainView()->addTab(tab, Application::icon(u), label);
+ QStackedWidget *stack = qobject_cast<QStackedWidget *>(w->mainView()->urlBarWidget());
+ stack->insertWidget(0, bar);
+ w->mainView()->updateTabBar();
+ }
+}
+
+
+void MainView::movedTab(int from, int to)
+{
+ QWidget *bar = _bars->widget(from);
+ _bars->removeWidget(bar);
+ _bars->insertWidget(to, bar);
}
diff --git a/src/mainview.h b/src/mainview.h
index 908389b1..eb5b3e02 100644
--- a/src/mainview.h
+++ b/src/mainview.h
@@ -2,9 +2,10 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +13,9 @@
* 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
+* 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
@@ -30,8 +31,10 @@
#define MAINVIEW_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Local Includes
-#include "rekonqprivate_export.h"
#include "webview.h"
#include "webpage.h"
#include "application.h"
@@ -43,6 +46,7 @@
// Qt Includes
#include <QtGui/QToolButton>
+#include <QStackedWidget>
// Forward Declarations
class QUrl;
@@ -55,7 +59,7 @@ class UrlBar;
/**
- * This class represent rekonq Main View.
+ * This class represent rekonq Main View.
* It contains all WebViews and the url bar.
*
*/
@@ -68,8 +72,7 @@ public:
MainView(MainWindow *parent);
~MainView();
-public:
-
+ QWidget *urlBarWidget() const;
UrlBar *urlBar() const;
WebTab *webTab(int index) const;
@@ -82,16 +85,15 @@ public:
*
*/
void updateTabBar();
-
+
void setTabBarHidden(bool hide);
-
+
QToolButton *addTabButton() const;
- void clear();
/**
* This function creates a new empty tab
* with a webview inside
- * @param focused decide if you wannna give focus
+ * @param focused decide if you wannna give focus
* (or not) to this new tab (default true)
* @param nearParent decide if you wanna create new tab near current or not
* @return the webview embedded in the new tab
@@ -106,7 +108,7 @@ signals:
void lastTabClosed();
// current tab signals
- void setCurrentTitle(const QString &url);
+ void currentTitle(const QString &url);
void showStatusBarMessage(const QString &message, Rekonq::Notify status = Rekonq::Info);
void linkHovered(const QString &link);
void browserTabLoading(bool);
@@ -123,14 +125,14 @@ public slots:
void newTab();
void cloneTab(int index = -1);
- void closeTab(int index = -1);
+ void closeTab(int index = -1, bool del = true);
void closeOtherTabs(int index);
void reloadTab(int index = -1);
void reloadAllTabs();
void nextTab();
void previousTab();
void detachTab(int index = -1);
-
+
// WEB slot actions
void webReload();
void webStop();
@@ -147,7 +149,7 @@ private slots:
void windowCloseRequested();
void postLaunch();
-
+ void movedTab(int, int);
protected:
virtual void resizeEvent(QResizeEvent *event);
@@ -167,8 +169,10 @@ private:
*/
QLabel *animatedLoading(int index, bool addMovie);
- UrlBar *m_urlBar;
- TabBar *m_tabBar;
+
+// --------------------------------------------------------------------------
+
+ QStackedWidget *_bars;
QString m_loadingGitPath;
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index d3c14d85..28c7dff1 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -2,9 +2,10 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -51,7 +52,6 @@
#include "ui_cleardata.h"
// KDE Includes
-#include <KUrl>
#include <KShortcut>
#include <KStandardAction>
#include <KAction>
@@ -64,23 +64,21 @@
#include <KTemporaryFile>
#include <KPassivePopup>
#include <KMenuBar>
-#include <KToolBar>
#include <KJobUiDelegate>
#include <kdeprintdialog.h>
#include <KToggleAction>
#include <KStandardDirs>
#include <KActionCategory>
+#include <KProcess>
// Qt Includes
#include <QtCore/QTimer>
#include <QtCore/QRect>
#include <QtCore/QSize>
#include <QtCore/QList>
-#include <QtCore/QPointer>
+#include <QtCore/QWeakPointer>
-#include <QtGui/QWidget>
#include <QtGui/QVBoxLayout>
-#include <QtGui/QAction>
#include <QtGui/QFont>
#include <QtGui/QDesktopWidget>
#include <QtGui/QPrinter>
@@ -95,25 +93,23 @@
MainWindow::MainWindow()
- : KMainWindow()
- , m_view( new MainView(this) )
- , m_findBar( new FindBar(this) )
- , m_historyPanel(0)
- , m_bookmarksPanel(0)
- , m_webInspectorPanel(0)
- , m_historyBackMenu(0)
- , m_mainBar( new KToolBar( QString("MainToolBar"), this, Qt::TopToolBarArea, true, false, false) )
- , m_bmBar( new KToolBar( QString("BookmarkToolBar"), this, Qt::TopToolBarArea, true, false, false) )
- , m_popup( new KPassivePopup(this) )
- , m_hidePopup( new QTimer(this) )
- , m_ac( new KActionCollection(this) )
+ : KMainWindow()
+ , m_view(new MainView(this))
+ , m_findBar(new FindBar(this))
+ , m_historyPanel(0)
+ , m_bookmarksPanel(0)
+ , m_webInspectorPanel(0)
+ , m_historyBackMenu(0)
+ , m_encodingMenu(new KMenu(this))
+ , m_mainBar(new KToolBar(QString("MainToolBar"), this, Qt::TopToolBarArea, true, true, true))
+ , m_bmBar(new KToolBar(QString("BookmarkToolBar"), this, Qt::TopToolBarArea, true, false, true))
+ , m_popup(new KPassivePopup(this))
+ , m_hidePopup(new QTimer(this))
+ , m_ac(new KActionCollection(this))
{
// enable window size "auto-save"
setAutoSaveSettings();
- // updating rekonq configuration
- updateConfiguration();
-
// creating a centralWidget containing panel, m_view and the hidden findbar
QWidget *centralWidget = new QWidget;
centralWidget->setContentsMargins(0, 0, 0, 0);
@@ -148,7 +144,7 @@ MainWindow::MainWindow()
// setting popup notification
m_popup->setAutoDelete(false);
- connect(Application::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)), m_popup, SLOT(hide()));
+ connect(Application::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)), m_popup, SLOT(hide()));
m_popup->setFrameShape(QFrame::NoFrame);
m_popup->setLineWidth(0);
connect(m_hidePopup, SIGNAL(timeout()), m_popup, SLOT(hide()));
@@ -159,36 +155,49 @@ MainWindow::MainWindow()
MainWindow::~MainWindow()
{
+ Application::bookmarkProvider()->removeToolBar(m_bmBar);
Application::instance()->removeMainWindow(this);
delete m_popup;
+ delete m_encodingMenu;
}
void MainWindow::setupToolbars()
{
// ============ Main ToolBar ================================
- m_mainBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
-
- m_mainBar->addAction( actionByName(KStandardAction::name(KStandardAction::Back)) );
- m_mainBar->addAction( actionByName(KStandardAction::name(KStandardAction::Forward)) );
+ m_mainBar->addAction(actionByName(KStandardAction::name(KStandardAction::Back)));
+ m_mainBar->addAction(actionByName(KStandardAction::name(KStandardAction::Forward)));
m_mainBar->addSeparator();
- m_mainBar->addAction( actionByName("stop_reload") );
- m_mainBar->addAction( actionByName(KStandardAction::name(KStandardAction::Home)) );
+ m_mainBar->addAction(actionByName("stop_reload"));
+ m_mainBar->addAction(actionByName(KStandardAction::name(KStandardAction::Home)));
// location bar
KAction *urlBarAction = new KAction(this);
- urlBarAction->setDefaultWidget(m_view->urlBar());
- m_mainBar->addAction( urlBarAction );
+ urlBarAction->setDefaultWidget(m_view->urlBarWidget());
+ m_mainBar->addAction(urlBarAction);
- m_mainBar->addAction( actionByName("bookmarksActionMenu") );
- m_mainBar->addAction( actionByName("rekonq_tools") );
+ m_mainBar->addAction(actionByName("bookmarksActionMenu"));
+ m_mainBar->addAction(actionByName("rekonq_tools"));
+
+ m_mainBar->show(); // this just to fix reopening rekonq after fullscreen close
// =========== Bookmarks ToolBar ================================
- m_bmBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
m_bmBar->setAcceptDrops(true);
- m_bmBar->setContextMenuPolicy(Qt::CustomContextMenu);
- m_bmBar->setIconDimensions(16);
Application::bookmarkProvider()->setupBookmarkBar(m_bmBar);
+
+ if (ReKonfig::firstExecution())
+ {
+ m_mainBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
+
+ m_bmBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ m_bmBar->setIconDimensions(16);
+ m_bmBar->hide();
+
+ KToolBar::setToolBarsEditable(false);
+ KToolBar::setToolBarsLocked(true);
+
+ ReKonfig::setFirstExecution(false);
+ }
}
@@ -196,13 +205,13 @@ void MainWindow::postLaunch()
{
// KActionCollection read settings
m_ac->readSettings();
-
+
// notification system
connect(m_view, SIGNAL(showStatusBarMessage(const QString&, Rekonq::Notify)), this, SLOT(notifyMessage(const QString&, Rekonq::Notify)));
connect(m_view, SIGNAL(linkHovered(const QString&)), this, SLOT(notifyMessage(const QString&)));
// --------- connect signals and slots
- connect(m_view, SIGNAL(setCurrentTitle(const QString &)), this, SLOT(updateWindowTitle(const QString &)));
+ connect(m_view, SIGNAL(currentTitle(const QString &)), this, SLOT(updateWindowTitle(const QString &)));
connect(m_view, SIGNAL(printRequested(QWebFrame *)), this, SLOT(printRequested(QWebFrame *)));
// (shift +) ctrl + tab switching
@@ -251,8 +260,8 @@ void MainWindow::setupActions()
// new window action
a = new KAction(KIcon("window-new"), i18n("&New Window"), this);
a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_N));
- actionCollection()->addAction(QLatin1String("new_window"), a);
- connect(a, SIGNAL(triggered(bool)), Application::instance(), SLOT(newMainWindow()));
+ actionCollection()->addAction(QL1S("new_window"), a);
+ connect(a, SIGNAL(triggered(bool)), Application::instance(), SLOT(newWindow()));
// Standard Actions
KStandardAction::open(this, SLOT(fileOpen()), actionCollection());
@@ -261,142 +270,157 @@ void MainWindow::setupActions()
KStandardAction::quit(this , SLOT(close()), actionCollection());
a = KStandardAction::find(m_findBar, SLOT(show()), actionCollection());
- QList<QKeySequence> shortcutFindList;
- shortcutFindList << KStandardShortcut::find() << QKeySequence( Qt::Key_Slash );
- a->setShortcuts( shortcutFindList );
+ KShortcut findShortcut = KStandardShortcut::find();
+ findShortcut.setAlternate(Qt::Key_Slash);
+ a->setShortcut(findShortcut);
KStandardAction::findNext(this, SLOT(findNext()) , actionCollection());
KStandardAction::findPrev(this, SLOT(findPrevious()) , actionCollection());
-
+
a = KStandardAction::fullScreen(this, SLOT(viewFullScreen(bool)), this, actionCollection());
- QList<QKeySequence> shortcutFullScreenList;
- shortcutFullScreenList << KStandardShortcut::fullScreen() << QKeySequence( Qt::Key_F11 );
- a->setShortcuts( shortcutFullScreenList );
+ KShortcut fullScreenShortcut = KStandardShortcut::fullScreen();
+ fullScreenShortcut.setAlternate(Qt::Key_F11);
+ a->setShortcut(fullScreenShortcut);
- KStandardAction::home(this, SLOT(homePage()), actionCollection());
+ a = actionCollection()->addAction(KStandardAction::Home);
+ connect(a, SIGNAL(triggered(Qt::MouseButtons, Qt::KeyboardModifiers)), this, SLOT(homePage(Qt::MouseButtons, Qt::KeyboardModifiers)));
KStandardAction::preferences(this, SLOT(preferences()), actionCollection());
a = KStandardAction::redisplay(m_view, SLOT(webReload()), actionCollection());
a->setText(i18n("Reload"));
+ KShortcut reloadShortcut = KStandardShortcut::reload();
+ reloadShortcut.setAlternate(Qt::CTRL + Qt::Key_R);
+ a->setShortcut(reloadShortcut);
a = new KAction(KIcon("process-stop"), i18n("&Stop"), this);
a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_Period));
- actionCollection()->addAction(QLatin1String("stop"), a);
+ actionCollection()->addAction(QL1S("stop"), a);
connect(a, SIGNAL(triggered(bool)), m_view, SLOT(webStop()));
// stop reload Action
m_stopReloadAction = new KAction(this);
- actionCollection()->addAction(QLatin1String("stop_reload") , m_stopReloadAction);
+ actionCollection()->addAction(QL1S("stop_reload") , m_stopReloadAction);
m_stopReloadAction->setShortcutConfigurable(false);
connect(m_view, SIGNAL(browserTabLoading(bool)), this, SLOT(browserLoading(bool)));
browserLoading(false); //first init for blank start page
a = new KAction(i18n("Open Location"), this);
a->setShortcut(Qt::CTRL + Qt::Key_L);
- actionCollection()->addAction(QLatin1String("open_location"), a);
+ actionCollection()->addAction(QL1S("open_location"), a);
connect(a, SIGNAL(triggered(bool)) , this, SLOT(openLocation()));
// ============================= Zoom Actions ===================================
- a = new KAction(KIcon("zoom-in"), i18n("&Enlarge Font"), this);
+ a = new KAction(KIcon("zoom-in"), i18n("&Zoom In"), this);
a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_Plus));
- actionCollection()->addAction(QLatin1String("bigger_font"), a);
- connect(a, SIGNAL(triggered(bool)), this, SLOT(viewTextBigger()));
+ actionCollection()->addAction(QL1S("zoom_in"), a);
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(zoomIn()));
- a = new KAction(KIcon("zoom-original"), i18n("&Normal Font"), this);
+ a = new KAction(KIcon("zoom-original"), i18n("&Normal Zoom"), this);
a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_0));
- actionCollection()->addAction(QLatin1String("normal_font"), a);
- connect(a, SIGNAL(triggered(bool)), this, SLOT(viewTextNormal()));
+ actionCollection()->addAction(QL1S("zoom_normal"), a);
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(zoomNormal()));
- a = new KAction(KIcon("zoom-out"), i18n("&Shrink Font"), this);
+ a = new KAction(KIcon("zoom-out"), i18n("&Zoom Out"), this);
a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_Minus));
- actionCollection()->addAction(QLatin1String("smaller_font"), a);
- connect(a, SIGNAL(triggered(bool)), this, SLOT(viewTextSmaller()));
+ actionCollection()->addAction(QL1S("zoom_out"), a);
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(zoomOut()));
// =============================== Tools Actions =================================
a = new KAction(i18n("Page S&ource"), this);
a->setIcon(KIcon("application-xhtml+xml"));
- actionCollection()->addAction(QLatin1String("page_source"), a);
+ actionCollection()->addAction(QL1S("page_source"), a);
connect(a, SIGNAL(triggered(bool)), this, SLOT(viewPageSource()));
a = new KAction(KIcon("view-media-artist"), i18n("Private &Browsing"), this);
a->setCheckable(true);
- actionCollection()->addAction(QLatin1String("private_browsing"), a);
+ actionCollection()->addAction(QL1S("private_browsing"), a);
connect(a, SIGNAL(triggered(bool)), this, SLOT(privateBrowsing(bool)));
a = new KAction(KIcon("edit-clear"), i18n("Clear Private Data..."), this);
- actionCollection()->addAction(QLatin1String("clear_private_data"), a);
+ actionCollection()->addAction(QL1S("clear_private_data"), a);
connect(a, SIGNAL(triggered(bool)), this, SLOT(clearPrivateData()));
// ========================= History related actions ==============================
- a = KStandardAction::back(this, SLOT(openPrevious()) , actionCollection());
+ a = actionCollection()->addAction(KStandardAction::Back);
+ connect(a, SIGNAL(triggered(Qt::MouseButtons, Qt::KeyboardModifiers)), this, SLOT(openPrevious(Qt::MouseButtons, Qt::KeyboardModifiers)));
m_historyBackMenu = new KMenu(this);
a->setMenu(m_historyBackMenu);
connect(m_historyBackMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowBackMenu()));
connect(m_historyBackMenu, SIGNAL(triggered(QAction *)), this, SLOT(openActionUrl(QAction *)));
- KStandardAction::forward(this, SLOT(openNext()) , actionCollection());
+ a = actionCollection()->addAction(KStandardAction::Forward);
+ connect(a, SIGNAL(triggered(Qt::MouseButtons, Qt::KeyboardModifiers)), this, SLOT(openNext(Qt::MouseButtons, Qt::KeyboardModifiers)));
// ============================== General Tab Actions ====================================
a = new KAction(KIcon("tab-new"), i18n("New &Tab"), this);
a->setShortcut(KShortcut(Qt::CTRL + Qt::Key_T));
- actionCollection()->addAction(QLatin1String("new_tab"), a);
+ actionCollection()->addAction(QL1S("new_tab"), a);
connect(a, SIGNAL(triggered(bool)), m_view, SLOT(newTab()));
a = new KAction(KIcon("view-refresh"), i18n("Reload All Tabs"), this);
- actionCollection()->addAction( QLatin1String("reload_all_tabs"), a);
- connect(a, SIGNAL(triggered(bool)), m_view, SLOT(reloadAllTabs()) );
+ actionCollection()->addAction(QL1S("reload_all_tabs"), a);
+ connect(a, SIGNAL(triggered(bool)), m_view, SLOT(reloadAllTabs()));
a = new KAction(i18n("Show Next Tab"), this);
a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabPrev() : KStandardShortcut::tabNext());
- actionCollection()->addAction(QLatin1String("show_next_tab"), a);
+ actionCollection()->addAction(QL1S("show_next_tab"), a);
connect(a, SIGNAL(triggered(bool)), m_view, SLOT(nextTab()));
a = new KAction(i18n("Show Previous Tab"), this);
a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabNext() : KStandardShortcut::tabPrev());
- actionCollection()->addAction(QLatin1String("show_prev_tab"), a);
+ actionCollection()->addAction(QL1S("show_prev_tab"), a);
connect(a, SIGNAL(triggered(bool)), m_view, SLOT(previousTab()));
// ============================== Indexed Tab Actions ====================================
a = new KAction(KIcon("tab-close"), i18n("&Close Tab"), this);
- actionCollection()->addAction(QLatin1String("close_tab"), a);
+ actionCollection()->addAction(QL1S("close_tab"), a);
connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(closeTab()));
a = new KAction(KIcon("tab-duplicate"), i18n("Clone Tab"), this);
- actionCollection()->addAction(QLatin1String("clone_tab"), a);
- connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(cloneTab()) );
+ actionCollection()->addAction(QL1S("clone_tab"), a);
+ connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(cloneTab()));
a = new KAction(KIcon("tab-close-other"), i18n("Close &Other Tabs"), this);
- actionCollection()->addAction( QLatin1String("close_other_tabs"), a);
- connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(closeOtherTabs()) );
+ actionCollection()->addAction(QL1S("close_other_tabs"), a);
+ connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(closeOtherTabs()));
a = new KAction(KIcon("view-refresh"), i18n("Reload Tab"), this);
- actionCollection()->addAction( QLatin1String("reload_tab"), a);
- connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(reloadTab()) );
+ actionCollection()->addAction(QL1S("reload_tab"), a);
+ connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(reloadTab()));
a = new KAction(KIcon("tab-detach"), i18n("Detach Tab"), this);
- actionCollection()->addAction( QLatin1String("detach_tab"), a);
- connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(detachTab()) );
-
+ actionCollection()->addAction(QL1S("detach_tab"), a);
+ connect(a, SIGNAL(triggered(bool)), m_view->tabBar(), SLOT(detachTab()));
+
+
// ----------------------- Bookmarks ToolBar Action --------------------------------------
QAction *qa;
-
+
qa = m_mainBar->toggleViewAction();
- qa->setText( i18n("Main Toolbar") );
- qa->setIcon( KIcon("bookmark-toolbar") );
- actionCollection()->addAction(QLatin1String("main_bar"), qa);
-
+ qa->setText(i18n("Main Toolbar"));
+ qa->setIcon(KIcon("bookmark-toolbar"));
+ actionCollection()->addAction(QL1S("main_bar"), qa);
+
qa = m_bmBar->toggleViewAction();
- qa->setText( i18n("Bookmarks Toolbar") );
- qa->setIcon( KIcon("bookmark-toolbar") );
- actionCollection()->addAction(QLatin1String("bm_bar"), qa);
+ qa->setText(i18n("Bookmarks Toolbar"));
+ qa->setIcon(KIcon("bookmark-toolbar"));
+ actionCollection()->addAction(QL1S("bm_bar"), qa);
// Bookmark Menu
KActionMenu *bmMenu = Application::bookmarkProvider()->bookmarkActionMenu(this);
bmMenu->setIcon(KIcon("bookmarks"));
bmMenu->setDelayed(false);
- actionCollection()->addAction(QLatin1String("bookmarksActionMenu"), bmMenu);
+ actionCollection()->addAction(QL1S("bookmarksActionMenu"), bmMenu);
+
+
+ // ---------------- Encodings -----------------------------------
+ a = new KAction(KIcon("character-set"), i18n("Set Encoding"), this);
+ actionCollection()->addAction(QL1S("encodings"), a);
+ a->setMenu(m_encodingMenu);
+ connect(m_encodingMenu, SIGNAL(aboutToShow()), this, SLOT(populateEncodingMenu()));
+ connect(m_encodingMenu, SIGNAL(triggered(QAction *)), this, SLOT(setEncoding(QAction *)));
}
@@ -410,162 +434,121 @@ void MainWindow::setupTools()
toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::Print)));
toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::Find)));
- KActionMenu *fontMenu = new KActionMenu(KIcon("page-zoom"), i18n("Zoom"), this);
- fontMenu->addAction(actionByName(QLatin1String("smaller_font")));
- fontMenu->addAction(actionByName(QLatin1String("normal_font")));
- fontMenu->addAction(actionByName(QLatin1String("bigger_font")));
- toolsMenu->addAction(fontMenu);
+ // setup zoom widget
+ QWidget *zoomWidget = new QWidget(this);
+
+ QToolButton *zoomOut = new QToolButton(zoomWidget);
+ zoomOut->setDefaultAction(actionByName(QL1S("zoom_out")));
+ zoomOut->setAutoRaise(true);
+
+ m_zoomSlider = new QSlider(Qt::Horizontal, zoomWidget);
+ m_zoomSlider->setTracking(true);
+ m_zoomSlider->setRange(1, 19); // divide by 10 to obtain a qreal for zoomFactor()
+ m_zoomSlider->setValue(10);
+ m_zoomSlider->setPageStep(3);
+ connect(m_zoomSlider, SIGNAL(valueChanged(int)), this, SLOT(setZoomFactor(int)));
+
+ QToolButton *zoomIn = new QToolButton(zoomWidget);
+ zoomIn->setDefaultAction(actionByName(QL1S("zoom_in")));
+ zoomIn->setAutoRaise(true);
+
+ QToolButton *zoomNormal = new QToolButton(zoomWidget);
+ zoomNormal->setDefaultAction(actionByName(QL1S("zoom_normal")));
+ zoomNormal->setAutoRaise(true);
+
+ QHBoxLayout* zoomWidgetLayout = new QHBoxLayout(zoomWidget);
+ zoomWidgetLayout->setSpacing(0);
+ zoomWidgetLayout->setMargin(0);
+ zoomWidgetLayout->addWidget(zoomOut);
+ zoomWidgetLayout->addWidget(m_zoomSlider);
+ zoomWidgetLayout->addWidget(zoomIn);
+ zoomWidgetLayout->addWidget(zoomNormal);
+
+ QWidgetAction *zoomAction = new QWidgetAction(this);
+ zoomAction->setDefaultWidget(zoomWidget);
+ toolsMenu->addAction(zoomAction);
toolsMenu->addSeparator();
- toolsMenu->addAction(actionByName(QLatin1String("private_browsing")));
- toolsMenu->addAction(actionByName(QLatin1String("clear_private_data")));
+ toolsMenu->addAction(actionByName(QL1S("private_browsing")));
+ toolsMenu->addAction(actionByName(QL1S("clear_private_data")));
toolsMenu->addSeparator();
KActionMenu *webMenu = new KActionMenu(KIcon("applications-development-web"), i18n("Web Development"), this);
- webMenu->addAction(actionByName(QLatin1String("web_inspector")));
- webMenu->addAction(actionByName(QLatin1String("page_source")));
+ webMenu->addAction(actionByName(QL1S("web_inspector")));
+ webMenu->addAction(actionByName(QL1S("page_source")));
toolsMenu->addAction(webMenu);
toolsMenu->addSeparator();
- toolsMenu->addAction(actionByName(QLatin1String("bm_bar")));
- toolsMenu->addAction(actionByName(QLatin1String("show_history_panel")));
- toolsMenu->addAction(actionByName(QLatin1String("show_bookmarks_panel")));
+ toolsMenu->addAction(actionByName(QL1S("bm_bar")));
+ toolsMenu->addAction(actionByName(QL1S("show_history_panel")));
+ toolsMenu->addAction(actionByName(QL1S("show_bookmarks_panel")));
toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::FullScreen)));
toolsMenu->addSeparator();
+ toolsMenu->addAction(actionByName(QL1S("encodings")));
+
helpMenu()->setIcon(KIcon("help-browser"));
toolsMenu->addAction(helpMenu()->menuAction());
toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::Preferences)));
// adding rekonq_tools to rekonq actionCollection
- actionCollection()->addAction(QLatin1String("rekonq_tools"), toolsMenu);
+ actionCollection()->addAction(QL1S("rekonq_tools"), toolsMenu);
}
void MainWindow::setupPanels()
{
KAction* a;
-
+
// STEP 1
// Setup history panel
m_historyPanel = new HistoryPanel(i18n("History Panel"), this);
- connect(m_historyPanel, SIGNAL(openUrl(const KUrl&)), Application::instance(), SLOT(loadUrl(const KUrl&)));
+ connect(m_historyPanel, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)), Application::instance(), SLOT(loadUrl(const KUrl&, const Rekonq::OpenType &)));
+ connect(m_historyPanel, SIGNAL(itemHovered(QString)), this, SLOT(notifyMessage(QString)));
connect(m_historyPanel, SIGNAL(destroyed()), Application::instance(), SLOT(saveConfiguration()));
addDockWidget(Qt::LeftDockWidgetArea, m_historyPanel);
// setup history panel action
a = (KAction *) m_historyPanel->toggleViewAction();
- a->setShortcut( QKeySequence(Qt::CTRL + Qt::Key_H) );
+ a->setShortcut(KShortcut(Qt::CTRL + Qt::Key_H));
a->setIcon(KIcon("view-history"));
- actionCollection()->addAction(QLatin1String("show_history_panel"), a);
+ actionCollection()->addAction(QL1S("show_history_panel"), a);
// STEP 2
// Setup bookmarks panel
m_bookmarksPanel = new BookmarksPanel(i18n("Bookmarks Panel"), this);
- connect(m_bookmarksPanel, SIGNAL(openUrl(const KUrl&)), Application::instance(), SLOT(loadUrl(const KUrl&)));
+ connect(m_bookmarksPanel, SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType &)), Application::instance(), SLOT(loadUrl(const KUrl&, const Rekonq::OpenType &)));
+ connect(m_bookmarksPanel, SIGNAL(itemHovered(QString)), this, SLOT(notifyMessage(QString)));
connect(m_bookmarksPanel, SIGNAL(destroyed()), Application::instance(), SLOT(saveConfiguration()));
addDockWidget(Qt::LeftDockWidgetArea, m_bookmarksPanel);
// setup bookmarks panel action
a = (KAction *) m_bookmarksPanel->toggleViewAction();
- a->setShortcut( QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_B) );
+ a->setShortcut(KShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_B));
a->setIcon(KIcon("bookmarks-organize"));
- actionCollection()->addAction(QLatin1String("show_bookmarks_panel"), a);
+ actionCollection()->addAction(QL1S("show_bookmarks_panel"), a);
// STEP 3
// Setup webinspector panel
m_webInspectorPanel = new WebInspectorPanel(i18n("Web Inspector"), this);
connect(mainView(), SIGNAL(currentChanged(int)), m_webInspectorPanel, SLOT(changeCurrentPage()));
-
+
a = new KAction(KIcon("tools-report-bug"), i18n("Web &Inspector"), this);
a->setCheckable(true);
- actionCollection()->addAction(QLatin1String("web_inspector"), a);
+ actionCollection()->addAction(QL1S("web_inspector"), a);
connect(a, SIGNAL(triggered(bool)), m_webInspectorPanel, SLOT(toggle(bool)));
-
+
addDockWidget(Qt::BottomDockWidgetArea, m_webInspectorPanel);
m_webInspectorPanel->hide();
}
-
-void MainWindow::updateConfiguration()
-{
- // ============== General ==================
- m_view->updateTabBar();
-
- // ============== Tabs ==================
- if (ReKonfig::closeTabSelectPrevious())
- m_view->tabBar()->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
- else
- m_view->tabBar()->setSelectionBehaviorOnRemove(QTabBar::SelectRightTab);
-
- // =========== Fonts ==============
- QWebSettings *defaultSettings = QWebSettings::globalSettings();
-
- int fnSize = ReKonfig::fontSize();
- int minFnSize = ReKonfig::minFontSize();
-
- QFont standardFont = ReKonfig::standardFont();
- defaultSettings->setFontFamily(QWebSettings::StandardFont, standardFont.family());
- defaultSettings->setFontSize(QWebSettings::DefaultFontSize, fnSize);
- defaultSettings->setFontSize(QWebSettings::MinimumFontSize, minFnSize);
-
- QFont fixedFont = ReKonfig::fixedFont();
- defaultSettings->setFontFamily(QWebSettings::FixedFont, fixedFont.family());
- defaultSettings->setFontSize(QWebSettings::DefaultFixedFontSize, fnSize);
-
- // ================ WebKit ============================
- defaultSettings->setAttribute(QWebSettings::AutoLoadImages, ReKonfig::autoLoadImages());
- defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, ReKonfig::javascriptEnabled());
- defaultSettings->setAttribute(QWebSettings::JavaEnabled, ReKonfig::javaEnabled());
- defaultSettings->setAttribute(QWebSettings::JavascriptCanOpenWindows, ReKonfig::javascriptCanOpenWindows());
- defaultSettings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, ReKonfig::javascriptCanAccessClipboard());
- defaultSettings->setAttribute(QWebSettings::LinksIncludedInFocusChain, ReKonfig::linksIncludedInFocusChain());
- defaultSettings->setAttribute(QWebSettings::ZoomTextOnly, ReKonfig::zoomTextOnly());
- defaultSettings->setAttribute(QWebSettings::PrintElementBackgrounds, ReKonfig::printElementBackgrounds());
-
- if(ReKonfig::pluginsEnabled() == 2)
- defaultSettings->setAttribute(QWebSettings::PluginsEnabled, false);
- else
- defaultSettings->setAttribute(QWebSettings::PluginsEnabled, true);
-
- // ===== HTML 5 features WebKit support ======
- defaultSettings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, ReKonfig::offlineStorageDatabaseEnabled());
- defaultSettings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, ReKonfig::offlineWebApplicationCacheEnabled());
- defaultSettings->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, ReKonfig::localStorageDatabaseEnabled());
- if(ReKonfig::localStorageDatabaseEnabled())
- {
- QString path = KStandardDirs::locateLocal("cache", QString("WebkitLocalStorage/rekonq"), true);
- path.remove("rekonq");
- QWebSettings::setOfflineStoragePath(path);
- QWebSettings::setOfflineStorageDefaultQuota(50000);
- }
-
- // Applies user defined CSS to all open webpages. If there no longer is a
- // user defined CSS removes it from all open webpages.
- defaultSettings->setUserStyleSheetUrl(ReKonfig::userCSS());
-
- // ====== load Settings on main classes
- Application::historyManager()->loadSettings();
- Application::adblockManager()->loadSettings();
-
- defaultSettings = 0;
-}
-
-
-void MainWindow::updateBrowser()
-{
- updateConfiguration();
- mainView()->reloadAllTabs();
-}
-
-
void MainWindow::openLocation()
{
m_view->urlBar()->selectAll();
@@ -578,7 +561,7 @@ void MainWindow::fileSaveAs()
KUrl srcUrl = currentTab()->url();
QString name = srcUrl.fileName();
- if(name.isNull())
+ if (name.isNull())
{
name = srcUrl.host() + QString(".html");
}
@@ -602,7 +585,7 @@ void MainWindow::preferences()
QPointer<SettingsDialog> s = new SettingsDialog(this);
// keep us informed when the user changes settings
- connect(s, SIGNAL(settingsChanged(const QString&)), this, SLOT(updateBrowser()));
+ connect(s, SIGNAL(settingsChanged(const QString&)), Application::instance(), SLOT(updateConfiguration()));
s->exec();
delete s;
@@ -624,9 +607,9 @@ void MainWindow::updateWindowTitle(const QString &title)
QWebSettings *settings = QWebSettings::globalSettings();
if (title.isEmpty())
{
- if(settings->testAttribute(QWebSettings::PrivateBrowsingEnabled))
+ if (settings->testAttribute(QWebSettings::PrivateBrowsingEnabled))
{
- setWindowTitle("rekonq (" + i18n("Private Browsing") + ")");
+ setWindowTitle(i18nc("Window title when private browsing is activated", "rekonq (Private Browsing)"));
}
else
{
@@ -635,13 +618,13 @@ void MainWindow::updateWindowTitle(const QString &title)
}
else
{
- if(settings->testAttribute(QWebSettings::PrivateBrowsingEnabled))
+ if (settings->testAttribute(QWebSettings::PrivateBrowsingEnabled))
{
- setWindowTitle(title + " - rekonq (" + i18n("Private Browsing") + ")");
+ setWindowTitle(i18nc("window title, %1 = title of the active website", "%1 – rekonq (Private Browsing)", title));
}
else
{
- setWindowTitle(title + " - rekonq");
+ setWindowTitle(i18nc("window title, %1 = title of the active website", "%1 – rekonq", title));
}
}
}
@@ -651,7 +634,7 @@ void MainWindow::fileOpen()
{
QString filePath = KFileDialog::getOpenFileName(KUrl(),
i18n("*.html *.htm *.svg *.png *.gif *.svgz|Web Resources (*.html *.htm *.svg *.png *.gif *.svgz)\n"
- "*.*|All files (*.*)"),
+ "*.*|All files (*.*)"),
this,
i18n("Open Web Resource"));
@@ -668,7 +651,7 @@ void MainWindow::printRequested(QWebFrame *frame)
return;
QWebFrame *printFrame = 0;
- if(frame == 0)
+ if (frame == 0)
{
printFrame = currentTab()->page()->mainFrame();
}
@@ -696,16 +679,15 @@ void MainWindow::privateBrowsing(bool enable)
"<p>When private browsing is turned on,"
" web pages are not added to the history,"
" new cookies are not stored, current cookies cannot be accessed,"
- " site icons will not be stored, the session will not be saved, "
- " and searches are not added to the pop-up menu in the Google search box."
- " Until you close the window, you can still click the Back and Forward buttons"
+ " site icons will not be stored, the session will not be saved."
+ " Until you close the window, you can still click the Back and Forward buttons"
" to return to the web pages you have opened.</p>", title);
- int button = KMessageBox::questionYesNo(this, text, title);
- if (button == KMessageBox::Yes)
+ int button = KMessageBox::warningContinueCancel(this, text, title);
+ if (button == KMessageBox::Continue)
{
settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
- m_view->urlBar()->setBackgroundColor(Qt::lightGray); // palette().color(QPalette::Active, QPalette::Background));
+ m_view->urlBar()->setPrivateMode(true);
}
else
{
@@ -715,10 +697,9 @@ void MainWindow::privateBrowsing(bool enable)
else
{
settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false);
- m_view->urlBar()->setBackgroundColor(palette().color(QPalette::Active, QPalette::Base));
+ m_view->urlBar()->setPrivateMode(false);
m_lastSearch.clear();
- m_view->clear();
m_view->reloadAllTabs();
}
}
@@ -729,57 +710,111 @@ void MainWindow::find(const QString & search)
if (!currentTab())
return;
m_lastSearch = search;
+
+ findNext();
+}
+
+
+void MainWindow::matchCaseUpdate()
+{
+ if (!currentTab())
+ return;
+
+ currentTab()->view()->findText(m_lastSearch, QWebPage::FindBackward);
findNext();
}
void MainWindow::findNext()
{
- if (!currentTab() && m_lastSearch.isEmpty())
+ if (!currentTab())
+ return;
+
+ highlightAll();
+
+ if (m_findBar->isHidden())
+ {
+ QPoint previous_position = currentTab()->view()->page()->currentFrame()->scrollPosition();
+ currentTab()->view()->page()->focusNextPrevChild(true);
+ currentTab()->view()->page()->currentFrame()->setScrollPosition(previous_position);
return;
+ }
+
+ highlightAll();
QWebPage::FindFlags options = QWebPage::FindWrapsAroundDocument;
if (m_findBar->matchCase())
options |= QWebPage::FindCaseSensitively;
- m_findBar->notifyMatch(currentTab()->view()->findText(m_lastSearch, options));
+ bool found = currentTab()->view()->findText(m_lastSearch, options);
+ m_findBar->notifyMatch(found);
+
+ if (!found)
+ {
+ QPoint previous_position = currentTab()->view()->page()->currentFrame()->scrollPosition();
+ currentTab()->view()->page()->focusNextPrevChild(true);
+ currentTab()->view()->page()->currentFrame()->setScrollPosition(previous_position);
+ }
}
void MainWindow::findPrevious()
{
- if (!currentTab() && m_lastSearch.isEmpty())
+ if (!currentTab())
return;
QWebPage::FindFlags options = QWebPage::FindBackward | QWebPage::FindWrapsAroundDocument;
if (m_findBar->matchCase())
options |= QWebPage::FindCaseSensitively;
- m_findBar->notifyMatch(currentTab()->view()->findText(m_lastSearch, options));
+ bool found = currentTab()->view()->findText(m_lastSearch, options);
+ m_findBar->notifyMatch(found);
}
-
-void MainWindow::viewTextBigger()
+void MainWindow::highlightAll()
{
if (!currentTab())
return;
- currentTab()->view()->setTextSizeMultiplier(currentTab()->view()->textSizeMultiplier() + 0.1);
+
+ QWebPage::FindFlags options = QWebPage::HighlightAllOccurrences;
+
+ currentTab()->view()->findText("", options); //Clear an existing highlight
+
+ if (m_findBar->highlightAllState() && !m_findBar->isHidden())
+ {
+ if (m_findBar->matchCase())
+ options |= QWebPage::FindCaseSensitively;
+
+ currentTab()->view()->findText(m_lastSearch, options);
+ }
}
-void MainWindow::viewTextNormal()
+void MainWindow::zoomIn()
{
- if (!currentTab())
- return;
- currentTab()->view()->setTextSizeMultiplier(1.0);
+ m_zoomSlider->setValue(m_zoomSlider->value() + 1);
+}
+
+void MainWindow::zoomNormal()
+{
+ m_zoomSlider->setValue(10);
}
+void MainWindow::zoomOut()
+{
+ m_zoomSlider->setValue(m_zoomSlider->value() - 1);
+}
-void MainWindow::viewTextSmaller()
+void MainWindow::setZoomFactor(int factor)
{
if (!currentTab())
return;
- currentTab()->view()->setTextSizeMultiplier(currentTab()->view()->textSizeMultiplier() - 0.1);
+ currentTab()->view()->setZoomFactor(QVariant(factor).toReal() / 10);
+}
+
+void MainWindow::setZoomSliderFactor(qreal factor)
+{
+ m_zoomSlider->setValue(factor*10);
}
@@ -806,10 +841,10 @@ void MainWindow::setWidgetsVisible(bool makeVisible)
historyPanelFlag = m_historyPanel->isHidden();
bookmarksPanelFlag = m_bookmarksPanel->isHidden();
}
-
- m_bmBar->hide();
+
+ m_bmBar->hide();
m_view->setTabBarHidden(true);
- m_historyPanel->hide();
+ m_historyPanel->hide();
m_bookmarksPanel->hide();
// hide main toolbar
@@ -828,7 +863,7 @@ void MainWindow::setWidgetsVisible(bool makeVisible)
m_historyPanel->show();
if (!bookmarksPanelFlag)
m_bookmarksPanel->show();
- }
+ }
}
@@ -856,13 +891,16 @@ void MainWindow::viewPageSource()
isTempFile = true;
}
}
- KRun::runUrl(url, QLatin1String("text/plain"), this, isTempFile);
+ KRun::runUrl(url, QL1S("text/plain"), this, isTempFile);
}
-void MainWindow::homePage()
+void MainWindow::homePage(Qt::MouseButtons mouseButtons, Qt::KeyboardModifiers keyboardModifiers)
{
- currentTab()->view()->load( QUrl(ReKonfig::homePage()) );
+ if (mouseButtons == Qt::MidButton || keyboardModifiers == Qt::ControlModifier)
+ Application::instance()->loadUrl(KUrl(ReKonfig::homePage()), Rekonq::SettingOpenTab);
+ else
+ currentTab()->view()->load(QUrl(ReKonfig::homePage()));
}
@@ -903,19 +941,41 @@ void MainWindow::browserLoading(bool v)
}
-void MainWindow::openPrevious()
+void MainWindow::openPrevious(Qt::MouseButtons mouseButtons, Qt::KeyboardModifiers keyboardModifiers)
{
QWebHistory *history = currentTab()->view()->history();
if (history->canGoBack())
- history->goToItem(history->backItem());
+ {
+ if (mouseButtons == Qt::MidButton || keyboardModifiers == Qt::ControlModifier)
+ {
+ Application::instance()->loadUrl(history->backItem().url(), Rekonq::SettingOpenTab);
+ }
+ else
+ {
+ history->goToItem(history->backItem());
+ }
+
+ updateActions();
+ }
+
}
-void MainWindow::openNext()
+void MainWindow::openNext(Qt::MouseButtons mouseButtons, Qt::KeyboardModifiers keyboardModifiers)
{
QWebHistory *history = currentTab()->view()->history();
if (history->canGoForward())
- history->goToItem(history->forwardItem());
+ {
+ if (mouseButtons == Qt::MidButton || keyboardModifiers == Qt::ControlModifier)
+ {
+ Application::instance()->loadUrl(history->forwardItem().url(), Rekonq::SettingOpenTab);
+ }
+ else
+ {
+ history->goToItem(history->forwardItem());
+ }
+ updateActions();
+ }
}
@@ -925,6 +985,7 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
if (event->key() == Qt::Key_Escape)
{
m_findBar->hide();
+ currentTab()->setFocus(); // give focus to web pages
return;
}
@@ -961,7 +1022,7 @@ QAction *MainWindow::actionByName(const QString name)
return ret;
/* else */
- kWarning() << "Action named: " << name << " not found, returning empty action.";
+ kDebug() << "Action named: " << name << " not found, returning empty action.";
return new QAction(this); // return empty object instead of NULL pointer
}
@@ -975,7 +1036,7 @@ void MainWindow::notifyMessage(const QString &msg, Rekonq::Notify status)
}
// deleting popus if empty msgs
- if(msg.isEmpty())
+ if (msg.isEmpty())
{
m_hidePopup->start(250);
return;
@@ -984,7 +1045,7 @@ void MainWindow::notifyMessage(const QString &msg, Rekonq::Notify status)
m_hidePopup->stop();
- switch(status)
+ switch (status)
{
case Rekonq::Info:
break;
@@ -1003,78 +1064,95 @@ void MainWindow::notifyMessage(const QString &msg, Rekonq::Notify status)
// setting the popup
QLabel *label = new QLabel(msg);
m_popup->setView(label);
- QSize labelSize(label->fontMetrics().width(msg)+2*margin, label->fontMetrics().height()+2*margin);
+ QSize labelSize(label->fontMetrics().width(msg) + 2*margin, label->fontMetrics().height() + 2*margin);
if (labelSize.width() > width()) labelSize.setWidth(width());
m_popup->setFixedSize(labelSize);
m_popup->layout()->setAlignment(Qt::AlignTop);
m_popup->layout()->setMargin(margin);
// useful values
-
+ WebTab *tab = m_view->currentWebTab();
+
+ // fix crash on window close
+ if (!tab)
+ return;
+
// fix crash on window close
- if(!m_view->currentWebTab()->page()->currentFrame())
+ if (!tab->page())
return;
-
- bool scrollbarIsVisible = m_view->currentWebTab()->page()->currentFrame()->scrollBarMaximum(Qt::Horizontal);
+
+ bool scrollbarIsVisible = tab->page()->currentFrame()->scrollBarMaximum(Qt::Horizontal);
int scrollbarSize = 0;
if (scrollbarIsVisible)
{
//TODO: detect QStyle size
scrollbarSize = 17;
}
- QPoint webViewOrigin = m_view->currentWebTab()->mapToGlobal(QPoint(0,0));
- int bottomLeftY=webViewOrigin.y() + m_view->currentWebTab()->page()->viewportSize().height() - labelSize.height() - scrollbarSize;
+
+ QPoint webViewOrigin = tab->view()->mapToGlobal(QPoint(0, 0));
+ int bottomLeftY = webViewOrigin.y() + tab->page()->viewportSize().height() - labelSize.height() - scrollbarSize;
// setting popup in bottom-left position
int x = geometry().x();
int y = bottomLeftY;
- QPoint mousePos = m_view->currentWebTab()->mapToGlobal(m_view->currentWebTab()->view()->mousePos());
- if(QRect(webViewOrigin.x(),bottomLeftY,labelSize.width(),labelSize.height()).contains(mousePos))
+ QPoint mousePos = tab->mapToGlobal(tab->view()->mousePos());
+ if (QRect(webViewOrigin.x() , bottomLeftY , labelSize.width() , labelSize.height()).contains(mousePos))
{
// setting popup above the mouse
y = bottomLeftY - labelSize.height();
}
- m_popup->show(QPoint(x,y));
+ m_popup->show(QPoint(x, y));
}
void MainWindow::clearPrivateData()
{
- QPointer<KDialog> dialog = new KDialog(this, Qt::Sheet);
+ QPointer<KDialog> dialog = new KDialog(this);
+ dialog->setCaption(i18n("Clear Private Data"));
dialog->setButtons(KDialog::Ok | KDialog::Cancel);
+ dialog->button(KDialog::Ok)->setIcon(KIcon("edit-clear"));
+ dialog->button(KDialog::Ok)->setText(i18n("Clear"));
+
Ui::ClearDataWidget clearWidget;
QWidget widget;
clearWidget.setupUi(&widget);
dialog->setMainWidget(&widget);
+ dialog->exec();
- if (dialog->exec() == KDialog::Accepted)
+ if (dialog->result() == QDialog::Accepted)
{
- if(clearWidget.clearHistory->isChecked())
+ if (clearWidget.clearHistory->isChecked())
{
Application::historyManager()->clear();
}
- if(clearWidget.clearCookies->isChecked())
+ if (clearWidget.clearDownloads->isChecked())
+ {
+ Application::historyManager()->clearDownloadsHistory();
+ }
+
+ if (clearWidget.clearCookies->isChecked())
{
QDBusInterface kcookiejar("org.kde.kded", "/modules/kcookiejar", "org.kde.KCookieServer");
- QDBusReply<void> reply = kcookiejar.call( "deleteAllCookies" );
+ QDBusReply<void> reply = kcookiejar.call("deleteAllCookies");
}
- if(clearWidget.clearCachedPages->isChecked())
+ if (clearWidget.clearCachedPages->isChecked())
{
- // TODO implement me!
+ KProcess::startDetached(KStandardDirs::findExe("kio_http_cache_cleaner"),
+ QStringList(QL1S("--clear-all")));
}
- if(clearWidget.clearWebIcons->isChecked())
+ if (clearWidget.clearWebIcons->isChecked())
{
QWebSettings::clearIconDatabase();
}
- if(clearWidget.homePageThumbs->isChecked())
+ if (clearWidget.homePageThumbs->isChecked())
{
QString path = KStandardDirs::locateLocal("cache", QString("thumbs/rekonq"), true);
path.remove("rekonq");
@@ -1087,6 +1165,8 @@ void MainWindow::clearPrivateData()
}
}
}
+
+ dialog->deleteLater();
}
@@ -1100,19 +1180,17 @@ void MainWindow::aboutToShowBackMenu()
int offset = 0;
QList<QWebHistoryItem> historyList = history->backItems(8); //no more than 8 elements!
int listCount = historyList.count();
- if(pivot >= 8)
- offset = pivot - 8;
-
-
+ if (pivot >= 8)
+ offset = pivot - 8;
- for(int i = listCount - 1; i>=0; --i)
+ for (int i = listCount - 1; i >= 0; --i)
{
QWebHistoryItem item = historyList.at(i);
KAction *action = new KAction(this);
action->setData(i + offset);
- QIcon icon = Application::icon( item.url() );
- action->setIcon( icon );
- action->setText( item.title() );
+ KIcon icon = Application::icon(item.url());
+ action->setIcon(icon);
+ action->setText(item.title());
m_historyBackMenu->addAction(action);
}
}
@@ -1121,13 +1199,47 @@ void MainWindow::aboutToShowBackMenu()
void MainWindow::openActionUrl(QAction *action)
{
int index = action->data().toInt();
-
- QWebHistory *history = currentTab()->view()->history();
- if(!history->itemAt(index).isValid())
+
+ QWebHistory *history = currentTab()->view()->history();
+ if (!history->itemAt(index).isValid())
{
- kDebug() << "Invalid Index!: "<< index;
+ kDebug() << "Invalid Index!: " << index;
return;
}
- history->goToItem( history->itemAt(index) );
+ history->goToItem(history->itemAt(index));
+}
+
+
+void MainWindow::setEncoding(QAction *qa)
+{
+ QString currentCodec = qa->text().toLatin1();
+ currentCodec = currentCodec.remove('&');
+ kDebug() << currentCodec;
+ QWebSettings::globalSettings()->setDefaultTextEncoding(currentCodec);
+ ReKonfig::setDefaultEncoding(currentCodec);
+}
+
+
+void MainWindow::populateEncodingMenu()
+{
+ QList<QByteArray> byteCodecs = QTextCodec::availableCodecs();
+ QStringList codecs;
+ Q_FOREACH(const QByteArray &b, byteCodecs)
+ {
+ codecs << QString(b);
+ }
+ codecs.sort();
+
+ QString currentCodec = ReKonfig::defaultEncoding();
+ kDebug() << "Current Codec: " << currentCodec;
+
+ m_encodingMenu->clear();
+ Q_FOREACH(const QString &codec, codecs)
+ {
+ QAction *action = m_encodingMenu->addAction(codec);
+ action->setCheckable(true);
+ if (currentCodec == codec)
+ action->setChecked(true);
+ }
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 7083591d..0f0fea96 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -1,10 +1,12 @@
+
/* ============================================================
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -29,9 +31,8 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
-
-// Local Includes
-#include "application.h"
+// Rekonq Includes
+#include "rekonq_defines.h"
// KDE Includes
#include <KMainWindow>
@@ -40,11 +41,6 @@
#include <KUrl>
// Forward Declarations
-class QWebFrame;
-
-class KAction;
-class KPassivePopup;
-
class FindBar;
class HistoryPanel;
class BookmarksPanel;
@@ -52,13 +48,20 @@ class WebInspectorPanel;
class WebTab;
class MainView;
+class KAction;
+class KPassivePopup;
+
+class QWebFrame;
+class QSlider;
+
+
/**
* This class serves as the main window for rekonq.
* It handles the menus, toolbars, and status bars.
*
*/
-class MainWindow : public KMainWindow
+class REKONQ_TESTS_EXPORT MainWindow : public KMainWindow
{
Q_OBJECT
@@ -70,18 +73,19 @@ public:
WebTab *currentTab() const;
QAction *actionByName(const QString name);
virtual QSize sizeHint() const;
- virtual KActionCollection *actionCollection () const;
+ virtual KActionCollection *actionCollection() const;
void setWidgetsVisible(bool makeFullScreen);
-
+
+ void setZoomSliderFactor(qreal factor);
+
private:
void setupActions();
void setupTools();
void setupToolbars();
void setupPanels();
-
+
public slots:
- void updateBrowser();
- void homePage();
+ void homePage(Qt::MouseButtons = Qt::LeftButton, Qt::KeyboardModifiers = Qt::NoModifier);
/**
* Notifies a message in a popup
@@ -94,7 +98,7 @@ public slots:
void notifyMessage(const QString &msg, Rekonq::Notify status = Rekonq::Info);
void printRequested(QWebFrame *frame = 0);
-
+
signals:
// switching tabs
void ctrlTabPressed();
@@ -110,24 +114,26 @@ protected:
private slots:
void postLaunch();
- void updateConfiguration();
void browserLoading(bool);
void updateActions();
void updateWindowTitle(const QString &title = QString());
// history related
- void openPrevious();
- void openNext();
+ void openPrevious(Qt::MouseButtons = Qt::LeftButton, Qt::KeyboardModifiers = Qt::NoModifier);
+ void openNext(Qt::MouseButtons = Qt::LeftButton, Qt::KeyboardModifiers = Qt::NoModifier);
// Find Action slots
void find(const QString &);
+ void matchCaseUpdate();
void findNext();
void findPrevious();
+ void highlightAll();
// Zoom slots
- void viewTextBigger();
- void viewTextNormal();
- void viewTextSmaller();
+ void zoomIn();
+ void zoomNormal();
+ void zoomOut();
+ void setZoomFactor(int factor);
// File Menu slots
void openLocation();
@@ -149,20 +155,27 @@ private slots:
void aboutToShowBackMenu();
void openActionUrl(QAction *action);
+ // encodings
+ void setEncoding(QAction *);
+ void populateEncodingMenu();
+
private:
MainView *m_view;
FindBar *m_findBar;
-
+
HistoryPanel *m_historyPanel;
BookmarksPanel *m_bookmarksPanel;
WebInspectorPanel *m_webInspectorPanel;
KAction *m_stopReloadAction;
KMenu *m_historyBackMenu;
+ KMenu *m_encodingMenu;
KToolBar *m_mainBar;
KToolBar *m_bmBar;
+ QSlider *m_zoomSlider;
+
QString m_lastSearch;
KPassivePopup *m_popup;
diff --git a/src/networkaccessmanager.cpp b/src/networkaccessmanager.cpp
index eadbfab3..765604dc 100644
--- a/src/networkaccessmanager.cpp
+++ b/src/networkaccessmanager.cpp
@@ -3,16 +3,17 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>*
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 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
+* 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
@@ -24,6 +25,7 @@
* ============================================================ */
+
// Self Includes
#include "networkaccessmanager.h"
#include "networkaccessmanager.moc"
@@ -31,23 +33,65 @@
// Local Includes
#include "application.h"
#include "adblockmanager.h"
-#include <KDebug>
+#include "webpage.h"
+
+// KDE Includes
+#include <KLocale>
+#include <KProtocolManager>
+
NetworkAccessManager::NetworkAccessManager(QObject *parent)
- : AccessManager(parent)
+ : AccessManager(parent)
{
+ QString c = KGlobal::locale()->country();
+ if (c == QL1S("C"))
+ c = QL1S("en_US");
+ if (c != QL1S("en_US"))
+ c.append(QL1S(", en_US"));
+
+ _acceptLanguage = c.toLatin1();
}
-QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData)
+QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
{
- // Adblock
+ WebPage *parentPage = qobject_cast<WebPage *>(parent());
+
+ QNetworkReply *reply = 0;
+
+ QNetworkRequest req = request;
+ req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
+ req.setRawHeader("Accept-Language", _acceptLanguage);
+
+ KIO::CacheControl cc = KProtocolManager::cacheControl();
+ switch (cc)
+ {
+ case KIO::CC_CacheOnly: // Fail request if not in cache.
+ req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
+ break;
+
+ case KIO::CC_Refresh: // Always validate cached entry with remote site.
+ req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork);
+ break;
+
+ case KIO::CC_Reload: // Always fetch from remote site
+ req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
+ break;
+
+ case KIO::CC_Cache: // Use cached entry if available.
+ case KIO::CC_Verify: // Validate cached entry with remote site if expired.
+ default:
+ req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
+ break;
+ }
+
+
if (op == QNetworkAccessManager::GetOperation)
{
- QNetworkReply *reply = Application::adblockManager()->block(req);
+ reply = Application::adblockManager()->block(req, parentPage);
if (reply)
return reply;
}
- return AccessManager::createRequest(op,req,outgoingData);
+ return AccessManager::createRequest(op, req, outgoingData);
}
diff --git a/src/networkaccessmanager.h b/src/networkaccessmanager.h
index 5c34ebd7..aefd1a25 100644
--- a/src/networkaccessmanager.h
+++ b/src/networkaccessmanager.h
@@ -3,16 +3,17 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>*
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 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
+* 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
@@ -28,6 +29,12 @@
#define NETWORKACCESSMANAGER_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Local Includes
+#include "webpage.h"
+
// KDE Includes
#include <kio/accessmanager.h>
@@ -35,15 +42,18 @@
using namespace KIO::Integration;
-class NetworkAccessManager : public AccessManager
+class REKONQ_TESTS_EXPORT NetworkAccessManager : public AccessManager
{
Q_OBJECT
public:
- NetworkAccessManager(QObject *parent = 0);
+ NetworkAccessManager(QObject *parent);
protected:
- virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData = 0);
+ virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0);
+
+private:
+ QByteArray _acceptLanguage;
};
#endif // NETWORKACCESSMANAGER_H
diff --git a/src/newtabpage.cpp b/src/newtabpage.cpp
new file mode 100644
index 00000000..f177cbf3
--- /dev/null
+++ b/src/newtabpage.cpp
@@ -0,0 +1,597 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 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 "newtabpage.h"
+#include "newtabpage.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// Local Includes
+#include "historymodels.h"
+#include "bookmarksmanager.h"
+#include "application.h"
+#include "mainwindow.h"
+#include "mainview.h"
+#include "websnap.h"
+#include "previewselectorbar.h"
+#include "webtab.h"
+
+// KDE Includes
+#include <KStandardDirs>
+#include <KIconLoader>
+#include <KConfig>
+#include <KDialog>
+#include <KCalendarSystem>
+
+// Qt Includes
+#include <QtCore/QFile>
+
+
+NewTabPage::NewTabPage(QWebFrame *frame)
+ : QObject(frame)
+ , m_root(frame->documentElement())
+{
+ QString htmlFilePath = KStandardDirs::locate("data", "rekonq/htmls/home.html");
+ QString imagesPath = QString("file://") + KGlobal::dirs()->findResourceDir("data", "rekonq/pics/bg.png") + QString("rekonq/pics");
+
+ QFile file(htmlFilePath);
+ bool isOpened = file.open(QIODevice::ReadOnly);
+ if (!isOpened)
+ {
+ kDebug() << "Couldn't open the home.html file";
+ }
+ else
+ {
+ m_html = file.readAll();
+ m_html.replace(QString("%2"), imagesPath);
+ }
+}
+
+
+NewTabPage::~NewTabPage()
+{
+}
+
+
+void NewTabPage::generate(const KUrl &url)
+{
+ if (KUrl("about:preview").isParentOf(url))
+ {
+ if (url.fileName() == QString("add"))
+ {
+ QStringList names = ReKonfig::previewNames();
+ QStringList urls = ReKonfig::previewUrls();
+
+ names.append("");
+ urls.append("");
+
+ ReKonfig::setPreviewNames(names);
+ ReKonfig::setPreviewUrls(urls);
+
+ // Why doesn't it work well ?
+ // m_root.appendInside(emptyPreview(names.length() - 1));
+ // Replacing with this :
+ generate(KUrl("about:favorites"));
+ return;
+ }
+ if (url.directory() == QString("preview/remove"))
+ {
+ removePreview(url.fileName().toInt());
+ return;
+ }
+ if (url.directory() == QString("preview/modify"))
+ {
+ int index = url.fileName().toInt();
+ Application::instance()->mainWindow()->currentTab()->createPreviewSelectorBar(index);
+ return;
+ }
+ }
+ if (url.fileName() == QString("clear"))
+ {
+ Application::instance()->mainWindow()->actionByName("clear_private_data")->trigger();
+ generate(QString("about:" + url.directory()));
+ return;
+ }
+ if (url == KUrl("about:bookmarks/edit"))
+ {
+ Application::bookmarkProvider()->bookmarkManager()->slotEditBookmarks();
+ return;
+ }
+
+ QWebPage *page = m_root.webFrame()->page();
+ page->mainFrame()->setHtml(m_html);
+
+ m_root = page->mainFrame()->documentElement().findFirst("#content");
+
+ browsingMenu(url);
+
+ QString title;
+ if (url == KUrl("about:favorites"))
+ {
+ favoritesPage();
+ title = i18n("Favorites");
+ }
+ else if (url == KUrl("about:closedTabs"))
+ {
+ closedTabsPage();
+ title = i18n("Closed Tabs");
+ }
+ else if (url == KUrl("about:history"))
+ {
+ historyPage();
+ title = i18n("History");
+ }
+ else if (url == KUrl("about:bookmarks"))
+ {
+ bookmarksPage();
+ title = i18n("Bookmarks");
+ }
+ else if (url == KUrl("about:downloads"))
+ {
+ downloadsPage();
+ title = i18n("Downloads");
+ }
+
+ m_root.document().findFirst("title").setPlainText(title);
+}
+
+
+void NewTabPage::favoritesPage()
+{
+ m_root.addClass("favorites");
+
+ QWebElement add = markup(".link");
+ add.findFirst("a").setAttribute("href", "about:preview/add");
+ add.findFirst("img").setAttribute("src" , QString("file:///" +
+ KIconLoader::global()->iconPath("list-add", KIconLoader::Small || KIconLoader::SizeSmall)));
+ add.findFirst("span").appendInside(i18n("Add Preview"));
+ m_root.document().findFirst("#actions").appendInside(add);
+
+ QStringList names = ReKonfig::previewNames();
+ QStringList urls = ReKonfig::previewUrls();
+
+ if (urls.isEmpty())
+ {
+ m_root.addClass("empty");
+ m_root.setPlainText(i18n("You can add a preview by clicking the \"Add Preview\" button in the top-right corner of this page"));
+ return;
+ }
+
+ for (int i = 0; i < urls.count() ; ++i)
+ {
+ KUrl url = KUrl(urls.at(i));
+ QWebElement prev;
+
+ if (url.isEmpty())
+ prev = emptyPreview(i);
+ else if (!WebSnap::existsImage(url))
+ prev = loadingPreview(i, url);
+ else
+ prev = validPreview(i, url, names.at(i));
+
+ setupPreview(prev, i);
+
+ m_root.appendInside(prev);
+ }
+}
+
+
+QWebElement NewTabPage::emptyPreview(int index)
+{
+ QWebElement prev = markup(".thumbnail");
+
+ prev.findFirst(".preview img").setAttribute("src" , QString("file:///") +
+ KIconLoader::global()->iconPath("insert-image", KIconLoader::Desktop));
+ prev.findFirst("span a").setPlainText(i18n("Set a Preview..."));
+ prev.findFirst("a").setAttribute("href", QString("about:preview/modify/" + QVariant(index).toString()));
+
+ setupPreview(prev, index);
+ //hideControls(prev);
+
+ return prev;
+}
+
+
+QWebElement NewTabPage::loadingPreview(int index, const KUrl &url)
+{
+ QWebElement prev = markup(".thumbnail");
+
+ prev.findFirst(".preview img").setAttribute("src" ,
+ QString("file:///") + KStandardDirs::locate("appdata", "pics/busywidget.gif"));
+ prev.findFirst("span a").setPlainText(i18n("Loading Preview..."));
+ prev.findFirst("a").setAttribute("href", url.toMimeDataString());
+
+ setupPreview(prev, index);
+ showControls(prev);
+
+ // NOTE: we need the page frame for two reasons
+ // 1) to link to the WebPage calling the snapFinished slot
+ // 2) to "auto-destroy" snaps on tab closing :)
+ QWebFrame *frame = qobject_cast<QWebFrame *>(parent());
+ WebSnap *snap = new WebSnap(url, frame);
+ connect(snap, SIGNAL(snapDone(bool)), frame->page(), SLOT(updateImage(bool)));
+ return prev;
+}
+
+
+QWebElement NewTabPage::validPreview(int index, const KUrl &url, const QString &title)
+{
+ QWebElement prev = markup(".thumbnail");
+ QString previewPath = QL1S("file://") + WebSnap::imagePathFromUrl(url);
+ QString iString = QVariant(index).toString();
+
+ prev.findFirst(".preview img").setAttribute("src" , previewPath);
+ prev.findFirst("a").setAttribute("href", url.toMimeDataString()); // NOTE ?
+ prev.findFirst("span a").setAttribute("href", url.toMimeDataString()); // NOTE ?
+ prev.findFirst("span a").setPlainText(checkTitle(title));
+
+ setupPreview(prev, index);
+ showControls(prev);
+
+ return prev;
+}
+
+
+void NewTabPage::hideControls(QWebElement e)
+{
+ e.findFirst(".remove").setStyleProperty("visibility", "hidden");
+ e.findFirst(".modify").setStyleProperty("visibility", "hidden");
+}
+
+
+void NewTabPage::showControls(QWebElement e)
+{
+ e.findFirst(".remove").setStyleProperty("visibility", "visible");
+ e.findFirst(".modify").setStyleProperty("visibility", "visible");
+}
+
+
+void NewTabPage::setupPreview(QWebElement e, int index)
+{
+ e.findFirst(".remove img").setAttribute("src", QString("file:///") +
+ KIconLoader::global()->iconPath("edit-delete", KIconLoader::DefaultState));
+ e.findFirst(".remove").setAttribute("title", "Remove favorite");
+ e.findFirst(".modify img").setAttribute("src", QString("file:///") +
+ KIconLoader::global()->iconPath("insert-image", KIconLoader::DefaultState));
+ e.findFirst(".modify").setAttribute("title", "Set new favorite");
+
+ e.findFirst(".modify").setAttribute("href", QString("about:preview/modify/" + QVariant(index).toString()));
+ e.findFirst(".remove").setAttribute("href", QString("about:preview/remove/" + QVariant(index).toString()));
+
+ e.setAttribute("id", "preview" + QVariant(index).toString());
+}
+
+
+void NewTabPage::snapFinished()
+{
+ // Update page, but only if open
+ if (m_root.document().findAll("#rekonq-newtabpage").count() == 0)
+ return;
+ if (m_root.findAll(".favorites").count() == 0 && m_root.findAll(".closedTabs").count() == 0)
+ return;
+
+ QStringList urls = ReKonfig::previewUrls();
+ QStringList names = ReKonfig::previewNames();
+
+ for (int i = 0; i < urls.count(); i++)
+ {
+ KUrl url = KUrl(urls.at(i));
+ QString title = names.at(i);
+
+ if (WebSnap::existsImage(url))
+ {
+ QWebElement prev = m_root.findFirst("#preview" + QVariant(i).toString());
+ if (KUrl(prev.findFirst("a").attribute("href")) == url)
+ {
+ QWebElement newPrev = validPreview(i, url, title);
+
+ if (m_root.findAll(".closedTabs").count() != 0)
+ hideControls(newPrev);
+
+ prev.replace(newPrev);
+ }
+ }
+ }
+}
+
+
+void NewTabPage::removePreview(int index)
+{
+ QStringList names = ReKonfig::previewNames();
+ QStringList urls = ReKonfig::previewUrls();
+
+ urls.removeAt(index);
+ names.removeAt(index);
+
+ ReKonfig::setPreviewNames(names);
+ ReKonfig::setPreviewUrls(urls);
+
+ generate(KUrl("about:favorites"));
+
+ ReKonfig::self()->writeConfig();
+}
+
+
+void NewTabPage::browsingMenu(const KUrl &currentUrl)
+{
+ QList<QWebElement> navItems;
+
+ KIconLoader *loader = KIconLoader::global();
+
+ QWebElement nav = markup(".link"); // Favorites
+ nav.findFirst("a").setAttribute("href", "about:favorites");
+ nav.findFirst("img").setAttribute("src" , QString("file:///" +
+ loader->iconPath("emblem-favorite", KIconLoader::Desktop || KIconLoader::SizeSmall)));
+ nav.findFirst("span").appendInside(i18n("Favorites"));
+ navItems.append(nav);
+
+ nav = markup(".link"); // Closed Tabs
+ nav.findFirst("a").setAttribute("href", "about:closedTabs");
+ nav.findFirst("img").setAttribute("src" , QString("file:///" +
+ loader->iconPath("tab-close", KIconLoader::Desktop || KIconLoader::SizeSmall)));
+ nav.findFirst("span").appendInside(i18n("Closed Tabs"));
+ navItems.append(nav);
+
+ nav = markup(".link"); // Bookmarks
+ nav.findFirst("a").setAttribute("href", "about:bookmarks");
+ nav.findFirst("img").setAttribute("src" , QString("file:///" +
+ loader->iconPath("bookmarks", KIconLoader::Desktop || KIconLoader::SizeSmall)));
+ nav.findFirst("span").appendInside(i18n("Bookmarks"));
+ navItems.append(nav);
+
+ nav = markup(".link"); // History
+ nav.findFirst("a").setAttribute("href", "about:history");
+ nav.findFirst("img").setAttribute("src" , QString("file:///" +
+ loader->iconPath("view-history", KIconLoader::Desktop || KIconLoader::SizeSmall)));
+ nav.findFirst("span").appendInside(i18n("History"));
+ navItems.append(nav);
+
+ nav = markup(".link"); // Downloads
+ nav.findFirst("a").setAttribute("href", "about:downloads");
+ nav.findFirst("img").setAttribute("src" , QString("file:///" +
+ loader->iconPath("download", KIconLoader::Desktop || KIconLoader::SizeSmall)));
+ nav.findFirst("span").appendInside(i18n("Downloads"));
+ navItems.append(nav);
+
+ QWebElement it;
+ foreach(it, navItems)
+ {
+ if (it.findFirst("a").attribute("href") == currentUrl.toMimeDataString())
+ it.addClass("current");
+ else if (currentUrl == "about:home" && it.findFirst("a").attribute("href") == "about:favorites")
+ it.addClass("current");
+ m_root.document().findFirst("#navigation").appendInside(it);
+ }
+}
+
+
+void NewTabPage::historyPage()
+{
+ m_root.addClass("history");
+
+ QWebElement clearData = markup(".link");
+ clearData.findFirst("a").setAttribute("href", "about:history/clear");
+ QString iconPath = QString("file:///" + KIconLoader::global()->iconPath("edit-clear", KIconLoader::SizeSmall || KIconLoader::Small));
+ clearData.findFirst("img").setAttribute("src" , iconPath);
+ clearData.findFirst("span").appendInside(i18n("Clear Private Data"));
+ m_root.document().findFirst("#actions").appendInside(clearData);
+
+ HistoryTreeModel *model = Application::historyManager()->historyTreeModel();
+
+ if (model->rowCount() == 0)
+ {
+ m_root.addClass("empty");
+ m_root.setPlainText(i18n("Your browsing history is empty"));
+ return;
+ }
+
+ int i = 0;
+ do
+ {
+ QModelIndex index = model->index(i, 0, QModelIndex());
+ if (model->hasChildren(index))
+ {
+ m_root.appendInside(markup("h3"));
+ m_root.lastChild().setPlainText(index.data().toString());
+
+ for (int j = 0; j < model->rowCount(index); ++j)
+ {
+ QModelIndex son = model->index(j, 0, index);
+ m_root.appendInside(son.data(HistoryModel::DateTimeRole).toDateTime().toString("hh:mm"));
+ m_root.appendInside(" ");
+ m_root.appendInside(markup("a"));
+ m_root.lastChild().setAttribute("href" , son.data(HistoryModel::UrlStringRole).toString());
+ m_root.lastChild().appendInside(son.data().toString());
+ m_root.appendInside("<br/>");
+ }
+ }
+ i++;
+ }
+ while (model->hasIndex(i , 0 , QModelIndex()));
+}
+
+
+void NewTabPage::bookmarksPage()
+{
+ m_root.addClass("bookmarks");
+
+ QWebElement editBookmarks = markup(".link");
+ editBookmarks.findFirst("a").setAttribute("href", "about:bookmarks/edit");
+ QString iconPath = QString("file:///" + KIconLoader::global()->iconPath("bookmarks-organize", KIconLoader::SizeSmall || KIconLoader::Small));
+ editBookmarks.findFirst("img").setAttribute("src" , iconPath);
+ editBookmarks.findFirst("span").appendInside(i18n("Edit Bookmarks"));
+ m_root.document().findFirst("#actions").appendInside(editBookmarks);
+
+ KBookmarkGroup bookGroup = Application::bookmarkProvider()->rootGroup();
+ if (bookGroup.isNull())
+ {
+ m_root.addClass("empty");
+ m_root.setPlainText(i18n("You have no bookmarks"));
+ return;
+ }
+
+ KBookmark bookmark = bookGroup.first();
+ while (!bookmark.isNull())
+ {
+ createBookItem(bookmark, m_root);
+ bookmark = bookGroup.next(bookmark);
+ }
+}
+
+
+void NewTabPage::createBookItem(const KBookmark &bookmark, QWebElement parent)
+{
+ if (bookmark.isGroup())
+ {
+ KBookmarkGroup group = bookmark.toGroup();
+ KBookmark bm = group.first();
+ parent.appendInside(markup("h3"));
+ parent.lastChild().setPlainText(group.text());
+ parent.appendInside(markup(".bookfolder"));
+ while (!bm.isNull())
+ {
+ createBookItem(bm, parent.lastChild()); // it is .bookfolder
+ bm = group.next(bm);
+ }
+ }
+ else if (bookmark.isSeparator())
+ {
+ parent.appendInside("<hr/>");
+ }
+ else
+ {
+ parent.appendInside(markup("a"));
+ parent.lastChild().setAttribute("href" , bookmark.url().prettyUrl());
+ parent.lastChild().setPlainText(bookmark.text());
+ parent.appendInside("<br/>");
+ }
+}
+
+
+void NewTabPage::closedTabsPage()
+{
+ m_root.addClass("closedTabs");
+
+ QList<HistoryItem> links = Application::instance()->mainWindow()->mainView()->recentlyClosedTabs();
+
+ if (links.isEmpty())
+ {
+ m_root.addClass("empty");
+ m_root.setPlainText(i18n("There are no recently closed tabs"));
+ return;
+ }
+
+ for (int i = 0; i < links.count(); ++i)
+ {
+ HistoryItem item = links.at(i);
+ QWebElement prev;
+
+ if (item.url.isEmpty())
+ continue;
+
+ prev = WebSnap::existsImage(KUrl(item.url))
+ ? validPreview(i, item.url, item.title)
+ : loadingPreview(i, item.url);
+
+ prev.setAttribute("id", "preview" + QVariant(i).toString());
+ hideControls(prev);
+ m_root.appendInside(prev);
+ }
+}
+
+
+QString NewTabPage::checkTitle(const QString &title)
+{
+ QString t(title);
+ if (t.length() > 23)
+ {
+ t.truncate(20);
+ t += "...";
+ }
+ return t;
+}
+
+
+void NewTabPage::downloadsPage()
+{
+ m_root.addClass("downloads");
+
+ QWebElement clearData = markup(".link");
+ clearData.findFirst("a").setAttribute("href", "about:downloads/clear");
+ QString iconPath = QString("file:///" + KIconLoader::global()->iconPath("edit-clear", KIconLoader::SizeSmall || KIconLoader::Small));
+ clearData.findFirst("img").setAttribute("src" , iconPath);
+ clearData.findFirst("span").appendInside(i18n("Clear Private Data"));
+ m_root.document().findFirst("#actions").appendInside(clearData);
+
+ DownloadList list = Application::historyManager()->downloads();
+
+ if (list.isEmpty())
+ {
+ m_root.addClass("empty");
+ m_root.setPlainText(i18n("There are no recently downloaded files to show"));
+ return;
+ }
+
+ foreach(const DownloadItem &item, list)
+ {
+ m_root.prependInside(markup("div"));
+
+ QWebElement div = m_root.firstChild();
+ div.addClass("download");
+
+ KUrl u = KUrl(item.destUrlString);
+ QString fName = u.fileName();
+ QString dir = QL1S("file://") + u.directory();
+
+ KIconLoader *loader = KIconLoader::global();
+ QString iconPath = "file://" + loader->iconPath(KMimeType::iconNameForUrl(u), KIconLoader::Desktop);
+
+ div.appendInside(markup("img"));
+ div.lastChild().setAttribute("src", iconPath);
+
+ div.appendInside("<strong>" + fName + "</strong>");
+ div.appendInside(" - ");
+ QString date = KGlobal::locale()->formatDateTime(item.dateTime, KLocale::FancyLongDate);
+ div.appendInside("<em>" + date + "</em>");
+ div.appendInside("<br/>");
+
+ div.appendInside(item.srcUrlString);
+ div.appendInside("<br/>");
+
+ div.appendInside(markup("a"));
+ div.lastChild().setAttribute("href" , dir);
+ div.lastChild().setPlainText("Browse dir");
+
+ /* TODO : make this link work
+ div.appendInside(" - ");
+ div.appendInside(markup("a"));
+ div.lastChild().setAttribute("href" , u.toMimeDataString());
+ div.lastChild().setPlainText("Open file");*/
+ }
+}
diff --git a/src/newtabpage.h b/src/newtabpage.h
new file mode 100644
index 00000000..ad4941d3
--- /dev/null
+++ b/src/newtabpage.h
@@ -0,0 +1,122 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 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 REKONQ_NEW_TAB_PAGE
+#define REKONQ_NEW_TAB_PAGE
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// KDE Includes
+#include <KUrl>
+
+// Qt Includes
+#include <QObject>
+#include <QString>
+#include <QWebElement>
+
+// Forward Includes
+class KBookmark;
+class WebPage;
+
+
+class REKONQ_TESTS_EXPORT NewTabPage : public QObject
+{
+ Q_OBJECT
+
+public:
+ NewTabPage(QWebFrame *frame);
+ ~NewTabPage();
+
+ /**
+ * This method takes an about: url and loads
+ * the corresponding part of the new tab page
+ */
+ void generate(const KUrl &url = KUrl("about:home"));
+
+ /**
+ * This method updates thumbs, removing loading previews
+ * and providing a real picture
+ */
+ void snapFinished();
+
+private:
+ // these are the "high-level" functions to build the new tab page.
+ // Basically, you call browsingMenu + one of the *Page methods
+ // to load a page
+ void browsingMenu(const KUrl &currentUrl);
+
+ void favoritesPage();
+ void historyPage();
+ void bookmarksPage();
+ void closedTabsPage();
+ void downloadsPage();
+
+ // --------------------------------------------------------------------------
+ // "low-level" functions
+ // we use these to create the pages over
+
+ // Previews handling
+ QWebElement emptyPreview(int index);
+ QWebElement loadingPreview(int index, const KUrl &url);
+ QWebElement validPreview(int index, const KUrl &url, const QString &title);
+
+ void removePreview(int index);
+
+ /**
+ * This function takes a QwebElement with the .thumbnail structure,
+ * hiding the "remove" and "modify" buttons
+ *
+ */
+ void hideControls(QWebElement e);
+ void showControls(QWebElement e);
+ void setupPreview(QWebElement e, int index);
+
+ void createBookItem(const KBookmark &bookmark, QWebElement parent);
+
+ /**
+ * This function helps to get faster a new markup of one type,
+ * it isn't easy to create one with QWebElement.
+ *
+ * It gets it in the #models div of home.html.
+ * It works for all elements defined here.
+ *
+ */
+ inline QWebElement markup(const QString &selector)
+ {
+ return m_root.document().findFirst("#models > " + selector).clone();
+ }
+
+ QString checkTitle(const QString &title);
+
+private:
+ QString m_html;
+ QWebElement m_root;
+};
+
+#endif // REKONQ_NEW_TAB_PAGE
diff --git a/src/paneltreeview.cpp b/src/paneltreeview.cpp
new file mode 100644
index 00000000..58673d60
--- /dev/null
+++ b/src/paneltreeview.cpp
@@ -0,0 +1,200 @@
+/* ============================================================
+*
+* 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 "paneltreeview.h"
+#include "paneltreeview.moc"
+
+// Local Includes
+#include "application.h"
+
+// KDE Includes
+#include <KUrl>
+
+// Qt Includes
+#include <QtGui/QMouseEvent>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QClipboard>
+
+
+PanelTreeView::PanelTreeView(QWidget *parent)
+ : QTreeView(parent)
+{
+ connect(this, SIGNAL(itemHovered(const QString &)), parent, SIGNAL(itemHovered(const QString &)));
+ connect(this, SIGNAL(openUrl(const KUrl &, Rekonq::OpenType)), parent, SIGNAL(openUrl(const KUrl &, Rekonq::OpenType)));
+ setMouseTracking(true);
+ setExpandsOnDoubleClick(false);
+}
+
+
+PanelTreeView::~PanelTreeView()
+{
+}
+
+
+void PanelTreeView::mousePressEvent(QMouseEvent *event)
+{
+ const QModelIndex index = indexAt(event->pos());
+ bool expanded = isExpanded(index);
+
+ QTreeView::mousePressEvent(event);
+
+ // A change of an item expansion is handle by mouseReleaseEvent()
+ // So toggle again the item
+ if (expanded != isExpanded(index))
+ setExpanded(index, !isExpanded(index));
+
+ if (!index.isValid())
+ {
+ clearSelection();
+ setCurrentIndex(QModelIndex());
+
+ if (event->button() == Qt::RightButton)
+ emit contextMenuEmptyRequested(event->pos());
+ return;
+ }
+
+ if (event->button() == Qt::RightButton)
+ {
+ if (model()->rowCount(index) == 0)
+ {
+ // An empty group needs to be handle by the panels
+ emit contextMenuItemRequested(event->pos());
+ }
+ else
+ {
+ emit contextMenuGroupRequested(event->pos());
+ }
+ }
+}
+
+
+void PanelTreeView::mouseReleaseEvent(QMouseEvent *event)
+{
+ QTreeView::mouseReleaseEvent(event);
+
+ const QModelIndex index = indexAt(event->pos());
+ if (!index.isValid())
+ return;
+
+ if (event->button() == Qt::MidButton || event->modifiers() == Qt::ControlModifier)
+ validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::SettingOpenTab);
+
+ else if (event->button() == Qt::LeftButton)
+ {
+ if (model()->rowCount(index) == 0)
+ validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)));
+ else
+ setExpanded(index, !isExpanded(index));
+ }
+}
+
+
+void PanelTreeView::keyPressEvent(QKeyEvent *event)
+{
+ QTreeView::keyPressEvent(event);
+ QModelIndex index = currentIndex();
+
+ if (!index.isValid())
+ return;
+
+ if (event->key() == Qt::Key_Return)
+ {
+ if (model()->rowCount(index) == 0)
+ validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)));
+ else
+ setExpanded(index, !isExpanded(index));
+ }
+
+ else if (event->key() == Qt::Key_Delete)
+ {
+ emit delKeyPressed();
+ }
+}
+
+
+void PanelTreeView::validOpenUrl(const KUrl &url, Rekonq::OpenType openType)
+{
+ // To workaround a crash when the url is about:blank
+ if (url.url() == "about:blank")
+ emit openUrl(KUrl("about:home"), openType);
+ else
+ emit openUrl(url, openType);
+}
+
+
+void PanelTreeView::mouseMoveEvent(QMouseEvent *event)
+{
+ QTreeView::mouseMoveEvent(event);
+ const QModelIndex index = indexAt(event->pos());
+ if (!index.isValid())
+ {
+ emit itemHovered("");
+ return;
+ }
+ emit itemHovered(qVariantValue< KUrl >(index.data(Qt::UserRole)).url());
+}
+
+
+void PanelTreeView::openInCurrentTab()
+{
+ QModelIndex index = currentIndex();
+ if (!index.isValid())
+ return;
+
+ validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)));
+}
+
+
+void PanelTreeView::copyToClipboard()
+{
+ QModelIndex index = currentIndex();
+ if (!index.isValid())
+ return;
+
+ QClipboard *cb = Application::clipboard();
+ cb->setText(qVariantValue< KUrl >(index.data(Qt::UserRole)).url());
+}
+
+
+void PanelTreeView::openInNewTab()
+{
+ QModelIndex index = currentIndex();
+ if (!index.isValid())
+ return;
+
+ validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::SettingOpenTab);
+}
+
+
+void PanelTreeView::openInNewWindow()
+{
+ QModelIndex index = currentIndex();
+ if (!index.isValid())
+ return;
+
+ validOpenUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::NewWindow);
+}
diff --git a/src/paneltreeview.h b/src/paneltreeview.h
new file mode 100644
index 00000000..75aee8e7
--- /dev/null
+++ b/src/paneltreeview.h
@@ -0,0 +1,72 @@
+/* ============================================================
+*
+* 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/>.
+*
+* ============================================================ */
+
+
+#ifndef PANELTREEVIEW_H
+#define PANELTREEVIEW_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Qt Includes
+#include <QTreeView>
+
+// Forward Declarations
+class KUrl;
+
+
+class REKONQ_TESTS_EXPORT PanelTreeView : public QTreeView
+{
+ Q_OBJECT
+
+public:
+ PanelTreeView(QWidget *parent = 0);
+ ~PanelTreeView();
+
+signals:
+ void openUrl(const KUrl &, const Rekonq::OpenType &);
+ void itemHovered(const QString &);
+ void delKeyPressed();
+ void contextMenuItemRequested(const QPoint &pos);
+ void contextMenuGroupRequested(const QPoint &pos);
+ void contextMenuEmptyRequested(const QPoint &pos);
+
+public slots:
+ void copyToClipboard();
+ void openInCurrentTab();
+ void openInNewTab();
+ void openInNewWindow();
+
+protected:
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+
+private:
+ void validOpenUrl(const KUrl &url, Rekonq::OpenType openType = Rekonq::CurrentTab);
+};
+
+#endif // PANELTREEVIEW_H
diff --git a/src/previewimage.cpp b/src/previewimage.cpp
deleted file mode 100644
index 9c8bb194..00000000
--- a/src/previewimage.cpp
+++ /dev/null
@@ -1,430 +0,0 @@
-/* ============================================================
-*
-* This file is a part of the rekonq project
-*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 "previewimage.h"
-#include "previewimage.moc"
-
-// Local Includes
-#include "historymanager.h"
-#include "rekonq.h"
-#include "mainwindow.h"
-#include "mainview.h"
-
-// KDE Includes
-#include <KUrl>
-#include <KStandardDirs>
-#include <KDebug>
-#include <KMenu>
-#include <KAction>
-#include <KLocale>
-
-// Qt Includes
-#include <QFile>
-#include <QMovie>
-#include <QMouseEvent>
-#include <QHBoxLayout>
-#include <QVBoxLayout>
-#include <QPainter>
-
-
-PreviewImage::PreviewImage(const QUrl &url, const QString &title, int index, bool isFavorite)
- : QWidget()
- , ws(0)
- , loadingSnapshot(false)
- , m_url(url)
- , m_title(title)
- , m_isFavorite(isFavorite)
- , m_index(index)
- , m_button(0)
- , m_imageLabel(new QLabel)
- , m_textLabel(new QLabel)
- , m_backgroundLabel(new QLabel)
- , m_previewLabel(new QLabel)
-{
-
- int borderTop = 14;
- int borderRight = 16;
- int borderBottom = 14;
- int borderLeft = 16;
-
- int previewWidth = 200;
- int previewHeight = 150;
-
- int urlHeight = 18;
-
- m_size = QSize(borderLeft+previewWidth+borderRight, borderTop+previewHeight+borderBottom+urlHeight);
-
- setFixedSize(m_size);
- m_previewLabel->setFixedSize(m_size);
-
- m_backgroundLabel->setPixmap(renderBackground(previewWidth,previewHeight, borderTop, borderBottom, borderLeft, borderRight));
-
- m_previewLabel->setAlignment(Qt::AlignCenter);
- m_backgroundLabel->setAlignment(Qt::AlignCenter);
- m_imageLabel->setAlignment(Qt::AlignCenter);
- m_textLabel->setAlignment(Qt::AlignCenter);
-
- m_previewLabel->setLayout(new QVBoxLayout);
- m_previewLabel->layout()->setMargin(0);
- m_previewLabel->layout()->addWidget(m_backgroundLabel);
- m_previewLabel->layout()->addWidget(m_textLabel);
- m_previewLabel->setCursor(Qt::PointingHandCursor);
-
- m_backgroundLabel->setLayout(new QVBoxLayout);
- m_backgroundLabel->layout()->addWidget(m_imageLabel);
-
- setLayout(new QHBoxLayout);
- layout()->setMargin(0);
- layout()->setAlignment(Qt::AlignCenter);
- layout()->addWidget(m_previewLabel);
-
- connect(this, SIGNAL(loadUrl(const KUrl &, const Rekonq::OpenType &)),
- Application::instance(), SLOT(loadUrl(const KUrl &, const Rekonq::OpenType &)));
-
- loadUrlPreview(url);
-}
-
-
-PreviewImage::~PreviewImage()
-{
- delete ws;
- delete m_textLabel;
- delete m_imageLabel;
- delete m_backgroundLabel;
- delete m_previewLabel;
-}
-
-
-QPixmap PreviewImage::renderBackground(int w, int h, int t, int b, int l, int r)
-{
- QImage backImage(KStandardDirs::locate("appdata", "pics/bg.png"));
- QImage resultImage(QSize(w + l + r, h + t + b), QImage::Format_ARGB32_Premultiplied);
-
- if (!backImage.isNull())
- {
- int sw = backImage.width() - l - r;
- int sh = backImage.height() - t - b;
- QPainter pt(&resultImage);
- pt.setCompositionMode(QPainter::CompositionMode_Source);
- pt.fillRect(resultImage.rect(), Qt::transparent);
- pt.drawImage(QRect(0, 0, l, t), backImage, QRect(0, 0, l, t));
- pt.drawImage(QRect(l, 0, w, t), backImage, QRect(l, 0, sw, t));
- pt.drawImage(QRect(l + w, 0, r, t), backImage, QRect(l + sw, 0, r, t));
- pt.drawImage(QRect(0, t, l, h), backImage, QRect(0, t, l, sh));
- pt.drawImage(QRect(l, t, w, h), backImage, QRect(l, t, sw, sh));
- pt.drawImage(QRect(l + w, t, r, h), backImage, QRect(l + sw, t, r, sh));
- pt.drawImage(QRect(0, t + h, l , b), backImage, QRect(0, t + sh, l , b));
- pt.drawImage(QRect(l, t + h, w, b), backImage, QRect(l, t + sh, sw, b));
- pt.drawImage(QRect(l + w, t + h, w, b), backImage, QRect(l + sw, t + sh, sw, b));
- pt.end();
- }
-
- return QPixmap::fromImage(resultImage);
-}
-
-
-void PreviewImage::loadUrlPreview(const QUrl& url)
-{
- m_url = url;
-
- if(url.isEmpty())
- {
- showEmptyPreview();
- return;
- }
-
- m_previewLabel->setFixedSize(m_size); //unhide
-
- m_savePath = KStandardDirs::locateLocal("cache", QString("thumbs/") + guessNameFromUrl(m_url) + ".png", true);
-
- if(QFile::exists(m_savePath))
- {
- m_pixmap.load(m_savePath);
- m_imageLabel->setPixmap(m_pixmap);
- checkTitle();
- m_textLabel->setText(m_title);
- }
- else
- {
- loadingSnapshot = true;
- ws = new WebSnap( url );
- connect(ws, SIGNAL(finished()), this, SLOT(snapFinished()));
-
- QString path = KStandardDirs::locate("appdata", "pics/busywidget.gif");
-
- // load an animation waiting for site preview
- QMovie *movie = new QMovie(path, QByteArray(), this);
- movie->setSpeed(50);
- m_imageLabel->setMovie(movie);
- movie->start();
- m_textLabel->setText( i18n("Loading preview...") );
- setCursor(Qt::BusyCursor);
- }
-}
-
-
-void PreviewImage::snapFinished()
-{
- loadingSnapshot = false;
- QMovie *m = m_imageLabel->movie();
- delete m;
- m_imageLabel->setMovie(0);
-
- m_pixmap = ws->previewImage();
- m_imageLabel->setPixmap(m_pixmap);
- checkTitle();
- m_textLabel->setText(m_title);
-
- setCursor(Qt::PointingHandCursor);
-
- m_pixmap.save(m_savePath);
-
- if(m_index > -1)
- {
- // Update title
- QStringList names = ReKonfig::previewNames();
- // update url (for added thumbs)
- QStringList urls = ReKonfig::previewUrls();
-
- // stripTrailingSlash to be sure to get the same string for same address
- urls.replace(m_index, ws->snapUrl().toString(QUrl::StripTrailingSlash));
- names.replace(m_index, ws->snapTitle());
-
- ReKonfig::setPreviewNames(names);
- ReKonfig::setPreviewUrls(urls);
-
- ReKonfig::self()->writeConfig();
- }
-}
-
-
-void PreviewImage::showEmptyPreview()
-{
- if(!m_isFavorite)
- return;
-
- m_imageLabel->clear();
- m_textLabel->clear();
-
- m_previewLabel->setFixedSize(0,0); //hide
-
-
- m_button = new QToolButton();
- m_button->setDefaultAction(historyMenu());
- m_button->setPopupMode(QToolButton::InstantPopup);
- m_button->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
- m_button->setText(i18n("Add Preview"));
- m_button->setAutoRaise(true);
- m_button->setIconSize(QSize(48, 48));
- layout()->addWidget(m_button);
-}
-
-
-void PreviewImage::mouseDoubleClickEvent(QMouseEvent *event)
-{
- kDebug() << "no double click over here, thanks :D";
- Q_UNUSED(event);
-}
-
-
-void PreviewImage::mouseMoveEvent(QMouseEvent *event)
-{
- kDebug() << "moving mouse over preview image";
- Q_UNUSED(event)
-}
-
-
-void PreviewImage::mousePressEvent(QMouseEvent *event)
-{
- if(event->button() == Qt::LeftButton)
- {
- emit loadUrl(m_url, Rekonq::CurrentTab);
- return;
- }
- else if(event->button() == Qt::MidButton)
- {
- emit loadUrl(m_url, Rekonq::SettingOpenTab);
- return;
- }
-
- QWidget::mousePressEvent(event);
-}
-
-
-void PreviewImage::mouseReleaseEvent(QMouseEvent *event)
-{
- kDebug() << "NO000... don't leave your finger from the button!!";
- Q_UNUSED(event)
-}
-
-
-void PreviewImage::contextMenuEvent(QContextMenuEvent* event)
-{
- if(!m_isFavorite)
- return;
-
- if(loadingSnapshot)
- return;
-
- KMenu menu(this);
- KAction *a;
-
- if(!m_url.isEmpty())
- {
- a = new KAction(KIcon("edit-delete"), i18n("Remove Thumbnail"), this);
- connect(a, SIGNAL(triggered(bool)), this, SLOT(removeMe()));
- menu.addAction(a);
-
- a = new KAction(KIcon("view-refresh"), i18n("Refresh Thumbnail"), &menu);
- connect(a, SIGNAL(triggered(bool)), this, SLOT(refreshPreview()));
- menu.addAction(a);
- }
- menu.addAction(historyMenu());
-
- menu.exec(mapToGlobal(event->pos()));
-}
-
-
-KActionMenu* PreviewImage::historyMenu()
-{
- KActionMenu *histMenu = new KActionMenu(KIcon("insert-image"), i18n("Set Page to Preview"), this);
- QList<HistoryItem> history = Application::historyManager()->history();
-
- if(history.isEmpty())
- {
- KAction *a = new KAction(i18n("History is Empty"), this);
- a->setEnabled(false);
- histMenu->addAction(a);
- return histMenu;
- }
-
- int maxItems = 15;
- for (int i = 0; i < maxItems && i < history.size() ; ++i)
- {
- HistoryItem it = history.at(i);
- KAction *a = new KAction(Application::icon(it.url), it.title, this);
- QStringList urlData;
- urlData << it.url << it.title;
- a->setData(urlData);
- connect(a, SIGNAL(triggered(bool)), this, SLOT(setUrlFromAction()));
- histMenu->addAction(a);
- }
-
- return histMenu;
-}
-
-
-void PreviewImage::removeMe()
-{
- QStringList names = ReKonfig::previewNames();
- QStringList urls = ReKonfig::previewUrls();
-
- int index = urls.indexOf(QRegExp(m_url.toString(QUrl::StripTrailingSlash), Qt::CaseSensitive, QRegExp::FixedString));
-
- urls.replace(index, QString(""));
- names.replace(index, QString(""));
-
- ReKonfig::setPreviewNames(names);
- ReKonfig::setPreviewUrls(urls);
-
- // sync file data
- ReKonfig::self()->writeConfig();
-
- showEmptyPreview();
-
- m_url = "";
-}
-
-
-void PreviewImage::setUrlFromAction()
-{
- KAction *a = qobject_cast<KAction*>(sender());
- QStringList urlData = a->data().toStringList();
-
- m_url = KUrl(urlData.at(0));
- m_title = urlData.at(1);
- checkTitle();
-
- if(m_button)
- {
- m_imageLabel->layout()->deleteLater();
- m_button->menu()->deleteLater();
- m_button->deleteLater();
- }
- loadUrlPreview(m_url);
-
- // Update title
- QStringList names = ReKonfig::previewNames();
- // update url (for added thumbs)
- QStringList urls = ReKonfig::previewUrls();
-
- // stripTrailingSlash to be sure to get the same string for same address
- urls.replace(m_index, m_url.toString(QUrl::StripTrailingSlash));
- names.replace(m_index, m_title);
-
- ReKonfig::setPreviewNames(names);
- ReKonfig::setPreviewUrls(urls);
-
- ReKonfig::self()->writeConfig();
-}
-
-
-void PreviewImage::refreshPreview()
-{
- QString path = KStandardDirs::locateLocal("cache", QString("thumbs/") + guessNameFromUrl(m_url) + ".png", true);
- QFile::remove(path);
- loadUrlPreview(m_url);
-}
-
-
-QString PreviewImage::guessNameFromUrl(QUrl url)
-{
- QString name = url.toString( QUrl::RemoveScheme | QUrl::RemoveUserInfo | QUrl::StripTrailingSlash );
-
- // TODO learn Regular Expressions :)
- // and implement something better here..
- name.remove('/');
- name.remove('&');
- name.remove('.');
- name.remove('-');
- name.remove('_');
- name.remove('?');
- name.remove('=');
- name.remove('+');
-
- return name;
-}
-
-
-void PreviewImage::checkTitle()
-{
- if(m_title.length() > 23)
- {
- m_title.truncate(20);
- m_title += "...";
- }
-}
diff --git a/src/previewimage.h b/src/previewimage.h
deleted file mode 100644
index 4dd8df3b..00000000
--- a/src/previewimage.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* ============================================================
-*
-* This file is a part of the rekonq project
-*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 PREVIEW_IMAGE_H
-#define PREVIEW_IMAGE_H
-
-// Local Includes
-#include "websnap.h"
-#include "application.h"
-
-// KDE Includes
-#include <KActionMenu>
-
-// Qt Includes
-#include <QLabel>
-#include <QFrame>
-#include <QImage>
-#include <QUrl>
-#include <QToolButton>
-#include <QSize>
-
-
-class PreviewImage : public QWidget
-{
- Q_OBJECT
-
-public:
- PreviewImage(const QUrl &url, const QString &title, int index, bool isFavorite);
- ~PreviewImage();
-
- QString guessNameFromUrl(QUrl url);
-
-public slots:
- void snapFinished();
- void removeMe();
- void setUrlFromAction();
- void refreshPreview();
-
-signals:
- void loadUrl(const KUrl &, const Rekonq::OpenType &);
-
-protected:
- void contextMenuEvent(QContextMenuEvent *event);
- void mouseDoubleClickEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
-
- void loadUrlPreview(const QUrl &url);
- KActionMenu *historyMenu();
- void showEmptyPreview();
-
-private:
- void checkTitle();
- QPixmap renderBackground(int w, int h, int t, int b, int l, int r);
-
- QPixmap m_pixmap;
- WebSnap *ws;
-
- QString m_savePath;
- bool loadingSnapshot;
-
- QUrl m_url;
- QString m_title;
- bool m_isFavorite;
- int m_index;
-
- QToolButton *m_button;
-
- QLabel *m_imageLabel;
- QLabel *m_textLabel;
- QLabel *m_backgroundLabel;
- QLabel *m_previewLabel;
-
- QSize m_size;
-};
-
-#endif // PREVIEW_IMAGE_H
diff --git a/src/previewselectorbar.cpp b/src/previewselectorbar.cpp
new file mode 100644
index 00000000..cacf6968
--- /dev/null
+++ b/src/previewselectorbar.cpp
@@ -0,0 +1,157 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 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/>.
+*
+* ============================================================ */
+
+
+// Auto Includes
+#include "previewselectorbar.h"
+#include "previewselectorbar.moc"
+
+// Self Includes
+#include "rekonq.h"
+
+// Local Include
+#include "websnap.h"
+#include "application.h"
+#include "mainwindow.h"
+#include "webtab.h"
+#include "webpage.h"
+
+// KDE Includes
+#include <KIcon>
+#include <KLocalizedString>
+
+// Qt Includes
+#include <QtCore/QString>
+
+#include <QtGui/QToolButton>
+#include <QtGui/QHBoxLayout>
+
+
+
+PreviewSelectorBar::PreviewSelectorBar(int index, QWidget* parent)
+ : QWidget(parent)
+ , m_button(0)
+ , m_label(0)
+ , m_previewIndex(index)
+{
+ m_label = new QLabel(i18n("Please open up the webpage you want to add as favorite"), this);
+ m_label->setWordWrap(true);
+
+ QToolButton *closeButton = new QToolButton(this);
+ closeButton->setAutoRaise(true);
+ closeButton->setIcon(KIcon("dialog-close"));
+ connect(closeButton, SIGNAL(clicked(bool)), this, SLOT(destroy()));
+
+ m_button = new QPushButton(KIcon("insert-image"), i18n("Set to This Page"), this);
+ m_button->setMaximumWidth(250);
+ connect(m_button, SIGNAL(clicked(bool)), this, SLOT(clicked()));
+
+ // layout
+ QHBoxLayout *layout = new QHBoxLayout(this);
+ layout->addWidget(closeButton);
+ layout->addWidget(m_label);
+ layout->addWidget(m_button);
+
+ layout->setContentsMargins(2, 0, 2, 0);
+
+ setLayout(layout);
+}
+
+
+PreviewSelectorBar::~PreviewSelectorBar()
+{
+}
+
+
+void PreviewSelectorBar::verifyUrl()
+{
+
+ if (Application::instance()->mainWindow()->currentTab()->page()->mainFrame()->url().scheme() != "about")
+ {
+ m_button->setEnabled(true);
+ m_button->setToolTip("");
+ }
+ else
+ {
+ m_button->setEnabled(false);
+ m_button->setToolTip(i18n("You can not add this webpage as favorite"));
+ }
+}
+
+
+void PreviewSelectorBar::loadProgress()
+{
+ m_button->setEnabled(false);
+ m_button->setToolTip(i18n("Page is loading..."));
+}
+
+
+void PreviewSelectorBar::loadFinished()
+{
+ m_button->setEnabled(true);
+ m_button->setToolTip("");
+
+ verifyUrl();
+}
+
+
+void PreviewSelectorBar::clicked()
+{
+ WebPage *page = Application::instance()->mainWindow()->currentTab()->page();
+
+ if (page)
+ {
+ // this is done just lo let the render process being faster..
+ WebSnap::renderPreview(*page);
+
+ KUrl url = page->mainFrame()->url();
+ QStringList names = ReKonfig::previewNames();
+ QStringList urls = ReKonfig::previewUrls();
+
+ urls.replace(m_previewIndex, url.toMimeDataString());
+ names.replace(m_previewIndex, page->mainFrame()->title());
+
+ ReKonfig::setPreviewNames(names);
+ ReKonfig::setPreviewUrls(urls);
+
+ ReKonfig::self()->writeConfig();
+
+
+ page->mainFrame()->load(KUrl("about:favorites"));
+ }
+
+ destroy();
+}
+
+
+void PreviewSelectorBar::destroy()
+{
+ if (parentWidget() && parentWidget()->layout())
+ {
+ parentWidget()->layout()->removeWidget(this);
+ }
+ this->deleteLater();
+}
diff --git a/src/urlbar/lineedit.cpp b/src/previewselectorbar.h
index f3c93e8e..6f2acd41 100644
--- a/src/urlbar/lineedit.cpp
+++ b/src/previewselectorbar.h
@@ -2,9 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +11,9 @@
* 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
+* 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
@@ -26,44 +25,41 @@
* ============================================================ */
-// Self Includes
-#include "lineedit.h"
-#include "lineedit.moc"
+#ifndef PREVIEWSELECTORBAR_H
+#define PREVIEWSELECTORBAR_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
// Qt Includes
-#include <QtGui/QContextMenuEvent>
-#include <QtGui/QFocusEvent>
-#include <QtGui/QKeyEvent>
+#include <QWidget>
+#include <QPushButton>
+#include <QLabel>
-LineEdit::LineEdit(QWidget* parent)
- : KLineEdit(parent)
+class REKONQ_TESTS_EXPORT PreviewSelectorBar : public QWidget
{
- setMinimumWidth(200);
- setFocusPolicy(Qt::WheelFocus);
- setHandleSignals(true);
- setClearButtonShown(true);
-}
+ Q_OBJECT
+public:
+ PreviewSelectorBar(int index, QWidget *parent);
+ ~PreviewSelectorBar();
-LineEdit::~LineEdit()
-{
-}
+private slots:
+ void clicked();
+ void loadProgress();
+ void loadFinished();
-void LineEdit::keyPressEvent(QKeyEvent *event)
-{
- if (event->key() == Qt::Key_Escape)
- {
- clearFocus();
- event->accept();
- }
+ void verifyUrl();
- KLineEdit::keyPressEvent(event);
-}
+ void destroy();
+private:
+ QPushButton *m_button;
+ QLabel *m_label;
-void LineEdit::mouseDoubleClickEvent(QMouseEvent *)
-{
- selectAll();
-}
+ int m_previewIndex;
+};
+
+#endif // PREVIEWSELECTORBAR_H
diff --git a/src/protocolhandler.cpp b/src/protocolhandler.cpp
index cd75d06f..51bd7e9a 100644
--- a/src/protocolhandler.cpp
+++ b/src/protocolhandler.cpp
@@ -2,16 +2,16 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 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
+* 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
@@ -36,7 +36,9 @@
#include "mainwindow.h"
#include "mainview.h"
#include "urlbar.h"
+#include "webtab.h"
#include "historymanager.h"
+#include "adblockmanager.h"
// KDE Includes
#include <klocalizedstring.h>
@@ -44,13 +46,13 @@
#include <KRun>
#include <KToolInvocation>
#include <KStandardDirs>
-#include <KDebug>
#include <KMimeType>
#include <KIconLoader>
#include <KDirLister>
#include <KFileItem>
#include <KJob>
#include <kio/udsentry.h>
+#include <KMessageBox>
// Qt Includes
#include <QLatin1String>
@@ -62,11 +64,10 @@
ProtocolHandler::ProtocolHandler(QObject *parent)
- : QObject(parent)
- , _lister(new KDirLister)
- , _frame(0)
+ : QObject(parent)
+ , _lister(0)
+ , _frame(0)
{
- connect( _lister, SIGNAL(newItems(const KFileItemList &)), this, SLOT(showResults(const KFileItemList &)));
}
@@ -79,38 +80,49 @@ bool ProtocolHandler::preHandling(const QNetworkRequest &request, QWebFrame *fra
{
_url = request.url();
_frame = frame;
-
- kDebug() << "URL PROTOCOL: " << _url;
-
- // relative urls
- if(_url.isRelative())
- return false;
-
+
// "http(s)" (fast) handling
- if( _url.protocol() == QLatin1String("http") || _url.protocol() == QLatin1String("https") )
+ if (_url.protocol() == QL1S("http") || _url.protocol() == QL1S("https"))
+ return false;
+
+ // relative urls
+ if (_url.isRelative())
return false;
-
+
// javascript handling
- if( _url.protocol() == QLatin1String("javascript") )
+ if (_url.protocol() == QL1S("javascript"))
{
QString scriptSource = _url.authority();
QVariant result = frame->evaluateJavaScript(scriptSource);
return true;
}
-
+
// "mailto" handling
- if ( _url.protocol() == QLatin1String("mailto") )
+ if (_url.protocol() == QL1S("mailto"))
{
KToolInvocation::invokeMailer(_url);
return true;
}
+ // "abp" handling
+ if (_url.protocol() == QL1S("abp"))
+ {
+ abpHandling();
+ return true;
+ }
+
// "about" handling
- if ( _url.protocol() == QLatin1String("about") )
+ if (_url.protocol() == QL1S("about"))
{
- if( _url == KUrl("about:home") )
+ // let webkit manage the about:blank url...
+ if (_url == KUrl("about:blank"))
+ {
+ return false;
+ }
+
+ if (_url == KUrl("about:home"))
{
- switch(ReKonfig::newTabStartPage())
+ switch (ReKonfig::newTabStartPage())
{
case 0: // favorites
_url = KUrl("about:favorites");
@@ -118,28 +130,24 @@ bool ProtocolHandler::preHandling(const QNetworkRequest &request, QWebFrame *fra
case 1: // closed tabs
_url = KUrl("about:closedTabs");
break;
- case 2: // history
- _url = KUrl("about:history");
- break;
- case 3: // bookmarks
+ case 2: // bookmarks
_url = KUrl("about:bookmarks");
break;
+ case 3: // history
+ _url = KUrl("about:history");
+ break;
+ case 4: // downloads
+ _url = KUrl("about:downloads");
default: // unuseful
break;
}
}
- if( _url == KUrl("about:closedTabs")
- || _url == KUrl("about:history")
- || _url == KUrl("about:bookmarks")
- || _url == KUrl("about:favorites")
- )
- {
- NewTabPage p(frame);
- p.generate(_url);
- return true;
- }
+
+ NewTabPage p(frame);
+ p.generate(_url);
+ return true;
}
-
+
return false;
}
@@ -148,16 +156,16 @@ bool ProtocolHandler::postHandling(const QNetworkRequest &request, QWebFrame *fr
{
_url = request.url();
_frame = frame;
-
+
kDebug() << "URL PROTOCOL: " << _url;
-
+
// "http(s)" (fast) handling
- if( _url.protocol() == QLatin1String("http") || _url.protocol() == QLatin1String("https") )
+ if (_url.protocol() == QL1S("http") || _url.protocol() == QL1S("https"))
return false;
-
+
// "mailto" handling: It needs to be handled both here(mail links clicked)
// and in prehandling (mail url launched)
- if ( _url.protocol() == QLatin1String("mailto") )
+ if (_url.protocol() == QL1S("mailto"))
{
KToolInvocation::invokeMailer(_url);
return true;
@@ -168,48 +176,63 @@ bool ProtocolHandler::postHandling(const QNetworkRequest &request, QWebFrame *fr
// My idea is: webkit cannot handle in any way ftp. So we have surely to return true here.
// We start trying to guess what the url represent: it's a dir? show its contents (and download them).
// it's a file? download it. It's another thing? beat me, but I don't know what to do...
- if( _url.protocol() == QLatin1String("ftp") )
+ if (_url.protocol() == QL1S("ftp"))
{
KIO::StatJob *job = KIO::stat(_url);
- connect(job, SIGNAL(result(KJob*)), this, SLOT( slotMostLocalUrlResult(KJob*) ));
+ connect(job, SIGNAL(result(KJob*)), this, SLOT(slotMostLocalUrlResult(KJob*)));
return true;
}
-
+
// "file" handling. This is quite trivial :)
- if(_url.protocol() == QLatin1String("file") )
+ if (_url.protocol() == QL1S("file"))
{
- QFileInfo fileInfo( _url.path() );
- if(fileInfo.isDir())
+ QFileInfo fileInfo(_url.path());
+ if (fileInfo.isDir())
{
+ _lister = new KDirLister;
+ connect(_lister, SIGNAL(newItems(const KFileItemList &)), this, SLOT(showResults(const KFileItemList &)));
_lister->openUrl(_url);
- Application::instance()->mainWindow()->mainView()->urlBar()->setUrl(_url);
+
return true;
}
}
-
+
return false;
}
-QString ProtocolHandler::dirHandling(const KFileItemList &list)
-{
+// ---------------------------------------------------------------------------------------------------------------------------
+
- KFileItem mainItem = _lister->rootItem();
- KUrl rootUrl = mainItem.url();
-
- if (mainItem.isNull())
+void ProtocolHandler::showResults(const KFileItemList &list)
+{
+ if (!_lister->rootItem().isNull() && _lister->rootItem().isReadable() && _lister->rootItem().isFile())
{
- QString errStr = i18n("Error opening: %1: No such file or directory", rootUrl.prettyUrl() );
- return errStr;
+ emit downloadUrl(_lister->rootItem().url());
+ return;
}
-
- if (!mainItem.isReadable())
+
+ QString html = dirHandling(list);
+ _frame->setHtml(html, _url);
+
+ Application::instance()->mainWindow()->currentTab()->setFocus();
+ Application::historyManager()->addHistoryEntry(_url.prettyUrl());
+
+ delete _lister;
+}
+
+
+QString ProtocolHandler::dirHandling(const KFileItemList &list)
+{
+ if (!_lister)
{
- QString errStr = i18n("Unable to read %1", rootUrl.prettyUrl() );
- return errStr;
+ return QString("rekonq error, sorry :(");
}
-
- // display "rekonq info" page
+
+ // let me modify it..
+ KUrl rootUrl = _url;
+
+ // display "rekonq info" page
QString infoFilePath = KStandardDirs::locate("data", "rekonq/htmls/rekonqinfo.html");
QFile file(infoFilePath);
@@ -219,18 +242,18 @@ QString ProtocolHandler::dirHandling(const KFileItemList &list)
return QString("rekonq error, sorry :(");
}
- QString title = _url.prettyUrl();
- QString msg = "<h1>" + i18n("Index of ") + _url.prettyUrl() + "</h1>";
+ QString title = _url.prettyUrl();
+ QString msg = i18nc("%1=an URL", "<h1>Index of %1</h1>", _url.prettyUrl());
- if(rootUrl.cd(".."))
+ if (rootUrl.cd(".."))
{
QString path = rootUrl.prettyUrl();
- QString uparrow = KIconLoader::global()->iconPath( "arrow-up", KIconLoader::Small );
+ QString uparrow = KIconLoader::global()->iconPath("arrow-up", KIconLoader::Small);
msg += "<img src=\"file://" + uparrow + "\" alt=\"up-arrow\" />";
msg += "<a href=\"" + path + "\">" + i18n("Up to higher level directory") + "</a><br /><br />";
}
-
+
msg += "<table width=\"100%\">";
msg += "<tr><th align=\"left\">" + i18n("Name") + "</th><th>" + i18n("Size") + "</th><th>" + i18n("Last Modified") + "</th></tr>";
@@ -238,63 +261,43 @@ QString ProtocolHandler::dirHandling(const KFileItemList &list)
{
msg += "<tr>";
QString fullPath = item.url().prettyUrl();
-
+
QString iconName = item.iconName();
- QString icon = QString("file://") + KIconLoader::global()->iconPath( iconName, KIconLoader::Small );
-
+ QString icon = QString("file://") + KIconLoader::global()->iconPath(iconName, KIconLoader::Small);
+
msg += "<td width=\"70%\">";
msg += "<img src=\"" + icon + "\" alt=\"" + iconName + "\" /> ";
msg += "<a href=\"" + fullPath + "\">" + item.name() + "</a>";
msg += "</td>";
-
+
msg += "<td align=\"right\">";
- if(item.isFile())
+ if (item.isFile())
{
- msg += QString::number( item.size()/1024 ) + " KB";
+ msg += QString::number(item.size() / 1024) + " KB";
}
msg += "</td>";
-
+
msg += "<td align=\"right\">";
msg += item.timeString();
msg += "</td>";
-
+
msg += "</tr>";
}
msg += "</table>";
-
-
- QString html = QString(QLatin1String(file.readAll()))
- .arg(title)
- .arg(msg)
- ;
-
- return html;
-}
-void ProtocolHandler::showResults(const KFileItemList &list)
-{
- if(_lister->rootItem().isFile())
- {
- WebPage *page = qobject_cast<WebPage *>( _frame->page() );
- page->downloadUrl( _lister->rootItem().url() );
- return;
- }
-
- if ( list.isEmpty() )
- return;
-
- QString html = dirHandling(list);
- _frame->setHtml(html);
+ QString html = QString(QL1S(file.readAll()))
+ .arg(title)
+ .arg(msg)
+ ;
- Application::instance()->mainWindow()->mainView()->urlBar()->setUrl(_url);
- Application::historyManager()->addHistoryEntry( _url.prettyUrl() );
+ return html;
}
void ProtocolHandler::slotMostLocalUrlResult(KJob *job)
{
- if(job->error())
+ if (job->error())
{
// TODO
kDebug() << "error";
@@ -303,9 +306,69 @@ void ProtocolHandler::slotMostLocalUrlResult(KJob *job)
{
KIO::StatJob *statJob = static_cast<KIO::StatJob*>(job);
KIO::UDSEntry entry = statJob->statResult();
- if( entry.isDir() )
+ if (entry.isDir())
+ {
+ _lister = new KDirLister;
+ connect(_lister, SIGNAL(newItems(const KFileItemList &)), this, SLOT(showResults(const KFileItemList &)));
_lister->openUrl(_url);
+ }
else
+ {
emit downloadUrl(_url);
+ }
+ }
+}
+
+
+/**
+ * abp scheme (easy) explanation
+ *
+ */
+void ProtocolHandler::abpHandling()
+{
+ kDebug() << _url;
+
+ QString path = _url.path();
+ if (path != QL1S("subscribe"))
+ return;
+
+ QMap<QString, QString> map = _url.queryItems(KUrl::CaseInsensitiveKeys);
+
+ QString location = map.value(QL1S("location"));
+ kDebug() << location;
+
+ QString title = map.value(QL1S("title"));
+ kDebug() << title;
+
+ QString requireslocation = map.value(QL1S("requireslocation"));
+ kDebug() << requireslocation;
+
+ QString requirestitle = map.value(QL1S("requirestitle"));
+ kDebug() << requirestitle;
+
+ QString info;
+ if (requirestitle.isEmpty() || requireslocation.isEmpty())
+ {
+ info = title;
+ }
+ else
+ {
+ info = i18n("\n %1,\n %2 (required by %3)\n", title, requirestitle, title);
+ }
+
+ if (KMessageBox::questionYesNo(0,
+ i18n("Do you want to add the following subscriptions to your adblock settings?\n") + info,
+ i18n("Add automatic subscription to the adblock"),
+ KGuiItem(i18n("Add")),
+ KGuiItem(i18n("Discard"))
+ )
+ )
+ {
+ if (!requireslocation.isEmpty() && !requirestitle.isEmpty())
+ {
+ Application::adblockManager()->addSubscription(requirestitle, requireslocation);
+ }
+ Application::adblockManager()->addSubscription(title, location);
+ Application::adblockManager()->loadSettings(false);
}
}
diff --git a/src/protocolhandler.h b/src/protocolhandler.h
index 6ae47b74..a8661f81 100644
--- a/src/protocolhandler.h
+++ b/src/protocolhandler.h
@@ -2,16 +2,16 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 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
+* 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
@@ -27,6 +27,10 @@
#ifndef PROTOCOL_HANDLER_H
#define PROTOCOL_HANDLER_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// KDE Includes
#include <KDirLister>
@@ -41,12 +45,12 @@ class KUrl;
class KJob;
-class ProtocolHandler : public QObject
+class REKONQ_TESTS_EXPORT ProtocolHandler : public QObject
{
-Q_OBJECT
+ Q_OBJECT
public:
- ProtocolHandler(QObject *parent = 0);
+ ProtocolHandler(QObject *parent = 0);
~ProtocolHandler();
/**
@@ -60,17 +64,18 @@ public:
* WebKit tried to
*/
bool postHandling(const QNetworkRequest &request, QWebFrame *frame);
-
+
signals:
- void downloadUrl( const KUrl &);
-
+ void downloadUrl(const KUrl &);
+
private slots:
void showResults(const KFileItemList &);
void slotMostLocalUrlResult(KJob *);
-
+
private:
QString dirHandling(const KFileItemList &list);
-
+ void abpHandling();
+
KDirLister *_lister;
QWebFrame *_frame;
KUrl _url;
diff --git a/src/rekonq.kcfg b/src/rekonq.kcfg
index a24508fc..3658b324 100644
--- a/src/rekonq.kcfg
+++ b/src/rekonq.kcfg
@@ -7,17 +7,40 @@
<!-- Includes -->
<include>QtWebKit</include>
+<include>QDateTime</include>
<include>KUrl</include>
<kcfgfile name="rekonqrc" />
+<!-- Miscellaneuos (not config UI) settins -->
+<group name="misc">
+ <entry name="FirstExecution" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry name="showHistoryPanel" type="Bool">
+ <default>false</default>
+ </entry>
+ <entry name="showBookmarksPanel" type="Bool">
+ <default>false</default>
+ </entry>
+ <entry name="walletBlackList" type="StringList">
+ <default></default>
+ </entry>
+ <entry name="recoverOnCrash" type="Int">
+ <default>0</default>
+ </entry>
+ <entry name="defaultEncoding" type="String">
+ <default>UTF-8</default>
+ </entry>
+</group>
+
<!-- New Tab Page Settings -->
<group name="NewTabPage">
<entry name="previewNames" type="StringList">
- <default>KDE Homepage,KDE-Apps,KDE-Look,UserBase,KDE Community Forums,TechBase,Planet KDE,rekonq</default>
+ <default>KDE Homepage,UserBase,rekonq site</default>
</entry>
<entry name="previewUrls" type="StringList">
- <default>http://www.kde.org,http://kde-apps.org,http://kde-look.org,http://userbase.kde.org,http://forum.kde.org,http://techbase.kde.org,http://planetkde.org,http://rekonq.sourceforge.net</default>
+ <default>http://www.kde.org,http://userbase.kde.org,http://rekonq.sourceforge.net</default>
</entry>
</group>
@@ -35,19 +58,16 @@
<entry name="homePage" type="String">
<default>http://www.kde.org/</default>
</entry>
- <entry name="showHistoryPanel" type="Bool">
- <default>false</default>
- </entry>
- <entry name="showBookmarksPanel" type="Bool">
- <default>false</default>
- </entry>
<entry name="kgetDownload" type="Bool">
<default>false</default>
</entry>
<entry name="kgetList" type="Bool">
<default>false</default>
</entry>
- </group>
+ <entry name="searchEngine" type="Int">
+ <default>0</default>
+ </entry>
+ </group>
<!-- Tabs Settings -->
<group name="Tabs">
@@ -93,12 +113,6 @@
<entry name="expireHistory" type="Int">
<default>1</default>
</entry>
- <entry name="acceptCookies" type="Int">
- <default>2</default>
- </entry>
- <entry name="keepCookiesUntil" type="Int">
- <default>0</default>
- </entry>
</group>
<!-- WebKit Settings -->
@@ -106,6 +120,9 @@
<entry name="autoLoadImages" type="Bool">
<default>true</default>
</entry>
+ <entry name="dnsPrefetch" type="Bool">
+ <default>true</default>
+ </entry>
<entry name="javascriptEnabled" type="Bool">
<default>true</default>
</entry>
@@ -136,7 +153,7 @@
<entry name="offlineWebApplicationCacheEnabled" type="Bool">
<default>true</default>
</entry>
- <entry name="localStorageDatabaseEnabled" type="Bool">
+ <entry name="localStorageEnabled" type="Bool">
<default>true</default>
</entry>
<entry name="userCSS" type="Url">
@@ -144,4 +161,27 @@
</entry>
</group>
+
+<!-- AdBlock Settings -->
+ <group name="AdBlock">
+ <entry name="adBlockEnabled" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry name="hideAdsEnabled" type="Bool">
+ <default>true</default>
+ </entry>
+ <entry name="subscriptionTitles" type="StringList">
+ <default>EasyList</default>
+ </entry>
+ <entry name="subscriptionLocations" type="StringList">
+ <default>https://easylist-downloads.adblockplus.org/easylist.txt</default>
+ </entry>
+ <entry name="lastUpdate" type="DateTime">
+ <default>QDateTime(QDate(2009,03,13))</default>
+ </entry>
+ <entry name="updateInterval" type="Int">
+ <default>7</default>
+ </entry>
+ </group>
+
</kcfg>
diff --git a/src/rekonq_defines.h b/src/rekonq_defines.h
new file mode 100644
index 00000000..c8755e03
--- /dev/null
+++ b/src/rekonq_defines.h
@@ -0,0 +1,98 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2007 David Faure <faure@kde.org>
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 REKONQ_DEFINES_H
+#define REKONQ_DEFINES_H
+
+
+// ----------------------------------------------------------------------------------------------------
+// UNIT TESTS NEED
+
+/* needed for KDE_EXPORT and KDE_IMPORT macros */
+#include <kdemacros.h>
+
+/* Classes from the rekonq application, which are exported only for unit tests */
+#ifndef REKONQ_TESTS_EXPORT
+/* We are building this library */
+#define REKONQ_TESTS_EXPORT KDE_EXPORT
+#else
+/* We are using this library */
+#define REKONQ_TESTS_EXPORT KDE_IMPORT
+#endif
+
+
+// ----------------------------------------------------------------------------------------------------
+// DEFINES
+
+#define QL1S(x) QLatin1String(x)
+#define QL1C(x) QLatin1Char(x)
+
+
+
+// ----------------------------------------------------------------------------------------------------
+// ENUMS
+
+namespace Rekonq
+{
+ /**
+ * @short notifying message status
+ * Different message status
+ */
+
+ enum Notify
+ {
+ Success, ///< url successfully (down)loaded
+ Error, ///< url failed to (down)load
+ Download, ///< downloading url
+ Info ///< information, (default)
+ };
+
+ /**
+ * @short Open link options
+ * Different modes of opening new tab
+ */
+ enum OpenType
+ {
+ CurrentTab, ///< open url in current tab
+ SettingOpenTab, ///< open url according to users settings
+ NewCurrentTab, ///< open url in new tab and make it current
+ NewBackTab, ///< open url in new tab in background
+ NewWindow ///< open url in new window
+ };
+}
+
+
+// ----------------------------------------------------------------------------------------------------
+// INCLUDES
+
+#include <KDebug>
+
+
+
+// ----------------------------------------------------------------------------------------------------
+
+#endif // REKONQ_DEFINES_H
diff --git a/src/rekonqpage/newtabpage.cpp b/src/rekonqpage/newtabpage.cpp
deleted file mode 100644
index 66f74b86..00000000
--- a/src/rekonqpage/newtabpage.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-/* ============================================================
-*
-* This file is a part of the rekonq project
-*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 "newtabpage.h"
-
-// Auto Includes
-#include "rekonq.h"
-
-// Local Includes
-#include "historymodels.h"
-#include "bookmarksmanager.h"
-#include "application.h"
-#include "mainwindow.h"
-#include "mainview.h"
-
-// KDE Includes
-#include <KStandardDirs>
-#include <KIconLoader>
-#include <KDebug>
-#include <KConfig>
-#include <KConfigGroup>
-
-// Qt Includes
-#include <QFile>
-
-
-NewTabPage::NewTabPage(QWebFrame *frame)
- : m_root(frame->documentElement())
-{
- QString htmlFilePath = KStandardDirs::locate("data", "rekonq/htmls/home.html");
-
- QFile file(htmlFilePath);
- bool isOpened = file.open(QIODevice::ReadOnly);
- if (!isOpened)
- kWarning() << "Couldn't open the home.html file";
-
- QString imagesPath = QString("file://") + KGlobal::dirs()->findResourceDir("data", "rekonq/pics/bg.png") + QString("rekonq/pics");
-
- m_html = file.readAll();
- m_html.replace(QString("%2"), imagesPath);
-}
-
-
-NewTabPage::~NewTabPage()
-{
-}
-
-
-void NewTabPage::generate(const KUrl &url)
-{
- QWebPage *page = m_root.webFrame()->page();
- page->mainFrame()->setHtml(m_html);
-
- m_root = page->mainFrame()->documentElement().findFirst("#content");
-
- browsingMenu(url);
-
- QString title;
- if(url == KUrl("about:closedTabs"))
- {
- closedTabsPage();
- title = i18n("Closed Tabs");
- }
- if(url == KUrl("about:history"))
- {
- historyPage();
- title = i18n("History");
- }
- if(url == KUrl("about:bookmarks"))
- {
- bookmarksPage();
- title = i18n("Bookmarks");
- }
- if(url == KUrl("about:home") || url == KUrl("about:favorites"))
- {
- favoritesPage();
- title = i18n("Favorites");
- }
-
- m_root.document().findFirst("title").setPlainText(title);
-}
-
-
-void NewTabPage::favoritesPage()
-{
- QStringList names = ReKonfig::previewNames();
- QStringList urls = ReKonfig::previewUrls();
-
- m_root.addClass("favorites");
-
- for(int i=0; i<8; ++i)
- {
- QWebElement speed = markup(".thumbnail");
- speed.findFirst("object").setAttribute("data" , urls.at(i));
- speed.findFirst("param[name=title]").setAttribute("value", names.at(i));
- speed.findFirst("param[name=index]").setAttribute("value", QString::number(i));
- speed.findFirst("param[name=isFavorite]").setAttribute("value", "true");
- m_root.appendInside(speed);
- }
-}
-
-
-// FIXME : port to new PreviewImage API to use...
-/*QString NewTabPage::lastVisitedPage()
-{
- QString last;
- QList<HistoryItem> history = Application::historyManager()->history();
- for (int i = 0; i < 8 && i < history.size(); ++i)
- {
- HistoryItem it = history.at(i);
- last += "<div class=\"thumbnail\">";
- last += "<object type=\"application/image-preview\" data=\"" + it.url + "\" >";
- last += "</object>";
- last += "<br />";
- last += "<a href=\"" + it.url + "\">" + it.title + "</a></div>";
- }
-
- return last;
-
-}*/
-
-
-void NewTabPage::browsingMenu(const KUrl &currentUrl)
-{
- QList<QWebElement> navItems;
-
- KIconLoader *loader = KIconLoader::global();
-
- QWebElement nav = markup(".link"); // Favorites
- nav.findFirst("a").setAttribute("href", "about:favorites");
- nav.findFirst("img").setAttribute("src" , QString("file:///" +
- loader->iconPath("emblem-favorite", KIconLoader::Desktop ||KIconLoader::SizeSmall)));
- nav.findFirst("a").appendInside(i18n("Favorites"));
- navItems.append(nav);
-
- nav = markup(".link"); // Closed Tabs
- nav.findFirst("a").setAttribute("href", "about:closedTabs");
- nav.findFirst("img").setAttribute("src" , QString("file:///" +
- loader->iconPath("tab-close", KIconLoader::Desktop ||KIconLoader::SizeSmall)));
- nav.findFirst("a").appendInside(i18n("Closed Tabs"));
- navItems.append(nav);
-
- nav = markup(".link"); // Bookmarks
- nav.findFirst("a").setAttribute("href", "about:bookmarks");
- nav.findFirst("img").setAttribute("src" , QString("file:///" +
- loader->iconPath("bookmarks", KIconLoader::Desktop ||KIconLoader::SizeSmall)));
- nav.findFirst("a").appendInside(i18n("Bookmarks"));
- navItems.append(nav);
-
- nav = markup(".link"); // History
- nav.findFirst("a").setAttribute("href", "about:history");
- nav.findFirst("img").setAttribute("src" , QString("file:///" +
- loader->iconPath("view-history", KIconLoader::Desktop ||KIconLoader::SizeSmall)));
- nav.findFirst("a").appendInside(i18n("History"));
- navItems.append(nav);
-
- QWebElement it;
- foreach(it, navItems)
- {
- if(it.findFirst("a").attribute("href") == currentUrl.toMimeDataString())
- it.addClass("current");
- else if(currentUrl == "about:home" && it.findFirst("a").attribute("href") == "about:favorites")
- it.addClass("current");
- m_root.document().findFirst("#navigation").appendInside(it);
- }
-}
-
-
-void NewTabPage::historyPage()
-{
- HistoryTreeModel *model = Application::historyManager()->historyTreeModel();
-
- int i = 0;
- do
- {
- QModelIndex index = model->index(i, 0, QModelIndex() );
- if(model->hasChildren(index))
- {
- m_root.appendInside(markup("h3"));
- m_root.lastChild().setPlainText(index.data().toString());
-
- for(int j=0; j< model->rowCount(index); ++j)
- {
- QModelIndex son = model->index(j, 0, index );
- m_root.appendInside(son.data(HistoryModel::DateTimeRole).toDateTime().toString("hh:mm"));
- m_root.appendInside(" ");
- m_root.appendInside(markup("a"));
- m_root.lastChild().setAttribute("href" , son.data(HistoryModel::UrlStringRole).toString());
- m_root.lastChild().appendInside(son.data().toString());
- m_root.appendInside("<br/>");
- }
- }
- i++;
- }
- while( model->hasIndex( i , 0 , QModelIndex() ) );
-}
-
-
-void NewTabPage::bookmarksPage()
-{
- KBookmarkGroup bookGroup = Application::bookmarkProvider()->rootGroup();
- if (bookGroup.isNull())
- {
- return;
- }
-
- KBookmark bookmark = bookGroup.first();
- while (!bookmark.isNull())
- {
- createBookItem(bookmark, m_root);
- bookmark = bookGroup.next(bookmark);
- }
-}
-
-
-void NewTabPage::createBookItem(const KBookmark &bookmark, QWebElement parent)
-{
- if (bookmark.isGroup())
- {
- KBookmarkGroup group = bookmark.toGroup();
- KBookmark bm = group.first();
- parent.appendInside(markup("h3"));
- parent.lastChild().setPlainText(group.text());
- parent.appendInside(markup(".bookfolder"));
- while (!bm.isNull())
- {
- createBookItem(bm, parent.lastChild()); // it is .bookfolder
- bm = group.next(bm);
- }
- }
- else if(bookmark.isSeparator())
- {
- parent.appendInside("<hr/>");
- }
- else
- {
- parent.appendInside(markup("a"));
- parent.lastChild().setAttribute("href" , bookmark.url().prettyUrl());
- parent.lastChild().setPlainText(bookmark.text());
- parent.appendInside("<br/>");
- }
-}
-
-
-void NewTabPage::closedTabsPage()
-{
- QList<HistoryItem> links = Application::instance()->mainWindow()->mainView()->recentlyClosedTabs();
-
- foreach(const HistoryItem &item, links)
- {
- QWebElement closed = markup(".thumbnail");
- closed.findFirst("object").setAttribute("data" , item.url);
- closed.findFirst("param[name=title]").setAttribute("value", item.title);
- m_root.appendInside(closed);
- }
-}
diff --git a/src/rekonqpage/newtabpage.h b/src/rekonqpage/newtabpage.h
deleted file mode 100644
index 003aa84e..00000000
--- a/src/rekonqpage/newtabpage.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* ============================================================
-*
-* This file is a part of the rekonq project
-*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 REKONQ_NEW_TAB_PAGE
-#define REKONQ_NEW_TAB_PAGE
-
-
-// rekonq Includes
-#include <webpage.h>
-
-// KDE Includes
-#include <KUrl>
-
-// Qt Includes
-#include <QtCore/QObject>
-#include <QtCore/QString>
-#include <QWebElement>
-
-// Forward Includes
-class KBookmark;
-
-
-class NewTabPage
-{
-
-public:
- NewTabPage(QWebFrame *frame);
- ~NewTabPage();
-
- /**
- * This is the unique NewTabPage public method. It takes an
- * about: url and loads the corresponding part of the
- * new tab page
- */
- void generate(const KUrl &url = KUrl("about:home"));
-
-protected: // these are the function to build the new tab page
- void browsingMenu(const KUrl &currentUrl);
-
- void favoritesPage();
- //QString lastVisitedPage();
- void historyPage();
- void bookmarksPage();
- void closedTabsPage();
-
-private:
- void createBookItem(const KBookmark &bookmark, QWebElement parent);
-
- /** This function helps to get faster a new markup of one type,it isn't easy to create one with QWebElement.
- It gets it in the #models div of home.html.
- It works for all elements defined here.
- */
- inline QWebElement markup(QString selector)
- {
- return m_root.document().findFirst("#models > " + selector).clone();
- }
-
- QString m_html;
-
- QWebElement m_root;
-};
-
-#endif // REKONQ_NEW_TAB_PAGE
diff --git a/src/searchengine.cpp b/src/searchengine.cpp
new file mode 100644
index 00000000..0d2c6aea
--- /dev/null
+++ b/src/searchengine.cpp
@@ -0,0 +1,167 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
+*
+*
+* 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/>.
+*
+* ============================================================ */
+
+
+//local includes
+#include "searchengine.h"
+
+// Auto Includes
+#include "rekonq.h"
+
+//KDE includes
+#include <KConfigGroup>
+#include <KServiceTypeTrader>
+
+
+QString SearchEngine::m_delimiter = "";
+
+
+QString SearchEngine::delimiter()
+{
+ if (m_delimiter == "") loadDelimiter();
+ return m_delimiter;
+}
+
+
+void SearchEngine::loadDelimiter()
+{
+ KConfig config("kuriikwsfilterrc"); //Share with konqueror
+ KConfigGroup cg = config.group("General");
+ m_delimiter = cg.readEntry("KeywordDelimiter", ":");
+}
+
+
+KService::Ptr SearchEngine::m_defaultWS;
+
+
+KService::Ptr SearchEngine::defaultWS()
+{
+ if (!m_defaultWS) loadDefaultWS();
+ return m_defaultWS;
+}
+
+
+void SearchEngine::loadDefaultWS()
+{
+ 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));
+}
+
+
+KService::Ptr SearchEngine::fromString(QString text)
+{
+ KService::List providers = KServiceTypeTrader::self()->query("SearchProvider");
+ int i = 0;
+ bool found = false;
+ KService::Ptr service;
+ while (!found && i < providers.size())
+ {
+ QStringList list = providers.at(i)->property("Keys").toStringList();
+ foreach(const QString &key, list)
+ {
+ const QString searchPrefix = key + delimiter();
+ if (text.startsWith(searchPrefix))
+ {
+ service = providers.at(i);
+ found = true;
+ }
+ }
+ i++;
+ }
+
+ return service;
+}
+
+
+QString SearchEngine::buildQuery(KService::Ptr engine, QString text)
+{
+ QString query = engine->property("Query").toString();
+ query = query.replace("\\{@}", KUrl::toPercentEncoding(text));
+ return query;
+}
+
+
+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 << "wikipedia" << "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()
+{
+ int n = ReKonfig::searchEngine();
+ QString engine;
+ switch (n)
+ {
+ case 0:
+ engine = QL1S("google");
+ break;
+ case 1:
+ engine = QL1S("altavista");
+ break;
+ case 2:
+ engine = QL1S("lycos");
+ break;
+ case 3:
+ engine = QL1S("wikipedia");
+ break;
+ case 4:
+ engine = QL1S("wolfram");
+ break;
+ default:
+ engine = QL1S("google");
+ break;
+ }
+
+ return KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine));
+}
diff --git a/src/searchengine.h b/src/searchengine.h
new file mode 100644
index 00000000..2e30e056
--- /dev/null
+++ b/src/searchengine.h
@@ -0,0 +1,62 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
+*
+*
+* 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 SEARCHENGINE_H
+#define SEARCHENGINE_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// KDE Includes
+#include <KService>
+
+//Qt Includes
+#include <QString>
+
+
+class SearchEngine
+{
+public:
+
+ 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 QString m_delimiter;
+ static KService::List m_favorites;
+ static KService::Ptr m_defaultWS;
+};
+
+#endif
diff --git a/src/sessionmanager.cpp b/src/sessionmanager.cpp
index f4e7cd3e..0b50791d 100644
--- a/src/sessionmanager.cpp
+++ b/src/sessionmanager.cpp
@@ -2,9 +2,9 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
* Copyright (C) 2009 by Yoram Bar-Haim <<yoram.b at zend dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -38,16 +38,16 @@
// KDE Includes
#include <KStandardDirs>
-#include <KDebug>
// Qt Includes
-#include <QFile>
-#include <QTextStream>
+#include <QtCore/QFile>
+#include <QtCore/QTextStream>
+
SessionManager::SessionManager(QObject *parent)
- : QObject(parent)
- , m_safe(true)
+ : QObject(parent)
+ , m_safe(true)
{
m_sessionFilePath = KStandardDirs::locateLocal("appdata" , "session");
}
@@ -60,21 +60,21 @@ SessionManager::~SessionManager()
void SessionManager::saveSession()
{
- if(!m_safe)
+ if (!m_safe)
return;
m_safe = false;
QFile sessionFile(m_sessionFilePath);
if (!sessionFile.open(QFile::WriteOnly | QFile::Truncate))
{
- kWarning() << "Unable to open session file" << sessionFile.fileName();
+ kDebug() << "Unable to open session file" << sessionFile.fileName();
return;
}
QTextStream out(&sessionFile);
MainWindowList wl = Application::instance()->mainWindowList();
- Q_FOREACH(QPointer<MainWindow> w, wl)
+ Q_FOREACH(const QWeakPointer<MainWindow> &w, wl)
{
out << "window\n";
- MainView *mv = w->mainView();
+ MainView *mv = w.data()->mainView();
for (int i = 0 ; i < mv->count() ; i++)
{
out << mv->webTab(i)->url().toEncoded() << "\n";
@@ -93,7 +93,7 @@ bool SessionManager::restoreSession()
return false;
if (!sessionFile.open(QFile::ReadOnly))
{
- kWarning() << "Unable to open session file" << sessionFile.fileName();
+ kDebug() << "Unable to open session file" << sessionFile.fileName();
return false;
}
@@ -102,18 +102,19 @@ bool SessionManager::restoreSession()
do
{
line = in.readLine();
- if(line == QString("window"))
+ if (line == QString("window"))
{
- Application::instance()->newMainWindow();
line = in.readLine();
- Application::instance()->loadUrl(line);
+ kDebug() << "New Window line: " << line;
+ Application::instance()->loadUrl(line, Rekonq::NewWindow);
}
else
{
+ kDebug() << "New Current Tab line: " << line;
Application::instance()->loadUrl(line, Rekonq::NewCurrentTab);
}
}
- while(!line.isNull());
-
+ while (!line.isEmpty());
+
return true;
}
diff --git a/src/sessionmanager.h b/src/sessionmanager.h
index f1b7a71f..7960fc3e 100644
--- a/src/sessionmanager.h
+++ b/src/sessionmanager.h
@@ -2,9 +2,9 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
* Copyright (C) 2009 by Yoram Bar-Haim <<yoram.b at zend dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -30,6 +30,9 @@
#define SESSION_MANAGER_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Qt Includes
#include <QtCore/QObject>
#include <QtCore/QString>
@@ -38,14 +41,14 @@
/**
* Session Management
*/
-class SessionManager : public QObject
+class REKONQ_TESTS_EXPORT SessionManager : public QObject
{
Q_OBJECT
public:
SessionManager(QObject *parent = 0);
~SessionManager();
bool restoreSession();
-
+
private slots:
void saveSession();
diff --git a/src/settings/adblockwidget.cpp b/src/settings/adblockwidget.cpp
new file mode 100644
index 00000000..59cb8a81
--- /dev/null
+++ b/src/settings/adblockwidget.cpp
@@ -0,0 +1,192 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 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 "adblockwidget.h"
+#include "adblockwidget.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// KDE Includes
+#include <KSharedConfig>
+#include <KIcon>
+#include <KDebug>
+
+// Qt Includes
+#include <QString>
+#include <QWhatsThis>
+#include <QListWidgetItem>
+
+
+AdBlockWidget::AdBlockWidget(QWidget *parent)
+ : QWidget(parent)
+ , _changed(false)
+{
+ setupUi(this);
+
+ hintLabel->setText(i18n("<qt>Filter expression (e.g. <tt>http://www.example.com/ad/*</tt>, <a href=\"filterhelp\">more information</a>):"));
+ connect(hintLabel, SIGNAL(linkActivated(const QString &)), this, SLOT(slotInfoLinkActivated(const QString &)));
+
+ listWidget->setSortingEnabled(true);
+ listWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+
+ searchLine->setListWidget(listWidget);
+
+ insertButton->setIcon(KIcon("list-add"));
+ connect(insertButton, SIGNAL(clicked()), this, SLOT(insertRule()));
+
+ removeButton->setIcon(KIcon("list-remove"));
+ connect(removeButton, SIGNAL(clicked()), this, SLOT(removeRule()));
+
+ load();
+
+ // emit changed signal
+ connect(insertButton, SIGNAL(clicked()), this, SLOT(hasChanged()));
+ connect(removeButton, SIGNAL(clicked()), this, SLOT(hasChanged()));
+ connect(checkEnableAdblock, SIGNAL(stateChanged(int)), this, SLOT(hasChanged()));
+ connect(checkHideAds, SIGNAL(stateChanged(int)), this, SLOT(hasChanged()));
+ connect(spinBox, SIGNAL(valueChanged(int)), this, SLOT(hasChanged()));
+}
+
+
+void AdBlockWidget::slotInfoLinkActivated(const QString &url)
+{
+ Q_UNUSED(url)
+
+ QString hintHelpString = i18n("<qt><p>Enter an expression to filter. Filters can be defined as either:"
+ "<ul><li>a shell-style wildcard, e.g. <tt>http://www.example.com/ads*</tt>, the wildcards <tt>*?[]</tt> may be used</li>"
+ "<li>a full regular expression by surrounding the string with '<tt>/</tt>', e.g. <tt>/\\/(ad|banner)\\./</tt></li></ul>"
+ "<p>Any filter string can be preceded by '<tt>@@</tt>' to whitelist (allow) any matching URL, "
+ "which takes priority over any blacklist (blocking) filter.");
+
+ QWhatsThis::showText(QCursor::pos(), hintHelpString);
+}
+
+
+void AdBlockWidget::insertRule()
+{
+ QString rule = addFilterLineEdit->text();
+ if (rule.isEmpty())
+ return;
+
+ listWidget->addItem(rule);
+ addFilterLineEdit->clear();
+}
+
+
+void AdBlockWidget::removeRule()
+{
+ listWidget->takeItem(listWidget->currentRow());
+}
+
+
+void AdBlockWidget::load()
+{
+ bool isAdBlockEnabled = ReKonfig::adBlockEnabled();
+ checkEnableAdblock->setChecked(isAdBlockEnabled);
+
+ bool areImageFiltered = ReKonfig::hideAdsEnabled();
+ checkHideAds->setChecked(areImageFiltered);
+
+ int days = ReKonfig::updateInterval();
+ spinBox->setValue(days);
+
+ QStringList subscriptions = ReKonfig::subscriptionTitles();
+
+ // load automatic rules
+ foreach(const QString &sub, subscriptions)
+ {
+ QTreeWidgetItem *subItem = new QTreeWidgetItem(treeWidget);
+ subItem->setText(0, sub);
+ loadRules(subItem);
+ }
+
+ // load local rules
+ KSharedConfig::Ptr config = KGlobal::config();
+ KConfigGroup localGroup(config, "rules");
+ QStringList rules = localGroup.readEntry("local-rules" , QStringList());
+ foreach(const QString &rule, rules)
+ {
+ listWidget->addItem(rule);
+ }
+}
+
+
+void AdBlockWidget::loadRules(QTreeWidgetItem *item)
+{
+ KSharedConfig::Ptr config = KGlobal::config();
+ KConfigGroup localGroup(config, "rules");
+
+ QString str = item->text(0) + "-rules";
+ QStringList rules = localGroup.readEntry(str , QStringList());
+
+ foreach(const QString &rule, rules)
+ {
+ QTreeWidgetItem *subItem = new QTreeWidgetItem(item);
+ subItem->setText(0, rule);
+ }
+}
+
+
+void AdBlockWidget::save()
+{
+ int n;
+
+ // local rules
+ KSharedConfig::Ptr config = KGlobal::config();
+ KConfigGroup localGroup(config , "rules");
+
+ QStringList localRules;
+
+ n = listWidget->count();
+ for (int i = 0; i < n; ++i)
+ {
+ QListWidgetItem *item = listWidget->item(i);
+ localRules << item->text();
+ }
+ localGroup.writeEntry("local-rules" , localRules);
+
+ ReKonfig::setAdBlockEnabled(checkEnableAdblock->isChecked());
+ ReKonfig::setHideAdsEnabled(checkHideAds->isChecked());
+ ReKonfig::setUpdateInterval(spinBox->value());
+
+ _changed = false;
+ emit changed(false);
+}
+
+
+void AdBlockWidget::hasChanged()
+{
+ _changed = true;
+ emit changed(true);
+}
+
+
+bool AdBlockWidget::changed()
+{
+ return _changed;
+}
diff --git a/src/rekonqprivate_export.h b/src/settings/adblockwidget.h
index 8f996a1f..1ed9aaa6 100644
--- a/src/rekonqprivate_export.h
+++ b/src/settings/adblockwidget.h
@@ -2,8 +2,7 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2007 David Faure <faure@kde.org>
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +10,9 @@
* 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
+* 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
@@ -25,19 +24,43 @@
* ============================================================ */
-#ifndef REKONQPRIVATE_EXPORT_H
-#define REKONQPRIVATE_EXPORT_H
+#ifndef ADBLOCK_WIDGET_H
+#define ADBLOCK_WIDGET_H
+
+
+// Ui Includes
+#include "ui_settings_adblock.h"
+
+// Qt Includes
+#include <QWidget>
+#include <QTreeWidgetItem>
+
+
+class AdBlockWidget : public QWidget, private Ui::adblock
+{
+ Q_OBJECT
+
+public:
+ AdBlockWidget(QWidget *parent = 0);
+
+ void save();
+ bool changed();
+
+signals:
+ void changed(bool);
+
+private slots:
+ void hasChanged();
+
+ void slotInfoLinkActivated(const QString &);
+ void insertRule();
+ void removeRule();
-/* needed for KDE_EXPORT and KDE_IMPORT macros */
-#include <kdemacros.h>
+private:
+ void load();
+ void loadRules(QTreeWidgetItem *item);
-/* Classes from the rekonq application, which are exported only for unit tests */
-#ifndef REKONQ_TESTS_EXPORT
- /* We are building this library */
- #define REKONQ_TESTS_EXPORT KDE_EXPORT
-#else
- /* We are using this library */
- #define REKONQ_TESTS_EXPORT KDE_IMPORT
-#endif
+ bool _changed;
+};
-#endif // REKONQPRIVATE_EXPORT_H
+#endif // ADBLOCK_WIDGET_H
diff --git a/src/settings/networkwidget.cpp b/src/settings/networkwidget.cpp
new file mode 100644
index 00000000..5495f0ce
--- /dev/null
+++ b/src/settings/networkwidget.cpp
@@ -0,0 +1,100 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 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 "networkwidget.h"
+#include "networkwidget.moc"
+
+// KDE Includes
+#include <KTabWidget>
+#include <KCModuleInfo>
+
+// Qt Includes
+#include <QVBoxLayout>
+
+
+NetworkWidget::NetworkWidget(QWidget *parent)
+ : QWidget(parent)
+ , _cacheModule(0)
+ , _cookiesModule(0)
+ , _proxyModule(0)
+ , _changed(false)
+{
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setMargin(0);
+ l->setSpacing(0);
+
+ KTabWidget *tabWidget = new KTabWidget(this);
+ l->addWidget(tabWidget);
+
+ KCModuleInfo cacheInfo("cache.desktop");
+ _cacheModule = new KCModuleProxy(cacheInfo, parent);
+ tabWidget->addTab(_cacheModule, i18n(cacheInfo.moduleName().toLocal8Bit()));
+
+ KCModuleInfo cookiesInfo("cookies.desktop");
+ _cookiesModule = new KCModuleProxy(cookiesInfo, parent);
+ tabWidget->addTab(_cookiesModule, i18n(cookiesInfo.moduleName().toLocal8Bit()));
+
+ KCModuleInfo proxyInfo("proxy.desktop");
+ _proxyModule = new KCModuleProxy(proxyInfo, parent);
+ tabWidget->addTab(_proxyModule, i18n(proxyInfo.moduleName().toLocal8Bit()));
+
+ connect(_cacheModule, SIGNAL(changed(bool)), this, SLOT(hasChanged()));
+ connect(_cookiesModule, SIGNAL(changed(bool)), this, SLOT(hasChanged()));
+ connect(_proxyModule, SIGNAL(changed(bool)), this, SLOT(hasChanged()));
+}
+
+
+NetworkWidget::~NetworkWidget()
+{
+ delete _cacheModule;
+ delete _cookiesModule;
+ delete _proxyModule;
+}
+
+
+void NetworkWidget::save()
+{
+ _cookiesModule->save();
+ _proxyModule->save();
+ _cacheModule->save();
+
+ _changed = false;
+ emit changed(false);
+}
+
+
+void NetworkWidget::hasChanged()
+{
+ _changed = true;
+ emit changed(true);
+}
+
+
+bool NetworkWidget::changed()
+{
+ return _changed;
+}
diff --git a/src/urlbar/lineedit.h b/src/settings/networkwidget.h
index 67ded052..6b7abffd 100644
--- a/src/urlbar/lineedit.h
+++ b/src/settings/networkwidget.h
@@ -2,9 +2,7 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Paweł Prażak <pawelprazak at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2010 by Andrea Diamantini <adjam7 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +10,9 @@
* 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
+* 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
@@ -26,30 +24,40 @@
* ============================================================ */
-#ifndef LINEEDIT_H
-#define LINEEDIT_H
+#ifndef NETWORK_WIDGET_H
+#define NETWORK_WIDGET_H
// KDE Includes
-#include <KLineEdit>
+#include <KCModuleProxy>
-// Forward Declarations
-class QContextMenuEvent;
-class QFocusEvent;
-class QKeyEvent;
+// Qt Includes
+#include <QWidget>
-class LineEdit : public KLineEdit
+class NetworkWidget : public QWidget
{
Q_OBJECT
public:
- explicit LineEdit(QWidget *parent = 0);
- virtual ~LineEdit();
+ NetworkWidget(QWidget *parent = 0);
+ ~NetworkWidget();
+
+ void save();
+ bool changed();
+
+signals:
+ void changed(bool);
+
+private slots:
+ void hasChanged();
+
+private:
+ KCModuleProxy *_cacheModule;
+ KCModuleProxy *_cookiesModule;
+ KCModuleProxy *_proxyModule;
-protected:
- virtual void keyPressEvent(QKeyEvent*);
- virtual void mouseDoubleClickEvent(QMouseEvent *);
+ bool _changed;
};
-#endif // LINEEDIT_H
+#endif // NETWORK_WIDGET_H
diff --git a/src/settings/settings_adblock.ui b/src/settings/settings_adblock.ui
new file mode 100644
index 00000000..445431c5
--- /dev/null
+++ b/src/settings/settings_adblock.ui
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>adblock</class>
+ <widget class="QWidget" name="adblock">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>601</width>
+ <height>507</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QCheckBox" name="checkEnableAdblock">
+ <property name="text">
+ <string>&amp;Enable AdBlock</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkHideAds">
+ <property name="text">
+ <string>&amp;Hide filtered Elements</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KTabWidget" name="tabWidget">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab_3">
+ <attribute name="title">
+ <string>Automatic Filters</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QTreeWidget" name="treeWidget">
+ <column>
+ <property name="text">
+ <string notr="true">1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Automatic update interval:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBox">
+ <property name="value">
+ <number>7</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Manual Filters</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Search:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="KListWidgetSearchLine" name="searchLine"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="KListWidget" name="listWidget"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="hintLabel">
+ <property name="text">
+ <string>TextLabel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="KLineEdit" name="addFilterLineEdit"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="insertButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="removeButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KListWidget</class>
+ <extends>QListWidget</extends>
+ <header>klistwidget.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>klineedit.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KTabWidget</class>
+ <extends>QTabWidget</extends>
+ <header>ktabwidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>KListWidgetSearchLine</class>
+ <extends>KLineEdit</extends>
+ <header>klistwidgetsearchline.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/settings/settings_general.ui b/src/settings/settings_general.ui
index 17ac0d0f..eaa91859 100644
--- a/src/settings/settings_general.ui
+++ b/src/settings/settings_general.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>751</width>
- <height>523</height>
+ <width>552</width>
+ <height>512</height>
</rect>
</property>
<property name="windowTitle">
@@ -150,11 +150,11 @@
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
- <string>New Tabs Behaviour</string>
+ <string>Search Engine</string>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_4">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -169,20 +169,20 @@
</property>
<property name="baseSize">
<size>
- <width>120</width>
+ <width>0</width>
<height>0</height>
</size>
</property>
+ <property name="layoutDirection">
+ <enum>Qt::LeftToRight</enum>
+ </property>
<property name="text">
- <string>New tab opens:</string>
+ <string>Default search engine:</string>
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="KComboBox" name="kcfg_newTabsBehaviour">
- <property name="enabled">
- <bool>true</bool>
- </property>
+ <item>
+ <widget class="KComboBox" name="kcfg_searchEngine">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -191,75 +191,27 @@
</property>
<item>
<property name="text">
- <string>New Tab Page</string>
+ <string>google</string>
</property>
</item>
<item>
<property name="text">
- <string>Blank Page</string>
+ <string>altavista</string>
</property>
</item>
<item>
<property name="text">
- <string comment="@item:inlistbox">Home Page</string>
+ <string>lycos</string>
</property>
</item>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>120</width>
- <height>0</height>
- </size>
- </property>
- <property name="baseSize">
- <size>
- <width>120</width>
- <height>0</height>
- </size>
- </property>
- <property name="text">
- <string>New tab page starts with:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="KComboBox" name="kcfg_newTabStartPage">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
<item>
<property name="text">
- <string>favorites</string>
+ <string>wikipedia</string>
</property>
</item>
<item>
<property name="text">
- <string>closed tabs</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>history</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>bookmarks</string>
+ <string>wolfram</string>
</property>
</item>
</widget>
@@ -272,16 +224,19 @@
<property name="title">
<string>Download Manager</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="kcfg_kgetDownload">
<property name="text">
- <string>Download with KGet</string>
+ <string>Use KGet for downloading files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="kcfg_kgetList">
+ <property name="whatsThis">
+ <string>If enabled, rekonq will display an additional context menu entry, which, when selected, lists all available links of the current website in KGet.</string>
+ </property>
<property name="text">
<string>List links with KGet</string>
</property>
@@ -298,7 +253,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
- <height>40</height>
+ <height>179</height>
</size>
</property>
</spacer>
diff --git a/src/settings/settings_tabs.ui b/src/settings/settings_tabs.ui
index 9104843a..45579e90 100644
--- a/src/settings/settings_tabs.ui
+++ b/src/settings/settings_tabs.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>456</width>
- <height>329</height>
+ <width>483</width>
+ <height>427</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,6 +15,131 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>New Tabs Behaviour</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>120</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>120</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>New tab opens:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="KComboBox" name="kcfg_newTabsBehaviour">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>New Tab Page</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Blank Page</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string comment="@item:inlistbox">Home Page</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>120</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="baseSize">
+ <size>
+ <width>120</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>New tab page starts with:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="KComboBox" name="kcfg_newTabStartPage">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>Favorites</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Closed Tabs</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Bookmarks</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>History</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Downloads</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Tabbed Browsing</string>
@@ -79,13 +204,20 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
- <height>142</height>
+ <height>120</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>KComboBox</class>
+ <extends>QComboBox</extends>
+ <header>kcombobox.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/src/settings/settings_webkit.ui b/src/settings/settings_webkit.ui
index 5074522b..55f34ab3 100644
--- a/src/settings/settings_webkit.ui
+++ b/src/settings/settings_webkit.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>437</width>
- <height>346</height>
+ <width>643</width>
+ <height>560</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -17,99 +17,106 @@
<string>WebKit Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0" colspan="2">
+ <item row="0" column="0">
<widget class="QCheckBox" name="kcfg_autoLoadImages">
<property name="text">
<string>Autoload images</string>
</property>
</widget>
</item>
- <item row="0" column="3">
+ <item row="0" column="1" rowspan="7">
+ <widget class="Line" name="line">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
<widget class="QCheckBox" name="kcfg_linksIncludedInFocusChain">
<property name="text">
<string>Links included in focus chain</string>
</property>
</widget>
</item>
- <item row="1" column="0" colspan="2">
- <widget class="QCheckBox" name="kcfg_javascriptEnabled">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="kcfg_dnsPrefetch">
<property name="text">
- <string>JavaScript support</string>
+ <string>Prefetch DNS entries</string>
</property>
</widget>
</item>
- <item row="1" column="3">
+ <item row="1" column="2">
<widget class="QCheckBox" name="kcfg_zoomTextOnly">
<property name="text">
<string>Zoom text only</string>
</property>
</widget>
</item>
- <item row="2" column="0" colspan="2">
- <widget class="QCheckBox" name="kcfg_javaEnabled">
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="kcfg_javascriptEnabled">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text">
- <string>Java support</string>
+ <string>JavaScript support</string>
</property>
</widget>
</item>
- <item row="2" column="3">
+ <item row="2" column="2">
<widget class="QCheckBox" name="kcfg_printElementBackgrounds">
<property name="text">
<string>Print element backgrounds</string>
</property>
</widget>
</item>
- <item row="3" column="3">
+ <item row="4" column="2">
<widget class="QCheckBox" name="kcfg_offlineStorageDatabaseEnabled">
<property name="text">
<string>Offline storage database</string>
</property>
</widget>
</item>
- <item row="4" column="3">
- <widget class="QCheckBox" name="kcfg_offlineWebApplicationCacheEnabled">
+ <item row="3" column="0" rowspan="2">
+ <widget class="QCheckBox" name="kcfg_javaEnabled">
<property name="text">
- <string>Offline web application cache</string>
+ <string>Java support</string>
</property>
</widget>
</item>
- <item row="5" column="3">
- <widget class="QCheckBox" name="kcfg_localStorageDatabaseEnabled">
+ <item row="5" column="0">
+ <widget class="QCheckBox" name="kcfg_javascriptCanOpenWindows">
<property name="text">
- <string>Local storage database</string>
+ <string>JavaScript can open windows</string>
</property>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QCheckBox" name="kcfg_javascriptCanOpenWindows">
+ <item row="5" column="2">
+ <widget class="QCheckBox" name="kcfg_offlineWebApplicationCacheEnabled">
<property name="text">
- <string>JavaScript can open windows</string>
+ <string>Offline web application cache</string>
</property>
</widget>
</item>
- <item row="4" column="0">
+ <item row="6" column="0">
<widget class="QCheckBox" name="kcfg_javascriptCanAccessClipboard">
<property name="text">
<string>JavaScript can access clipboard</string>
</property>
</widget>
</item>
- <item row="0" column="2" rowspan="6">
- <widget class="Line" name="line">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <item row="6" column="2">
+ <widget class="QCheckBox" name="kcfg_localStorageEnabled">
+ <property name="text">
+ <string>Local Storage</string>
</property>
</widget>
</item>
@@ -148,13 +155,7 @@
</widget>
</item>
<item>
- <widget class="QComboBox" name="kcfg_pluginsEnabled">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
+ <widget class="KComboBox" name="kcfg_pluginsEnabled">
<item>
<property name="text">
<string>Autoload Plugins</string>
@@ -219,6 +220,11 @@
<extends>QFrame</extends>
<header>kurlrequester.h</header>
</customwidget>
+ <customwidget>
+ <class>KComboBox</class>
+ <extends>QComboBox</extends>
+ <header>kcombobox.h</header>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>
diff --git a/src/settings/settingsdialog.cpp b/src/settings/settingsdialog.cpp
index e37481aa..d2d5c0d0 100644
--- a/src/settings/settingsdialog.cpp
+++ b/src/settings/settingsdialog.cpp
@@ -2,9 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +11,9 @@
* 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
+* 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
@@ -37,6 +36,9 @@
#include "application.h"
#include "mainwindow.h"
#include "webtab.h"
+#include "adblockwidget.h"
+#include "networkwidget.h"
+#include "searchengine.h"
//Ui Includes
#include "ui_settings_general.h"
@@ -53,26 +55,25 @@
#include <KCModuleProxy>
// Qt Includes
-#include <QtCore/QPointer>
#include <QtGui/QWidget>
class Private
{
private:
-
+
Ui::general generalUi;
Ui::tabs tabsUi;
Ui::fonts fontsUi;
Ui::webkit webkitUi;
-
- KCModuleProxy *proxyModule;
+
+ AdBlockWidget *adBlockWidg;
+ NetworkWidget *networkWidg;
+
KCModuleProxy *ebrowsingModule;
- KCModuleProxy *cookiesModule;
- KCModuleProxy *cacheModule;
- KCModuleProxy *adblockModule;
+
KShortcutsEditor *shortcutsEditor;
-
+
Private(SettingsDialog *parent);
friend class SettingsDialog;
@@ -102,21 +103,6 @@ Private::Private(SettingsDialog *parent)
pageItem = parent->addPage(widget , i18n("Fonts"));
pageItem->setIcon(KIcon("preferences-desktop-font"));
- KCModuleInfo cookiesInfo("cookies.desktop");
- cookiesModule = new KCModuleProxy(cookiesInfo,parent);
- pageItem = parent->addPage(cookiesModule, i18n(cookiesInfo.moduleName().toLocal8Bit()));
- pageItem->setIcon(KIcon(cookiesInfo.icon()));
-
- KCModuleInfo proxyInfo("proxy.desktop");
- proxyModule = new KCModuleProxy(proxyInfo,parent);
- pageItem = parent->addPage(proxyModule, i18n(proxyInfo.moduleName().toLocal8Bit()));
- pageItem->setIcon(KIcon(proxyInfo.icon()));
-
- KCModuleInfo cacheInfo("cache.desktop");
- cacheModule = new KCModuleProxy(cacheInfo,parent);
- pageItem = parent->addPage(cacheModule, i18n(cacheInfo.moduleName().toLocal8Bit()));
- pageItem->setIcon(KIcon(cacheInfo.icon()));
-
widget = new QWidget;
webkitUi.setupUi(widget);
widget->layout()->setMargin(0);
@@ -125,23 +111,28 @@ Private::Private(SettingsDialog *parent)
KIcon webkitIcon = KIcon(QIcon(webkitIconPath));
pageItem->setIcon(webkitIcon);
- KCModuleInfo adblockInfo("khtml_filter.desktop");
- adblockModule = new KCModuleProxy(adblockInfo,parent);
- pageItem = parent->addPage(adblockModule, i18n(adblockInfo.moduleName().toLocal8Bit()));
- pageItem->setIcon(KIcon(adblockInfo.icon()));
-
+ networkWidg = new NetworkWidget(parent);
+ networkWidg->layout()->setMargin(0);
+ pageItem = parent->addPage(networkWidg , i18n("Network"));
+ pageItem->setIcon(KIcon("preferences-system-network"));
+
+ adBlockWidg = new AdBlockWidget(parent);
+ adBlockWidg->layout()->setMargin(0);
+ pageItem = parent->addPage(adBlockWidg , i18n("Ad Block"));
+ pageItem->setIcon(KIcon("preferences-web-browser-adblock"));
+
shortcutsEditor = new KShortcutsEditor(Application::instance()->mainWindow()->actionCollection(), parent);
pageItem = parent->addPage(shortcutsEditor , i18n("Shortcuts"));
pageItem->setIcon(KIcon("configure-shortcuts"));
KCModuleInfo ebrowsingInfo("ebrowsing.desktop");
- ebrowsingModule = new KCModuleProxy(ebrowsingInfo,parent);
+ ebrowsingModule = new KCModuleProxy(ebrowsingInfo, parent);
pageItem = parent->addPage(ebrowsingModule, i18n(ebrowsingInfo.moduleName().toLocal8Bit()));
pageItem->setIcon(KIcon(ebrowsingInfo.icon()));
- // WARNING remember wheh changing here that the smaller netbooks
- // have a 1024x576 resolution. So DONT bother that limits!!
- parent->setMinimumSize(700,525);
+ // WARNING remember wheh changing here that the smallest netbooks
+ // have a 1024x576 resolution. So DON'T bother that limits!!
+ parent->setMinimumSize(700, 525);
}
@@ -153,24 +144,24 @@ SettingsDialog::SettingsDialog(QWidget *parent)
, d(new Private(this))
{
showButtonSeparator(false);
- setWindowTitle(i18n("Configure - rekonq"));
+ setWindowTitle(i18nc("Window title of the settings dialog", "Configure – rekonq"));
setModal(true);
readConfig();
connect(d->generalUi.setHomeToCurrentPageButton, SIGNAL(clicked()), this, SLOT(setHomeToCurrentPage()));
-
+
+ // update buttons
+ connect(d->adBlockWidg, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
+ connect(d->networkWidg, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
connect(d->ebrowsingModule, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
- connect(d->cookiesModule, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
- connect(d->proxyModule, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
- connect(d->cacheModule, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
- connect(d->adblockModule, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
-
- connect(d->shortcutsEditor, SIGNAL(keyChange()), this, SLOT(updateButtons()));
-
+
+ connect(d->shortcutsEditor, SIGNAL(keyChange()), this, SLOT(updateButtons()));
+
+ // save settings
connect(this, SIGNAL(applyClicked()), this, SLOT(saveSettings()));
- connect(this, SIGNAL(okClicked()), this, SLOT(saveSettings()));
-
+ connect(this, SIGNAL(okClicked()), this, SLOT(saveSettings()));
+
setWebSettingsToolTips();
}
@@ -184,6 +175,7 @@ SettingsDialog::~SettingsDialog()
void SettingsDialog::setWebSettingsToolTips()
{
d->webkitUi.kcfg_autoLoadImages->setToolTip(i18n("Specifies whether images are automatically loaded in web pages."));
+ d->webkitUi.kcfg_dnsPrefetch->setToolTip(i18n("Specifies whether WebKit will try to prefetch DNS entries to speed up browsing."));
d->webkitUi.kcfg_javascriptEnabled->setToolTip(i18n("Enables the execution of JavaScript programs."));
d->webkitUi.kcfg_javaEnabled->setToolTip(i18n("Enables support for Java applets."));
d->webkitUi.kcfg_pluginsEnabled->setToolTip(i18n("Enables support for plugins in web pages."));
@@ -194,7 +186,7 @@ void SettingsDialog::setWebSettingsToolTips()
d->webkitUi.kcfg_printElementBackgrounds->setToolTip(i18n("If enabled, background colors and images are also drawn when the page is printed."));
d->webkitUi.kcfg_offlineStorageDatabaseEnabled->setToolTip(i18n("Enables support for the HTML 5 offline storage feature."));
d->webkitUi.kcfg_offlineWebApplicationCacheEnabled->setToolTip(i18n("Enables support for the HTML 5 web application cache feature."));
- d->webkitUi.kcfg_localStorageDatabaseEnabled->setToolTip(i18n("Enables support for the HTML 5 local storage feature."));
+ d->webkitUi.kcfg_localStorageEnabled->setToolTip(i18n("Enables support for the HTML 5 local storage feature."));
}
@@ -209,26 +201,32 @@ void SettingsDialog::readConfig()
// we need this function to SAVE settings in rc file..
void SettingsDialog::saveSettings()
{
+ if (!hasChanged())
+ return;
+
ReKonfig::self()->writeConfig();
d->ebrowsingModule->save();
- d->cookiesModule->save();
- d->proxyModule->save();
- d->cacheModule->save();
d->shortcutsEditor->save();
- d->adblockModule->save();
+ d->adBlockWidg->save();
+ d->networkWidg->save();
+ SearchEngine::loadDefaultWS();
+ SearchEngine::loadDelimiter();
+ SearchEngine::loadFavorites();
+
+
+ updateButtons();
+ emit settingsChanged("ReKonfig");
}
bool SettingsDialog::hasChanged()
{
- return KConfigDialog::hasChanged()
- || d->ebrowsingModule->changed()
- || d->cookiesModule->changed()
- || d->proxyModule->changed()
- || d->cacheModule->changed()
- || d->adblockModule->changed()
- || d->shortcutsEditor->isModified();
- ;
+ return KConfigDialog::hasChanged()
+ || d->adBlockWidg->changed()
+ || d->networkWidg->changed()
+ || d->ebrowsingModule->changed()
+ || d->shortcutsEditor->isModified();
+ ;
}
diff --git a/src/settings/settingsdialog.h b/src/settings/settingsdialog.h
index 360fe246..25b2fe9b 100644
--- a/src/settings/settingsdialog.h
+++ b/src/settings/settingsdialog.h
@@ -2,9 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -12,9 +11,9 @@
* 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
+* 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
@@ -30,6 +29,9 @@
#define SETTINGS_DIALOG_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// KDE Includes
#include <KConfigDialog>
@@ -38,14 +40,14 @@ class QWidget;
class Private;
-class SettingsDialog : public KConfigDialog
+class REKONQ_TESTS_EXPORT SettingsDialog : public KConfigDialog
{
Q_OBJECT
public:
SettingsDialog(QWidget *parent = 0);
~SettingsDialog();
-
+
virtual bool hasChanged();
private:
diff --git a/src/sslinfodialog_p.h b/src/sslinfodialog_p.h
new file mode 100644
index 00000000..72f16791
--- /dev/null
+++ b/src/sslinfodialog_p.h
@@ -0,0 +1,107 @@
+/* This file is part of the KDE project
+ *
+ * Copyright (C) 2000-2003 George Staikos <staikos@kde.org>
+ * Copyright (C) 2000 Malte Starostik <malte@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef SSLINFODIALOG_P_H
+#define SSLINFODIALOG_P_H
+
+#include <kdemacros.h>
+
+#include <KDE/KDialog>
+#include <ktcpsocket.h>
+
+// NOTE: We need a copy of this header file is needed here because it
+// is never installed by default by KIO.
+
+/**
+ * KDE SSL Information Dialog
+ *
+ * This class creates a dialog that can be used to display information about
+ * an SSL session.
+ *
+ * There are NO GUARANTEES that KSslInfoDialog will remain binary compatible/
+ * Contact staikos@kde.org for details if needed.
+ *
+ * @author George Staikos <staikos@kde.org>
+ * @see KSSL
+ * @short KDE SSL Information Dialog
+ */
+class KDE_EXPORT KSslInfoDialog : public KDialog
+{
+ Q_OBJECT
+
+public:
+ /**
+ * Construct a KSSL Information Dialog
+ *
+ * @param parent the parent widget
+ */
+ explicit KSslInfoDialog(QWidget *parent = 0);
+
+ /**
+ * Destroy this dialog
+ */
+ virtual ~KSslInfoDialog();
+
+ /**
+ * Tell the dialog if the connection has portions that may not be
+ * secure (ie. a mixture of secure and insecure frames)
+ *
+ * @param isIt true if security is in question
+ */
+ void setSecurityInQuestion(bool isIt);
+
+ /**
+ * Set information to display about the SSL connection.
+ *
+ * @param certificateChain the certificate chain leading from the certificate
+ * authority to the peer.
+ * @param ip the ip of the remote host
+ * @param host the remote hostname
+ * @param sslProtocol the version of SSL in use (SSLv2, SSLv3, TLSv1)
+ * @param cipher the cipher in use
+ * @param usedBits the used bits of the key
+ * @param bits the key size of the cipher in use
+ * @param validationErrors errors validating the certificates, if any
+ */
+ void setSslInfo(const QList<QSslCertificate> &certificateChain,
+ const QString &ip, const QString &host,
+ const QString &sslProtocol, const QString &cipher,
+ int usedBits, int bits,
+ const QList<QList<KSslError::Error> > &validationErrors);
+
+ void setMainPartEncrypted(bool);
+ void setAuxiliaryPartsEncrypted(bool);
+
+ static QList<QList<KSslError::Error> > errorsFromString(const QString &s);
+
+private Q_SLOTS:
+ void launchConfig();
+ void displayFromChain(int);
+
+private:
+ void updateWhichPartsEncrypted();
+
+ class KSslInfoDialogPrivate;
+ KSslInfoDialogPrivate* const d;
+};
+
+#endif // SSLINFODIALOG_P_H
diff --git a/src/tabbar.cpp b/src/tabbar.cpp
index 7326d7af..27835892 100644
--- a/src/tabbar.cpp
+++ b/src/tabbar.cpp
@@ -3,9 +3,9 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2008 Benjamin C. Meyer <ben@meyerhome.net>
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -13,9 +13,9 @@
* 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
+* 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
@@ -86,29 +86,29 @@ TabBar::~TabBar()
QSize TabBar::tabSizeHint(int index) const
{
MainView *view = qobject_cast<MainView *>(parent());
-
+
int buttonSize = view->addTabButton()->size().width();
int tabBarWidth = view->size().width() - buttonSize;
- int baseWidth = view->sizeHint().width()/BASE_WIDTH_DIVISOR;
- int minWidth = view->sizeHint().width()/MIN_WIDTH_DIVISOR;
+ int baseWidth = view->sizeHint().width() / BASE_WIDTH_DIVISOR;
+ int minWidth = view->sizeHint().width() / MIN_WIDTH_DIVISOR;
int w;
- if (baseWidth*count()<tabBarWidth)
+ if (baseWidth*count() < tabBarWidth)
{
w = baseWidth;
}
- else
+ else
{
- if (count() > 0 && tabBarWidth/count()>minWidth)
+ if (count() > 0 && tabBarWidth / count() > minWidth)
{
- w = tabBarWidth/count();
+ w = tabBarWidth / count();
}
else
{
w = minWidth;
}
}
-
+
int h = KTabBar::tabSizeHint(index).height();
QSize ts = QSize(w, h);
@@ -149,68 +149,83 @@ void TabBar::detachTab()
void TabBar::showTabPreview(int tab)
{
MainView *mv = qobject_cast<MainView *>(parent());
-
- WebTab *view = mv->webTab(tab);
- WebTab *currentView = mv->webTab(currentIndex());
+
+ WebTab *indexedTab = mv->webTab(tab);
+ WebTab *currentTab = mv->webTab(currentIndex());
// check if view && currentView exist before using them :)
- if(!currentView || !view)
+ if (!currentTab || !indexedTab)
return;
-
+
int w = tabSizeHint(tab).width();
- int h = w*((0.0 + currentView->height())/currentView->width());
+ int h = w * ((0.0 + currentTab->height()) / currentTab->width());
//delete previous tab preview
- if (m_previewPopup)
- {
- delete m_previewPopup;
- }
+ delete m_previewPopup.data();
+ m_previewPopup.clear();
+
+ if (indexedTab->progress() != 0)
+ return;
m_previewPopup = new KPassivePopup(this);
- m_previewPopup->setFrameShape(QFrame::StyledPanel);
- m_previewPopup->setFrameShadow(QFrame::Plain);
- m_previewPopup->setFixedSize(w, h);
+ m_previewPopup.data()->setFrameShape(QFrame::StyledPanel);
+ m_previewPopup.data()->setFrameShadow(QFrame::Plain);
+ m_previewPopup.data()->setFixedSize(w, h);
+
QLabel *l = new QLabel();
- view->page()->setViewportSize(currentView->page()->viewportSize());
- l->setPixmap(WebSnap::renderPreview(*(view->page()), w, h));
- m_previewPopup->setView(l);
- m_previewPopup->layout()->setAlignment(Qt::AlignTop);
- m_previewPopup->layout()->setMargin(0);
-
- QPoint pos( tabRect(tab).x() , tabRect(tab).y() + tabRect(tab).height() );
- m_previewPopup->show(mapToGlobal(pos));
+ l->setPixmap(WebSnap::renderPreview(*indexedTab->page(), w, h));
+
+ m_previewPopup.data()->setView(l);
+ m_previewPopup.data()->layout()->setAlignment(Qt::AlignTop);
+ m_previewPopup.data()->layout()->setMargin(0);
+
+ QPoint pos(tabRect(tab).x() , tabRect(tab).y() + tabRect(tab).height());
+ m_previewPopup.data()->show(mapToGlobal(pos));
}
void TabBar::mouseMoveEvent(QMouseEvent *event)
{
+ if (event->buttons() & Qt::LeftButton)
+ {
+ // hide addNewTabButton when moving tabs
+ MainView *view = qobject_cast<MainView *>(parent());
+ QTimer::singleShot(200, view->addTabButton(), SLOT(hide()));
+ }
+
if (ReKonfig::alwaysShowTabPreviews())
{
//Find the tab under the mouse
int i = 0;
- int tab = -1;
- while (i<count() && tab==-1)
+ int tabIndex = -1;
+ while (i < count()
+ && tabIndex == -1
+ )
{
- if (tabRect(i).contains(event->pos()))
+ if (tabRect(i).contains(event->pos()))
{
- tab = i;
+ tabIndex = i;
}
i++;
}
- //if found and not the current tab then show tab preview
- if (tab != -1 && tab != currentIndex() && m_currentTabPreview != tab)
+ // if found and not the current tab then show tab preview
+ if (tabIndex != -1
+ && tabIndex != currentIndex()
+ && m_currentTabPreview != tabIndex
+ && event->buttons() == Qt::NoButton
+ )
{
- showTabPreview(tab);
- m_currentTabPreview = tab;
+ showTabPreview(tabIndex);
+ m_currentTabPreview = tabIndex;
}
- //if current tab or not found then hide previous tab preview
- if (tab==currentIndex() || tab==-1)
+ // if current tab or not found then hide previous tab preview
+ if (tabIndex == currentIndex() || tabIndex == -1)
{
- if ( m_previewPopup)
+ if (!m_previewPopup.isNull())
{
- m_previewPopup->hide();
+ m_previewPopup.data()->hide();
}
m_currentTabPreview = -1;
}
@@ -225,9 +240,9 @@ void TabBar::leaveEvent(QEvent *event)
if (ReKonfig::alwaysShowTabPreviews())
{
//if leave tabwidget then hide previous tab preview
- if ( m_previewPopup)
+ if (!m_previewPopup.isNull())
{
- m_previewPopup->hide();
+ m_previewPopup.data()->hide();
}
m_currentTabPreview = -1;
}
@@ -238,10 +253,19 @@ void TabBar::leaveEvent(QEvent *event)
void TabBar::mousePressEvent(QMouseEvent *event)
{
+ if (ReKonfig::alwaysShowTabPreviews())
+ {
+ if (!m_previewPopup.isNull())
+ {
+ m_previewPopup.data()->hide();
+ }
+ m_currentTabPreview = -1;
+ }
+
// just close tab on middle mouse click
if (event->button() == Qt::MidButton)
return;
-
+
KTabBar::mousePressEvent(event);
}
@@ -253,15 +277,17 @@ void TabBar::contextMenu(int tab, const QPoint &pos)
KMenu menu;
MainWindow *mainWindow = Application::instance()->mainWindow();
- menu.addAction(mainWindow->actionByName(QLatin1String("new_tab")));
- menu.addAction( mainWindow->actionByName("clone_tab") );
- menu.addAction( mainWindow->actionByName("detach_tab") );
+ menu.addAction(mainWindow->actionByName( QL1S("new_tab") ));
+ menu.addAction(mainWindow->actionByName( QL1S("clone_tab") ));
+
+ if (count() > 1)
+ menu.addAction(mainWindow->actionByName( QL1S("detach_tab") ));
menu.addSeparator();
- menu.addAction( mainWindow->actionByName("close_tab") );
- menu.addAction( mainWindow->actionByName("close_other_tabs") );
+ menu.addAction(mainWindow->actionByName( QL1S("close_tab") ));
+ menu.addAction(mainWindow->actionByName( QL1S("close_other_tabs") ));
menu.addSeparator();
- menu.addAction( mainWindow->actionByName("reload_tab") );
- menu.addAction( mainWindow->actionByName("reload_all_tabs") );
+ menu.addAction(mainWindow->actionByName( QL1S("reload_tab") ));
+ menu.addAction(mainWindow->actionByName( QL1S("reload_all_tabs") ));
menu.exec(pos);
}
@@ -272,9 +298,32 @@ void TabBar::emptyAreaContextMenu(const QPoint &pos)
KMenu menu;
MainWindow *mainWindow = Application::instance()->mainWindow();
- menu.addAction(mainWindow->actionByName(QLatin1String("new_tab")));
+ menu.addAction(mainWindow->actionByName( QL1S("new_tab") ));
menu.addSeparator();
- menu.addAction( mainWindow->actionByName("reload_all_tabs") );
+ menu.addAction(mainWindow->actionByName( QL1S("reload_all_tabs") ));
menu.exec(pos);
}
+
+
+void TabBar::mouseReleaseEvent(QMouseEvent *event)
+{
+ MainView *mv = qobject_cast<MainView *>(parent());
+ QTimer::singleShot(200, mv->addTabButton(), SLOT(show()));
+
+ KTabBar::mouseReleaseEvent(event);
+}
+
+
+void TabBar::tabRemoved(int index)
+{
+ Q_UNUSED(index)
+ if (ReKonfig::alwaysShowTabPreviews())
+ {
+ if (!m_previewPopup.isNull())
+ {
+ m_previewPopup.data()->hide();
+ }
+ m_currentTabPreview = -1;
+ }
+}
diff --git a/src/tabbar.h b/src/tabbar.h
index f0476cbd..af3c537b 100644
--- a/src/tabbar.h
+++ b/src/tabbar.h
@@ -3,9 +3,9 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2008 Benjamin C. Meyer <ben@meyerhome.net>
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* 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 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -13,9 +13,9 @@
* 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
+* 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
@@ -31,11 +31,11 @@
#define TABBAR_H
-// Local Includes
-#include "rekonqprivate_export.h"
+// Rekonq Includes
+#include "rekonq_defines.h"
// Qt Includes
-#include <QPointer>
+#include <QWeakPointer>
// KDE Includes
#include <KTabBar>
@@ -61,8 +61,6 @@ public:
TabBar(QWidget *parent);
~TabBar();
- void showTabPreview(int tab);
-
signals:
void cloneTab(int index);
void closeTab(int index);
@@ -76,30 +74,34 @@ protected:
* Added to fix tab dimension
*/
virtual QSize tabSizeHint(int index) const;
-
+
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void leaveEvent(QEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
-
+ virtual void mouseReleaseEvent(QMouseEvent *event);
+ virtual void tabRemoved(int);
+
private slots:
void cloneTab();
void closeTab();
void closeOtherTabs();
void reloadTab();
void detachTab();
-
+
void contextMenu(int, const QPoint &);
void emptyAreaContextMenu(const QPoint &);
private:
+ void showTabPreview(int tab);
+
friend class MainView;
-
+
/**
* the index in which we are seeing a Context menu
*/
int m_actualIndex;
- QPointer<KPassivePopup> m_previewPopup;
+ QWeakPointer<KPassivePopup> m_previewPopup;
int m_currentTabPreview;
};
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 5df23e24..3bc9a27f 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -2,16 +2,34 @@
SET( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
-INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR}/..
+INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../adblock
+ ${CMAKE_CURRENT_SOURCE_DIR}/../bookmarks
+ ${CMAKE_CURRENT_SOURCE_DIR}/../history
+ ${CMAKE_CURRENT_SOURCE_DIR}/../settings
+ ${CMAKE_CURRENT_SOURCE_DIR}/../urlbar
${KDE4_INCLUDES}
${QT4_INCLUDES}
)
-##### ------------- tabbar test
+##### ------------- findbar test
-kde4_add_unit_test( tabbar_test tabbar_test.cpp )
+kde4_add_unit_test( findbar_test findbar_test.cpp )
-target_link_libraries( tabbar_test
+target_link_libraries( findbar_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${QT_QTGUI_LIBRARY}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- mainwindow test
+
+kde4_add_unit_test( mainwindow_test mainwindow_test.cpp )
+
+target_link_libraries( mainwindow_test
kdeinit_rekonq
${KDE4_KDECORE_LIBS}
${KDE4_KDEUI_LIBS}
@@ -29,4 +47,122 @@ target_link_libraries( mainview_test
${QT_QTTEST_LIBRARY}
)
+##### ------------- networkaccessmanager test
+
+kde4_add_unit_test( networkaccessmanager_test networkaccessmanager_test.cpp )
+
+target_link_libraries( networkaccessmanager_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- protocolhandler test
+
+kde4_add_unit_test( protocolhandler_test protocolhandler_test.cpp )
+
+target_link_libraries( protocolhandler_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${KDE4_KDEWEBKIT_LIBS}
+ ${QT_QTNETWORK_LIBRARY}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- sessionmanager test
+
+kde4_add_unit_test( sessionmanager_test sessionmanager_test.cpp )
+
+target_link_libraries( sessionmanager_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- tabbar test
+
+kde4_add_unit_test( tabbar_test tabbar_test.cpp )
+
+target_link_libraries( tabbar_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- walletbar test
+
+kde4_add_unit_test( walletbar_test walletbar_test.cpp )
+
+target_link_libraries( walletbar_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${KDE4_KDEWEBKIT_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- webpage test
+
+kde4_add_unit_test( webpage_test webpage_test.cpp )
+
+target_link_libraries( webpage_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${KDE4_KDEWEBKIT_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- websnap test
+
+kde4_add_unit_test( websnap_test websnap_test.cpp )
+
+target_link_libraries( websnap_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${KDE4_KDEWEBKIT_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- webtab test
+
+kde4_add_unit_test( webtab_test webtab_test.cpp )
+
+target_link_libraries( webtab_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${KDE4_KDEWEBKIT_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- webview test
+
+kde4_add_unit_test( webview_test webview_test.cpp )
+
+target_link_libraries( webview_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${KDE4_KDEWEBKIT_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
+##### ------------- urlbar test
+
+kde4_add_unit_test( urlbar_test urlbar_test.cpp )
+
+target_link_libraries( urlbar_test
+ kdeinit_rekonq
+ ${KDE4_KDECORE_LIBS}
+ ${KDE4_KDEUI_LIBS}
+ ${KDE4_KDEWEBKIT_LIBS}
+ ${QT_QTTEST_LIBRARY}
+)
+
############################################################
diff --git a/src/tests/HTTP_tests.html b/src/tests/HTTP_tests.html
new file mode 100644
index 00000000..7a5ac00d
--- /dev/null
+++ b/src/tests/HTTP_tests.html
@@ -0,0 +1,601 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>Test Cases for HTTP Content-Disposition header and RFC 2231/2047 Encoding</title>
+
+<style type="text/css">
+a.plain {
+ color: black;
+ text-decoration: none;
+}
+body {
+ color: black;
+ font-family: verdana, helvetica, arial, sans-serif;
+ font-size: 10pt;
+ margin-left: 2em;
+}
+h1 {
+ font-size: 18pt;
+}
+h2 {
+ font-size: 14pt;
+}
+h3 {
+ font-size: 12pt;
+}
+h4 {
+ font-size: 10pt;
+}
+pre {
+ border-style: dotted;
+ border-width: 1px;
+ background-color: #f0f0f0;
+}
+pre.invalid {
+ border-style: dotted;
+ border-width: 1px;
+ background-color: #ff8080;
+}
+table {
+ font-size: 9pt;
+}
+table.aside {
+ float: right;
+ margin: 4px;
+ border-style: dotted;
+ border-width: 1px;
+ background-color: #f0f0f0;
+}
+q {
+ font-style: italic;
+}
+th {
+ text-align: right;
+ vertical-align: top;
+}
+h2, h3, h4 {
+ clear: both;
+}
+.fail {
+ background-color: #ffd0d0;
+}
+.warn {
+ background-color: #ffff80;
+}
+.pass {
+ background-color: #d0ffd0;
+}
+.unsupported {
+ background-color: #e0e0e0;
+}
+
+</style>
+
+</head>
+
+<body>
+
+<h1>Test Cases for HTTP Content-Disposition header and RFC 2231/2047 Encoding</h1>
+
+
+<h2>Test Cases</h2><div id="c-d-inline"><h3><a href="#c-d-inline" class="plain">Content-Disposition: Disposition-Type Inline</a></h3>
+ <p>
+ Various tests relating to the "inline" disposition type, see
+ <a href="http://greenbytes.de/tech/webdav/rfc2183.html#rfc.section.2.1">Section 2.1 of RFC 2183</a>.
+ </p>
+ <div id="inlonly"><h4><a href="#inlonly" class="plain">inlonly</a>
+ [<a href="http://greenbytes.de/tech/tc2231/inlonly.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>inline</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>'inline' only</p><p><em>This should be equivalent to not including the header at all.</em></p></div><div id="inlwithasciifilename"><h4><a href="#inlwithasciifilename" class="plain">inlwithasciifilename</a>
+ [<a href="http://greenbytes.de/tech/tc2231/inlwithasciifilename.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>inline; filename="<b>foo.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass
+ (uses the filename in subsequent 'save' operation)
+ </td></tr><tr class="pass"><td>MSIE8</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>Op10</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>Saf4</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>Konq</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>Chrome</td><td>pass
+ (filename information not used)
+ </td></tr></tbody></table><p>
+ 'inline', specifying a filename of <code>foo.html</code>
+ </p><p><em>
+ Some UAs use this filename in a subsequent "save" operation.
+ </em></p></div><div id="inlwithasciifilenamepdf"><h4><a href="#inlwithasciifilenamepdf" class="plain">inlwithasciifilenamepdf</a>
+ [<a href="http://greenbytes.de/tech/tc2231/inlwithasciifilenamepdf.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>inline; filename="<b>foo.pdf</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>MSIE8</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>Op10</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>Saf4</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>Konq</td><td>pass
+ (filename information not used)
+ </td></tr><tr class="pass"><td>Chrome</td><td>pass
+ (filename information not used)
+ </td></tr></tbody></table><p>
+ 'inline', specifying a filename of <code>foo.pdf</code>
+ </p><p><em>
+ Some UAs use this filename in a subsequent "save" operation.
+ This variation of the test checks whether whatever handles PDF display
+ receives the filename information, and acts upon it
+ (this was tested with the latest Acrobat Reader plugin).
+ </em></p></div></div><div id="c-d-attachment"><h3><a href="#c-d-attachment" class="plain">Content-Disposition: Disposition-Type Attachment</a></h3>
+ <p>
+ Various tests relating to the "attchment" disposition type, see
+ <a href="http://greenbytes.de/tech/webdav/rfc2183.html#rfc.section.2.2">Section 2.2 of RFC 2183</a>.
+ </p>
+ <div id="attonly"><h4><a href="#attonly" class="plain">attonly</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attonly.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>'attachment' only</p><p><em>UA should offer to download the resource.</em></p></div><div id="attonlyucase"><h4><a href="#attonlyucase" class="plain">attonlyucase</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attonlyucase.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>ATTACHMENT</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="fail"><td>Konq</td><td>fail</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>'ATTACHMENT' only</p><p><em>UA should offer to download the resource.</em></p></div><div id="attwithasciifilename"><h4><a href="#attwithasciifilename" class="plain">attwithasciifilename</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithasciifilename.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename="<b>foo.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo.html</code>
+ </p><p><em>UA should offer to download the resource as "foo.html".</em></p></div><div id="attwithasciifnescapedchar"><h4><a href="#attwithasciifnescapedchar" class="plain">attwithasciifnescapedchar</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithasciifnescapedchar.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename="<b>f\oo.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (apparently does not treat the backslash as escape character, replaces it with '_')
+ </td></tr><tr class="fail"><td>MSIE8</td><td>fail
+ (apparently does not treat the backslash as escape character, replaces it with '_')
+ </td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="fail"><td>Saf4</td><td>fail
+ (apparently does not treat the backslash as escape character, replaces it with '-')
+ </td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="fail"><td>Chrome</td><td>fail
+ (saves "oo.html" (what's going on here?))
+ </td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>f\oo.html</code> (the first 'o' being escaped)
+ </p><p><em>UA should offer to download the resource as "foo.html".</em></p></div><div id="attwithfilenameandextparam"><h4><a href="#attwithfilenameandextparam" class="plain">attwithfilenameandextparam</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfilenameandextparam.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; foo="bar"; filename="<b>foo.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo.html</code>
+ and an extension parameter "foo" which should be ignored
+ (see <a href="http://greenbytes.de/tech/webdav/rfc2183.html#rfc.section.2.8">Section 2.8 of RFC 2183</a>.).
+ </p><p><em>UA should offer to download the resource as "foo.html".</em></p></div><div id="attwithasciifilenameucase"><h4><a href="#attwithasciifilenameucase" class="plain">attwithasciifilenameucase</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithasciifilenameucase.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; FILENAME="<b>foo.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="fail"><td>Konq</td><td>fail
+ (filename parameter is ignored)
+ </td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo.html</code>
+ </p><p><em>UA should offer to download the resource as "foo.html".</em></p></div><div id="attwithasciifilenamenq"><h4><a href="#attwithasciifilenamenq" class="plain">attwithasciifilenamenq</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithasciifilenamenq.asis">TEST</a>]
+ </h4><pre class="invalid"><b>Content-Disposition: </b>attachment; filename=<b>foo.html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="warn"><td>FF3</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>MSIE8</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>Op10</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>Saf4</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>Konq</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>Chrome</td><td>warn
+ (accepts the unquoted value)
+ </td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo.html</code>, but missing
+ the quotes.
+ </p><p><em>This is invalid according to <a href="http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.19.5.1">Section 19.5.1 of RFC2616</a>, so UAs should
+ ignore it.</em></p></div><div id="attwithisofnplain"><h4><a href="#attwithisofnplain" class="plain">attwithisofnplain</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithisofnplain.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename="<b>foo-ä.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using plain ISO-8859-1
+ </p><p><em>UA should offer to download the resource as "foo-ä.html".</em></p></div><div id="attwithutf8fnplain"><h4><a href="#attwithutf8fnplain" class="plain">attwithutf8fnplain</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithutf8fnplain.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename="<b>foo-ä.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (decodes as UTF-8)
+ </td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="fail"><td>Chrome</td><td>fail
+ (decodes as UTF-8)
+ </td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>,
+ which happens to be <code>foo-ä.html</code> using UTF-8 encoding.
+ </p><p><em>UA should offer to download the resource as "foo-ä.html".
+ Displaying "foo-ä.html" instead indicates that the UA tried to be smart by detecting
+ something that happens to look like UTF-8.</em></p></div><div id="attwithfnrawpctenca"><h4><a href="#attwithfnrawpctenca" class="plain">attwithfnrawpctenca</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfnrawpctenca.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename="<b>foo-%41.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="fail"><td>MSIE8</td><td>fail
+ (displays "foo-A.html")
+ </td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="fail"><td>Chrome</td><td>fail
+ (displays "foo-A.html" (see <a href="http://code.google.com/p/chromium/issues/detail?id=118">Chrome Issue 118</a>))
+ </td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-%41.html</code>
+ </p><p><em>UA should offer to download the resource as "foo-%41.html".
+ Displaying "foo-A.html" instead would indicate that the UA has attempted
+ to percent-decode the parameter.
+ </em></p></div><div id="attwithfnrawpctenclong"><h4><a href="#attwithfnrawpctenclong" class="plain">attwithfnrawpctenclong</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfnrawpctenclong.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename="<b>foo-%c3%a4-%e2%82%ac.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="fail"><td>MSIE8</td><td>fail
+ (displays "foo-ä-€.html")
+ </td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="fail"><td>Chrome</td><td>fail
+ (displays "foo-ä-€.html" (see <a href="http://code.google.com/p/chromium/issues/detail?id=118">Chrome Issue 118</a>))
+ </td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-%c3%a4-%e2%82%ac.html</code>, using raw percent encoded UTF-8
+ to represent <code>foo-ä-€.html</code>
+ </p><p><em>UA should offer to download the resource as "foo-%c3%a4-%e2%82%ac.html".
+ Displaying "foo-ä-€.html" instead would indicate that the UA has attempted
+ to percent-decode the parameter (using UTF-8). Displaying something else
+ would indicate that the UA tried to percent-decode, but used a different encoding.
+ </em></p></div><div id="attwithasciifilenamews1"><h4><a href="#attwithasciifilenamews1" class="plain">attwithasciifilenamews1</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithasciifilenamews1.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename ="<b>foo.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo.html</code>, with one
+ blank space <em>before</em> the equals character.
+ </p><p><em>UA should offer to download the resource as "foo.html".</em></p></div><div id="attwithasciifilenamews2"><h4><a href="#attwithasciifilenamews2" class="plain">attwithasciifilenamews2</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithasciifilenamews2.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename= "<b>foo.html</b>"</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="pass"><td>MSIE8</td><td>pass</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="pass"><td>Saf4</td><td>pass</td></tr><tr class="pass"><td>Konq</td><td>pass</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo.html</code>, with one
+ blank space <em>after</em> the equals character.
+ </p><p><em>UA should offer to download the resource as "foo.html".</em></p></div><div id="attfnbrokentoken"><h4><a href="#attfnbrokentoken" class="plain">attfnbrokentoken</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfnbrokentoken.asis">TEST</a>]
+ </h4><pre class="invalid"><b>Content-Disposition: </b>attachment; filename=<b>foo[1](2).html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="warn"><td>FF3</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>MSIE8</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>Op10</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>Saf4</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>Konq</td><td>warn
+ (accepts the unquoted value)
+ </td></tr><tr class="warn"><td>Chrome</td><td>warn
+ (accepts the unquoted value)
+ </td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo[1](2).html</code>, but missing
+ the quotes. Also, "[", "]", "(" and ")" are not allowed in the HTTP <a href="http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p1-messaging-latest.html#rfc.section.1.2.2">token</a>
+ production.
+ </p><p><em>This is invalid according to <a href="http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.19.5.1">Section 19.5.1 of RFC2616</a>,
+ so UAs should ignore it.</em></p></div></div><div id="c-d-parms"><h3><a href="#c-d-parms" class="plain">Content-Disposition: Additional Parameters</a></h3>
+ <p>
+ Various tests relating to the additional parameters defined in
+ <a href="http://greenbytes.de/tech/webdav/rfc2183.html#rfc.section.2">Section 2 of RFC 2183</a>.
+ </p>
+ <div id="attcdate"><h4><a href="#attcdate" class="plain">attcdate</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attcdate.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; <b>creation-date="Wed, 12 Feb 1997 16:29:51 -0500"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="unsupported"><td>FF3</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>Op10</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>Konq</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr></tbody></table><p>'attachment', plus creation-date (see <a href="http://greenbytes.de/tech/webdav/rfc2183.html#rfc.section.2.4">Section 2.4 of RFC 2183</a>)</p><p><em>UA should offer to download the resource. When doing so,
+ the creation date should be set to 12 Feb 1997.</em></p></div><div id="attmdate"><h4><a href="#attmdate" class="plain">attmdate</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attmdate.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; <b>modification-date="Wed, 12 Feb 1997 16:29:51 -0500"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="unsupported"><td>FF3</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>Op10</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>Konq</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported
+ (seems to ignore the parameter)
+ </td></tr></tbody></table><p>'attachment', plus modification-date (see <a href="http://greenbytes.de/tech/webdav/rfc2183.html#rfc.section.2.5">Section 2.5 of RFC 2183</a>)</p><p><em>UA should offer to download the resource. When doing so,
+ the modification date should be set to 12 Feb 1997.</em></p></div></div><div id="c-d-extension"><h3><a href="#c-d-extension" class="plain">Content-Disposition: Disposition-Type Extension</a></h3>
+ <p>
+ A test checking behavior for disposition type extensions,
+ which should be treated as "attachment", see
+ <a href="http://greenbytes.de/tech/webdav/rfc2183.html#rfc.section.2.8">Section 2.8 of RFC 2183</a>.
+ </p>
+ <div id="dispext"><h4><a href="#dispext" class="plain">dispext</a>
+ [<a href="http://greenbytes.de/tech/tc2231/dispext.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>foobar</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="fail (does not treat it as 'attachment')"><td>MSIE8</td><td>fail (does not treat it as 'attachment')</td></tr><tr class="fail (does not treat it as 'attachment')"><td>Op10</td><td>fail (does not treat it as 'attachment')</td></tr><tr class="fail (does not treat it as 'attachment')"><td>Saf4</td><td>fail (does not treat it as 'attachment')</td></tr><tr class="fail (does not treat it as 'attachment')"><td>Konq</td><td>fail (does not treat it as 'attachment')</td></tr><tr class="pass"><td>Chrome</td><td>pass</td></tr></tbody></table><p>'foobar' only</p><p><em>This should be equivalent to using "attachment".</em></p></div></div><div id="encoding-2231-char"><h3><a href="#encoding-2231-char" class="plain">RFC2231 Encoding: Character Sets</a></h3>
+ <p>
+ Various tests using the parameter value encoding defined
+ in <a href="http://greenbytes.de/tech/webdav/rfc2231.html#rfc.section.4">Section 4 of RFC 2231</a>.
+ </p>
+ <div id="attwithisofn2231iso"><h4><a href="#attwithisofn2231iso" class="plain">attwithisofn2231iso</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithisofn2231iso.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*=<b>iso-8859-1''foo-%E4.html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using RFC2231 encoded ISO-8859-1
+ </p><p><em>UA should offer to download the resource as "foo-ä.html".
+ </em></p></div><div id="attwithfn2231utf8"><h4><a href="#attwithfn2231utf8" class="plain">attwithfn2231utf8</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231utf8.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*=<b>UTF-8''foo-%c3%a4-%e2%82%ac.html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä-€.html</code>, using RFC2231 encoded UTF-8
+ </p><p><em>UA should offer to download the resource as "foo-ä-€.html".
+ </em></p></div><div id="attwithfn2231noc"><h4><a href="#attwithfn2231noc" class="plain">attwithfn2231noc</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231noc.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*=<b>''foo-%c3%a4-%e2%82%ac.html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="warn"><td>FF3</td><td>warn
+ (decodes as UTF-8)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="warn"><td>Op10</td><td>warn
+ (decodes as 8bit encoding (ISO-8859-1?))
+ </td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ Behavior is undefined in RFC 2231, the charset part is missing, although UTF-8 was used.
+ </p></div><div id="attwithfn2231utf8comp"><h4><a href="#attwithfn2231utf8comp" class="plain">attwithfn2231utf8comp</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231utf8comp.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*=<b>UTF-8''foo-a%cc%88.html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="warn"><td>Op10</td><td>warn
+ (displays "foo-ä.html")
+ </td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using RFC2231 encoded UTF-8, but
+ choosing the decomposed form (lowercase a plus COMBINING DIAERESIS) --
+ on a Windows target system, this should be translated to the preferred
+ Unicode normal form (composed).
+ </p><p><em>UA should offer to download the resource as "foo-ä.html".
+ </em></p></div><div id="attwithfn2231utf8-bad"><h4><a href="#attwithfn2231utf8-bad" class="plain">attwithfn2231utf8-bad</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231utf8-bad.asis">TEST</a>]
+ </h4><pre class="invalid"><b>Content-Disposition: </b>attachment; filename*=<b>iso-8859-1''foo-%c3%a4-%e2%82%ac.html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (falls back to UTF-8)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="warn"><td>Op10</td><td>warn
+ (displays the raw octet sequence as if it was ISO-8859-1 (which is internally
+ treated as windows-1252, which <em>does</em> allow %82))
+ </td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä-€.html</code>, using RFC2231 encoded UTF-8, but declaring ISO-8859-1
+ </p><p><em>
+ The octet %82 does not represent a valid ISO-8859-1 code point, so
+ the UA should really ignore the parameter.
+ </em></p></div><div id="attwithfn2231ws1"><h4><a href="#attwithfn2231ws1" class="plain">attwithfn2231ws1</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231ws1.asis">TEST</a>]
+ </h4><pre class="invalid"><b>Content-Disposition: </b>attachment; filename<b> *=</b>UTF-8''foo-%c3%a4.html</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (displays garbage)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using RFC2231 encoded UTF-8, with whitespace before "*="
+ </p><p><em>
+ The parameter is invalid, thus should be ignored.
+ </em></p></div><div id="attwithfn2231ws2"><h4><a href="#attwithfn2231ws2" class="plain">attwithfn2231ws2</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231ws2.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename<b>*= </b>UTF-8''foo-%c3%a4.html</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using RFC2231 encoded UTF-8, with whitespace after "*="
+ </p><p><em>
+ UA should offer to download the resource as "foo-ä.html".
+ </em></p></div><div id="attwithfn2231ws3"><h4><a href="#attwithfn2231ws3" class="plain">attwithfn2231ws3</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231ws3.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename<b>* =</b>UTF-8''foo-%c3%a4.html</pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using RFC2231 encoded UTF-8, with whitespace inside "* ="
+ </p><p><em>
+ UA should offer to download the resource as "foo-ä.html".
+ </em></p></div><div id="attwithfn2231quot"><h4><a href="#attwithfn2231quot" class="plain">attwithfn2231quot</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231quot.asis">TEST</a>]
+ </h4><pre class="invalid"><b>Content-Disposition: </b>attachment; filename*=<b>"</b>UTF-8''foo-%c3%a4.html<b>"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (tries to be helpful by removing the quotes)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using RFC2231 encoded UTF-8, with double quotes
+ around the parameter value.
+ </p><p><em>
+ The parameter is invalid, thus should be ignored.
+ </em></p></div><div id="attwithfn2231encmissing"><h4><a href="#attwithfn2231encmissing" class="plain">attwithfn2231encmissing</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attwithfn2231encmissing.asis">TEST</a>]
+ </h4><pre class="invalid"><b>Content-Disposition: </b>attachment; filename*=<b>''foo-%c3%a4.html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (sniffs the encoding as UTF-8)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="fail"><td>Op10</td><td>fail
+ (assumes a default of ISO-8859-1)
+ </td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using RFC2231 encoded UTF-8, but
+ leaving out the charset field.
+ </p><p><em>
+ The parameter is invalid, thus should be ignored.
+ </em></p></div></div><div id="encoding-2231-cont"><h3><a href="#encoding-2231-cont" class="plain">RFC2231 Encoding: Continuations</a></h3>
+ <p>
+ Various tests using the parameter value continuation efined
+ in <a href="http://greenbytes.de/tech/webdav/rfc2231.html#rfc.section.3">Section 3 of RFC 2231</a>.
+ </p>
+ <div id="attfncont"><h4><a href="#attfncont" class="plain">attfncont</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfncont.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*0=<b>"foo."</b>; filename*1=<b>"html"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo.html</code>, using RFC2231-style parameter continuations.
+ </p><p><em>
+ UA should offer to download the resource as "foo.html".
+ </em></p></div><div id="attfncontenc"><h4><a href="#attfncontenc" class="plain">attfncontenc</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfncontenc.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*0*=<b>UTF-8''foo-%c3%a4</b>; filename*1=<b>".html"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ä.html</code>, using both RFC2231-style parameter continuations
+ and UTF-8 encoding.
+ </p><p><em>
+ UA should offer to download the resource as "foo-ä.html".
+ </em></p></div><div id="attfncontlz"><h4><a href="#attfncontlz" class="plain">attfncontlz</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfncontlz.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*0=<b>"foo"</b>; filename*01=<b>"bar"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="warn"><td>FF3</td><td>warn
+ (accepts leading zeros)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="warn"><td>Op10</td><td>warn
+ (accepts leading zeros)
+ </td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo</code> (the parameter filename*01 should be ignored because of the leading zero)
+ </p><p><em>
+ UA should offer to download the resource as "foo".
+ </em></p></div><div id="attfncontnc"><h4><a href="#attfncontnc" class="plain">attfncontnc</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfncontnc.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*0=<b>"foo"</b>; filename*2=<b>"bar"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="warn"><td>FF3</td><td>warn
+ (accepts gaps)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo</code> (the parameter filename*2 because there's no filename*1 parameter)
+ </p><p><em>
+ UA should offer to download the resource as "foo".
+ </em></p></div><div id="attfnconts1"><h4><a href="#attfnconts1" class="plain">attfnconts1</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfnconts1.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*1=<b>"foo."</b>; filename*2=<b>"html"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass</td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment' (the filename* parameters should be ignored because filename*0 is missing)
+ </p><p><em>
+ UA should offer to download, not getting the filename from the header.
+ </em></p></div><div id="attfncontord"><h4><a href="#attfncontord" class="plain">attfncontord</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfncontord.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*1=<b>"bar"</b>; filename*0=<b>"foo"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (parameters are expected to be ordered)
+ </td></tr><tr class="unsupported"><td>MSIE8</td><td>unsupported</td></tr><tr class="pass"><td>Op10</td><td>pass</td></tr><tr class="unsupported"><td>Saf4</td><td>unsupported</td></tr><tr class="unsupported"><td>Konq</td><td>unsupported</td></tr><tr class="unsupported"><td>Chrome</td><td>unsupported</td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foobar</code>
+ </p><p><em>
+ UA should offer to download the resource as "foobar".
+ </em></p></div></div><div id="encoding-2231-fb"><h3><a href="#encoding-2231-fb" class="plain">RFC2231 Encoding: Fallback Behaviour</a></h3>
+ <p>
+ This tests how the UA behaves when the same parameter name appear
+ both in traditional and RFC 2231 extended format.
+ </p>
+ <div id="attfnboth"><h4><a href="#attfnboth" class="plain">attfnboth</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfnboth.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename="<b>foo-ae.html</b>"; filename*=<b>UTF-8''foo-%c3%a4.html</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass
+ (picks the traditionally encoded value -- the first of both)
+ </td></tr><tr class="pass"><td>MSIE8</td><td>pass
+ (picks the traditionally encoded value -- the first of both)
+ </td></tr><tr class="pass"><td>Op10</td><td>pass
+ (picks the traditionally encoded value -- the first of both)
+ </td></tr><tr class="pass"><td>Saf4</td><td>pass
+ (picks the traditionally encoded value -- the first of both)
+ </td></tr><tr class="pass"><td>Konq</td><td>pass
+ (picks the traditionally encoded value -- the first of both)
+ </td></tr><tr class="pass"><td>Chrome</td><td>pass
+ (picks the traditionally encoded value -- the first of both)
+ </td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ae.html</code> in
+ the traditional format, and <code>foo-ä.html</code> in RFC2231 format.
+ </p><p><em>
+ The behaviour of this undefined. Thus UAs should one of the two values.
+ </em></p></div><div id="attfnboth2"><h4><a href="#attfnboth2" class="plain">attfnboth2</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attfnboth2.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename*=<b>UTF-8''foo-%c3%a4.html</b>; filename=<b>"foo-ae.html"</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="pass"><td>FF3</td><td>pass
+ (picks the RFC2231 encoded value -- the first of both)
+ </td></tr><tr class="fail"><td>MSIE8</td><td>fail
+ (ignores the parameter (this indicates a parsing bug))
+ </td></tr><tr class="pass"><td>Op10</td><td>pass
+ (picks the RFC2231 encoded value -- the first of both)
+ </td></tr><tr class="pass"><td>Saf4</td><td>pass
+ (picks the traditionally encoded value -- the one it understands)
+ </td></tr><tr class="pass"><td>Konq</td><td>pass
+ (picks the traditionally encoded value -- the one it understands)
+ </td></tr><tr class="fail"><td>Chrome</td><td>fail
+ (ignores the parameter (this indicates a parsing bug))
+ </td></tr></tbody></table><p>
+ 'attachment', specifying a filename of <code>foo-ae.html</code> in
+ the traditional format, and <code>foo-ä.html</code> in RFC2231 format.
+ </p><p><em>
+ The behaviour of this undefined. Thus UAs should one of the two values.
+ </em></p></div></div><div id="encoding-2047"><h3><a href="#encoding-2047" class="plain">RFC2047 Encoding</a></h3>
+ <p>
+ These tests RFC 2047 style encoding.
+ </p>
+ <p>
+ Note that according to <a href="http://greenbytes.de/tech/webdav/rfc2047.html#rfc.section.5">Section 5 of RFC 2047</a>,
+ this encoding does not apply here: <q cite="http://greenbytes.de/tech/webdav/rfc2047.html#rfc.section.5">An 'encoded-word' MUST NOT appear within a 'quoted-string'.</q>, and
+ <q cite="http://greenbytes.de/tech/webdav/rfc2047.html#rfc.section.5">An 'encoded-word' MUST NOT be used in parameter of a MIME
+ Content-Type or Content-Disposition field, or in any structured
+ field body except within a 'comment' or 'phrase'.</q>
+ </p>
+ <p>
+ Therefore, these tests are only be present in order to check
+ whether the UA by mistake tries to implement RFC2047.
+ </p>
+ <div id="attrfc2047token"><h4><a href="#attrfc2047token" class="plain">attrfc2047token</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attrfc2047token.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename=<b>=?ISO-8859-1?Q?foo-=E4.html?=</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (decodes it anyway to "foo-ä.html")
+ </td></tr><tr class="pass"><td>MSIE8</td><td>pass
+ (takes the whole value as filename, but does not decode it (replacing question marks by underscores))
+ </td></tr><tr class="fail"><td>Op10</td><td>fail
+ (displays garbage ("=.htm"))
+ </td></tr><tr class="pass"><td>Saf4</td><td>pass
+ (takes the whole value as filename, but does not decode it (replacing question marks by underscores))
+ </td></tr><tr class="fail"><td>Konq</td><td>fail
+ (decodes it anyway to "foo-ä.html")
+ </td></tr><tr class="fail"><td>Chrome</td><td>fail
+ (decodes it anyway to "foo-ä.html")
+ </td></tr></tbody></table><p>
+ Uses RFC 2047 style encoded word. "=" is invalid inside the <code>token</code>
+ production, so this is invalid.
+ </p></div><div id="attrfc2047quoted"><h4><a href="#attrfc2047quoted" class="plain">attrfc2047quoted</a>
+ [<a href="http://greenbytes.de/tech/tc2231/attrfc2047quoted.asis">TEST</a>]
+ </h4><pre><b>Content-Disposition: </b>attachment; filename=<b>"=?ISO-8859-1?Q?foo-=E4.html?="</b></pre><table class="aside"><thead><tr><th colspan="2">
+ Test Results
+ </th></tr></thead><tbody><tr class="fail"><td>FF3</td><td>fail
+ (decodes it anyway to "foo-ä.html")
+ </td></tr><tr class="pass"><td>MSIE8</td><td>pass
+ (takes the whole value as filename, but does not decode it)
+ </td></tr><tr class="fail"><td>Op10</td><td>fail
+ (displays garbage ("=.htm"))
+ </td></tr><tr class="pass"><td>Saf4</td><td>pass
+ (takes the whole value as filename, but does not decode it)
+ </td></tr><tr class="fail"><td>Konq</td><td>fail
+ (decodes it anyway to "foo-ä.html")
+ </td></tr><tr class="fail"><td>Chrome</td><td>fail
+ (decodes it anyway to "foo-ä.html")
+ </td></tr></tbody></table><p>
+ Uses RFC 2047 style encoded word, using the <code>quoted-string</code> production.
+ </p></div></div>
+</body></html> \ No newline at end of file
diff --git a/src/tests/findbar_test.cpp b/src/tests/findbar_test.cpp
new file mode 100644
index 00000000..c9555441
--- /dev/null
+++ b/src/tests/findbar_test.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtGui>
+#include <QtTest/QtTest>
+
+#include "findbar.h"
+#include "mainwindow.h"
+
+
+class FindBarTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void matchCase();
+ void notifyMatch();
+
+private:
+ FindBar *bar;
+ MainWindow *w;
+};
+
+
+// -------------------------------------------
+
+
+void FindBarTest::initTestCase()
+{
+ w = new MainWindow;
+ bar = new FindBar(w);
+}
+
+
+void FindBarTest::cleanupTestCase()
+{
+ delete bar;
+}
+
+void FindBarTest::matchCase()
+{
+
+}
+
+void FindBarTest::notifyMatch()
+{
+}
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(FindBarTest, GUI)
+#include "findbar_test.moc"
diff --git a/src/tests/link_test.html b/src/tests/link_test.html
index 7dd1470d..5ca3cd41 100644
--- a/src/tests/link_test.html
+++ b/src/tests/link_test.html
@@ -135,6 +135,13 @@
<td><a href="http://ads.cnn.com/" target="_blank">link</a></td>
</tr>
+
+<tr>
+<td>http://ja.wikipedia.org/wiki/特別:最近の更新</td>
+<td>KGet import links with particular encoding</td>
+<td><a href="http://ja.wikipedia.org/wiki/特別:最近の更新">link</a></td>
+</tr>
+
<tr>
<td></td>
<td></td>
diff --git a/src/tests/mainview_test.cpp b/src/tests/mainview_test.cpp
index f56d73ab..d32eb58f 100644
--- a/src/tests/mainview_test.cpp
+++ b/src/tests/mainview_test.cpp
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -27,12 +27,13 @@
#include <qtest_kde.h>
-#include <QtTest>
#include <QtCore>
#include <QtGui>
+#include <QtTest>
-#include "../mainview.h"
-#include "../webview.h"
+#include "mainwindow.h"
+#include "mainview.h"
+#include "webview.h"
class MainViewTest : public QObject
@@ -42,71 +43,60 @@ class MainViewTest : public QObject
public slots:
void initTestCase();
void cleanupTestCase();
- void init();
- void cleanup();
private slots:
void tabwidget_data();
void tabwidget();
-
+
void closeTab_data();
void closeTab();
-
+
void currentWebView_data();
void currentWebView();
-
+
void newTab_data();
void newTab();
-
+
void nextTab_data();
void nextTab();
-
+
void previousTab_data();
void previousTab();
-
+
void recentlyClosedTabs_data();
void recentlyClosedTabs();
-
+
void setCurrentTitle_data();
void setCurrentTitle(const QString &);
-
+
void showStatusBarMessage_data();
void showStatusBarMessage(const QString &);
-
+
void currentChanged_data();
void currentChanged();
+
+private:
+ MainWindow *window;
+ MainView *view;
};
-// Subclass that exposes the protected functions.
-class SubMainView : public MainView
-{
-public:
- void call_resizeEvent(QResizeEvent *event)
- { return SubMainView::resizeEvent(event); }
-};
+// -------------------------------------------------------------------------------
// This will be called before the first test function is executed.
// It is only called once.
void MainViewTest::initTestCase()
{
+ window = new MainWindow;
+ view = window->mainView();
}
// This will be called after the last test function is executed.
// It is only called once.
void MainViewTest::cleanupTestCase()
{
-}
-
-// This will be called before each test function is executed.
-void MainViewTest::init()
-{
-}
-
-// This will be called after every test function.
-void MainViewTest::cleanup()
-{
+// delete window; // FIXME: this let the test fail. Why??
}
// -------------------------------------------
@@ -117,14 +107,16 @@ void MainViewTest::tabwidget_data()
void MainViewTest::tabwidget()
{
- SubMainView widget;
-// widget.currentWebView();
-// QCOMPARE(widget.currentIndex(), 0);
-// widget.newTab();
-// widget.nextTab();
-// QCOMPARE(widget.currentIndex(), 1);
-// widget.previousTab();
-// QCOMPARE(widget.currentIndex(), 0);
+ QCOMPARE(view->currentIndex(), -1);
+
+// view->newTab();
+// QCOMPARE(view->currentIndex(), 1);
+// view->newTab();
+// view->nextTab();
+// QCOMPARE(view->currentIndex(), 0);
+//
+// view->previousTab();
+// QCOMPARE(view->currentIndex(), 0);
}
// -------------------------------------------
@@ -135,33 +127,30 @@ void MainViewTest::closeTab_data()
QTest::newRow("null") << 0;
}
-// public void closeTab(int index = -1)
+
void MainViewTest::closeTab()
{
- QFETCH(int, index);
-
- SubMainView widget;
-/*
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
-QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
-
- widget.newTab();
- widget.slotCloseTab(index);
- widget.newTab();
- widget.slotCloseTab(index);
- widget.newTab();
-
- QCOMPARE(spy0.count(), 0);
- QCOMPARE(spy3.count(), 2);
- QCOMPARE(spy5.count(), 0);
- QCOMPARE(spy6.count(), 0);*/
+// QFETCH(int, index);
+//
+// QSignalSpy spy1(view, SIGNAL(linkHovered(const QString &)));
+// QSignalSpy spy2(view, SIGNAL(setCurrentTitle(const QString &)));
+// QSignalSpy spy3(view, SIGNAL(tabsChanged()));
+// QSignalSpy spy4(view, SIGNAL(lastTabClosed()));
+//
+// view->newTab();
+// view->closeTab(index);
+// view->newTab();
+// view->closeTab(index);
+// view->newTab();
+//
+// QCOMPARE(spy1.count(), 0);
+// QCOMPARE(spy2.count(), 2);
+// QCOMPARE(spy3.count(), 0);
+// QCOMPARE(spy4.count(), 0);
}
// -------------------------------------------
-Q_DECLARE_METATYPE(WebView*)
void MainViewTest::currentWebView_data()
{
/*
@@ -170,7 +159,6 @@ void MainViewTest::currentWebView_data()
*/
}
-// public WebView *currentWebView() const
void MainViewTest::currentWebView()
{
/*
@@ -178,12 +166,12 @@ void MainViewTest::currentWebView()
SubMainView widget;
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy2(&widget, SIGNAL(loadProgress(int)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
- QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &)));
- QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
+ QSignalSpy spy0(view, SIGNAL(linkHovered(const QString &)));
+ QSignalSpy spy2(view, SIGNAL(loadProgress(int)));
+ QSignalSpy spy3(view, SIGNAL(setCurrentTitle(const QString &)));
+ QSignalSpy spy4(view, SIGNAL(showStatusBarMessage(const QString &)));
+ QSignalSpy spy5(view, SIGNAL(tabsChanged()));
+ QSignalSpy spy6(view, SIGNAL(lastTabClosed()));
QCOMPARE(widget.currentWebView(), currentWebView);
@@ -205,31 +193,24 @@ void MainViewTest::newTab_data()
QTest::newRow("null") << 0;
}
-// public void newTab()
+
void MainViewTest::newTab()
{
- /*
- QFETCH(int, foo);
-
- SubMainView widget;
-
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy2(&widget, SIGNAL(loadProgress(int)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
- QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &)));
- QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
-
- widget.newTab();
-
- QCOMPARE(spy0.count(), 0);
- QCOMPARE(spy2.count(), 0);
- QCOMPARE(spy3.count(), 0);
- QCOMPARE(spy4.count(), 0);
- QCOMPARE(spy5.count(), 0);
- QCOMPARE(spy6.count(), 0);
- */
- QSKIP("Test is not implemented.", SkipAll);
+// QFETCH(int, foo);
+//
+// QSignalSpy spy0(view, SIGNAL(linkHovered(const QString &)));
+// QSignalSpy spy1(view, SIGNAL(setCurrentTitle(const QString &)));
+// QSignalSpy spy2(view, SIGNAL(showStatusBarMessage(const QString &)));
+// QSignalSpy spy3(view, SIGNAL(tabsChanged()));
+// QSignalSpy spy4(view, SIGNAL(lastTabClosed()));
+//
+// view->newTab();
+//
+// QCOMPARE(spy0.count(), 0);
+// QCOMPARE(spy1.count(), 0);
+// QCOMPARE(spy2.count(), 0);
+// QCOMPARE(spy3.count(), 0);
+// QCOMPARE(spy4.count(), 0);
}
// -------------------------------------------
@@ -248,12 +229,12 @@ void MainViewTest::nextTab()
SubMainView widget;
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy2(&widget, SIGNAL(loadProgress(int)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
- QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &)));
- QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
+ QSignalSpy spy0(view, SIGNAL(linkHovered(const QString &)));
+ QSignalSpy spy2(view, SIGNAL(loadProgress(int)));
+ QSignalSpy spy3(view, SIGNAL(setCurrentTitle(const QString &)));
+ QSignalSpy spy4(view, SIGNAL(showStatusBarMessage(const QString &)));
+ QSignalSpy spy5(view, SIGNAL(tabsChanged()));
+ QSignalSpy spy6(view, SIGNAL(lastTabClosed()));
widget.nextTab();
@@ -284,12 +265,12 @@ void MainViewTest::previousTab()
SubMainView widget;
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy2(&widget, SIGNAL(loadProgress(int)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
- QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &)));
- QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
+ QSignalSpy spy0(view, SIGNAL(linkHovered(const QString &)));
+ QSignalSpy spy2(view, SIGNAL(loadProgress(int)));
+ QSignalSpy spy3(view, SIGNAL(setCurrentTitle(const QString &)));
+ QSignalSpy spy4(view, SIGNAL(showStatusBarMessage(const QString &)));
+ QSignalSpy spy5(view, SIGNAL(tabsChanged()));
+ QSignalSpy spy6(view, SIGNAL(lastTabClosed()));
widget.previousTab();
@@ -314,12 +295,12 @@ void MainViewTest::recentlyClosedTabs()
/*
SubMainView widget;
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy2(&widget, SIGNAL(loadProgress(int)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
- QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &)));
- QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
+ QSignalSpy spy0(view, SIGNAL(linkHovered(const QString &)));
+ QSignalSpy spy2(view, SIGNAL(loadProgress(int)));
+ QSignalSpy spy3(view, SIGNAL(setCurrentTitle(const QString &)));
+ QSignalSpy spy4(view, SIGNAL(showStatusBarMessage(const QString &)));
+ QSignalSpy spy5(view, SIGNAL(tabsChanged()));
+ QSignalSpy spy6(view, SIGNAL(lastTabClosed()));
QCOMPARE(spy0.count(), 0);
QCOMPARE(spy2.count(), 0);
@@ -347,12 +328,12 @@ void MainViewTest::setCurrentTitle(const QString &)
SubMainView widget;
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy2(&widget, SIGNAL(loadProgress(int)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
- QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &)));
- QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
+ QSignalSpy spy0(view, SIGNAL(linkHovered(const QString &)));
+ QSignalSpy spy2(view, SIGNAL(loadProgress(int)));
+ QSignalSpy spy3(view, SIGNAL(setCurrentTitle(const QString &)));
+ QSignalSpy spy4(view, SIGNAL(showStatusBarMessage(const QString &)));
+ QSignalSpy spy5(view, SIGNAL(tabsChanged()));
+ QSignalSpy spy6(view, SIGNAL(lastTabClosed()));
widget.call_setCurrentTitle(url);
@@ -382,12 +363,12 @@ void MainViewTest::showStatusBarMessage(const QString &)
SubMainView widget;
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy2(&widget, SIGNAL(loadProgress(int)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
- QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &)));
- QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
+ QSignalSpy spy0(view, SIGNAL(linkHovered(const QString &)));
+ QSignalSpy spy2(view, SIGNAL(loadProgress(int)));
+ QSignalSpy spy3(view, SIGNAL(setCurrentTitle(const QString &)));
+ QSignalSpy spy4(view, SIGNAL(showStatusBarMessage(const QString &)));
+ QSignalSpy spy5(view, SIGNAL(tabsChanged()));
+ QSignalSpy spy6(view, SIGNAL(lastTabClosed()));
widget.call_showStatusBarMessage(message);
@@ -403,14 +384,12 @@ void MainViewTest::showStatusBarMessage(const QString &)
// -------------------------------------------
-// void slotCurrentChanged(int index);
void MainViewTest::currentChanged_data()
{
QTest::addColumn<int>("foo");
QTest::newRow("null") << 0;
}
-// private slotCurrentChanged
void MainViewTest::currentChanged()
{
/*
@@ -418,12 +397,12 @@ void MainViewTest::currentChanged()
SubMainView widget;
- QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &)));
- QSignalSpy spy2(&widget, SIGNAL(loadProgress(int)));
- QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &)));
- QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &)));
- QSignalSpy spy5(&widget, SIGNAL(tabsChanged()));
- QSignalSpy spy6(&widget, SIGNAL(lastTabClosed()));
+ QSignalSpy spy0(view, SIGNAL(linkHovered(const QString &)));
+ QSignalSpy spy2(view, SIGNAL(loadProgress(int)));
+ QSignalSpy spy3(view, SIGNAL(setCurrentTitle(const QString &)));
+ QSignalSpy spy4(view, SIGNAL(showStatusBarMessage(const QString &)));
+ QSignalSpy spy5(view, SIGNAL(tabsChanged()));
+ QSignalSpy spy6(view, SIGNAL(lastTabClosed()));
widget.call_tabsChanged();
diff --git a/src/tests/mainwindow_test.cpp b/src/tests/mainwindow_test.cpp
new file mode 100644
index 00000000..af3a2aa2
--- /dev/null
+++ b/src/tests/mainwindow_test.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+
+#include "mainwindow.h"
+#include "application.h"
+
+
+class MainWindowTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+
+
+private:
+ MainWindow *window;
+};
+
+
+// -------------------------------------------
+
+
+void MainWindowTest::initTestCase()
+{
+ window = new MainWindow;
+}
+
+
+void MainWindowTest::cleanupTestCase()
+{
+// delete window;
+}
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(MainWindowTest, GUI)
+#include "mainwindow_test.moc"
diff --git a/src/tests/networkaccessmanager_test.cpp b/src/tests/networkaccessmanager_test.cpp
new file mode 100644
index 00000000..28b05075
--- /dev/null
+++ b/src/tests/networkaccessmanager_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+
+#include "networkaccessmanager.h"
+
+
+class NetworkAccessManagerTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+
+private:
+ NetworkAccessManager *manager;
+};
+
+
+// -------------------------------------------
+
+void NetworkAccessManagerTest::initTestCase()
+{
+ manager = new NetworkAccessManager(this);
+}
+
+
+void NetworkAccessManagerTest::cleanupTestCase()
+{
+ delete manager;
+}
+
+
+// -------------------------------------------
+
+
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(NetworkAccessManagerTest, GUI)
+#include "networkaccessmanager_test.moc"
diff --git a/src/tests/protocolhandler_test.cpp b/src/tests/protocolhandler_test.cpp
new file mode 100644
index 00000000..dbf33684
--- /dev/null
+++ b/src/tests/protocolhandler_test.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+#include <QtNetwork>
+#include <QtWebKit>
+
+#include "protocolhandler.h"
+
+
+class ProtocolhandlerTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void preHandling_data();
+ void preHandling();
+
+ void postHandling_data();
+ void postHandling();
+
+private:
+ ProtocolHandler *handler;
+};
+
+
+// -------------------------------------------
+
+void ProtocolhandlerTest::initTestCase()
+{
+ handler = new ProtocolHandler;
+}
+
+
+void ProtocolhandlerTest::cleanupTestCase()
+{
+ delete handler;
+}
+
+
+// -------------------------------------------
+
+
+void ProtocolhandlerTest::preHandling_data()
+{
+ QTest::addColumn<QString>("urlString");
+ QTest::addColumn<bool>("result");
+
+ QTest::newRow("mailto") << "mailto:me@here.com" << true ;
+ QTest::newRow("relative") << "google.it" << false ;
+ QTest::newRow("javascript") << "javascript:alertbox('hello')" << true ;
+ QTest::newRow("aboutblank") << "about:blank" << false ;
+ QTest::newRow("abouthome") << "about:home" << true ;
+ QTest::newRow("ftp") << "ftp://ftp.kde.org" << false ;
+ QTest::newRow("file") << "file:///home" << false ;
+}
+
+
+void ProtocolhandlerTest::preHandling()
+{
+ QFETCH(QString, urlString);
+ QFETCH(bool , result);
+
+ QWebView *view = new QWebView;
+ QWebFrame *frame = view->page()->mainFrame();
+
+ QNetworkRequest request = QNetworkRequest(QUrl(urlString));
+
+ QCOMPARE(handler->preHandling(request, frame) , result);
+}
+
+
+void ProtocolhandlerTest::postHandling_data()
+{
+ QTest::addColumn<QString>("urlString");
+ QTest::addColumn<bool>("result");
+
+ QTest::newRow("mailto") << "mailto:me@here.com" << true ;
+ QTest::newRow("relative") << "google.it" << false ;
+ QTest::newRow("javascript") << "javascript:alertbox('hello')" << false ;
+ QTest::newRow("aboutblank") << "about:blank" << false ;
+ QTest::newRow("abouthome") << "about:home" << false ;
+ QTest::newRow("ftp") << "ftp://ftp.kde.org" << true ;
+ QTest::newRow("file") << "file:///home" << true ;
+}
+
+
+void ProtocolhandlerTest::postHandling()
+{
+ QFETCH(QString, urlString);
+ QFETCH(bool , result);
+
+ QWebView *view = new QWebView;
+ QWebFrame *frame = view->page()->mainFrame();
+
+ QNetworkRequest request = QNetworkRequest(QUrl(urlString));
+
+ QCOMPARE(handler->postHandling(request, frame) , result);
+}
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(ProtocolhandlerTest, GUI)
+#include "protocolhandler_test.moc"
diff --git a/src/tests/sessionmanager_test.cpp b/src/tests/sessionmanager_test.cpp
new file mode 100644
index 00000000..bb784219
--- /dev/null
+++ b/src/tests/sessionmanager_test.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+
+
+#include "sessionmanager.h"
+
+
+class SessionManagerTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+
+private:
+ SessionManager *sessman;
+};
+
+
+// -------------------------------------------
+
+
+void SessionManagerTest::initTestCase()
+{
+ sessman = new SessionManager;
+}
+
+
+void SessionManagerTest::cleanupTestCase()
+{
+ delete sessman;
+}
+
+
+// -------------------------------------------
+
+
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(SessionManagerTest, GUI)
+#include "sessionmanager_test.moc"
diff --git a/src/tests/tabbar_test.cpp b/src/tests/tabbar_test.cpp
index 08f295d1..6df38657 100644
--- a/src/tests/tabbar_test.cpp
+++ b/src/tests/tabbar_test.cpp
@@ -24,116 +24,125 @@
#include <QtCore>
#include <QtGui>
-#include "../tabbar.h"
+#include "mainwindow.h"
+#include "mainview.h"
+#include "tabbar.h"
-class TabBarTest : public QObject
+/**
+ * Subclass that exposes the protected functions.
+ */
+class SubTabBar : public TabBar
{
- Q_OBJECT
+public:
-public slots:
- void initTestCase();
- void cleanupTestCase();
- void init();
- void cleanup();
+ SubTabBar(QWidget *parent) : TabBar(parent) {};
-private slots:
- void tabbar_data();
- void tabbar();
+ QSize call_tabSizeHint(int index) const
+ {
+ return SubTabBar::tabSizeHint(index);
+ }
- void tabSizeHint_data();
- void tabSizeHint();
-};
+ void call_mouseMoveEvent(QMouseEvent* event)
+ {
+ return SubTabBar::mouseMoveEvent(event);
+ }
+ void call_leaveEvent(QEvent* event)
+ {
+ return SubTabBar::leaveEvent(event);
+ }
-// Subclass that exposes the protected functions.
-class SubTabBar : public TabBar
-{
-public:
- void call_cloneTab(int index)
- { return SubTabBar::cloneTab(index); }
+ void call_mousePressEvent(QMouseEvent* event)
+ {
+ return SubTabBar::mousePressEvent(event);
+ }
+
+ void call_mouseReleaseEvent(QMouseEvent* event)
+ {
+ return SubTabBar::mouseReleaseEvent(event);
+ }
+};
- void call_closeOtherTabs(int index)
- { return SubTabBar::closeOtherTabs(index); }
- void call_closeTab(int index)
- { return SubTabBar::closeTab(index); }
+// ------------------------------------------------------------------
- void call_mouseMoveEvent(QMouseEvent* event)
- { return SubTabBar::mouseMoveEvent(event); }
- void call_mousePressEvent(QMouseEvent* event)
- { return SubTabBar::mousePressEvent(event); }
+class TabBarTest : public QObject
+{
+ Q_OBJECT
- void call_reloadAllTabs()
- { return SubTabBar::reloadAllTabs(); }
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
- void call_reloadTab(int index)
- { return SubTabBar::reloadTab(index); }
+private slots:
+ void tabSizeHint_data();
+ void tabSizeHint();
- QSize call_tabSizeHint(int index) const
- { return SubTabBar::tabSizeHint(index); }
+ void mousePress_data();
+ void mousePress();
- void call_showTabPreview(int tab)
- { return SubTabBar::showTabPreview(tab); }
+private:
+ SubTabBar *_bar;
};
-// This will be called before the first test function is executed.
-// It is only called once.
+// -------------------------------------------
+
void TabBarTest::initTestCase()
{
+ MainWindow *w = new MainWindow;
+ MainView *mv = new MainView(w);
+ _bar = new SubTabBar(mv);
}
-
-// This will be called after the last test function is executed.
-// It is only called once.
void TabBarTest::cleanupTestCase()
{
+ delete _bar;
}
+// -------------------------------------------
-// This will be called before each test function is executed.
-void TabBarTest::init()
+void TabBarTest::tabSizeHint_data()
{
+ QTest::addColumn<int>("index");
+
+ QTest::newRow("1th") << 0;
+ QTest::newRow("2nd") << 1;
+ QTest::newRow("3rd") << 2;
+ QTest::newRow("4th") << 3;
+ QTest::newRow("5th") << 4;
+ QTest::newRow("6th") << 5;
+ QTest::newRow("7th") << 6;
+ QTest::newRow("8th") << 7;
+ QTest::newRow("9th") << 8;
+ QTest::newRow("10th") << 9;
}
-// This will be called after every test function.
-void TabBarTest::cleanup()
+void TabBarTest::tabSizeHint()
{
-}
-
-// -------------------------------------------
+ QFETCH(int, index);
-void TabBarTest::tabbar_data()
-{
+ QVERIFY(_bar->call_tabSizeHint(index).width() > 0);
}
-void TabBarTest::tabbar()
+void TabBarTest::mousePress_data()
{
- SubTabBar widget;
}
-// -------------------------------------------
-void TabBarTest::tabSizeHint_data()
+void TabBarTest::mousePress()
{
-// QTest::addColumn<int>("index");
-// QTest::newRow("0") << 0;
+// QTest::mousePress(_bar, Qt::MidButton);
+// // QCOMPARE(); ?
+//
+// QTest::mousePress(_bar, Qt::LeftButton);
+// // QCOMPARE(); ?
}
-
-// protected QSize tabSizeHint(int index) const
-void TabBarTest::tabSizeHint()
-{
- // Need fixes as our function uses MainView methods to determine size
-// QFETCH(int, index);
-// SubTabBar bar;
-// QVERIFY(bar.call_tabSizeHint(index).width() <= 250);
-}
-
// -------------------------------------------
QTEST_KDEMAIN(TabBarTest, GUI)
diff --git a/src/tests/urlbar_test.cpp b/src/tests/urlbar_test.cpp
new file mode 100644
index 00000000..fc7c1718
--- /dev/null
+++ b/src/tests/urlbar_test.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+
+#include "webpage.h"
+#include "webview.h"
+#include "webtab.h"
+
+#include "urlbar.h"
+
+
+class UrlBarTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+
+private:
+ UrlBar *bar;
+ WebTab *tab;
+};
+
+
+// -------------------------------------------
+
+void UrlBarTest::initTestCase()
+{
+ tab = new WebTab;
+ bar = new UrlBar(tab);
+}
+
+
+void UrlBarTest::cleanupTestCase()
+{
+ delete bar;
+ delete tab;
+}
+
+
+// -------------------------------------------
+
+
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(UrlBarTest, GUI)
+#include "urlbar_test.moc"
diff --git a/src/tests/walletbar_test.cpp b/src/tests/walletbar_test.cpp
new file mode 100644
index 00000000..d4036981
--- /dev/null
+++ b/src/tests/walletbar_test.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+
+#include "walletbar.h"
+
+
+class WalletBarTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+
+private:
+ WalletBar *bar;
+};
+
+
+// -------------------------------------------
+
+
+void WalletBarTest::initTestCase()
+{
+ QWidget *w = new QWidget;
+ bar = new WalletBar(w);
+}
+
+
+void WalletBarTest::cleanupTestCase()
+{
+ delete bar;
+}
+
+
+// -------------------------------------------
+
+
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(WalletBarTest, GUI)
+#include "walletbar_test.moc"
diff --git a/src/tests/webpage_test.cpp b/src/tests/webpage_test.cpp
new file mode 100644
index 00000000..c06ce7a5
--- /dev/null
+++ b/src/tests/webpage_test.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+#include <QtWebKit>
+
+#include "webpage.h"
+#include "webview.h"
+#include "webtab.h"
+
+
+class WebPageTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void manageNetworkErrors();
+ void downloadRequest();
+ void downloadAllContentsWithKGet();
+
+ void createWindow();
+ void acceptNavigationRequest();
+
+ void handleUnsupportedContent();
+
+ void loadFinished();
+
+private:
+ WebTab *tab;
+ WebPage *page;
+ WebView *view;
+};
+
+
+// -------------------------------------------
+
+
+void WebPageTest::initTestCase()
+{
+ tab = new WebTab;
+ view = tab->view();
+ page = tab->page();
+}
+
+
+void WebPageTest::cleanupTestCase()
+{
+ delete tab;
+}
+
+
+// -------------------------------------------
+
+
+void WebPageTest::manageNetworkErrors()
+{
+}
+
+void WebPageTest::downloadRequest()
+{
+}
+
+void WebPageTest::downloadAllContentsWithKGet()
+{
+}
+
+void WebPageTest::createWindow()
+{
+}
+
+void WebPageTest::acceptNavigationRequest()
+{
+}
+
+void WebPageTest::handleUnsupportedContent()
+{
+}
+
+void WebPageTest::loadFinished()
+{
+}
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(WebPageTest, GUI)
+#include "webpage_test.moc"
diff --git a/src/tests/websnap_test.cpp b/src/tests/websnap_test.cpp
new file mode 100644
index 00000000..1bfb440d
--- /dev/null
+++ b/src/tests/websnap_test.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+#include <QtWebKit>
+
+#include "websnap.h"
+
+
+class WebSnapTest : public QObject
+{
+ Q_OBJECT
+
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+
+private:
+ WebSnap *snap;
+};
+
+
+// -------------------------------------------
+
+
+void WebSnapTest::initTestCase()
+{
+}
+
+
+void WebSnapTest::cleanupTestCase()
+{
+ delete snap;
+}
+
+
+// -------------------------------------------
+
+
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(WebSnapTest, GUI)
+#include "websnap_test.moc"
diff --git a/src/tests/webtab_test.cpp b/src/tests/webtab_test.cpp
new file mode 100644
index 00000000..0e5833b4
--- /dev/null
+++ b/src/tests/webtab_test.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+#include <QtWebKit>
+
+#include "webpage.h"
+#include "webview.h"
+#include "webtab.h"
+
+
+class WebTabTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private:
+ WebTab *tab;
+};
+
+
+// -------------------------------------------
+
+
+void WebTabTest::initTestCase()
+{
+ tab = new WebTab;
+}
+
+
+void WebTabTest::cleanupTestCase()
+{
+ delete tab;
+}
+
+
+// -------------------------------------------
+
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(WebTabTest, GUI)
+#include "webtab_test.moc"
diff --git a/src/tests/webview_test.cpp b/src/tests/webview_test.cpp
new file mode 100644
index 00000000..7eb968c7
--- /dev/null
+++ b/src/tests/webview_test.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010 Andrea Diamantini <adjam7@gmail.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) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+
+
+#include <qtest_kde.h>
+
+#include <QtCore>
+#include <QtGui>
+#include <QtTest>
+#include <QtWebKit>
+
+#include "webview.h"
+#include "webtab.h"
+
+
+class WebViewTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+
+private:
+ WebView *view;
+ WebTab *tab;
+};
+
+
+// -------------------------------------------
+
+
+void WebViewTest::initTestCase()
+{
+ tab = new WebTab;
+ view = tab->view();
+}
+
+
+void WebViewTest::cleanupTestCase()
+{
+ delete tab;
+}
+
+
+// -------------------------------------------
+
+
+// -------------------------------------------
+
+QTEST_KDEMAIN(WebViewTest, GUI)
+#include "webview_test.moc"
diff --git a/src/urlbar/completionwidget.cpp b/src/urlbar/completionwidget.cpp
new file mode 100644
index 00000000..6dae6285
--- /dev/null
+++ b/src/urlbar/completionwidget.cpp
@@ -0,0 +1,282 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 "completionwidget.h"
+#include "completionwidget.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// Local Includes
+#include "application.h"
+#include "urlresolver.h"
+#include "searchengine.h"
+
+// KDE Includes
+#include <KGlobalSettings>
+#include <KUrl>
+
+// Qt Includes
+#include <QtCore/QPoint>
+#include <QtCore/QSize>
+#include <QtCore/QEvent>
+
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QKeyEvent>
+
+
+
+CompletionWidget::CompletionWidget(QWidget *parent)
+ : QFrame(parent, Qt::ToolTip)
+ , _parent(parent)
+ , _currentIndex(-1)
+ , _searchEngine(SearchEngine::defaultEngine())
+{
+ setFrameStyle(QFrame::Panel);
+ setLayoutDirection(Qt::LeftToRight);
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setMargin(0);
+ layout->setSpacing(0);
+ setLayout(layout);
+}
+
+
+void CompletionWidget::insertSearchList(const UrlSearchList &list, const QString& text)
+{
+ _list = list;
+ int i = 0;
+ foreach(const UrlSearchItem &item, _list)
+ {
+ ListItem *suggestion = ListItemFactory::create(item, text, this);
+ suggestion->setBackgroundRole(i % 2 ? QPalette::AlternateBase : QPalette::Base);
+ connect(suggestion, SIGNAL(itemClicked(ListItem *, Qt::MouseButton)), this, SLOT(itemChosen(ListItem *, Qt::MouseButton)));
+ connect(this, SIGNAL(nextItemSubChoice()), suggestion, SLOT(nextItemSubChoice()));
+ suggestion->setObjectName(QString::number(i++));
+ layout()->addWidget(suggestion);
+ }
+}
+
+
+void CompletionWidget::sizeAndPosition()
+{
+ setFixedWidth(_parent->width());
+ adjustSize();
+
+ // position
+ QPoint p = _parent->mapToGlobal(QPoint(0, 0));
+ move(p.x(), p.y() + _parent->height());
+}
+
+
+void CompletionWidget::popup()
+{
+ down();
+ sizeAndPosition();
+ if (!isVisible())
+ show();
+}
+
+
+void CompletionWidget::up()
+{
+ // deactivate previous
+ if (_currentIndex != -1)
+ {
+ ListItem *widget = findChild<ListItem *>(QString::number(_currentIndex));
+ widget->deactivate();
+ }
+
+ if (_currentIndex > 0)
+ _currentIndex--;
+ else
+ _currentIndex = layout()->count() - 1;
+
+ // activate "new" current
+ ListItem *widget = findChild<ListItem *>(QString::number(_currentIndex));
+ widget->activate();
+}
+
+
+void CompletionWidget::down()
+{
+ // deactivate previous
+ if (_currentIndex != -1)
+ {
+ ListItem *widget = findChild<ListItem *>(QString::number(_currentIndex));
+ widget->deactivate();
+ }
+
+ if (_currentIndex < _list.count() - 1)
+ _currentIndex++;
+ else
+ _currentIndex = 0;
+
+ // activate "new" current
+ ListItem *widget = findChild<ListItem *>(QString::number(_currentIndex));
+ widget->activate();
+}
+
+
+void CompletionWidget::clear()
+{
+ QLayoutItem *child;
+ while ((child = layout()->takeAt(0)) != 0)
+ {
+ delete child->widget();
+ delete child;
+ }
+ _currentIndex = -1;
+}
+
+
+bool CompletionWidget::eventFilter(QObject *o, QEvent *e)
+{
+ int type = e->type();
+ QWidget *wid = qobject_cast<QWidget*>(o);
+
+ if (o == this)
+ {
+ return false;
+ }
+
+ //hide conditions of the CompletionWidget
+ if (wid
+ && ((wid == _parent && (type == QEvent::Move || type == QEvent::Resize))
+ || ((wid->windowFlags() & Qt::Window)
+ && (type == QEvent::Move || type == QEvent::Hide || type == QEvent::WindowDeactivate)
+ && wid == _parent->window())
+ || (type == QEvent::MouseButtonPress && !isAncestorOf(wid)))
+ )
+ {
+ hide();
+ return false;
+ }
+
+ //actions on the CompletionWidget
+ if (wid && wid->isAncestorOf(_parent) && isVisible())
+ {
+ ListItem *child;
+
+ if (type == QEvent::KeyPress)
+ {
+ QKeyEvent *ev = static_cast<QKeyEvent *>(e);
+ switch (ev->key())
+ {
+ case Qt::Key_Up:
+ case Qt::Key_Backtab:
+ if (ev->modifiers() == Qt::NoButton || (ev->modifiers() & Qt::ShiftModifier))
+ {
+ up();
+ ev->accept();
+ return true;
+ }
+ break;
+
+ case Qt::Key_Down:
+ case Qt::Key_Tab:
+ if (ev->modifiers() == Qt::NoButton)
+ {
+ down();
+ ev->accept();
+ return true;
+ }
+ if (ev->modifiers() & Qt::ControlModifier)
+ {
+ emit nextItemSubChoice();
+ ev->accept();
+ return true;
+ }
+ break;
+
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ child = findChild<ListItem *>(QString::number(_currentIndex));
+ emit chosenUrl(child->url(), Rekonq::CurrentTab);
+ ev->accept();
+ hide();
+ return true;
+
+ case Qt::Key_Escape:
+ hide();
+ return true;
+ }
+ }
+ }
+
+ return QFrame::eventFilter(o, e);
+}
+
+
+void CompletionWidget::setVisible(bool visible)
+{
+ if (visible)
+ {
+ Application::instance()->installEventFilter(this);
+ }
+ else
+ {
+ Application::instance()->removeEventFilter(this);
+ }
+
+
+ QFrame::setVisible(visible);
+}
+
+
+void CompletionWidget::itemChosen(ListItem *item, Qt::MouseButton button)
+{
+ if (button == Qt::MidButton)
+ emit chosenUrl(item->url(), Rekonq::NewCurrentTab);
+ else
+ emit chosenUrl(item->url(), Rekonq::CurrentTab);
+ hide();
+}
+
+
+void CompletionWidget::suggestUrls(const QString &text)
+{
+ QWidget *w = qobject_cast<QWidget *>(parent());
+ if (!w->hasFocus())
+ return;
+
+ if (text.isEmpty())
+ {
+ hide();
+ return;
+ }
+
+ UrlResolver res(text);
+ UrlSearchList list = res.orderedSearchItems();
+ if (list.count() > 0)
+ {
+ clear();
+ insertSearchList(list, text);
+ popup();
+ }
+}
+
+
diff --git a/src/urlbar/completionwidget.h b/src/urlbar/completionwidget.h
new file mode 100644
index 00000000..fc0798e7
--- /dev/null
+++ b/src/urlbar/completionwidget.h
@@ -0,0 +1,89 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 COMPLETION_WIDGET_H
+#define COMPLETION_WIDGET_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Local Includes
+#include "listitem.h"
+
+// KDE Includes
+#include <KService>
+
+// Qt Includes
+#include <QFrame>
+
+
+class CompletionWidget : public QFrame
+{
+ Q_OBJECT
+
+public:
+ CompletionWidget(QWidget *parent);
+
+ virtual bool eventFilter(QObject *obj, QEvent *ev);
+ void setVisible(bool visible);
+
+ KService::Ptr searchEngine()
+ {
+ return _searchEngine;
+ };
+
+ void setCurrentEngine(KService::Ptr engine)
+ {
+ _searchEngine = engine;
+ };
+
+private slots:
+ void itemChosen(ListItem *item, Qt::MouseButton = Qt::LeftButton);
+ void suggestUrls(const QString &text);
+
+signals:
+ void chosenUrl(const KUrl &, Rekonq::OpenType);
+ void nextItemSubChoice();
+
+private:
+ void insertSearchList(const UrlSearchList &list, const QString& text);
+ void popup();
+ void clear();
+
+ void sizeAndPosition();
+ void up();
+ void down();
+
+ QWidget *_parent;
+
+ UrlSearchList _list;
+ int _currentIndex;
+
+ KService::Ptr _searchEngine;
+};
+
+#endif // COMPLETION_WIDGET_H
diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp
new file mode 100644
index 00000000..c6f75348
--- /dev/null
+++ b/src/urlbar/listitem.cpp
@@ -0,0 +1,427 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 "listitem.h"
+#include "listitem.moc"
+
+// Auto Includes
+#include "rekonq.h"
+
+// Local Includes
+#include "urlresolver.h"
+#include "application.h"
+#include "websnap.h"
+#include "completionwidget.h"
+#include "searchengine.h"
+
+// KDE Includes
+#include <KIcon>
+#include <KAction>
+
+// Qt Includes
+#include <QActionGroup>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QSizePolicy>
+#include <QPixmap>
+#include <QStylePainter>
+#include <QMouseEvent>
+#include <QWebSettings>
+#include <QFile>
+
+
+ListItem::ListItem(const UrlSearchItem &item, QWidget *parent)
+ : QWidget(parent)
+ , m_option()
+ , m_url(item.url)
+{
+ setAutoFillBackground(true);
+
+ m_option.initFrom(this);
+ m_option.direction = Qt::LeftToRight;
+
+ QPalette p(palette());
+ p.setColor(QPalette::Base, Qt::white); // TODO: choose the correct color
+
+ p.setColor(QPalette::AlternateBase, QColor(247, 247, 247)); // TODO: choose the correct color
+ setPalette(p);
+
+ deactivate();
+}
+
+
+ListItem::~ListItem()
+{
+ disconnect();
+}
+
+
+
+void ListItem::activate()
+{
+ m_option.state |= QStyle::State_Selected;
+ update();
+}
+
+
+void ListItem::deactivate()
+{
+ m_option.state &= ~QStyle::State_Selected;
+ update();
+}
+
+
+void ListItem::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+
+ if (m_option.state.testFlag(QStyle::State_Selected) || m_option.state.testFlag(QStyle::State_MouseOver))
+ {
+ QPainter painter(this);
+ m_option.rect = QRect(QPoint(), size());
+ style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &m_option, &painter, this);
+ }
+
+ QWidget::paintEvent(event);
+}
+
+
+void ListItem::enterEvent(QEvent *e)
+{
+ m_option.state |= QStyle::State_MouseOver;
+ update();
+ QWidget::enterEvent(e);
+}
+
+
+void ListItem::leaveEvent(QEvent *e)
+{
+ m_option.state &= ~QStyle::State_MouseOver;
+ update();
+ QWidget::enterEvent(e);
+}
+
+
+void ListItem::mousePressEvent(QMouseEvent *e)
+{
+ emit itemClicked(this, e->button());
+ QWidget::mousePressEvent(e);
+}
+
+
+KUrl ListItem::url()
+{
+ return m_url;
+}
+
+
+void ListItem::nextItemSubChoice()
+{
+ //will be override
+}
+
+
+// ---------------------------------------------------------------
+
+
+TypeIconLabel::TypeIconLabel(int type, QWidget *parent)
+ : QLabel(parent)
+{
+ setMinimumWidth(40);
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setMargin(0);
+ hLayout->setAlignment(Qt::AlignRight);
+ setLayout(hLayout);
+
+ if (type & UrlSearchItem::Search) hLayout->addWidget(getIcon("edit-find"));
+ if (type & UrlSearchItem::Browse) hLayout->addWidget(getIcon("applications-internet"));
+ if (type & UrlSearchItem::Bookmark) hLayout->addWidget(getIcon("rating"));
+ if (type & UrlSearchItem::History) hLayout->addWidget(getIcon("view-history"));
+}
+
+
+QLabel *TypeIconLabel::getIcon(QString icon)
+{
+ QLabel *iconLabel = new QLabel(this);
+ iconLabel->setFixedSize(16, 16);
+ QPixmap pixmap = KIcon(icon).pixmap(16);
+ iconLabel->setPixmap(pixmap);
+ return iconLabel;
+}
+
+
+// ---------------------------------------------------------------
+
+
+IconLabel::IconLabel(const QString &icon, QWidget *parent)
+ : QLabel(parent)
+{
+ QPixmap pixmapIcon = Application::icon(KUrl(icon)).pixmap(16);
+ setFixedSize(16, 16);
+ setPixmap(pixmapIcon);
+}
+
+
+// ---------------------------------------------------------------
+
+
+TextLabel::TextLabel(const QString &text, const QString &textToPointOut, QWidget *parent)
+ : QLabel(parent)
+{
+ QString t = text;
+ if (!textToPointOut.isEmpty())
+ t = t.replace(QRegExp('(' + textToPointOut + ')', Qt::CaseInsensitive), "<b>\\1</b>");
+
+ setText(t);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
+}
+
+
+//--------------------------------------------------------------------------------------------
+
+
+PreviewListItem::PreviewListItem(const UrlSearchItem &item, const QString &text, QWidget *parent)
+ : ListItem(item, parent)
+{
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setSpacing(4);
+
+ QLabel *previewLabelIcon = new QLabel(this);
+ previewLabelIcon->setFixedSize(45, 33);
+ new PreviewLabel(item.url.url(), 38, 29, previewLabelIcon);
+ IconLabel* icon = new IconLabel(item.url.url(), previewLabelIcon);
+ icon->move(27, 16);
+ hLayout->addWidget(previewLabelIcon);
+
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ vLayout->setMargin(0);
+ vLayout->addWidget(new TextLabel(item.title, text, this));
+ vLayout->addWidget(new TextLabel("<i>" + item.url.url() + "</i>", text, this));
+
+ hLayout->addLayout(vLayout);
+
+ hLayout->addWidget(new TypeIconLabel(item.type, this));
+
+ setLayout(hLayout);
+}
+
+
+// ---------------------------------------------------------------
+
+
+PreviewLabel::PreviewLabel(const QString &url, int width, int height, QWidget *parent)
+ : QLabel(parent)
+{
+ setFixedSize(width, height);
+ setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+
+ KUrl u = KUrl(url);
+ if (WebSnap::existsImage(KUrl(u)))
+ {
+ QPixmap preview;
+ preview.load(WebSnap::imagePathFromUrl(u));
+ setPixmap(preview.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
+ }
+}
+
+
+// ---------------------------------------------------------------
+
+
+SearchListItem::SearchListItem(const UrlSearchItem &item, const QString &text, QWidget *parent)
+ : ListItem(item, parent)
+ , m_text(text)
+{
+ KService::Ptr currentEngine = SearchEngine::defaultEngine();
+
+ QString query = text;
+ KService::Ptr engine = SearchEngine::fromString(text);
+ if (engine)
+ {
+ query = query.remove(0, text.indexOf(SearchEngine::delimiter()) + 1);
+ }
+ else
+ {
+ engine = currentEngine;
+ }
+
+ m_url = SearchEngine::buildQuery(engine, query);
+
+ m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon
+ m_titleLabel = new TextLabel(searchItemTitle(engine->name(), query), QString(), this);
+ m_engineBar = new EngineBar(currentEngine, parent);
+
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setSpacing(4);
+
+ hLayout->addWidget(m_iconLabel);
+ hLayout->addWidget(m_titleLabel);
+ hLayout->addWidget(new QLabel(i18n("Engines: "), this));
+ hLayout->addWidget(m_engineBar);
+ hLayout->addWidget(new TypeIconLabel(item.type, this));
+
+ setLayout(hLayout);
+
+ connect(m_engineBar, SIGNAL(searchEngineChanged(KService::Ptr)), this, SLOT(changeSearchEngine(KService::Ptr)));
+}
+
+
+QString SearchListItem::searchItemTitle(QString engine, QString text)
+{
+ return QString(i18nc("%1=search engine, e.g. Google, Wikipedia %2=text to search for", "Search %1 for <b>%2</b>", engine, text));
+}
+
+void SearchListItem::changeSearchEngine(KService::Ptr engine)
+{
+ m_titleLabel->setText(searchItemTitle(engine->name(), m_text));
+ m_iconLabel->setPixmap(Application::icon(KUrl(engine->property("Query").toString())).pixmap(16));
+ m_url = SearchEngine::buildQuery(engine, m_text);
+
+ CompletionWidget *w = qobject_cast<CompletionWidget *>(parent());
+ w->setCurrentEngine(engine);
+}
+
+
+void SearchListItem::nextItemSubChoice()
+{
+ m_engineBar->selectNextEngine();
+}
+
+
+// -----------------------------------------------------------------------------------------------
+
+
+EngineBar::EngineBar(KService::Ptr selectedEngine, QWidget *parent)
+ : KToolBar(parent)
+{
+ setIconSize(QSize(16, 16));
+ setToolButtonStyle(Qt::ToolButtonIconOnly);
+
+ m_engineGroup = new QActionGroup(this);
+ m_engineGroup->setExclusive(true);
+
+ m_engineGroup->addAction(newEngineAction(SearchEngine::defaultEngine(), selectedEngine));
+ foreach(KService::Ptr engine, SearchEngine::favorites())
+ {
+ if (engine->desktopEntryName() != SearchEngine::defaultEngine()->desktopEntryName())
+ {
+ m_engineGroup->addAction(newEngineAction(engine, selectedEngine));
+ }
+ }
+
+ addActions(m_engineGroup->actions());
+}
+
+
+KAction *EngineBar::newEngineAction(KService::Ptr engine, KService::Ptr selectedEngine)
+{
+ QString url = engine->property("Query").toString();
+ KAction *a = new KAction(Application::icon(url), engine->name(), this);
+ a->setCheckable(true);
+ if (engine->desktopEntryName() == selectedEngine->desktopEntryName()) a->setChecked(true);
+ a->setData(engine->entryPath());
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(changeSearchEngine()));
+ return a;
+}
+
+
+void EngineBar::changeSearchEngine()
+{
+ KAction *a = qobject_cast<KAction*>(sender());
+ emit searchEngineChanged(KService::serviceByDesktopPath(a->data().toString()));
+}
+
+
+void EngineBar::selectNextEngine()
+{
+ QList<QAction *> e = m_engineGroup->actions();
+ int i = 0;
+ while (i < e.count() && !e.at(i)->isChecked())
+ {
+ i++;
+ }
+
+ if (i + 1 == e.count())
+ {
+ e.at(0)->setChecked(true);
+ e.at(0)->trigger();
+ }
+ else
+ {
+ e.at(i + 1)->setChecked(true);
+ e.at(i + 1)->trigger();
+ }
+}
+
+
+// ---------------------------------------------------------------
+
+
+BrowseListItem::BrowseListItem(const UrlSearchItem &item, const QString &text, QWidget *parent)
+ : ListItem(item, parent)
+{
+ QString url = text;
+
+ kDebug() << text;
+
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->setSpacing(4);
+
+ hLayout->addWidget(new IconLabel(item.url.url(), this));
+ hLayout->addWidget(new TextLabel(item.url.url(), text, this));
+ hLayout->addWidget(new TypeIconLabel(item.type, this));
+
+ setLayout(hLayout);
+}
+
+
+// ---------------------------------------------------------------
+
+
+ListItem *ListItemFactory::create(const UrlSearchItem &item, const QString &text, QWidget *parent)
+{
+ ListItem *newItem;
+
+ if (item.type & UrlSearchItem::Browse)
+ {
+ newItem = new BrowseListItem(item, text, parent);
+ }
+ else
+ {
+ if (item.type & UrlSearchItem::Search)
+ {
+ newItem = new SearchListItem(item, text, parent);
+ }
+ else
+ {
+ newItem = new PreviewListItem(item, text, parent);
+ }
+ }
+
+ return newItem;
+}
diff --git a/src/urlbar/listitem.h b/src/urlbar/listitem.h
new file mode 100644
index 00000000..6737ed70
--- /dev/null
+++ b/src/urlbar/listitem.h
@@ -0,0 +1,220 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 LISTITEM_H
+#define LISTITEM_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// Local Includes
+#include "urlresolver.h"
+
+// KDE Includes
+#include <KToolBar>
+#include <KService>
+
+// Qt Includes
+#include <QWidget>
+#include <QStyleOptionViewItemV4>
+#include <QLabel>
+
+// Forward Declarations
+class UrlSearchItem;
+class KAction;
+class QActionGroup;
+
+
+class ListItem : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ListItem(const UrlSearchItem &item, QWidget *parent = 0);
+ virtual ~ListItem();
+
+ void activate();
+ void deactivate();
+
+ KUrl url();
+
+public slots:
+ virtual void nextItemSubChoice();
+
+signals:
+ void itemClicked(ListItem *item, Qt::MouseButton);
+
+protected:
+ virtual void paintEvent(QPaintEvent *event);
+ virtual void enterEvent(QEvent *);
+ virtual void leaveEvent(QEvent *);
+ virtual void mousePressEvent(QMouseEvent *e);
+
+private:
+ QStyleOptionViewItemV4 m_option;
+
+protected:
+ KUrl m_url;
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class TypeIconLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ explicit TypeIconLabel(int type, QWidget *parent = 0);
+
+private:
+ QLabel *getIcon(QString icon);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class IconLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ IconLabel(const QString &icon, QWidget *parent = 0);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class TextLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ TextLabel(const QString &text, const QString &textToPointOut = QString(), QWidget *parent = 0);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class EngineBar : public KToolBar
+{
+ Q_OBJECT
+
+public:
+ explicit EngineBar(KService::Ptr selectedEngine, QWidget *parent = 0);
+ void selectNextEngine();
+
+signals:
+ void searchEngineChanged(KService::Ptr engine);
+
+private slots:
+ void changeSearchEngine();
+
+private:
+ KAction *newEngineAction(KService::Ptr engine, KService::Ptr selectedEngine);
+ QActionGroup *m_engineGroup;
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class SearchListItem : public ListItem
+{
+ Q_OBJECT
+
+public:
+ explicit SearchListItem(const UrlSearchItem &item, const QString &text, QWidget *parent = 0);
+
+public slots:
+ virtual void nextItemSubChoice();
+
+private slots:
+ void changeSearchEngine(KService::Ptr engine);
+
+private:
+ QString searchItemTitle(QString engine, QString text);
+
+ TextLabel* m_titleLabel;
+ IconLabel* m_iconLabel;
+ EngineBar* m_engineBar;
+ QString m_text;
+ KService::Ptr m_currentEngine;
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class PreviewListItem : public ListItem
+{
+ Q_OBJECT
+
+public:
+ PreviewListItem(const UrlSearchItem &item, const QString &text, QWidget *parent = 0);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class PreviewLabel : public QLabel
+{
+ Q_OBJECT
+
+public:
+ PreviewLabel(const QString &url, int width, int height, QWidget *parent = 0);
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class BrowseListItem : public ListItem
+{
+ Q_OBJECT
+
+public:
+ BrowseListItem(const UrlSearchItem &item, const QString &text, QWidget *parent = 0);
+};
+
+
+//-------------------------------------------------------------------------------------------------
+
+
+class ListItemFactory
+{
+public:
+ static ListItem *create(const UrlSearchItem &item, const QString &text, QWidget *parent);
+};
+
+
+#endif
diff --git a/src/urlbar/rsswidget.cpp b/src/urlbar/rsswidget.cpp
new file mode 100644
index 00000000..1cce6e8c
--- /dev/null
+++ b/src/urlbar/rsswidget.cpp
@@ -0,0 +1,154 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 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/>.
+*
+* ============================================================ */
+
+
+// Auto Includes
+#include "rsswidget.h"
+#include "rsswidget.moc"
+
+// Local includes
+#include "application.h"
+#include "mainwindow.h"
+#include "webtab.h"
+#include "webview.h"
+
+// KDE Includes
+#include <KLocalizedString>
+#include <KIcon>
+#include <KProcess>
+#include <KMessageBox>
+
+// Qt Includes
+#include <QtGui/QFormLayout>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QLabel>
+#include <QtGui/QPushButton>
+
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusConnectionInterface>
+
+
+
+RSSWidget::RSSWidget(QMap< KUrl, QString > map, QWidget *parent)
+ : QFrame(parent, Qt::Popup)
+ , m_map(map)
+{
+ setAttribute(Qt::WA_DeleteOnClose);
+ setFixedWidth(250);
+ setFrameStyle(Panel);
+
+ QFormLayout *layout = new QFormLayout(this);
+ setLayout(layout);
+
+ QLabel *agregator = new QLabel(this);
+ agregator->setText(i18n("Aggregator:"));
+
+ m_agregators = new KComboBox(this);
+ m_agregators->addItem(KIcon("application-rss+xml"), QString("Akregator"));
+ m_agregators->addItem(Application::icon(KUrl("http://google.com/reader")), i18n("Google Reader"));
+
+ layout->addRow(agregator, m_agregators);
+
+
+ QLabel *feed = new QLabel(this);
+ feed->setText(i18n("Feed:"));
+
+ m_feeds = new KComboBox(this);
+
+ foreach(const QString &title, m_map)
+ {
+ m_feeds->addItem(title);
+ }
+
+ layout->addRow(feed, m_feeds);
+
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
+ buttonBox->button(QDialogButtonBox::Ok)->setText(i18n("Add Feed"));
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(accepted()));
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
+
+ layout->addWidget(buttonBox);
+}
+
+
+void RSSWidget::showAt(QPoint pos)
+{
+ pos.setX(pos.x() - 200);
+ pos.setY(pos.y() + 10);
+ move(pos);
+ show();
+}
+
+
+void RSSWidget::accepted()
+{
+ QString url = m_map.key(m_feeds->currentText()).toMimeDataString();
+
+ if (m_agregators->currentIndex() == 0)
+ addWithAkregator(url);
+ else
+ addWithGoogleReader(url);
+
+ close();
+}
+
+
+void RSSWidget::addWithGoogleReader(QString url)
+{
+ KUrl toLoad = KUrl("http://www.google.com/ig/add?feedurl=" + url);
+ Application::instance()->mainWindow()->currentTab()->view()->load(toLoad);
+}
+
+
+void RSSWidget::addWithAkregator(QString url)
+{
+ // Akregator is running
+ if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.akregator"))
+ {
+ QDBusInterface akregator("org.kde.akregator", "/Akregator", "org.kde.akregator.part");
+ QDBusReply<void> reply = akregator.call("addFeedsToGroup", QStringList(url) , i18n("Imported Feeds"));
+
+ if (!reply.isValid())
+ {
+ KMessageBox::error(0, QString(i18n("Could not add stream to akregator, Please add it manually :")
+ + "<br /><br /> <a href=\"" + url + "\">" + url + "</a>"));
+ }
+ }
+ // Akregator is not running
+ else
+ {
+ KProcess proc;
+ proc << "akregator" << "-g" << i18n("Imported Feeds");
+ proc << "-a" << url;
+ if (proc.startDetached() == 0)
+ {
+ KMessageBox::error(0, QString(i18n("There was an error. Please verify Akregator is installed on your system.")
+ + "<br /><br /> <a href=\"" + url + "\">" + url + "</a>"));
+ }
+
+ }
+}
+
diff --git a/src/urlbar/rsswidget.h b/src/urlbar/rsswidget.h
new file mode 100644
index 00000000..258107eb
--- /dev/null
+++ b/src/urlbar/rsswidget.h
@@ -0,0 +1,66 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 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 RSSWIDGET_H
+#define RSSWIDGET_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// KDE Includes
+#include <KComboBox>
+#include <KUrl>
+
+// Qt Includes
+#include <QtCore/QMap>
+
+#include <QtGui/QFrame>
+
+
+class RSSWidget : public QFrame
+{
+ Q_OBJECT
+
+public:
+ // QMap< feedUrl, feedTitle>
+ RSSWidget(QMap<KUrl, QString> map, QWidget *parent);
+
+ void showAt(QPoint pos);
+
+public slots:
+ void accepted();
+
+private:
+ void addWithAkregator(QString url);
+ void addWithGoogleReader(QString url);
+
+ QMap<KUrl, QString> m_map;
+
+ KComboBox *m_agregators;
+ KComboBox *m_feeds;
+};
+
+#endif // RSSWIDGET_H
diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp
index be19dae4..ad0f34a1 100644
--- a/src/urlbar/urlbar.cpp
+++ b/src/urlbar/urlbar.cpp
@@ -13,9 +13,9 @@
* 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
+* 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
@@ -31,307 +31,361 @@
#include "urlbar.h"
#include "urlbar.moc"
+// Auto Includes
+#include "rekonq.h"
+
// Local Includes
#include "application.h"
-#include "lineedit.h"
#include "mainwindow.h"
+#include "webtab.h"
+#include "webpage.h"
#include "webview.h"
-#include "historymanager.h"
+#include "completionwidget.h"
// KDE Includes
-#include <KDebug>
#include <KCompletionBox>
-#include <KUrl>
// Qt Includes
-#include <QPainter>
-#include <QPaintEvent>
-#include <QPalette>
-#include <QTimer>
+#include <QtGui/QPainter>
+#include <QtGui/QPaintEvent>
+#include <QtGui/QPalette>
+#include <QtGui/QVBoxLayout>
-QColor UrlBar::s_defaultBaseColor;
+IconButton::IconButton(QWidget *parent)
+ : QToolButton(parent)
+{
+ setToolButtonStyle(Qt::ToolButtonIconOnly);
+ setStyleSheet("IconButton { background-color:transparent; border: none; padding: 0px}");
+ setCursor(Qt::ArrowCursor);
+}
-UrlBar::UrlBar(QWidget *parent)
- : KHistoryComboBox(true, parent)
- , m_lineEdit(new LineEdit)
- , m_progress(0)
+void IconButton::mouseReleaseEvent(QMouseEvent* event)
{
- setUrlDropsEnabled(true);
- setAutoDeleteCompletionObject(true);
+ emit clicked(event->globalPos());
+}
- //cosmetic
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- setMinimumWidth(180);
-
- setTrapReturnKey(true);
- setupLineEdit();
+// -----------------------------------------------------------------------------------------------------------
- // add every item to history
- connect(this, SIGNAL(returnPressed(const QString&)), SLOT(activated(const QString&)));
- connect(completionBox(), SIGNAL(activated(const QString&)), SLOT(activated(const QString&)));
- connect(this, SIGNAL(cleared()), SLOT(cleared()));
+UrlBar::UrlBar(QWidget *parent)
+ : KLineEdit(parent)
+ , _tab(0)
+ , _privateMode(false)
+ , _icon(new IconButton(this))
+{
+ // initial style
+ setStyleSheet(QString("UrlBar { padding: 0 0 0 %1px;} ").arg(_icon->sizeHint().width()));
- // setup completion box
- setCompletionObject( Application::historyManager()->completionObject() );
-
- // set dropdown list background
- QPalette p = view()->palette();
- p.setColor(QPalette::Base, palette().color(QPalette::Base));
- view()->setPalette(p);
+ // cosmetic
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ setMinimumWidth(200);
+ setMinimumHeight(26);
- // load urls on activated urlbar signal
- connect(this, SIGNAL(activated(const KUrl&)), Application::instance(), SLOT(loadUrl(const KUrl&)));
-}
+ // doesn't show the clear button
+ setClearButtonShown(false);
+ // trap Key_Enter & Key_Return events, while emitting the returnPressed signal
+ setTrapReturnKey(true);
-UrlBar::~UrlBar()
-{
-}
+ // insert decoded URLs
+ setUrlDropsEnabled(true);
+ // accept focus, via tabbing, clicking & wheeling
+ setFocusPolicy(Qt::WheelFocus);
-void UrlBar::selectAll() const
-{
- lineEdit()->selectAll();
-}
+ // disable completion object (we have our own :) )
+ setCompletionObject(0);
+ _tab = qobject_cast<WebTab *>(parent);
-KUrl UrlBar::url() const
-{
- return m_currentUrl;
-}
+ connect(_tab->view(), SIGNAL(urlChanged(const QUrl &)), this, SLOT(setQUrl(const QUrl &)));
+ connect(_tab->view(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
+ connect(_tab->view(), SIGNAL(loadStarted()), this, SLOT(clearRightIcons()));
+ // load typed urls
+ connect(this, SIGNAL(returnPressed(const QString &)), this, SLOT(loadTyped(const QString &)));
-KLineEdit *UrlBar::lineEdit() const
-{
- return m_lineEdit;
+ activateSuggestions(true);
}
-void UrlBar::setupLineEdit()
+UrlBar::~UrlBar()
{
- // Make m_lineEdit background transparent
- QPalette p = m_lineEdit->palette();
- p.setColor(QPalette::Base, Qt::transparent);
- m_lineEdit->setPalette(p);
-
- if (!s_defaultBaseColor.isValid())
- {
- s_defaultBaseColor = palette().color(QPalette::Base);
- }
-
- setLineEdit(m_lineEdit);
-
- // Make the lineedit consume the Qt::Key_Enter event...
- lineEdit()->setTrapReturnKey(true);
-
- lineEdit()->setHandleSignals(true);
-
- // clear the URL bar
- lineEdit()->clear();
+ activateSuggestions(false);
+ delete _icon;
+ _box.clear();
}
-void UrlBar::setUrl(const QUrl& url)
+void UrlBar::setQUrl(const QUrl& url)
{
- if(url.scheme() == "about")
+ if (url.scheme() == QL1S("about"))
{
- m_currentUrl = KUrl();
+ _icon->setIcon(KIcon("arrow-right"));
+ clear();
setFocus();
}
else
{
- m_currentUrl = KUrl(url);
+ clearFocus();
+ KLineEdit::setUrl(url);
+ setCursorPosition(0);
+ _icon->setIcon(Application::icon(url));
}
- updateUrl();
}
-void UrlBar::setProgress(int progress)
+void UrlBar::activated(const KUrl& url, Rekonq::OpenType type)
{
- m_progress = progress;
- repaint();
+ activateSuggestions(false);
+
+ clearFocus();
+ setUrl(url);
+ Application::instance()->loadUrl(url, type);
}
-void UrlBar::updateUrl()
+void UrlBar::paintEvent(QPaintEvent *event)
{
- // Don't change my typed url...
- // FIXME this is not a proper solution (also if it works...)
- if(hasFocus())
+ QColor backgroundColor;
+ if (_privateMode)
{
- kDebug() << "Don't change my typed url...";
- return;
- }
-
- KIcon icon;
- if(m_currentUrl.isEmpty())
- {
- icon = KIcon("arrow-right");
+ backgroundColor = QColor(220, 220, 220); // light gray
}
- else
+ else
{
- icon = Application::icon(m_currentUrl);
+ backgroundColor = Application::palette().color(QPalette::Base);
}
- if (count())
+ // set background color of UrlBar
+ QPalette p = palette();
+
+ int progr = _tab->progress();
+ if (progr == 0)
{
- changeUrl(0, icon, m_currentUrl);
+ if (_tab->url().scheme() == QL1S("https"))
+ {
+ backgroundColor = QColor(255, 255, 171); // light yellow
+ }
+ p.setBrush(QPalette::Base, backgroundColor);
}
else
{
- insertUrl(0, icon, m_currentUrl);
+ QColor loadingColor = QColor(116, 192, 250);
+
+ QLinearGradient gradient(0, 0, width(), 0);
+ gradient.setColorAt(0, loadingColor);
+ gradient.setColorAt(((double)progr) / 100, backgroundColor);
+ p.setBrush(QPalette::Base, gradient);
}
+ setPalette(p);
- setCurrentIndex(0);
+ // you need this before our code to draw inside the line edit..
+ KLineEdit::paintEvent(event);
- // important security consideration: always display the beginning
- // of the url rather than its end to prevent spoofing attempts.
- // Must be AFTER setCurrentIndex
- if (!hasFocus())
+ if (text().isEmpty())
{
- lineEdit()->setCursorPosition(0);
+ QStyleOptionFrame option;
+ initStyleOption(&option);
+ QRect textRect = style()->subElementRect(QStyle::SE_LineEditContents, &option, this);
+ QPainter painter(this);
+ painter.setPen(Qt::gray);
+ painter.drawText(textRect,
+ Qt::AlignCenter,
+ i18n("Start typing here to search your bookmarks, history and the web...")
+ );
}
}
-void UrlBar::activated(const QString& urlString)
+void UrlBar::keyPressEvent(QKeyEvent *event)
{
- if (urlString.isEmpty())
- return;
+ // this handles the Modifiers + Return key combinations
+ QString currentText = text().trimmed();
+ if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
+ && !currentText.startsWith(QL1S("http://"), Qt::CaseInsensitive))
+ {
+ QString append;
+ if (event->modifiers() == Qt::ControlModifier)
+ {
+ append = QL1S(".com");
+ }
+ else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))
+ {
+ append = QL1S(".org");
+ }
+ else if (event->modifiers() == Qt::ShiftModifier)
+ {
+ append = QL1S(".net");
+ }
+
+ QUrl url(QL1S("http://www.") + currentText);
+ QString host = url.host();
+ if (!host.endsWith(append, Qt::CaseInsensitive))
+ {
+ host += append;
+ url.setHost(host);
+ setText(url.toString());
+ }
+ }
- setUrl(urlString);
- emit activated(m_currentUrl);
+ if (event->key() == Qt::Key_Escape)
+ {
+ clearFocus();
+ event->accept();
+ }
+
+ KLineEdit::keyPressEvent(event);
}
-void UrlBar::cleared()
+void UrlBar::focusInEvent(QFocusEvent *event)
{
- // clear the history on user's request from context menu
- clear();
+ activateSuggestions(true);
+
+ KLineEdit::focusInEvent(event);
}
-void UrlBar::loadFinished(bool)
+void UrlBar::setPrivateMode(bool on)
{
- // reset progress bar after small delay
- m_progress = 0;
- QTimer::singleShot(200, this, SLOT(repaint()));
+ _privateMode = on;
}
-void UrlBar::updateProgress(int progress)
+void UrlBar::dropEvent(QDropEvent *event)
{
- m_progress = progress;
- repaint();
+ KLineEdit::dropEvent(event);
+ activated(text());
}
-void UrlBar::paintEvent(QPaintEvent *event)
+void UrlBar::loadFinished()
{
- // set background color of UrlBar
- QPalette p = palette();
- p.setColor(QPalette::Base, s_defaultBaseColor);
- setPalette(p);
+ if (_tab->progress() != 0)
+ return;
- KHistoryComboBox::paintEvent(event);
+ if (_tab->url().scheme() == QL1S("about"))
+ {
+ update();
+ return;
+ }
- if (!hasFocus())
+ // show KGet downloads??
+ if (ReKonfig::kgetList())
{
- QPainter painter(this);
+ IconButton *bt = addRightIcon(UrlBar::KGet);
+ connect(bt, SIGNAL(clicked(QPoint)), _tab->page(), SLOT(downloadAllContentsWithKGet(QPoint)));
+ }
- QColor loadingColor;
- if (m_currentUrl.scheme() == QLatin1String("https"))
- {
- loadingColor = QColor(248, 248, 100);
- }
- else
- {
- loadingColor = QColor(116, 192, 250);
- }
- painter.setBrush(generateGradient(loadingColor, height()));
- painter.setPen(Qt::transparent);
-
- QRect backgroundRect = lineEdit()->frameGeometry();
- int mid = backgroundRect.width() * m_progress / 100;
- QRect progressRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height());
- painter.drawRect(progressRect);
- painter.end();
+ // show RSS
+ if (_tab->hasRSSInfo())
+ {
+ IconButton *bt = addRightIcon(UrlBar::RSS);
+ connect(bt, SIGNAL(clicked(QPoint)), _tab, SLOT(showRSSInfo(QPoint)));
+ }
+
+ // show SSL
+ if (_tab->url().scheme() == QL1S("https"))
+ {
+ IconButton *bt = addRightIcon(UrlBar::SSL);
+ connect(bt, SIGNAL(clicked(QPoint)), _tab->page(), SLOT(showSSLInfo(QPoint)));
}
+
+ update();
}
-QSize UrlBar::sizeHint() const
+void UrlBar::loadTyped(const QString &text)
{
- return lineEdit()->sizeHint();
+ activated(KUrl(text));
}
-QLinearGradient UrlBar::generateGradient(const QColor &color, int height)
+void UrlBar::activateSuggestions(bool b)
{
- QColor base = s_defaultBaseColor;
- base.setAlpha(0);
- QColor barColor = color;
- barColor.setAlpha(200);
- QLinearGradient gradient(0, 0, 0, height);
- gradient.setColorAt(0, base);
- gradient.setColorAt(0.25, barColor.lighter(120));
- gradient.setColorAt(0.5, barColor);
- gradient.setColorAt(0.75, barColor.lighter(120));
- gradient.setColorAt(1, base);
- return gradient;
+ if (b)
+ {
+ if (_box.isNull())
+ {
+ _box = new CompletionWidget(this);
+ installEventFilter(_box.data());
+ connect(_box.data(), SIGNAL(chosenUrl(const KUrl &, Rekonq::OpenType)), this, SLOT(activated(const KUrl &, Rekonq::OpenType)));
+
+ // activate suggestions on edit text
+ connect(this, SIGNAL(textChanged(const QString &)), _box.data(), SLOT(suggestUrls(const QString &)));
+ }
+ }
+ else
+ {
+ removeEventFilter(_box.data());
+ _box.data()->deleteLater();
+ }
}
-void UrlBar::setBackgroundColor(QColor c)
+void UrlBar::mouseDoubleClickEvent(QMouseEvent *)
{
- s_defaultBaseColor = c;
- repaint();
+ selectAll();
}
-bool UrlBar::isLoading()
+IconButton *UrlBar::addRightIcon(UrlBar::icon ic)
{
- if(m_progress == 0)
+ IconButton *rightIcon = new IconButton(this);
+
+ switch (ic)
{
- return false;
+ case UrlBar::KGet:
+ rightIcon->setIcon(KIcon("download"));
+ rightIcon->setToolTip(i18n("List all links with KGet"));
+ break;
+ case UrlBar::RSS:
+ rightIcon->setIcon(KIcon("application-rss+xml"));
+ rightIcon->setToolTip(i18n("List all available RSS feeds"));
+ break;
+ case UrlBar::SSL:
+ rightIcon->setIcon(KIcon("object-locked"));
+ rightIcon->setToolTip(i18n("Show SSL Info"));
+ break;
+ default:
+ kDebug() << "ERROR.. default non extant case!!";
+ break;
}
- return true;
+
+ _rightIconsList << rightIcon;
+ int iconsCount = _rightIconsList.count();
+ rightIcon->move(width() - 23*iconsCount, 6);
+ rightIcon->show();
+
+ return rightIcon;
}
-void UrlBar::keyPressEvent(QKeyEvent *event)
+
+void UrlBar::clearRightIcons()
{
- QString currentText = m_lineEdit->text().trimmed();
- if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
- && !currentText.startsWith(QLatin1String("http://"), Qt::CaseInsensitive))
- {
- QString append;
- if (event->modifiers() == Qt::ControlModifier)
- {
- append = QLatin1String(".com");
- }
- else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))
- {
- append = QLatin1String(".org");
- }
- else if (event->modifiers() == Qt::ShiftModifier)
- {
- append = QLatin1String(".net");
- }
+ qDeleteAll(_rightIconsList);
+ _rightIconsList.clear();
+}
- QUrl url(QLatin1String("http://www.") + currentText);
- QString host = url.host();
- if (!host.endsWith(append, Qt::CaseInsensitive))
- {
- host += append;
- url.setHost(host);
- m_lineEdit->setText(url.toString());
- }
+
+void UrlBar::resizeEvent(QResizeEvent *event)
+{
+ int newHeight = (height() - 19) / 2;
+ _icon->move(4, newHeight);
+
+ int iconsCount = _rightIconsList.count();
+ int w = width();
+
+ for (int i = 0; i < iconsCount; ++i)
+ {
+ IconButton *bt = _rightIconsList.at(i);
+ bt->move(w - 25*(i + 1), newHeight);
}
- KHistoryComboBox::keyPressEvent(event);
-}
+ KLineEdit::resizeEvent(event);
+}
diff --git a/src/urlbar/urlbar.h b/src/urlbar/urlbar.h
index 8d267b2c..b644f84f 100644
--- a/src/urlbar/urlbar.h
+++ b/src/urlbar/urlbar.h
@@ -13,9 +13,9 @@
* 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
+* 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
@@ -30,69 +30,93 @@
#ifndef URLBAR_H
#define URLBAR_H
-
-// Local Includes
-#include "lineedit.h"
+// Rekonq Includes
+#include "rekonq_defines.h"
// KDE Includes
#include <KUrl>
-#include <KHistoryComboBox>
+#include <KLineEdit>
// Qt Includes
-#include <QUrl>
+#include <QWeakPointer>
+#include <QToolButton>
// Forward Declarations
class QLinearGradient;
class QWidget;
-class KCompletion;
+class CompletionWidget;
+class WebTab;
-class UrlBar : public KHistoryComboBox
+class IconButton : public QToolButton
{
Q_OBJECT
public:
- UrlBar(QWidget *parent = 0);
- ~UrlBar();
-
- void selectAll() const;
- KUrl url() const;
- QSize sizeHint() const;
- void setBackgroundColor(QColor);
- bool isLoading();
+ IconButton(QWidget *parent = 0);
- void setProgress(int progress);
-
signals:
- void activated(const KUrl&);
-
-public slots:
- void setUrl(const QUrl &url);
- void updateProgress(int progress);
- void updateUrl();
-
-private slots:
- void activated(const QString& url);
- void loadFinished(bool);
- void cleared();
+ void clicked(QPoint);
protected:
- virtual void paintEvent(QPaintEvent *event);
- virtual void keyPressEvent(QKeyEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+
+};
+
+
+// Definitions
+typedef QList<IconButton *> IconButtonPointerList;
+
+
+// ------------------------------------------------------------------------------------
-private:
- void setupLineEdit();
- KLineEdit *lineEdit() const;
+class REKONQ_TESTS_EXPORT UrlBar : public KLineEdit
+{
+ Q_OBJECT
+
+public:
- static QLinearGradient generateGradient(const QColor &color, int height);
+ enum icon
+ {
+ KGet = 0x00000001,
+ RSS = 0x00000010,
+ SSL = 0x00000100,
+ };
- static QColor s_defaultBaseColor;
+ explicit UrlBar(QWidget *parent = 0);
+ ~UrlBar();
+
+ void setPrivateMode(bool on);
+
+private slots:
+ void activated(const KUrl& url, Rekonq::OpenType = Rekonq::CurrentTab);
+ void setQUrl(const QUrl &url);
- LineEdit *m_lineEdit;
+ void loadFinished();
+ void loadTyped(const QString &);
- KUrl m_currentUrl;
- int m_progress;
+ void clearRightIcons();
+
+protected:
+ void paintEvent(QPaintEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void focusInEvent(QFocusEvent *event);
+ void dropEvent(QDropEvent *event);
+ void mouseDoubleClickEvent(QMouseEvent *);
+ void resizeEvent(QResizeEvent *);
+
+private:
+ IconButton *addRightIcon(UrlBar::icon);
+ void activateSuggestions(bool);
+
+ QWeakPointer<CompletionWidget> _box;
+ WebTab *_tab;
+ bool _privateMode;
+
+ IconButton *_icon;
+ IconButtonPointerList _rightIconsList;
};
+
#endif
diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp
new file mode 100644
index 00000000..276c2531
--- /dev/null
+++ b/src/urlbar/urlresolver.cpp
@@ -0,0 +1,217 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 "urlresolver.h"
+
+// Local Includes
+#include "application.h"
+#include "historymanager.h"
+#include "bookmarksmanager.h"
+
+// KDE Includes
+#include <KUriFilter>
+#include <KCompletion>
+#include <KService>
+#include <KConfig>
+#include <KConfigGroup>
+
+// Qt Includes
+#include <QByteArray>
+
+// defines
+#define MAX_ELEMENTS 9
+
+
+// NOTE default kurifilter plugin list (at least in my box)
+// 1. "kshorturifilter"
+// 2. "kurisearchfilter"
+// 3. "localdomainurifilter"
+// 4 ."kuriikwsfilter"
+// 5. "fixhosturifilter"
+
+
+bool UrlSearchItem::operator==(const UrlSearchItem &i)
+{
+ return url == i.url;
+}
+
+
+UrlResolver::UrlResolver(const QString &typedUrl)
+ : _typedString(typedUrl.trimmed())
+{
+}
+
+
+UrlSearchList UrlResolver::orderedSearchItems()
+{
+ // NOTE: the logic here is : "we wanna suggest (at least) 9 elements"
+ // so we have (more or less) 3 from first results (1 from QUrl Resolutions, 2 from
+ // default search engines).
+ // There are 6 remaining: if bookmarkResults + historyResults <= 6, catch all, else
+ // catch first 3 results from the two resulting lists :)
+
+ UrlSearchList list;
+
+// if(isHttp())
+// {
+// list << qurlFromUserInputResolution();
+// }
+
+ list << qurlFromUserInputResolution();
+ list << webSearchesResolution();
+
+ if (_typedString.length() >= 2)
+ {
+ int firstResults = list.count();
+ int checkPoint = 9 - firstResults;
+
+ UrlSearchList historyList = historyResolution();
+ int historyResults = historyList.count();
+
+ UrlSearchList bookmarksList = bookmarksResolution();
+ int bookmarkResults = bookmarksList.count();
+
+ if (historyResults + bookmarkResults > checkPoint)
+ {
+ historyList = historyList.mid(0, 3);
+ bookmarksList = bookmarksList.mid(0, 3);
+ }
+
+ QList<UrlSearchItem> common;
+
+ foreach(UrlSearchItem i, historyList)
+ {
+ if (!bookmarksList.contains(i))
+ {
+ list << i;
+ }
+ else
+ {
+ i.type |= UrlSearchItem::Bookmark;
+ common << i;
+ }
+ }
+
+ foreach(const UrlSearchItem &i, common)
+ {
+ list << i;
+ }
+
+ foreach(const UrlSearchItem &i, bookmarksList)
+ {
+ if (!common.contains(i))
+ list << i;
+ }
+ }
+
+ return list;
+}
+
+
+bool UrlResolver::isHttp()
+{
+ QString ipv4 = "^0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])"\
+ "\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
+
+ QString ipv6 = "^([0-9a-fA-F]{4}|0)(\\:([0-9a-fA-F]{4}|0)){7}";
+
+ QString address = "[\\d\\w-.]+\\.(a[cdefgilmnoqrstuwz]|b[abdefghijmnorstvwyz]|"\
+ "c[acdfghiklmnoruvxyz]|d[ejkmnoz]|e[ceghrst]|f[ijkmnor]|g[abdefghilmnpqrstuwy]|"\
+ "h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|"\
+ "m[acdghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eouw]|"\
+ "s[abcdeghijklmnortuvyz]|t[cdfghjkmnoprtvwz]|u[augkmsyz]|v[aceginu]|w[fs]|"\
+ "y[etu]|z[amw]|aero|arpa|biz|com|coop|edu|info|int|gov|mil|museum|name|net|org|"\
+ "pro)";
+
+ return _typedString.startsWith( QL1S("http://") )
+ || _typedString.startsWith( QL1S("https://") )
+ || (QRegExp(address, Qt::CaseInsensitive).indexIn(_typedString) != -1)
+ || (QRegExp(ipv4, Qt::CaseInsensitive).indexIn(_typedString) != -1)
+ || (QRegExp(ipv6, Qt::CaseInsensitive).indexIn(_typedString) != -1);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// PRIVATE ENGINES
+
+
+// STEP 1 = QUrl from User Input (easily the best solution... )
+UrlSearchList UrlResolver::qurlFromUserInputResolution()
+{
+ UrlSearchList list;
+ QString url2 = _typedString;
+ QUrl urlFromUserInput = QUrl::fromUserInput(url2);
+ if (urlFromUserInput.isValid())
+ {
+ QString gTitle = i18nc("Browse a website", "Browse");
+ UrlSearchItem gItem(UrlSearchItem::Browse, urlFromUserInput, gTitle);
+ list << gItem;
+ }
+
+ return list;
+}
+
+
+// STEP 2 = Web Searches
+UrlSearchList UrlResolver::webSearchesResolution()
+{
+ return UrlSearchList() << UrlSearchItem(UrlSearchItem::Search, KUrl(), QString());
+}
+
+
+// STEP 3 = history completion
+UrlSearchList UrlResolver::historyResolution()
+{
+ UrlSearchList list;
+
+ KCompletion *historyCompletion = Application::historyManager()->completionObject();
+ QStringList historyResults = historyCompletion->substringCompletion(_typedString);
+ Q_FOREACH(const QString &s, historyResults)
+ {
+ UrlSearchItem it(UrlSearchItem::History, KUrl(s), Application::historyManager()->titleForHistoryUrl(s));
+ list << it;
+ }
+
+ return list;
+}
+
+
+// STEP 4 = bookmarks completion
+UrlSearchList UrlResolver::bookmarksResolution()
+{
+ UrlSearchList list;
+
+ KCompletion *bookmarkCompletion = Application::bookmarkProvider()->completionObject();
+ QStringList bookmarkResults = bookmarkCompletion->substringCompletion(_typedString);
+ Q_FOREACH(const QString &s, bookmarkResults)
+ {
+ UrlSearchItem it(UrlSearchItem::Bookmark, KUrl(s), Application::bookmarkProvider()->titleForBookmarkUrl(s));
+ list << it;
+ }
+
+ return list;
+}
diff --git a/src/urlbar/urlresolver.h b/src/urlbar/urlresolver.h
new file mode 100644
index 00000000..d3cdedbe
--- /dev/null
+++ b/src/urlbar/urlresolver.h
@@ -0,0 +1,88 @@
+/* ============================================================
+*
+* This file is a part of the rekonq project
+*
+* Copyright (C) 2009 by Andrea Diamantini <adjam7 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 URL_RESOLVER_H
+#define URL_RESOLVER_H
+
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
+// KDE Includes
+#include <KUrl>
+
+// Qt Includes
+#include <QString>
+#include <QList>
+
+
+class UrlSearchItem
+{
+public:
+
+ enum types
+ {
+ Search = 0x00000001,
+ Browse = 0x00000010,
+ History = 0x00000100,
+ Bookmark = 0x00001000,
+ };
+
+ int type;
+ KUrl url;
+ QString title;
+
+ UrlSearchItem(const int &_type, const KUrl &_url, const QString &_title = QString())
+ : type(_type), url(_url), title(_title)
+ {};
+
+ bool operator==(const UrlSearchItem &i);
+};
+
+typedef QList <UrlSearchItem> UrlSearchList;
+
+
+// ----------------------------------------------------------------------
+
+
+class UrlResolver
+{
+public:
+ UrlResolver(const QString &typedUrl);
+
+ UrlSearchList orderedSearchItems();
+
+private:
+ QString _typedString;
+
+ UrlSearchList webSearchesResolution();
+ UrlSearchList historyResolution();
+ UrlSearchList qurlFromUserInputResolution();
+ UrlSearchList bookmarksResolution();
+ bool isHttp();
+};
+
+#endif // URL_RESOLVER_H
diff --git a/src/walletbar.cpp b/src/walletbar.cpp
index c5d705e0..292e48bd 100644
--- a/src/walletbar.cpp
+++ b/src/walletbar.cpp
@@ -10,9 +10,9 @@
* 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
+* 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
@@ -28,6 +28,9 @@
#include "walletbar.h"
#include "walletbar.moc"
+// Auto Includes
+#include "rekonq.h"
+
// KDE Includes
#include <klocalizedstring.h>
#include <KIcon>
@@ -40,8 +43,8 @@
WalletBar::WalletBar(QWidget *parent)
- : QWidget(parent)
- , m_label( new QLabel(this) )
+ : QWidget(parent)
+ , m_label(new QLabel(this))
{
m_label->setWordWrap(true);
@@ -57,15 +60,15 @@ WalletBar::WalletBar(QWidget *parent)
connect(rememberButton, SIGNAL(clicked()), this, SLOT(rememberData()));
connect(neverHereButton, SIGNAL(clicked()), this, SLOT(neverRememberData()));
connect(notNowButton, SIGNAL(clicked()), this, SLOT(notNowRememberData()));
-
+
// layout
QGridLayout *layout = new QGridLayout(this);
- layout->addWidget(closeButton,0,0);
- layout->addWidget(m_label,0,1);
- layout->addWidget(rememberButton,0,2);
- layout->addWidget(neverHereButton,0,3);
- layout->addWidget(notNowButton,0,4);
- layout->setColumnStretch(1,100);
+ layout->addWidget(closeButton, 0, 0);
+ layout->addWidget(m_label, 0, 1);
+ layout->addWidget(rememberButton, 0, 2);
+ layout->addWidget(neverHereButton, 0, 3);
+ layout->addWidget(notNowButton, 0, 4);
+ layout->setColumnStretch(1, 100);
setLayout(layout);
}
@@ -85,14 +88,18 @@ void WalletBar::rememberData()
void WalletBar::neverRememberData()
{
- // TODO: store site url (to remember never bother about)
+ // add url to the blacklist
+ QStringList list = ReKonfig::walletBlackList();
+ list << m_url.toString();
+ ReKonfig::setWalletBlackList(list);
+
notNowRememberData();
}
void WalletBar::notNowRememberData()
{
- emit saveFormDataRejected (m_key);
+ emit saveFormDataRejected(m_key);
destroy();
}
@@ -109,7 +116,7 @@ void WalletBar::destroy()
void WalletBar::onSaveFormData(const QString &key, const QUrl &url)
{
- m_label->setText( i18n("Do you want rekonq to remember the password on %1?", url.host() ) );
+ m_label->setText(i18n("Do you want rekonq to remember the password on %1?", url.host()));
m_key = key;
m_url = url;
diff --git a/src/walletbar.h b/src/walletbar.h
index d2e39373..5901c659 100644
--- a/src/walletbar.h
+++ b/src/walletbar.h
@@ -10,9 +10,9 @@
* 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
+* 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
@@ -24,9 +24,12 @@
* ============================================================ */
-#ifndef WALLET_WIDGET_H
-#define WALLET_WIDGET_H
+#ifndef WALLET_BAR_H
+#define WALLET_BAR_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
// Qt Includes
#include <QWidget>
@@ -35,7 +38,7 @@
#include <QLabel>
-class WalletBar : public QWidget
+class REKONQ_TESTS_EXPORT WalletBar : public QWidget
{
Q_OBJECT
@@ -44,7 +47,7 @@ public:
~WalletBar();
private slots:
-
+
void rememberData();
void neverRememberData();
void notNowRememberData();
@@ -52,7 +55,7 @@ private slots:
public slots:
void onSaveFormData(const QString &, const QUrl &);
-signals:
+signals:
void saveFormDataAccepted(const QString &);
void saveFormDataRejected(const QString &);
@@ -65,4 +68,4 @@ private:
QLabel *m_label;
};
-#endif // WALLET_WIDGET_H
+#endif // WALLET_BAR_H
diff --git a/src/webinspectorpanel.cpp b/src/webinspectorpanel.cpp
index a038d280..31833ea9 100644
--- a/src/webinspectorpanel.cpp
+++ b/src/webinspectorpanel.cpp
@@ -2,7 +2,7 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Matthieu Gicquel<matgic78@gmail.com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -35,29 +35,28 @@
// KDE Includes
#include "KAction"
-#include "KDebug"
// Qt Includes
#include <QWebInspector>
-WebInspectorPanel::WebInspectorPanel(QString title, QWidget *parent)
- : QDockWidget(title, parent)
+WebInspectorPanel::WebInspectorPanel(QString title, QWidget *parent)
+ : QDockWidget(title, parent)
{
setObjectName("webInspectorDock");
- setWidget( new QWebInspector(this) );
+ setWidget(new QWebInspector(this));
}
-
-void WebInspectorPanel::closeEvent(QCloseEvent *event)
-{
+
+void WebInspectorPanel::closeEvent(QCloseEvent *event)
+{
Q_UNUSED(event);
toggle(false);
}
MainWindow* WebInspectorPanel::mainWindow()
-{
+{
return qobject_cast< MainWindow* >(parentWidget());
}
@@ -79,8 +78,8 @@ void WebInspectorPanel::toggle(bool enable)
}
-void WebInspectorPanel::changeCurrentPage()
-{
+void WebInspectorPanel::changeCurrentPage()
+{
bool enable = mainWindow()->currentTab()->view()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled);
toggle(enable);
}
diff --git a/src/webinspectorpanel.h b/src/webinspectorpanel.h
index 8f65b48a..8b1e3507 100644
--- a/src/webinspectorpanel.h
+++ b/src/webinspectorpanel.h
@@ -2,7 +2,7 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Matthieu Gicquel<matgic78@gmail.com>
+* Copyright (C) 2010 by Matthieu Gicquel<matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -10,9 +10,9 @@
* 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
+* 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
@@ -28,6 +28,9 @@
#define WEBINSPECTOR_PANEL_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Local Includes
#include "mainwindow.h"
@@ -38,21 +41,21 @@
Docked web inspector
behaviour : hide/show by tab, not globally
*/
-class WebInspectorPanel : public QDockWidget
+class REKONQ_TESTS_EXPORT WebInspectorPanel : public QDockWidget
{
Q_OBJECT
public:
WebInspectorPanel(QString title, QWidget *parent);
-
+
public slots:
void toggle(bool enable);
- void changeCurrentPage();
-
+ void changeCurrentPage();
+
protected:
virtual void closeEvent(QCloseEvent *event);
-
+
MainWindow *mainWindow();
-
+
};
#endif
diff --git a/src/webpage.cpp b/src/webpage.cpp
index b2bedffc..b510311e 100644
--- a/src/webpage.cpp
+++ b/src/webpage.cpp
@@ -6,7 +6,8 @@
* Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
* Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2008 Michael Howell <mhowell123@gmail.com>
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -14,9 +15,9 @@
* 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
+* 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
@@ -44,10 +45,11 @@
#include "networkaccessmanager.h"
#include "adblockmanager.h"
+#include "sslinfodialog_p.h"
+
// KDE Includes
#include <KStandardDirs>
#include <KUrl>
-#include <KDebug>
#include <KToolInvocation>
#include <KProtocolManager>
#include <kwebwallet.h>
@@ -69,31 +71,68 @@
#include <QtGui/QClipboard>
#include <QtGui/QKeyEvent>
+#include <QtWebKit/QWebFrame>
+
+
+// Returns true if the scheme and domain of the two urls match...
+static bool domainSchemeMatch(const QUrl& u1, const QUrl& u2)
+{
+ if (u1.scheme() != u2.scheme())
+ return false;
+
+ QStringList u1List = u1.host().split(QL1C('.'), QString::SkipEmptyParts);
+ QStringList u2List = u2.host().split(QL1C('.'), QString::SkipEmptyParts);
+
+ if (qMin(u1List.count(), u2List.count()) < 2)
+ return false; // better safe than sorry...
-WebPage::WebPage(QObject *parent)
+ while (u1List.count() > 2)
+ u1List.removeFirst();
+
+ while (u2List.count() > 2)
+ u2List.removeFirst();
+
+ return (u1List == u2List);
+}
+
+
+// ---------------------------------------------------------------------------------
+
+
+WebPage::WebPage(QWidget *parent)
: KWebPage(parent, KWalletIntegration)
{
+ // ----- handling unsupported content...
setForwardUnsupportedContent(true);
+ connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), this, SLOT(handleUnsupportedContent(QNetworkReply *)));
- // rekonq Network Manager
+ // ----- rekonq Network Manager
NetworkAccessManager *manager = new NetworkAccessManager(this);
-
- // disable QtWebKit cache to just use KIO one..
- manager->setCache(0);
-
+ manager->setCache(0); // disable QtWebKit cache to just use KIO one..
+
+ // set cookieJar window ID..
+ if (parent && parent->window())
+ manager->setCookieJarWindowId(parent->window()->winId());
+
setNetworkAccessManager(manager);
-
- // Web Plugin Factory
+
+ // activate ssl warnings
+ setSessionMetaData("ssl_activate_warnings", "TRUE");
+
+ // Override the 'Accept' header sent by QtWebKit which favors XML over HTML!
+ // Setting the accept meta-data to null will force kio_http to use its own
+ // default settings for this header.
+ setSessionMetaData(QL1S("accept"), QString());
+
+ // ----- Web Plugin Factory
setPluginFactory(new WebPluginFactory(this));
-
- connect(networkAccessManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(manageNetworkErrors(QNetworkReply*)));
-
- connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), this, SLOT(handleUnsupportedContent(QNetworkReply *)));
+ // ----- last stuffs
+ connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(manageNetworkErrors(QNetworkReply*)));
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
// protocol handler signals
- connect(&m_protHandler, SIGNAL(downloadUrl(const KUrl &)), this, SLOT(downloadUrl(const KUrl &)));
+ connect(&_protHandler, SIGNAL(downloadUrl(const KUrl &)), this, SLOT(downloadUrl(const KUrl &)));
}
@@ -105,23 +144,68 @@ WebPage::~WebPage()
bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
{
- // advise users on resubmitting data
- if(type == QWebPage::NavigationTypeFormResubmitted)
+ _loadingUrl = request.url();
+
+ KIO::AccessManager *manager = qobject_cast<KIO::AccessManager*>(networkAccessManager());
+ KIO::MetaData metaData = manager->requestMetaData();
+
+ // Get the SSL information sent, if any...
+ if (metaData.contains(QL1S("ssl_in_use")))
{
- int risp = KMessageBox::warningContinueCancel(view(),
- i18n("Are you sure you want to send your data again?"),
- i18n("Resend form data") );
- if(risp == KMessageBox::Cancel)
- return false;
+ WebSslInfo info;
+ info.fromMetaData(metaData.toVariant());
+ info.setUrl(request.url());
+ _sslInfo = info;
}
- if (frame && m_protHandler.preHandling( request, frame ))
+ if (frame)
{
- return false;
- }
+ if (_protHandler.preHandling(request, frame))
+ {
+ return false;
+ }
- m_requestedUrl = request.url();
+ switch (type)
+ {
+ case QWebPage::NavigationTypeLinkClicked:
+ if (_sslInfo.isValid())
+ {
+ setRequestMetaData("ssl_was_in_use", "TRUE");
+ }
+ break;
+
+ case QWebPage::NavigationTypeFormSubmitted:
+ break;
+
+ case QWebPage::NavigationTypeFormResubmitted:
+ if (KMessageBox::warningContinueCancel(view(),
+ i18n("Are you sure you want to send your data again?"),
+ i18n("Resend form data")
+ )
+ == KMessageBox::Cancel)
+ {
+ return false;
+ }
+ break;
+
+ case QWebPage::NavigationTypeReload:
+ case QWebPage::NavigationTypeBackOrForward:
+ case QWebPage::NavigationTypeOther:
+ break;
+
+ default:
+ break;
+ }
+ if (frame == mainFrame())
+ {
+ setRequestMetaData("main_frame_request", "TRUE");
+ }
+ else
+ {
+ setRequestMetaData("main_frame_request", "FALSE");
+ }
+ }
return KWebPage::acceptNavigationRequest(frame, request, type);
}
@@ -135,9 +219,9 @@ WebPage *WebPage::createWindow(QWebPage::WebWindowType type)
kDebug() << "Modal Dialog";
WebTab *w = 0;
- if(ReKonfig::openTabNoWindow())
+ if (ReKonfig::openTabNoWindow())
{
- w = Application::instance()->mainWindow()->mainView()->newWebTab(!ReKonfig::openTabsBack());
+ w = Application::instance()->mainWindow()->mainView()->newWebTab(!ReKonfig::openTabsBack(), ReKonfig::openTabsNearCurrent());
}
else
{
@@ -149,95 +233,158 @@ WebPage *WebPage::createWindow(QWebPage::WebWindowType type)
void WebPage::handleUnsupportedContent(QNetworkReply *reply)
{
+ // NOTE
+ // This is probably needed just in ONE stupid case..
+ if (_protHandler.postHandling(reply->request(), mainFrame()))
+ return;
+
if (reply->error() == QNetworkReply::NoError)
{
- const KUrl url( reply->url() );
+ const KUrl url(reply->url());
QString mimeType = reply->header(QNetworkRequest::ContentTypeHeader).toString();
- KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimeType);
+ KService::Ptr appService = KMimeTypeTrader::self()->preferredService(mimeType);
bool isLocal = url.isLocalFile();
-
- if( offer.isNull() ) // no service can handle this. We can just download it..
+
+ if (appService.isNull()) // no service can handle this. We can just download it..
{
- isLocal ? KMessageBox::sorry(view(), i18n("No service can handle this :(") ) : downloadRequest(reply->request());
+ kDebug() << "no service can handle this. We can just download it..";
+
+ isLocal
+ ? KMessageBox::sorry(view(), i18n("No service can handle this :("))
+ : downloadRequest(reply->request());
+
return;
}
- if(!isLocal)
+ if (!isLocal)
{
-
+
KParts::BrowserOpenOrSaveQuestion dlg(Application::instance()->mainWindow(), url, mimeType);
- switch ( dlg.askEmbedOrSave() )
+ switch (dlg.askEmbedOrSave())
{
- case KParts::BrowserOpenOrSaveQuestion::Save:
- downloadRequested(reply->request());
- return;
- case KParts::BrowserOpenOrSaveQuestion::Cancel:
- return;
- default: // non extant case
- break;
+ case KParts::BrowserOpenOrSaveQuestion::Save:
+ kDebug() << "service handling: download!";
+ downloadRequest(reply->request());
+ return;
+
+ case KParts::BrowserOpenOrSaveQuestion::Cancel:
+ return;
+
+ default: // non extant case
+ break;
}
}
+
// case KParts::BrowserRun::Embed
- KUrl::List list;
- list.append(url);
- KRun::run(*offer,url,0);
+
+ KService::List partServices = KMimeTypeTrader::self()->query(mimeType, QL1S("KParts/ReadOnlyPart"));
+ if (partServices.count() > 0)
+ {
+ // A part can handle this. Embed it!
+ QString html;
+ html += "<html>";
+ html += "<head>";
+ html += "<title>";
+ html += url.pathOrUrl();
+ html += "</title>";
+ html += "<style type=\"text/css\">";
+ html += "* { border: 0; padding: 0; margin: 0; }";
+ html += "</style>";
+ html += "</head>";
+ html += "<body>";
+ html += "<embed src=\"" + url.pathOrUrl() + "\" width=\"100%\" height=\"100%\" />";
+ html += "</body>";
+ html += "</html>";
+
+ mainFrame()->setHtml(html, url);
+ }
+ else
+ {
+ // No parts, just app services. Load it!
+ KRun::run(*appService, url, 0);
+ }
+
+ return;
}
}
-void WebPage::loadFinished(bool)
+void WebPage::loadFinished(bool ok)
{
+ Q_UNUSED(ok);
+
Application::adblockManager()->applyHidingRules(this);
-
+
+ QStringList list = ReKonfig::walletBlackList();
+
// KWallet Integration
- // TODO: Add check for sites exempt from automatic form filling...
- if (wallet())
+ if (wallet()
+ && !list.contains(mainFrame()->url().toString())
+ )
{
wallet()->fillFormData(mainFrame());
}
}
-void WebPage::manageNetworkErrors(QNetworkReply* reply)
+void WebPage::manageNetworkErrors(QNetworkReply *reply)
{
- if( reply->error() == QNetworkReply::NoError )
- return;
+ Q_ASSERT(reply);
- if(m_protHandler.postHandling( reply->request(), mainFrame() ))
- return;
+ QWebFrame* frame = qobject_cast<QWebFrame *>(reply->request().originatingObject());
+ const bool isMainFrameRequest = (frame == mainFrame());
- // don't bother on adblocked urls
- if( reply->error() == QNetworkReply::ContentAccessDenied )
- return;
-
- if( reply->url() != m_requestedUrl ) // prevent favicon loading
- return;
-
- if( reply->error() == QNetworkReply::ContentNotFoundError )
+ if (isMainFrameRequest
+ && _sslInfo.isValid()
+ && !domainSchemeMatch(reply->url(), _sslInfo.url())
+ )
{
- QList<QWebFrame*> frames;
- frames.append(mainFrame());
- while (!frames.isEmpty())
- {
- QWebFrame *firstFrame = frames.takeFirst();
-
- if (firstFrame->url() == reply->url())
- {
- firstFrame->setHtml(errorPage(reply), reply->url());
- return;
- }
- QList<QWebFrame *> children = firstFrame->childFrames();
- Q_FOREACH(QWebFrame *frame, children)
- {
- frames.append(frame);
- }
- }
+ //kDebug() << "Reseting cached SSL info...";
+ _sslInfo = WebSslInfo();
}
- else
+
+ // NOTE: These are not all networkreply errors,
+ // but just that supported directly by KIO
+ switch (reply->error())
{
- mainFrame()->setHtml(errorPage(reply), reply->url());
+
+ case QNetworkReply::NoError: // no error. Simple :)
+ if (isMainFrameRequest && !_sslInfo.isValid())
+ {
+ // Obtain and set the SSL information if any...
+ _sslInfo.fromMetaData(reply->attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData)));
+ _sslInfo.setUrl(reply->url());
+ }
+ break;
+
+ case QNetworkReply::ContentAccessDenied: // access to remote content denied (similar to HTTP error 401)
+ kDebug() << "We (hopefully) are managing this through the adblock :)";
+ break;
+
+ case QNetworkReply::UnknownNetworkError: // unknown network-related error detected
+ if (_protHandler.postHandling(reply->request(), mainFrame()))
+ break;
+
+ case QNetworkReply::ConnectionRefusedError: // remote server refused connection
+ case QNetworkReply::HostNotFoundError: // invalid hostname
+ case QNetworkReply::TimeoutError: // connection time out
+ case QNetworkReply::OperationCanceledError: // operation canceled via abort() or close() calls
+ case QNetworkReply::ProxyNotFoundError: // invalid proxy hostname
+ case QNetworkReply::ContentOperationNotPermittedError: // operation requested on remote content not permitted
+ case QNetworkReply::ContentNotFoundError: // remote content not found on server (similar to HTTP error 404)
+ case QNetworkReply::ProtocolUnknownError: // Unknown protocol
+ case QNetworkReply::ProtocolInvalidOperationError: // requested operation is invalid for this protocol
+
+ if (reply->url() == _loadingUrl)
+ mainFrame()->setHtml(errorPage(reply), reply->url());
+ break;
+
+ default:
+ kDebug() << "Nothing to do here..";
+ break;
+
}
}
@@ -254,11 +401,21 @@ QString WebPage::errorPage(QNetworkReply *reply)
return QString("Couldn't open the rekonqinfo.html file");
}
- QString title = i18n("Error loading: %1", reply->url().path());
- QString msg = "<h1>" + reply->errorString() + "</h1>";
- QString urlString = reply->url().toString( QUrl::RemoveUserInfo | QUrl::RemoveQuery );
-
- msg += "<h2>" + i18nc("%1=an URL, e.g.'kde.org'", "When connecting to: %1", urlString ) + "</h2>";
+ QString title = i18n("Error loading: %1", reply->url().path());
+ QString urlString = reply->url().toString(QUrl::RemoveUserInfo | QUrl::RemoveQuery);
+
+ QString iconPath = QString("file://") + KIconLoader::global()->iconPath("dialog-warning" , KIconLoader::Small);
+ iconPath.replace(QL1S("16"), QL1S("128"));
+
+ QString msg;
+ msg += "<table>";
+ msg += "<tr><td>";
+ msg += "<img src=\"" + iconPath + "\" />";
+ msg += "</td><td>";
+ msg += "<h1>" + reply->errorString() + "</h1>";
+ msg += "<h2>" + i18nc("%1=an URL, e.g.'kde.org'", "When connecting to: <b>%1</b>", urlString) + "</h2>";
+ msg += "</td></tr></table>";
+
msg += "<ul><li>" + i18n("Check the address for errors such as <b>ww</b>.kde.org instead of <b>www</b>.kde.org");
msg += "</li><li>" + i18n("If the address is correct, try to check the network connection.") + "</li><li>" ;
msg += i18n("If your computer or network is protected by a firewall or proxy, make sure that rekonq is permitted to access the network.");
@@ -266,83 +423,165 @@ QString WebPage::errorPage(QNetworkReply *reply)
msg += "</li></ul><br/><br/>";
msg += "<input type=\"button\" id=\"reloadButton\" onClick=\"document.location.href='" + urlString + "';\" value=\"";
msg += i18n("Try Again") + "\" />";
-
- QString html = QString(QLatin1String(file.readAll()))
- .arg(title)
- .arg(msg)
- ;
+
+ QString html = QString(QL1S(file.readAll()))
+ .arg(title)
+ .arg(msg)
+ ;
return html;
}
+// WARNING
+// this code is actually copied from KWebPage::downloadRequest to save
+// downloads data before. If you have some better ideas about,
+// feel free to let us know about :)
void WebPage::downloadRequest(const QNetworkRequest &request)
{
- if (ReKonfig::kgetDownload())
- {
- //*Copy of kwebpage code (Shouldn't be done in kwepage ?)
+ KUrl destUrl;
+ KUrl srcUrl(request.url());
+ int result = KIO::R_OVERWRITE;
- KUrl destUrl;
- KUrl srcUrl (request.url());
- int result = KIO::R_OVERWRITE;
+ do
+ {
+ destUrl = KFileDialog::getSaveFileName(srcUrl.fileName(), QString(), view());
- do
+ if (destUrl.isLocalFile())
{
- destUrl = KFileDialog::getSaveFileName(srcUrl.fileName(), QString(), view());
-
- if (destUrl.isLocalFile())
+ QFileInfo finfo(destUrl.toLocalFile());
+ if (finfo.exists())
{
- QFileInfo finfo (destUrl.toLocalFile());
- if (finfo.exists())
- {
- QDateTime now = QDateTime::currentDateTime();
- KIO::RenameDialog dlg (view(), 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();
- }
+ QDateTime now = QDateTime::currentDateTime();
+ QPointer<KIO::RenameDialog> dlg = new KIO::RenameDialog(view(),
+ 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;
}
- }
- while (result == KIO::R_CANCEL && destUrl.isValid());
+ }
+ }
+ while (result == KIO::R_CANCEL && destUrl.isValid());
+
+ if (result == KIO::R_OVERWRITE && destUrl.isValid())
+ {
+ // now store data
+ // now, destUrl, srcUrl
+ Application::historyManager()->addDownload(srcUrl.pathOrUrl() , destUrl.pathOrUrl());
- if (result == KIO::R_OVERWRITE && destUrl.isValid())
+ if (ReKonfig::kgetDownload())
{
- //*End of copy code
-
//KGet integration:
- if(!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget"))
+ if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget"))
{
KToolInvocation::kdeinitExecWait("kget");
}
QDBusInterface kget("org.kde.kget", "/KGet", "org.kde.kget.main");
- kget.call("addTransfer", srcUrl.prettyUrl(), destUrl.prettyUrl(), true);
+ if (kget.isValid())
+ {
+ kget.call("addTransfer", srcUrl.prettyUrl(), destUrl.prettyUrl(), true);
+ return;
+ }
}
+
+ // else, use KIO or fallback to it
+ KIO::Job *job = KIO::file_copy(srcUrl, destUrl, -1, KIO::Overwrite);
+ QVariant attr = request.attribute(static_cast<QNetworkRequest::Attribute>(KIO::AccessManager::MetaData));
+ if (attr.isValid() && attr.type() == QVariant::Map)
+ job->setMetaData(KIO::MetaData(attr.toMap()));
+
+ job->addMetaData(QL1S("MaxCacheSize"), QL1S("0")); // Don't store in http cache.
+ job->addMetaData(QL1S("cache"), QL1S("cache")); // Use entry from cache if available.
+ job->uiDelegate()->setAutoErrorHandlingEnabled(true);
}
- else KWebPage::downloadRequest(request);
}
-void WebPage::downloadAllContentsWithKGet()
+void WebPage::downloadAllContentsWithKGet(QPoint)
{
- QList<QString> contentList;
+ QSet<QString> contents;
+ KUrl baseUrl(currentFrame()->url());
+ KUrl relativeUrl;
QWebElementCollection images = mainFrame()->documentElement().findAll("img");
foreach(QWebElement img, images)
{
- contentList.append(img.attribute("src"));
+ relativeUrl.setEncodedUrl(img.attribute("src").toUtf8(), KUrl::TolerantMode);
+ contents << baseUrl.resolved(relativeUrl).toString();
}
-
+
QWebElementCollection links = mainFrame()->documentElement().findAll("a");
foreach(QWebElement link, links)
{
- contentList.append(link.attribute("href"));
+ relativeUrl.setEncodedUrl(link.attribute("href").toUtf8(), KUrl::TolerantMode);
+ contents << baseUrl.resolved(relativeUrl).toString();
}
-
- if(!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget"))
+
+ if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kget"))
{
KToolInvocation::kdeinitExecWait("kget");
}
QDBusInterface kget("org.kde.kget", "/KGet", "org.kde.kget.main");
- kget.call("importLinks", QVariant(contentList));
+ if (kget.isValid())
+ {
+ kget.call("importLinks", QVariant(contents.toList()));
+ }
+}
+
+
+void WebPage::showSSLInfo(QPoint)
+{
+ if (_sslInfo.isValid())
+ {
+ QPointer<KSslInfoDialog> dlg = new KSslInfoDialog(view());
+ dlg->setSslInfo(_sslInfo.certificateChain(),
+ _sslInfo.peerAddress().toString(),
+ mainFrame()->url().host(),
+ _sslInfo.protocol(),
+ _sslInfo.ciphers(),
+ _sslInfo.usedChiperBits(),
+ _sslInfo.supportedChiperBits(),
+ KSslInfoDialog::errorsFromString(_sslInfo.certificateErrors())
+ );
+
+ dlg->exec();
+ delete dlg;
+
+ return;
+ }
+
+ if (mainFrame()->url().scheme() == QL1S("https"))
+ {
+ KMessageBox::error(view(),
+ i18n("The SSL information for this site appears to be corrupt."),
+ i18nc("Secure Sockets Layer", "SSL")
+ );
+ }
+ else
+ {
+ KMessageBox::information(view(),
+ i18n("This site doesn't contain SSL information."),
+ i18nc("Secure Sockets Layer", "SSL")
+ );
+ }
+}
+
+
+
+
+void WebPage::updateImage(bool ok)
+{
+ if (ok)
+ {
+ NewTabPage p(mainFrame());
+ p.snapFinished();
+ }
}
diff --git a/src/webpage.h b/src/webpage.h
index 9169ad60..41c14295 100644
--- a/src/webpage.h
+++ b/src/webpage.h
@@ -6,7 +6,8 @@
* Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
* Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2008 Michael Howell <mhowell123@gmail.com>
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -14,9 +15,9 @@
* 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
+* 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
@@ -32,8 +33,13 @@
#define WEBPAGE_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// Local Includes
#include "protocolhandler.h"
+#include "newtabpage.h"
+#include "websslinfo.h"
// KDE Includes
#include <KWebPage>
@@ -46,36 +52,38 @@ class QWebFrame;
class QNetworkReply;
-class WebPage : public KWebPage
+class REKONQ_TESTS_EXPORT WebPage : public KWebPage
{
Q_OBJECT
public:
- explicit WebPage(QObject *parent = 0);
+ explicit WebPage(QWidget *parent = 0);
~WebPage();
public slots:
- void manageNetworkErrors(QNetworkReply *reply);
virtual void downloadRequest(const QNetworkRequest &request);
- void downloadAllContentsWithKGet();
+ void downloadAllContentsWithKGet(QPoint);
+
protected:
WebPage *createWindow(WebWindowType type);
-
- virtual bool acceptNavigationRequest(QWebFrame *frame,
- const QNetworkRequest &request,
+
+ virtual bool acceptNavigationRequest(QWebFrame *frame,
+ const QNetworkRequest &request,
NavigationType type);
-
-protected Q_SLOTS:
- virtual void handleUnsupportedContent(QNetworkReply *reply);
private slots:
+ void handleUnsupportedContent(QNetworkReply *reply);
+ void manageNetworkErrors(QNetworkReply *reply);
void loadFinished(bool);
+ void showSSLInfo(QPoint);
+ void updateImage(bool ok);
private:
QString errorPage(QNetworkReply *);
+ QUrl _loadingUrl;
- QUrl m_requestedUrl;
- ProtocolHandler m_protHandler;
+ ProtocolHandler _protHandler;
+ WebSslInfo _sslInfo;
};
#endif
diff --git a/src/webpluginfactory.cpp b/src/webpluginfactory.cpp
index aec4e18d..fe2f965b 100644
--- a/src/webpluginfactory.cpp
+++ b/src/webpluginfactory.cpp
@@ -2,7 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -10,9 +11,9 @@
* 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
+* 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
@@ -32,30 +33,20 @@
#include "rekonq.h"
#include "application.h"
#include "mainwindow.h"
-#include "previewimage.h"
#include "clicktoflash.h"
-// KDE Includes
-#include <KDebug>
-
WebPluginFactory::WebPluginFactory(QObject *parent)
- : KWebPluginFactory(parent)
+ : KWebPluginFactory(parent)
+ , _loadClickToFlash(false)
{
- loadClickToFlash = false;
connect(this, SIGNAL(signalLoadClickToFlash(bool)), SLOT(setLoadClickToFlash(bool)));
}
-WebPluginFactory::~WebPluginFactory()
-{
-}
-
-
-
void WebPluginFactory::setLoadClickToFlash(bool load)
{
- loadClickToFlash = load;
+ _loadClickToFlash = load;
}
@@ -65,62 +56,37 @@ QObject *WebPluginFactory::create(const QString &mimeType,
const QStringList &argumentValues) const
{
kDebug() << "loading mimeType: " << mimeType;
-
- if(mimeType == QString("application/image-preview") )
- {
- QString title;
- int number = -1;
- bool isFavorite = false;
- int i;
- i = argumentNames.indexOf( QString("title") );
- if(i > -1)
- title = argumentValues.at(i);
- i = argumentNames.indexOf( QString("isFavorite") );
- if(i > -1)
- isFavorite = true;
- i = argumentNames.indexOf( QString("index") );
- if(i > -1)
- number = argumentValues.at(i).toInt();
-
- return new PreviewImage(url, title, number, isFavorite);
- }
-
- if(ReKonfig::pluginsEnabled() == 0) // plugins are enabled
+ switch (ReKonfig::pluginsEnabled())
{
- kDebug() << "No plugins found for" << mimeType << ". Falling back to QtWebKit ones...";
+ case 0:
+ kDebug() << "No plugins found for" << mimeType << ". Falling back to KDEWebKit ones...";
+ return KWebPluginFactory::create(mimeType, url, argumentNames, argumentValues);
+
+ case 1:
+ if (mimeType != QString("application/x-shockwave-flash"))
+ break;
+
+ if (_loadClickToFlash)
+ {
+ emit signalLoadClickToFlash(false);
+ return 0; //KWebPluginFactory::create(mimeType, url, argumentNames, argumentValues);
+ }
+ else
+ {
+ ClickToFlash* ctf = new ClickToFlash(url);
+ connect(ctf, SIGNAL(signalLoadClickToFlash(bool)), this, SLOT(setLoadClickToFlash(bool)));
+ return ctf;
+ }
+ break;
+
+ case 2:
return 0;
- }
-
- if(mimeType == QString("application/x-shockwave-flash")
- && !loadClickToFlash)
- {
- ClickToFlash* ctf = new ClickToFlash(url);
- connect(ctf, SIGNAL(signalLoadClickToFlash(bool)), this, SLOT(setLoadClickToFlash(bool)));
- return ctf;
- }
-
- // this let QtWebKit using builtin plugins
- // to load in example flash contents and so on..
- kDebug() << "No plugins found for" << mimeType << ". Falling back to QtWebKit ones...";
- emit signalLoadClickToFlash(false);
- return KWebPluginFactory::create(mimeType, url, argumentNames, argumentValues);
-}
+ default:
+ kDebug() << "oh oh.. this should NEVER happen..";
+ break;
+ }
-QList<QWebPluginFactory::Plugin> WebPluginFactory::plugins() const
-{
- QList<KWebPluginFactory::Plugin> plugins = KWebPluginFactory::plugins();
-
- QWebPluginFactory::Plugin p;
- p.name = "application/image-preview";
- p.description = "plugin for embedding Web snapped images";
- plugins.append(p);
-
- p.name = "application/x-shockwave-flash";
- p.description = "Plugin for flash animations";
- plugins.append(p);
-
-
- return plugins;
+ return KWebPluginFactory::create(mimeType, url, argumentNames, argumentValues);
}
diff --git a/src/webpluginfactory.h b/src/webpluginfactory.h
index c1e4c28f..c5eefa45 100644
--- a/src/webpluginfactory.h
+++ b/src/webpluginfactory.h
@@ -2,7 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -10,9 +11,9 @@
* 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
+* 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
@@ -28,6 +29,9 @@
#define WEB_PLUGIN_FACTORY_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// KDE Includes
#include <KWebPluginFactory>
@@ -36,34 +40,30 @@
#include <QtGui/QWidget>
-class WebPluginFactory : public KWebPluginFactory
+class REKONQ_TESTS_EXPORT WebPluginFactory : public KWebPluginFactory
{
-Q_OBJECT
+ Q_OBJECT
public:
WebPluginFactory(QObject *parent);
- ~WebPluginFactory();
virtual QObject *create(const QString &mimeType,
const QUrl &url,
const QStringList &argumentNames,
const QStringList &argumentValues) const;
- virtual QList<Plugin> plugins() const;
-
signals:
-
void signalLoadClickToFlash(bool) const;
-
+
public slots:
void setLoadClickToFlash(bool load);
-
+
private:
/**
When true, force loading of next flash animation (don't show clicktoflash)
We use signals/slots to set this property because QWebPluginFactory::create is const
*/
- bool loadClickToFlash;
+ bool _loadClickToFlash;
};
#endif // WEB_PLUGIN_FACTORY_H
diff --git a/src/websnap.cpp b/src/websnap.cpp
index 7dcbb836..aaaed1d5 100644
--- a/src/websnap.cpp
+++ b/src/websnap.cpp
@@ -3,7 +3,8 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2009 Nokia Corporation <qt-info@nokia.com>
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +12,9 @@
* 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
+* 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
@@ -29,76 +30,73 @@
#include "websnap.h"
#include "websnap.moc"
+// Local Includes
+#include "newtabpage.h"
+
// KDE Includes
-#include <KDebug>
#include <KStandardDirs>
// Qt Includes
-#include <QSize>
-#include <QWebFrame>
-#include <QWebSettings>
-#include <QPainter>
-#include <QTimer>
-#include <QFile>
+#include <QtCore/QSize>
+#include <QtCore/QTimer>
+#include <QtCore/QFile>
+#include <QtGui/QPainter>
-#define WIDTH 200
-#define HEIGHT 150
+#include <QtWebKit/QWebFrame>
+#include <QtWebKit/QWebSettings>
-WebSnap::WebSnap(const QUrl &url)
- : QObject()
-{
- m_url = url;
+WebSnap::WebSnap(const KUrl& url, QObject *parent)
+ : QObject(parent)
+ , m_url(url)
+{
// this to not register websnap history
m_page.settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
-
+
// this to not let this page open other windows
m_page.settings()->setAttribute(QWebSettings::PluginsEnabled, false);
m_page.settings()->setAttribute(QWebSettings::JavascriptEnabled, false);
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(saveResult(bool)));
- QTimer::singleShot(0, this, SLOT(load()));
-}
-
-WebSnap::~WebSnap()
-{
+ QTimer::singleShot(0, this, SLOT(load()));
}
-
void WebSnap::load()
{
m_page.mainFrame()->load(m_url);
}
-QPixmap WebSnap::renderPreview(const QWebPage &page,int w, int h)
+// NOTE please, be careful modifying this.
+// You are playing with fire..
+QPixmap WebSnap::renderPreview(const QWebPage &page, int w, int h)
{
+ // NOTE
+ // it seems no way to enable/disable scrollbars in new QtWebKit's
+ // and this is affecting tabbed browsing
+
// prepare page
- page.mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); // Why it doesn't work with one setScrollBarPolicy?
- page.mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); // bug in qtwebkit ?
- page.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
- page.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
+ QSize oldSize = page.viewportSize();
+// page.mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
+// page.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
// find the best size
QSize size;
- if (page.viewportSize().width() && page.viewportSize().height())
- {
- size = page.viewportSize();
- }
- else
+ int width = page.mainFrame()->contentsSize().width();
+ if (width < 640)
{
- int width = page.mainFrame()->contentsSize().width();
- if (width < 640) width = 640;
- size = QSize(width,width*((0.0+h)/w));
- page.setViewportSize(size);
+ width = 640;
}
-
+ size = QSize(width, width * ((0.0 + h) / w));
+ page.setViewportSize(size);
+
// create the page image
QImage pageImage = QImage(size, QImage::Format_ARGB32_Premultiplied);
- pageImage.fill(Qt::transparent);
+ pageImage.fill(Qt::transparent);
+
// render it
QPainter p(&pageImage);
page.mainFrame()->render(&p);
@@ -106,43 +104,60 @@ QPixmap WebSnap::renderPreview(const QWebPage &page,int w, int h)
pageImage = pageImage.scaled(w, h, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
// restore page settings
- page.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded);
- page.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded);
- page.mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded);
- page.mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded);
-
- return QPixmap::fromImage(pageImage);
-}
+// page.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded);
+// page.mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded);
+ page.setViewportSize(oldSize);
+ QPixmap pm = QPixmap::fromImage(pageImage);
+ KUrl url(page.mainFrame()->url());
+ kDebug() << "saving preview";
-void WebSnap::saveResult(bool ok)
-{
- // crude error-checking
- if (!ok)
- {
- kDebug() << "Error loading site..";
- return;
- }
+ QString path = imagePathFromUrl(url);
+ QFile::remove(path);
+ pm.save(path);
- m_image = renderPreview(m_page, WIDTH, HEIGHT);
- emit finished();
+ return pm;
}
-
-QString WebSnap::snapTitle()
+QString WebSnap::imagePathFromUrl(const KUrl &url)
{
- return m_page.mainFrame()->title();
+ QUrl temp = QUrl(url.url());
+ QString name = temp.toString(QUrl::RemoveScheme | QUrl::RemoveUserInfo | QUrl::StripTrailingSlash);
+
+ // TODO learn Regular Expressions :)
+ // and implement something better here..
+ name.remove('/');
+ name.remove('&');
+ name.remove('.');
+ name.remove('-');
+ name.remove('_');
+ name.remove('?');
+ name.remove('=');
+ name.remove('+');
+
+ return KStandardDirs::locateLocal("cache", QString("thumbs/") + name + ".png", true);
}
-QUrl WebSnap::snapUrl()
+void WebSnap::saveResult(bool ok)
{
- return m_url;
+ if (ok)
+ {
+ QPixmap image = renderPreview(m_page, WIDTH, HEIGHT);
+ QString path = imagePathFromUrl(m_url);
+ QFile::remove(path);
+ image.save(path);
+ }
+
+ emit snapDone(ok);
+ kDebug() << "SAVE RESULTS: " << ok << " URL: " << m_url;
+
+ this->deleteLater();
}
-QPixmap WebSnap::previewImage()
+bool WebSnap::existsImage(const KUrl &u)
{
- return m_image;
+ return QFile::exists(imagePathFromUrl(u));
}
diff --git a/src/websnap.h b/src/websnap.h
index 6c5b4af9..c85dc0d2 100644
--- a/src/websnap.h
+++ b/src/websnap.h
@@ -3,7 +3,8 @@
* This file is a part of the rekonq project
*
* Copyright (C) 2009 Nokia Corporation <qt-info@nokia.com>
-* Copyright (C) 2009 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2010 by Matthieu Gicquel <matgic78 at gmail dot com>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +12,9 @@
* 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
+* 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
@@ -28,48 +29,92 @@
#ifndef WEB_SNAP_H
#define WEB_SNAP_H
+
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// KDE Includes
#include <KUrl>
// Qt Includes
#include <QtCore/QObject>
-#include <QPixmap>
-#include <QImage>
-#include <QWebPage>
+
+#include <QtGui/QPixmap>
+
+#include <QtWebKit/QWebPage>
+
+// Defines
+#define WIDTH 200
+#define HEIGHT 150
/**
- * This class renders a site producing an image based
- * on that.
+ * This class is used in many classes of rekonq to produce an image
+ * based on the site corresponding to the url passed as argument.
+ * It also cached the images to not retrieve them every time :)
+ *
* Heavily based on Graphics-Dojo WebSnap example (thanks!)
+ *
+ * We use this in the following rekonq classes:
+ *
+ * - TabBar class: to show a tab preview (given a page, you show AND save an image)
+ * - PreviewSelector class: to save new favorite selection (given a page, you show AND save an image)
+ *
+ * - NewTabPage class: to show the favorites page "preview" (given an url, you show AND save an image)
+ *
*/
-class WebSnap : public QObject
+class REKONQ_TESTS_EXPORT WebSnap : public QObject
{
Q_OBJECT
public:
- WebSnap(const QUrl &url);
- ~WebSnap();
-
- QPixmap previewImage();
- static QPixmap renderPreview(const QWebPage &page, int w, int h);
-
- QString snapTitle();
- QUrl snapUrl();
+ /**
+ * Creates a WebSnap object. It will load the url in one WebPage
+ * and snap an image from it.
+ *
+ * @param url the url to load
+ * @param parent the object parent
+ */
+ explicit WebSnap(const KUrl &url, QObject *parent = 0);
+
+ /**
+ * Snaps a pixmap of size w * h from a page and save it to cache
+ *
+ * @param page the page to snap
+ * @param w the image width
+ * @param h the image height
+ *
+ * @return the pixmap snapped from the page
+ */
+ static QPixmap renderPreview(const QWebPage &page, int w = WIDTH, int h = HEIGHT);
+
+ /**
+ * Guess the local path where the image for the url provided
+ * should be
+ *
+ * @param url the url to guess snap path
+ *
+ * @return the local path of the url snap
+ */
+ static QString imagePathFromUrl(const KUrl &url);
+
+ /**
+ * Determines if a snap exists for that url
+ *
+ */
+ static bool existsImage(const KUrl &url);
-signals:
- void finished();
private slots:
+ void saveResult(bool ok = true);
void load();
- void saveResult(bool ok);
+
+signals:
+ void snapDone(bool ok);
private:
QWebPage m_page;
- QPixmap m_image;
-
- QUrl m_url;
- QString m_snapTitle;
+ KUrl m_url;
};
#endif // WEB_SNAP_H
diff --git a/src/websslinfo.cpp b/src/websslinfo.cpp
new file mode 100644
index 00000000..35112504
--- /dev/null
+++ b/src/websslinfo.cpp
@@ -0,0 +1,214 @@
+/*
+ * This file is part of the KDE project.
+ *
+ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "websslinfo.h"
+
+#include <QtCore/QVariant>
+
+
+class WebSslInfo::WebSslInfoPrivate
+{
+public:
+ WebSslInfoPrivate()
+ : usedCipherBits(0), supportedCipherBits(0) {}
+
+ QUrl url;
+ QString ciphers;
+ QString protocol;
+ QString certErrors;
+ QHostAddress peerAddress;
+ QHostAddress parentAddress;
+ QList<QSslCertificate> certificateChain;
+
+ int usedCipherBits;
+ int supportedCipherBits;
+};
+
+WebSslInfo::WebSslInfo()
+ : d(new WebSslInfo::WebSslInfoPrivate)
+{
+}
+
+WebSslInfo::WebSslInfo(const WebSslInfo& other)
+ : d(new WebSslInfo::WebSslInfoPrivate)
+{
+ *this = other;
+}
+
+WebSslInfo::~WebSslInfo()
+{
+ delete d;
+ d = 0;
+}
+
+bool WebSslInfo::isValid() const
+{
+ return !d->peerAddress.isNull();
+}
+
+QUrl WebSslInfo::url() const
+{
+ return d->url;
+}
+
+QHostAddress WebSslInfo::parentAddress() const
+{
+ return d->parentAddress;
+}
+
+QHostAddress WebSslInfo::peerAddress() const
+{
+ return d->peerAddress;
+}
+
+QString WebSslInfo::protocol() const
+{
+ return d->protocol;
+}
+
+QString WebSslInfo::ciphers() const
+{
+ return d->ciphers;
+}
+
+QString WebSslInfo::certificateErrors() const
+{
+ return d->certErrors;
+}
+
+int WebSslInfo::supportedChiperBits() const
+{
+ return d->supportedCipherBits;
+}
+
+int WebSslInfo::usedChiperBits() const
+{
+ return d->usedCipherBits;
+}
+
+QList<QSslCertificate> WebSslInfo::certificateChain() const
+{
+ return d->certificateChain;
+}
+
+WebSslInfo& WebSslInfo::operator=(const WebSslInfo & other)
+{
+ d->ciphers = other.d->ciphers;
+ d->protocol = other.d->protocol;
+ d->certErrors = other.d->certErrors;
+ d->peerAddress = other.d->peerAddress;
+ d->parentAddress = other.d->parentAddress;
+ d->certificateChain = other.d->certificateChain;
+
+ d->usedCipherBits = other.d->usedCipherBits;
+ d->supportedCipherBits = other.d->supportedCipherBits;
+ d->url = other.d->url;
+
+ return *this;
+}
+
+QVariant WebSslInfo::toMetaData() const
+{
+ if (isValid())
+ {
+ QMap<QString, QVariant> data;
+ data.insert("ssl_in_use", true);
+ data.insert("ssl_peer_ip", d->peerAddress.toString());
+ data.insert("ssl_parent_ip", d->parentAddress.toString());
+ data.insert("ssl_protocol_version", d->protocol);
+ data.insert("ssl_cipher", d->ciphers);
+ data.insert("ssl_cert_errors", d->certErrors);
+ data.insert("ssl_cipher_used_bits", d->usedCipherBits);
+ data.insert("ssl_cipher_bits", d->supportedCipherBits);
+ QByteArray certChain;
+ Q_FOREACH(const QSslCertificate& cert, d->certificateChain)
+ certChain += cert.toPem();
+ data.insert("ssl_peer_chain", certChain);
+ return data;
+ }
+
+ return QVariant();
+}
+
+void WebSslInfo::fromMetaData(const QVariant& value)
+{
+ if (value.isValid() && value.type() == QVariant::Map)
+ {
+ QMap<QString, QVariant> metaData = value.toMap();
+ if (metaData.value("ssl_in_use", false).toBool())
+ {
+ setCertificateChain(metaData.value("ssl_peer_chain").toByteArray());
+ setPeerAddress(metaData.value("ssl_peer_ip").toString());
+ setParentAddress(metaData.value("ssl_parent_ip").toString());
+ setProtocol(metaData.value("ssl_protocol_version").toString());
+ setCiphers(metaData.value("ssl_cipher").toString());
+ setCertificateErrors(metaData.value("ssl_cert_errors").toString());
+ setUsedCipherBits(metaData.value("ssl_cipher_used_bits").toString());
+ setSupportedCipherBits(metaData.value("ssl_cipher_bits").toString());
+ }
+ }
+}
+
+void WebSslInfo::setUrl(const QUrl &url)
+{
+ d->url = url;
+}
+
+void WebSslInfo::setPeerAddress(const QString& address)
+{
+ d->peerAddress = address;
+}
+
+void WebSslInfo::setParentAddress(const QString& address)
+{
+ d->parentAddress = address;
+}
+
+void WebSslInfo::setProtocol(const QString& protocol)
+{
+ d->protocol = protocol;
+}
+
+void WebSslInfo::setCertificateChain(const QByteArray& chain)
+{
+ d->certificateChain = QSslCertificate::fromData(chain);
+}
+
+void WebSslInfo::setCiphers(const QString& ciphers)
+{
+ d->ciphers = ciphers;
+}
+
+void WebSslInfo::setUsedCipherBits(const QString& bits)
+{
+ d->usedCipherBits = bits.toInt();
+}
+
+void WebSslInfo::setSupportedCipherBits(const QString& bits)
+{
+ d->supportedCipherBits = bits.toInt();
+}
+
+void WebSslInfo::setCertificateErrors(const QString& certErrors)
+{
+ d->certErrors = certErrors;
+}
diff --git a/src/websslinfo.h b/src/websslinfo.h
new file mode 100644
index 00000000..4ac708cc
--- /dev/null
+++ b/src/websslinfo.h
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the KDE project.
+ *
+ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef WEBSSLINFO_H
+#define WEBSSLINFO_H
+
+#include <kdemacros.h>
+
+#include <QtCore/QUrl>
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtNetwork/QHostAddress>
+#include <QtNetwork/QSslCertificate>
+
+
+class WebSslInfo
+{
+public:
+ WebSslInfo();
+ WebSslInfo(const WebSslInfo&);
+ virtual ~WebSslInfo();
+
+ bool isValid() const;
+ QUrl url() const;
+ QHostAddress peerAddress() const;
+ QHostAddress parentAddress() const;
+ QString ciphers() const;
+ QString protocol() const;
+ QString certificateErrors() const;
+ int supportedChiperBits() const;
+ int usedChiperBits() const;
+ QList<QSslCertificate> certificateChain() const;
+
+ QVariant toMetaData() const;
+ void fromMetaData(const QVariant &);
+
+ void setUrl(const QUrl &url);
+ WebSslInfo& operator = (const WebSslInfo&);
+
+protected:
+ void setCiphers(const QString& ciphers);
+ void setProtocol(const QString& protocol);
+ void setPeerAddress(const QString& address);
+ void setParentAddress(const QString& address);
+ void setCertificateChain(const QByteArray& chain);
+ void setCertificateErrors(const QString& certErrors);
+ void setUsedCipherBits(const QString& bits);
+ void setSupportedCipherBits(const QString& bits);
+
+private:
+ class WebSslInfoPrivate;
+ WebSslInfoPrivate* d;
+};
+
+#endif // WEBSSLINFO_H
diff --git a/src/webtab.cpp b/src/webtab.cpp
index b1f2cdfc..e03fb72f 100644
--- a/src/webtab.cpp
+++ b/src/webtab.cpp
@@ -2,8 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -39,6 +39,8 @@
#include "webpage.h"
#include "bookmarksmanager.h"
#include "walletbar.h"
+#include "previewselectorbar.h"
+#include "rsswidget.h"
// KDE Includes
#include <KService>
@@ -48,73 +50,94 @@
#include <KActionMenu>
#include <KWebView>
#include <kwebwallet.h>
+#include <KDE/KMessageBox>
// Qt Includes
-#include <QContextMenuEvent>
-#include <QWheelEvent>
-#include <QMouseEvent>
-#include <QClipboard>
-#include <QKeyEvent>
-#include <QAction>
-#include <QVBoxLayout>
-
-
-WebTab::WebTab(QWidget* parent)
- : QWidget(parent)
- , m_view( new WebView(this) )
- , m_progress(0)
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QWheelEvent>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QClipboard>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QVBoxLayout>
+
+
+WebTab::WebTab(QWidget *parent)
+ : QWidget(parent)
+ , m_progress(0)
{
- QVBoxLayout* l = new QVBoxLayout(this);
+ QVBoxLayout *l = new QVBoxLayout(this);
l->setMargin(0);
l->setSpacing(0);
- QWidget* messageBar = new QWidget(this);
+ QWidget *messageBar = new QWidget(this);
l->addWidget(messageBar);
- messageBar->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum);
+ messageBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
- QVBoxLayout* l2 = new QVBoxLayout(messageBar);
+ QVBoxLayout *l2 = new QVBoxLayout(messageBar);
l2->setMargin(0);
l2->setSpacing(0);
- l->addWidget(m_view);
- m_view->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
-
- KWebWallet *wallet = page()->wallet();
-
- if(wallet)
+ WebView *view = new WebView(this);
+ l->addWidget(view);
+ view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ // fix focus handling
+ setFocusProxy(view);
+
+ KWebWallet *wallet = view->page()->wallet();
+
+ if (wallet)
{
connect(wallet, SIGNAL(saveFormDataRequested(const QString &, const QUrl &)),
this, SLOT(createWalletBar(const QString &, const QUrl &)));
}
- connect(page(), SIGNAL(statusBarMessage(const QString&)), this, SLOT(setStatusBarText(const QString&)));
-
- connect(m_view, SIGNAL(loadProgress(int)), this, SLOT(updateProgress(int)));
- connect(m_view, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
+ connect(view, SIGNAL(loadProgress(int)), this, SLOT(updateProgress(int)));
+ connect(view, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));
}
WebTab::~WebTab()
{
- delete m_view;
}
WebView *WebTab::view()
{
- return m_view;
+ WebView *view = qobject_cast<WebView *>(layout()->itemAt(1)->widget());
+ return view;
}
WebPage *WebTab::page()
{
- return m_view->page(); // FIXME
+ return view()->page();
}
-KUrl WebTab::url() const
-{
- return KUrl(m_view->url());
+// TODO:
+// Import the "about" check and the one in protocolhandler
+// in some (static?) methods in NewTabPage
+KUrl WebTab::url()
+{
+ KUrl u = KUrl(view()->url());
+ if (u.scheme() == QL1S("about"))
+ {
+ QWebElement rootElement = page()->mainFrame()->documentElement();
+ if (rootElement.document().findAll("#rekonq-newtabpage").count() == 0)
+ return u;
+ if (rootElement.findAll(".favorites").count() > 0)
+ return KUrl("about:favorites");
+ if (rootElement.findAll(".closedTabs").count() > 0)
+ return KUrl("about:closedTabs");
+ if (rootElement.findAll(".history").count() > 0)
+ return KUrl("about:history");
+ if (rootElement.findAll(".bookmarks").count() > 0)
+ return KUrl("about:bookmarks");
+ if (rootElement.findAll(".downloads").count() > 0)
+ return KUrl("about:downloads");
+ }
+ return u;
}
@@ -124,18 +147,6 @@ int WebTab::progress()
}
-QString WebTab::lastStatusBarText() const
-{
- return m_statusBarText;
-}
-
-
-void WebTab::setStatusBarText(const QString &string)
-{
- m_statusBarText = string;
-}
-
-
void WebTab::updateProgress(int p)
{
m_progress = p;
@@ -149,12 +160,18 @@ void WebTab::loadFinished(bool)
void WebTab::createWalletBar(const QString &key, const QUrl &url)
-{
+{
+ // check if the url is in the wallet blacklist
+ QString urlString = url.toString();
+ QStringList blackList = ReKonfig::walletBlackList();
+ if (blackList.contains(urlString))
+ return;
+
KWebWallet *wallet = page()->wallet();
QWidget *messageBar = layout()->itemAt(0)->widget();
WalletBar *walletBar = new WalletBar(messageBar);
- walletBar->onSaveFormData(key,url);
+ walletBar->onSaveFormData(key, url);
messageBar->layout()->addWidget(walletBar);
connect(walletBar, SIGNAL(saveFormDataAccepted(const QString &)),
@@ -162,3 +179,63 @@ void WebTab::createWalletBar(const QString &key, const QUrl &url)
connect(walletBar, SIGNAL(saveFormDataRejected(const QString &)),
wallet, SLOT(rejectSaveFormDataRequest(const QString &)));
}
+
+
+void WebTab::createPreviewSelectorBar(int index)
+{
+ QWidget *messageBar = layout()->itemAt(0)->widget();
+ PreviewSelectorBar *bar = new PreviewSelectorBar(index, messageBar);
+ messageBar->layout()->addWidget(bar);
+
+ connect(page(), SIGNAL(loadStarted()), bar, SLOT(loadProgress()));
+ connect(page(), SIGNAL(loadProgress(int)), bar, SLOT(loadProgress()));
+ connect(page(), SIGNAL(loadFinished(bool)), bar, SLOT(loadFinished()));
+ connect(page()->mainFrame(), SIGNAL(urlChanged(QUrl)), bar, SLOT(verifyUrl()));
+}
+
+
+bool WebTab::hasRSSInfo()
+{
+ QWebElementCollection col = page()->mainFrame()->findAllElements("link[type=\"application/rss+xml\"]");
+ col.append(page()->mainFrame()->findAllElements("link[type=\"application/atom+xml\"]"));
+ if (col.count() != 0)
+ return true;
+
+ return false;
+}
+
+
+void WebTab::showRSSInfo(QPoint pos)
+{
+ QWebElementCollection col = page()->mainFrame()->findAllElements("link[type=\"application/rss+xml\"]");
+ col.append(page()->mainFrame()->findAllElements("link[type=\"application/atom+xml\"]"));
+
+ QMap<KUrl, QString> map;
+ int i = 0;
+ foreach(QWebElement el, col)
+ {
+ QString urlString;
+ if (el.attribute("href").startsWith(QL1S("http")))
+ urlString = el.attribute("href");
+ else
+ {
+ KUrl u = url();
+ // NOTE
+ // cd() is probably better than setPath() here,
+ // for all those url sites just having a path
+ if (u.cd(el.attribute("href")))
+ urlString = u.toMimeDataString();
+ }
+
+ QString title = el.attribute("title");
+ if (title.isEmpty())
+ title = el.attribute("href");
+
+ map.insert(KUrl(urlString), title);
+
+ i++;
+ }
+
+ RSSWidget *widget = new RSSWidget(map, window());
+ widget->showAt(pos);
+}
diff --git a/src/webtab.h b/src/webtab.h
index ecf8e5b3..10b8fe94 100644
--- a/src/webtab.h
+++ b/src/webtab.h
@@ -2,8 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -29,16 +29,21 @@
#define WEBTAB_H
+// Rekonq Includes
+#include "rekonq_defines.h"
+
// KDE Includes
#include <KUrl>
-#include <KWebView>
+
+// Qt Includes
+#include <QWidget>
// Forward Declarations
class WebPage;
class WebView;
-class WebTab : public QWidget
+class REKONQ_TESTS_EXPORT WebTab : public QWidget
{
Q_OBJECT
@@ -48,21 +53,22 @@ public:
WebView *view();
WebPage *page();
- KUrl url() const;
- QString lastStatusBarText() const;
+ KUrl url();
+
int progress();
+ void createPreviewSelectorBar(int index);
+
+ bool hasRSSInfo();
private slots:
- void setStatusBarText(const QString &string);
void updateProgress(int progress);
void loadFinished(bool);
void createWalletBar(const QString &, const QUrl &);
-
+ void showRSSInfo(QPoint pos);
+
private:
- WebView *const m_view;
int m_progress;
- QString m_statusBarText;
};
#endif
diff --git a/src/webview.cpp b/src/webview.cpp
index 3936ed3c..e7226740 100644
--- a/src/webview.cpp
+++ b/src/webview.cpp
@@ -2,8 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -37,6 +37,7 @@
#include "mainview.h"
#include "webpage.h"
#include "bookmarksmanager.h"
+#include "searchengine.h"
// KDE Includes
#include <KService>
@@ -47,45 +48,64 @@
#include <ktoolinvocation.h>
// Qt Includes
-#include <QContextMenuEvent>
-#include <QWheelEvent>
-#include <QMouseEvent>
-#include <QClipboard>
-#include <QKeyEvent>
-#include <QAction>
-#include <QLayout>
+#include <QtCore/QDir>
+
+#include <QtGui/QAction>
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QWheelEvent>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QClipboard>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QLayout>
+
#include <QtDBus/QDBusConnectionInterface>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusReply>
-#include <QDir>
WebView::WebView(QWidget* parent)
- : KWebView(parent, false)
- , m_page( new WebPage(this) )
- , m_mousePos(QPoint(0,0))
+ : KWebView(parent, false)
+ , _mousePos(QPoint(0, 0))
+ , _scrollTimer(new QTimer(this))
+ , _VScrollSpeed(0)
+ , _HScrollSpeed(0)
+ , _canEnableAutoScroll(true)
+ , _isAutoScrollEnabled(false)
{
- setPage(m_page);
+ WebPage *page = new WebPage(this);
+ setPage(page);
// download system
- connect(this, SIGNAL(linkShiftClicked(const KUrl &)),
- m_page, SLOT(downloadUrl(const KUrl &)));
- connect(m_page, SIGNAL(downloadRequested(const QNetworkRequest &)),
- m_page, SLOT(downloadRequest(const QNetworkRequest &)));
-
+ connect(this, SIGNAL(linkShiftClicked(const KUrl &)),
+ page, SLOT(downloadUrl(const KUrl &)));
+ connect(page, SIGNAL(downloadRequested(const QNetworkRequest &)),
+ page, SLOT(downloadRequest(const QNetworkRequest &)));
+
// middle click || ctrl + click signal
- connect(this, SIGNAL(linkMiddleOrCtrlClicked(const KUrl &)),
- this, SLOT(loadUrlInNewTab(const KUrl &)) );
+ connect(this, SIGNAL(linkMiddleOrCtrlClicked(const KUrl &)),
+ this, SLOT(loadUrlInNewTab(const KUrl &)));
// loadUrl signal
- connect(this, SIGNAL(loadUrl(const KUrl &, const Rekonq::OpenType &)),
+ connect(this, SIGNAL(loadUrl(const KUrl &, const Rekonq::OpenType &)),
Application::instance(), SLOT(loadUrl(const KUrl &, const Rekonq::OpenType &)));
+
+ // scrolling timer
+ connect(_scrollTimer, SIGNAL(timeout()), this, SLOT(scrollFrameChanged()));
+ _scrollTimer->setInterval(100);
}
WebView::~WebView()
{
- disconnect();
+ delete _scrollTimer;
+ disconnect();
+}
+
+
+WebPage *WebView::page()
+{
+ WebPage *page = qobject_cast<WebPage *>(KWebView::page());
+ return page;
}
@@ -111,7 +131,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
connect(a, SIGNAL(triggered(bool)), this, SLOT(openLinkInNewWindow()));
menu.addAction(a);
- menu.addAction(pageAction(KWebPage::DownloadLinkToDisk));
+ menu.addAction(pageAction(KWebPage::DownloadLinkToDisk));
menu.addAction(pageAction(KWebPage::CopyLinkToClipboard));
menu.addSeparator();
}
@@ -124,10 +144,10 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
}
// is content selected) Add COPY
- if(result.isContentSelected())
+ if (result.isContentSelected())
{
a = pageAction(KWebPage::Copy);
- if(!result.linkUrl().isEmpty())
+ if (!result.linkUrl().isEmpty())
a->setText(i18n("Copy Text")); //for link
else
a->setText(i18n("Copy"));
@@ -135,41 +155,23 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
}
// is content editable? Add PASTE
- if(result.isContentEditable())
+ if (result.isContentEditable())
{
menu.addAction(pageAction(KWebPage::Paste));
}
// is content selected? Add SEARCH actions
- if(result.isContentSelected())
+ if (result.isContentSelected())
{
KActionMenu *searchMenu = new KActionMenu(KIcon("edit-find"), i18n("Search with"), this);
- KConfig config("kuriikwsfilterrc"); //Share with konqueror
- KConfigGroup cg = config.group("General");
- QStringList favoriteEngines;
- favoriteEngines << "wikipedia" << "google"; //defaults
- favoriteEngines = cg.readEntry("FavoriteSearchEngines", favoriteEngines);
- QString keywordDelimiter = cg.readEntry("KeywordDelimiter", ":");
- KService::Ptr service;
- KUriFilterData data;
-
- Q_FOREACH(const QString &engine, favoriteEngines)
+ foreach(KService::Ptr engine, SearchEngine::favorites())
{
- if(!engine.isEmpty())
- {
- service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine));
- if(service)
- {
- const QString searchProviderPrefix = *(service->property("Keys").toStringList().begin()) + keywordDelimiter;
- data.setData(searchProviderPrefix + "some keyword");
- a = new KAction(service->name(), this);
- a->setIcon(Application::icon(KUrl(data.uri())));
- a->setData(searchProviderPrefix);
- connect(a, SIGNAL(triggered(bool)), this, SLOT(search()));
- searchMenu->addAction(a);
- }
- }
+ a = new KAction(engine->name(), this);
+ a->setIcon(Application::icon(SearchEngine::buildQuery(engine, "")));
+ a->setData(engine->entryPath());
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(search()));
+ searchMenu->addAction(a);
}
if (!searchMenu->menu()->isEmpty())
@@ -178,7 +180,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
}
menu.addSeparator();
- // TODO Add translate, show translation
+ // TODO Add translate, show translation
}
// is an image?
@@ -186,7 +188,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
{
menu.addSeparator();
- // TODO remove copy_this_image action
+ // TODO remove copy_this_image action
a = new KAction(KIcon("view-media-visualization"), i18n("&View Image"), this);
a->setData(result.imageUrl());
connect(a, SIGNAL(triggered(Qt::MouseButtons, Qt::KeyboardModifiers)), this, SLOT(viewImage(Qt::MouseButtons, Qt::KeyboardModifiers)));
@@ -198,13 +200,13 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
}
// Open url text in new tab/window
- if(result.linkUrl().isEmpty())
+ if (result.linkUrl().isEmpty())
{
- QString text = selectedText();
- if (text.startsWith( QLatin1String("http://") )
- || text.startsWith( QLatin1String("https://") )
- || text.startsWith( QLatin1String("www.") )
+ QString text = selectedText();
+ if (text.startsWith(QL1S("http://"))
+ || text.startsWith(QL1S("https://"))
+ || text.startsWith(QL1S("www."))
)
{
QString truncatedURL = text;
@@ -237,23 +239,23 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
// navigation
QWebHistory *history = page()->history();
- if(history->canGoBack())
+ if (history->canGoBack())
{
menu.addAction(pageAction(KWebPage::Back));
}
- if(history->canGoForward())
+ if (history->canGoForward())
{
menu.addAction(pageAction(KWebPage::Forward));
}
menu.addAction(mainwindow->actionByName("view_redisplay"));
- if( result.pixmap().isNull() )
+ if (result.pixmap().isNull())
{
menu.addSeparator();
- menu.addAction(mainwindow->actionByName("new_tab"));
+ menu.addAction(mainwindow->actionByName("new_tab"));
menu.addAction(mainwindow->actionByName("new_window"));
menu.addSeparator();
@@ -263,14 +265,14 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
frameMenu->addAction(pageAction(KWebPage::OpenFrameInNewWindow));
- a = new KAction( KIcon("document-print-frame"), i18n("Print Frame"), this);
+ a = new KAction(KIcon("document-print-frame"), i18n("Print Frame"), this);
connect(a, SIGNAL(triggered()), this, SLOT(printFrame()));
frameMenu->addAction(a);
menu.addAction(frameMenu);
-
+
menu.addSeparator();
-
+
// Page Actions
menu.addAction(pageAction(KWebPage::SelectAll));
@@ -278,22 +280,22 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
if (ReKonfig::kgetList())
{
- a = new KAction(KIcon("kget"), i18n("List all links"), this);
+ a = new KAction(KIcon("kget"), i18n("List All Links"), this);
connect(a, SIGNAL(triggered(bool)), page(), SLOT(downloadAllContentsWithKGet()));
menu.addAction(a);
}
menu.addAction(mainwindow->actionByName("page_source"));
-
- a = new KAction( KIcon("layer-visible-on"), i18n("Inspect Element"), this);
+
+ a = new KAction(KIcon("layer-visible-on"), i18n("Inspect Element"), this);
connect(a, SIGNAL(triggered(bool)), this, SLOT(inspect()));
menu.addAction(a);
-
+
a = Application::bookmarkProvider()->actionByName("rekonq_add_bookmark");
menu.addAction(a);
}
- if(mainwindow->isFullScreen())
+ if (mainwindow->isFullScreen())
{
menu.addSeparator();
menu.addAction(mainwindow->actionByName("fullscreen"));
@@ -306,33 +308,69 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
void WebView::mousePressEvent(QMouseEvent *event)
{
- switch(event->button())
+ if (_isAutoScrollEnabled)
+ {
+ setCursor(Qt::ArrowCursor);
+ _VScrollSpeed = 0;
+ _HScrollSpeed = 0;
+ _scrollTimer->stop();
+ _isAutoScrollEnabled = false;
+ return;
+ }
+
+ QWebHitTestResult result = page()->mainFrame()->hitTestContent(event->pos());
+ _canEnableAutoScroll = !result.isContentEditable() && result.linkUrl().isEmpty();
+
+ switch (event->button())
{
- case Qt::XButton1:
+ case Qt::XButton1:
triggerPageAction(KWebPage::Back);
break;
- case Qt::XButton2:
+
+ case Qt::XButton2:
triggerPageAction(KWebPage::Forward);
break;
- default:
- KWebView::mousePressEvent(event);
+
+ case Qt::MidButton:
+ if (_canEnableAutoScroll && !_isAutoScrollEnabled)
+ {
+ setCursor(KIcon("transform-move").pixmap(32));
+ _clickPos = event->pos();
+ _isAutoScrollEnabled = true;
+ }
+ break;
+
+ default:
break;
};
+ KWebView::mousePressEvent(event);
}
void WebView::mouseMoveEvent(QMouseEvent *event)
{
- m_mousePos = event->pos();
+ _mousePos = event->pos();
+
+ if (_isAutoScrollEnabled)
+ {
+ QPoint r = _mousePos - _clickPos;
+ _HScrollSpeed = r.x() / 2; // you are too fast..
+ _VScrollSpeed = r.y() / 2;
+ if (!_scrollTimer->isActive())
+ _scrollTimer->start();
+
+ return;
+ }
+
if (Application::instance()->mainWindow()->isFullScreen())
- {
- if (event->pos().y()>=0 && event->pos().y()<=4)
+ {
+ if (event->pos().y() >= 0 && event->pos().y() <= 4)
{
- Application::instance()->mainWindow()->setWidgetsVisible(true);
+ Application::instance()->mainWindow()->setWidgetsVisible(true);
}
else
{
- Application::instance()->mainWindow()->setWidgetsVisible(false);
+ Application::instance()->mainWindow()->setWidgetsVisible(false);
}
}
KWebView::mouseMoveEvent(event);
@@ -341,16 +379,16 @@ void WebView::mouseMoveEvent(QMouseEvent *event)
QPoint WebView::mousePos()
{
- return m_mousePos;
+ return _mousePos;
}
void WebView::search()
{
KAction *a = qobject_cast<KAction*>(sender());
- QString search = a->data().toString() + selectedText();
- KUrl urlSearch = KUrl::fromEncoded(search.toUtf8());
-
+ KService::Ptr engine = KService::serviceByDesktopPath(a->data().toString());
+ KUrl urlSearch = KUrl(SearchEngine::buildQuery(engine, selectedText()));
+
emit loadUrl(urlSearch, Rekonq::NewCurrentTab);
}
@@ -381,7 +419,7 @@ void WebView::openLinkInNewWindow()
{
KAction *a = qobject_cast<KAction*>(sender());
KUrl url(a->data().toUrl());
-
+
emit loadUrl(url, Rekonq::NewWindow);
}
@@ -390,25 +428,80 @@ void WebView::openLinkInNewTab()
{
KAction *a = qobject_cast<KAction*>(sender());
KUrl url(a->data().toUrl());
-
+
emit loadUrl(url, Rekonq::SettingOpenTab);
}
void WebView::keyPressEvent(QKeyEvent *event)
{
- if ((event->modifiers() == Qt::ControlModifier) && (event->key() == Qt::Key_C))
+ if (event->modifiers() == Qt::ControlModifier)
{
- triggerPageAction(KWebPage::Copy);
- return;
+ if (event->key() == Qt::Key_C)
+ {
+ triggerPageAction(KWebPage::Copy);
+ return;
+ }
+
+ if (event->key() == Qt::Key_A)
+ {
+ triggerPageAction(KWebPage::SelectAll);
+ return;
+ }
}
- if ((event->modifiers() == Qt::ControlModifier) && (event->key() == Qt::Key_A))
+ if (!_canEnableAutoScroll)
{
- triggerPageAction(KWebPage::SelectAll);
+ KWebView::keyPressEvent(event);
return;
}
-
+
+ // Auto Scrolling
+ if (event->modifiers() == Qt::ShiftModifier)
+ {
+ if (event->key() == Qt::Key_Up)
+ {
+ _VScrollSpeed--;
+ if (!_scrollTimer->isActive())
+ _scrollTimer->start();
+ return;
+ }
+
+ if (event->key() == Qt::Key_Down)
+ {
+ _VScrollSpeed++;
+ if (!_scrollTimer->isActive())
+ _scrollTimer->start();
+ return;
+ }
+
+ if (event->key() == Qt::Key_Right)
+ {
+ _HScrollSpeed++;
+ if (!_scrollTimer->isActive())
+ _scrollTimer->start();
+ return;
+ }
+
+ if (event->key() == Qt::Key_Left)
+ {
+ _HScrollSpeed--;
+ if (!_scrollTimer->isActive())
+ _scrollTimer->start();
+ return;
+ }
+
+ if (_scrollTimer->isActive())
+ {
+ _scrollTimer->stop();
+ }
+ else
+ {
+ if (_VScrollSpeed || _HScrollSpeed)
+ _scrollTimer->start();
+ }
+ }
+
KWebView::keyPressEvent(event);
}
@@ -416,8 +509,9 @@ void WebView::keyPressEvent(QKeyEvent *event)
void WebView::inspect()
{
QAction *a = Application::instance()->mainWindow()->actionByName("web_inspector");
- if(a && !a->isChecked())
+ if (a && !a->isChecked())
a->trigger();
+ pageAction(QWebPage::InspectElement)->trigger();
}
@@ -425,3 +519,19 @@ void WebView::loadUrlInNewTab(const KUrl &url)
{
emit loadUrl(url, Rekonq::SettingOpenTab);
}
+
+
+void WebView::scrollFrameChanged()
+{
+ // do the scrolling
+ page()->currentFrame()->scroll(_HScrollSpeed, _VScrollSpeed);
+
+ // check if we reached the end
+ int y = page()->currentFrame()->scrollPosition().y();
+ if (y == 0 || y == page()->currentFrame()->scrollBarMaximum(Qt::Vertical))
+ _VScrollSpeed = 0;
+
+ int x = page()->currentFrame()->scrollPosition().x();
+ if (x == 0 || x == page()->currentFrame()->scrollBarMaximum(Qt::Horizontal))
+ _HScrollSpeed = 0;
+}
diff --git a/src/webview.h b/src/webview.h
index 263b2ec4..71e3047f 100644
--- a/src/webview.h
+++ b/src/webview.h
@@ -2,8 +2,8 @@
*
* This file is a part of the rekonq project
*
-* Copyright (C) 2008-2009 by Andrea Diamantini <adjam7 at gmail dot com>
-* Copyright (C) 2009 by Lionel Chauvin <megabigbug@yahoo.fr>
+* Copyright (C) 2008-2010 by Andrea Diamantini <adjam7 at gmail dot com>
+* Copyright (C) 2009-2010 by Lionel Chauvin <megabigbug@yahoo.fr>
*
*
* This program is free software; you can redistribute it and/or
@@ -11,9 +11,9 @@
* 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
+* 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
@@ -28,8 +28,9 @@
#ifndef WEBVIEW_H
#define WEBVIEW_H
-// Local Includes
-#include "application.h"
+
+// Rekonq Includes
+#include "rekonq_defines.h"
// KDE Includes
#include <KWebView>
@@ -38,7 +39,7 @@
class WebPage;
-class WebView : public KWebView
+class REKONQ_TESTS_EXPORT WebView : public KWebView
{
Q_OBJECT
@@ -46,12 +47,12 @@ public:
explicit WebView(QWidget *parent);
~WebView();
- WebPage *page() { return m_page; }
+ WebPage *page();
QPoint mousePos();
protected:
void contextMenuEvent(QContextMenuEvent *event);
- void mousePressEvent(QMouseEvent *event);// need to be ported
+ void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
@@ -63,16 +64,24 @@ private slots:
void loadUrlInNewTab(const KUrl &);
void openLinkInNewWindow();
void openLinkInNewTab();
-
+
void viewImage(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers);
void inspect();
+ void scrollFrameChanged();
+
signals:
void loadUrl(const KUrl &, const Rekonq::OpenType &);
-
+
private:
- WebPage *const m_page;
- QPoint m_mousePos;
+ QPoint _mousePos;
+ QPoint _clickPos;
+
+ QTimer *_scrollTimer;
+ int _VScrollSpeed;
+ int _HScrollSpeed;
+ bool _canEnableAutoScroll;
+ bool _isAutoScrollEnabled;
};
#endif