summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt26
-rw-r--r--src/Messages.sh2
-rw-r--r--src/adblock/adblockmanager.cpp259
-rw-r--r--src/adblock/adblockmanager.h26
-rw-r--r--src/adblock/adblocknetworkreply.cpp4
-rw-r--r--src/adblock/adblocknetworkreply.h7
-rw-r--r--src/adblock/adblockrule.cpp8
-rw-r--r--src/adblock/adblockrule.h7
-rw-r--r--src/application.cpp200
-rw-r--r--src/application.h28
-rw-r--r--src/bookmarks/bookmarkcontextmenu.cpp325
-rw-r--r--src/bookmarks/bookmarkcontextmenu.h65
-rw-r--r--src/bookmarks/bookmarksmanager.cpp278
-rw-r--r--src/bookmarks/bookmarksmanager.h44
-rw-r--r--src/bookmarks/bookmarkspanel.cpp146
-rw-r--r--src/bookmarks/bookmarkspanel.h30
-rw-r--r--src/bookmarks/bookmarksproxy.cpp1
-rw-r--r--src/bookmarks/bookmarksproxy.h16
-rw-r--r--src/bookmarks/bookmarkstreemodel.cpp284
-rw-r--r--src/bookmarks/bookmarkstreemodel.h64
-rw-r--r--src/cleardata.ui48
-rw-r--r--src/clicktoflash.cpp132
-rw-r--r--src/clicktoflash.h91
-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.desktop32
-rw-r--r--src/data/top.pngbin786 -> 0 bytes
-rw-r--r--src/data/webkit-icon.pngbin25694 -> 8121 bytes
-rw-r--r--src/filterurljob.cpp14
-rw-r--r--src/filterurljob.h3
-rw-r--r--src/findbar.cpp81
-rw-r--r--src/findbar.h26
-rw-r--r--src/history/autosaver.cpp6
-rw-r--r--src/history/autosaver.h7
-rw-r--r--src/history/historymanager.cpp95
-rw-r--r--src/history/historymanager.h41
-rw-r--r--src/history/historymodels.cpp10
-rw-r--r--src/history/historymodels.h7
-rw-r--r--src/history/historypanel.cpp96
-rw-r--r--src/history/historypanel.h17
-rw-r--r--src/main.cpp16
-rw-r--r--src/mainview.cpp233
-rw-r--r--src/mainview.h20
-rw-r--r--src/mainwindow.cpp334
-rw-r--r--src/mainwindow.h35
-rw-r--r--src/networkaccessmanager.cpp43
-rw-r--r--src/networkaccessmanager.h14
-rw-r--r--src/newtabpage.cpp596
-rw-r--r--src/newtabpage.h (renamed from src/rekonqpage/newtabpage.h)72
-rw-r--r--src/paneltreeview.cpp196
-rw-r--r--src/paneltreeview.h69
-rw-r--r--src/previewimage.cpp430
-rw-r--r--src/previewimage.h101
-rw-r--r--src/previewselectorbar.cpp152
-rw-r--r--src/previewselectorbar.h66
-rw-r--r--src/protocolhandler.cpp151
-rw-r--r--src/protocolhandler.h11
-rw-r--r--src/rekonq.kcfg64
-rw-r--r--src/rekonqpage/newtabpage.cpp280
-rw-r--r--src/sessionmanager.cpp19
-rw-r--r--src/sessionmanager.h9
-rw-r--r--src/settings/adblockwidget.cpp193
-rw-r--r--src/settings/adblockwidget.h66
-rw-r--r--src/settings/networkwidget.cpp101
-rw-r--r--src/settings/networkwidget.h63
-rw-r--r--src/settings/settings_adblock.ui167
-rw-r--r--src/settings/settings_general.ui102
-rw-r--r--src/settings/settings_tabs.ui138
-rw-r--r--src/settings/settings_webkit.ui13
-rw-r--r--src/settings/settingsdialog.cpp84
-rw-r--r--src/settings/settingsdialog.h10
-rw-r--r--src/sslinfodialog_p.h107
-rw-r--r--src/tabbar.cpp97
-rw-r--r--src/tabbar.h10
-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.cpp217
-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.cpp135
-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.cpp314
-rw-r--r--src/urlbar/completionwidget.h82
-rw-r--r--src/urlbar/lineedit.cpp130
-rw-r--r--src/urlbar/lineedit.h44
-rw-r--r--src/urlbar/listitem.cpp437
-rw-r--r--src/urlbar/listitem.h221
-rw-r--r--src/urlbar/urlbar.cpp366
-rw-r--r--src/urlbar/urlbar.h53
-rw-r--r--src/urlbar/urlresolver.cpp230
-rw-r--r--src/urlbar/urlresolver.h85
-rw-r--r--src/walletbar.cpp9
-rw-r--r--src/walletbar.h11
-rw-r--r--src/webinspectorpanel.cpp6
-rw-r--r--src/webinspectorpanel.h7
-rw-r--r--src/webpage.cpp421
-rw-r--r--src/webpage.h22
-rw-r--r--src/webpluginfactory.cpp93
-rw-r--r--src/webpluginfactory.h14
-rw-r--r--src/websnap.cpp124
-rw-r--r--src/websnap.h44
-rw-r--r--src/websslinfo.cpp211
-rw-r--r--src/websslinfo.h73
-rw-r--r--src/webtab.cpp125
-rw-r--r--src/webtab.h26
-rw-r--r--src/webview.cpp163
-rw-r--r--src/webview.h23
120 files changed, 9373 insertions, 2785 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b0a3fbd8..2ab308de 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,37 +8,41 @@ 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
#----------------------------------------
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
@@ -46,6 +50,9 @@ SET( rekonq_KDEINIT_SRCS
#----------------------------------------
urlbar/urlbar.cpp
urlbar/lineedit.cpp
+ urlbar/completionwidget.cpp
+ urlbar/urlresolver.cpp
+ urlbar/listitem.cpp
)
@@ -54,6 +61,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..0a139bdc 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
@@ -28,6 +28,9 @@
#include "adblockmanager.h"
#include "adblockmanager.moc"
+// Auto Includes
+#include "rekonq.h"
+
// Local Includes
#include "adblocknetworkreply.h"
#include "webpage.h"
@@ -36,6 +39,7 @@
#include <KSharedConfig>
#include <KConfigGroup>
#include <KDebug>
+#include <KIO/TransferJob>
// Qt Includes
#include <QUrl>
@@ -46,8 +50,8 @@ AdBlockManager::AdBlockManager(QObject *parent)
: QObject(parent)
, _isAdblockEnabled(false)
, _isHideAdsEnabled(false)
+ , _index(0)
{
- loadSettings();
}
@@ -56,60 +60,95 @@ 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);
+ ReKonfig::setLastUpdate( today );
+
+ updateNextSubscription();
+ return;
+ }
- // no need to load filters if adblock is not enabled :)
- if(!_isAdblockEnabled)
- return;
+ // else
+ QStringList titles = ReKonfig::subscriptionTitles();
+ foreach(const QString &title, titles)
+ {
+ rules = rulesGroup.readEntry( title + "-rules" , QStringList() );
+ loadRules(rules);
+ }
+}
- _whiteList.clear();
- _blackList.clear();
- _hideList.clear();
+
+void AdBlockManager::loadRules(const QStringList &rules)
+{
+ foreach(const QString &stringRule, rules)
+ {
+ // ! rules are comments
+ if( stringRule.startsWith('!') )
+ continue;
+
+ // [ rules are ABP infos
+ if( stringRule.startsWith('[') )
+ continue;
- QMap<QString,QString> entryMap = cg.entryMap();
- QMap<QString,QString>::ConstIterator it;
- for( it = entryMap.constBegin(); it != entryMap.constEnd(); ++it )
+ // 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( QLatin1String("@@") ) )
{
- QString name = it.key();
- QString url = it.value();
-
- 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;
- }
- }
+ AdBlockRule rule( stringRule.mid(2) );
+ _whiteList << rule;
+ continue;
+ }
+
+ // hide (CSS) rules
+ if( stringRule.startsWith( QLatin1String("##") ) )
+ {
+ _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;
@@ -125,7 +164,9 @@ QNetworkReply *AdBlockManager::block(const QNetworkRequest &request)
{
if(filter.match(urlString))
{
- kDebug() << "****ADBLOCK: WHITE RULE (@@) Matched: ***********" << urlString;
+ kDebug() << "****ADBLOCK: WHITE RULE (@@) Matched: ***********";
+ kDebug() << "Filter exp: " << filter.pattern();
+ kDebug() << "UrlString: " << urlString;
return 0;
}
}
@@ -135,7 +176,23 @@ QNetworkReply *AdBlockManager::block(const QNetworkRequest &request)
{
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(QLatin1String("visibility"), QLatin1String("hidden"));
+ el.setStyleProperty(QLatin1String("width"), QLatin1String("0"));
+ el.setStyleProperty(QLatin1String("height"), QLatin1String("0"));
+ }
+ }
+
AdBlockNetworkReply *reply = new AdBlockNetworkReply(request, urlString, this);
return reply;
}
@@ -148,7 +205,7 @@ QNetworkReply *AdBlockManager::block(const QNetworkRequest &request)
void AdBlockManager::applyHidingRules(WebPage *page)
{
- if(!page || !page->mainFrame())
+ if(!page)
return;
if (!_isAdblockEnabled)
@@ -156,16 +213,116 @@ void AdBlockManager::applyHidingRules(WebPage *page)
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(QLatin1String("visibility"), QLatin1String("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..9b1cc915 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
@@ -105,12 +105,15 @@
// Local Includes
+#include "rekonqprivate_export.h"
#include "adblockrule.h"
// Qt Includes
#include <QObject>
#include <QNetworkReply>
#include <QStringList>
+#include <QByteArray>
+#include <KIO/Job>
// Forward Includes
class QNetworkRequest;
@@ -120,7 +123,7 @@ class WebPage;
typedef QList<AdBlockRule> AdBlockRuleList;
-class AdBlockManager : public QObject
+class REKONQ_TESTS_EXPORT AdBlockManager : public QObject
{
Q_OBJECT
@@ -128,9 +131,21 @@ 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;
@@ -139,6 +154,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..3b73b8a0 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
@@ -68,7 +68,7 @@ AdBlockNetworkReply::AdBlockNetworkReply(const QNetworkRequest &request, const Q
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..bbc3471e 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
@@ -54,6 +54,9 @@
#define ADBLOCK_NETWORK_REPLY_H
+// Local Includes
+#include "rekonqprivate_export.h"
+
// Qt Includes
#include <QNetworkReply>
#include <QString>
@@ -62,7 +65,7 @@
class AdBlockRule;
-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..c0c3fd5b 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
@@ -181,3 +181,9 @@ QString AdBlockRule::convertPatternToRegExp(const QString &wildcardPattern)
// 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..ee4825d1 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
@@ -54,6 +54,7 @@
#ifndef ADBLOCKRULE_H
#define ADBLOCKRULE_H
+
// Qt Includes
#include <QRegExp>
#include <QString>
@@ -68,7 +69,9 @@ public:
AdBlockRule(const QString &filter);
bool match(const QString &encodedUrl) const;
-
+
+ QString pattern() const;
+
private:
QString convertPatternToRegExp(const QString &wildcardPattern);
diff --git a/src/application.cpp b/src/application.cpp
index 05004f30..db6d3c32 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
@@ -53,7 +53,6 @@
#include <KToolInvocation>
#include <KUriFilter>
#include <KMessageBox>
-#include <KWindowInfo>
#include <KUrl>
#include <ThreadWeaver/Weaver>
@@ -64,10 +63,10 @@
#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()
@@ -80,27 +79,51 @@ Application::Application()
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;
- delete s_historyManager;
- delete s_sessionManager;
- delete s_adblockManager;
+ delete s_bookmarkProvider.data();
+ s_bookmarkProvider.clear();
+
+ delete s_historyManager.data();
+ s_historyManager.clear();
+
+ delete s_sessionManager.data();
+ s_sessionManager.clear();
+
+ delete s_adblockManager.data();
+ s_adblockManager.clear();
}
int Application::newInstance()
{
- KCmdLineArgs::setCwd(QDir::currentPath().toUtf8());
+ KCmdLineArgs::setCwd( QDir::currentPath().toUtf8() );
KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
-
- // we share one process for several mainwindows,
- // so initialize only once
- static bool first = true;
+
+ 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())
{
@@ -120,54 +143,34 @@ int Application::newInstance()
}
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())
- {
- kDebug() << "session restored";
- return 1;
- }
-
- // are there args? load them..
- if (args->count() > 0)
+ else
{
- // 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;
}
@@ -192,6 +195,11 @@ void Application::postLaunch()
// 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();
}
@@ -210,7 +218,7 @@ MainWindow *Application::mainWindow()
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");
- }
-
+ // 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,12 +289,9 @@ 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;
}
@@ -316,19 +323,12 @@ void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type)
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 *w = new MainWindow();
@@ -343,7 +343,7 @@ MainWindow *Application::newMainWindow()
void Application::removeMainWindow(MainWindow *window)
{
- m_mainWindows.removeAt(m_mainWindows.indexOf(window, 0));
+ m_mainWindows.removeOne(window);
}
@@ -355,11 +355,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();
}
@@ -369,9 +369,11 @@ void Application::loadResolvedUrl(ThreadWeaver::Job *job)
KUrl url = threadedJob->url();
WebView *view = threadedJob->view();
+ // Bye and thanks :)
+ delete threadedJob;
+
if (view)
{
- view->setFocus();
view->load(url);
// we are sure of the url now, let's add it to history
@@ -380,7 +382,11 @@ void Application::loadResolvedUrl(ThreadWeaver::Job *job)
if( url.protocol() == QLatin1String("http") || url.protocol() == QLatin1String("https") )
historyManager()->addHistoryEntry( url.prettyUrl() );
}
-
- // Bye and thanks :)
- delete threadedJob;
+}
+
+
+void Application::newWindow()
+{
+ loadUrl( KUrl("about:home"), Rekonq::NewWindow );
+ mainWindow()->mainView()->urlBarWidget()->setFocus();
}
diff --git a/src/application.h b/src/application.h
index 4b951ded..c268d586 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
@@ -29,6 +29,8 @@
#ifndef APPLICATION_H
#define APPLICATION_H
+// Local Includes
+#include "rekonqprivate_export.h"
// KDE Includes
#include <KUniqueApplication>
@@ -38,7 +40,7 @@
#include <ThreadWeaver/Job>
// Qt Includes
-#include <QPointer>
+#include <QWeakPointer>
#include <QList>
// Forward Declarations
@@ -52,7 +54,7 @@ class AdBlockManager;
class WebView;
-typedef QList< QPointer<MainWindow> > MainWindowList;
+typedef QList< QWeakPointer<MainWindow> > MainWindowList;
namespace Rekonq
@@ -89,7 +91,7 @@ namespace Rekonq
/**
*
*/
-class Application : public KUniqueApplication
+class REKONQ_TESTS_EXPORT Application : public KUniqueApplication
{
Q_OBJECT
@@ -100,6 +102,7 @@ public:
static Application *instance();
MainWindow *mainWindow();
+ MainWindow *newMainWindow();
MainWindowList mainWindowList();
static KIcon icon(const KUrl &url);
@@ -117,16 +120,11 @@ public slots:
*/
void saveConfiguration() const;
- MainWindow *newMainWindow();
-
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:
@@ -139,10 +137,10 @@ private slots:
void loadResolvedUrl(ThreadWeaver::Job *);
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..aab6af90
--- /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..df6bc54b 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
@@ -34,28 +35,28 @@
#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()
+ : QObject(parent)
+ , KBookmarkOwner()
{
}
@@ -66,7 +67,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,14 +94,37 @@ 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;
}
@@ -111,27 +135,36 @@ BookmarkMenu::BookmarkMenu(KBookmarkManager *manager,
KBookmarkOwner *owner,
KMenu *menu,
KActionCollection* actionCollection)
- : KBookmarkMenu(manager, owner, menu, 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);
+ 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 +184,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 +263,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 +285,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 +306,47 @@ 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);
+ KBookmarkGroup toolBarGroup = m_manager->toolbar();
+ if (toolBarGroup.isNull())
+ return;
+
+ bookmarkToolBar->clear();
+
+ KBookmark bookmark = toolBarGroup.first();
+ while (!bookmark.isNull())
+ {
+ bookmarkToolBar->addAction(fillBookmarkBar(bookmark));
+ bookmark = toolBarGroup.next(bookmark);
+ }
}
}
}
@@ -244,13 +363,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));
}
@@ -269,21 +397,18 @@ KAction *BookmarkProvider::fillBookmarkBar(const KBookmark &bookmark)
{
if (bookmark.isGroup())
{
- KBookmarkGroup group = bookmark.toGroup();
- KBookmark bm = group.first();
- KActionMenu *menuAction = new KActionMenu(KIcon(bookmark.icon()), bookmark.text(), this);
+ KBookmarkActionMenu *menuAction = new KBookmarkActionMenu(bookmark.toGroup(), this);
menuAction->setDelayed(false);
- while (!bm.isNull())
- {
- menuAction->addAction(fillBookmarkBar(bm));
- bm = group.next(bm);
- }
+ new BookmarkMenu(bookmarkManager(), bookmarkOwner(), menuAction->menu(), bookmark.address());
+
return menuAction;
}
if(bookmark.isSeparator())
{
- KAction *a = new KAction(this);
+ KAction *a = new KBookmarkAction(bookmark, m_owner, this);
+ a->setText("");
+ a->setIcon(QIcon());
a->setSeparator(true);
return a;
}
@@ -298,3 +423,56 @@ 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;
+ }
+
+ KBookmark bookmark = bookGroup.first();
+ while (!bookmark.isNull() && title.isEmpty())
+ {
+ title = titleForBookmarkUrl(bookmark, url);
+ bookmark = bookGroup.next(bookmark);
+ }
+
+ if (title.isEmpty())
+ {
+ title = url;
+ }
+
+ return title;
+}
+
+
+QString BookmarkProvider::titleForBookmarkUrl(const KBookmark &bookmark, QString url)
+{
+ 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..8d09e122 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
@@ -31,6 +32,7 @@
// Local Includes
+#include "rekonqprivate_export.h"
#include "application.h"
// Qt Includes
@@ -38,6 +40,7 @@
// KDE Includes
#include <KBookmarkOwner>
+#include <KCompletion>
// Forward Declarations
class BookmarkProvider;
@@ -55,7 +58,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 +113,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 +133,6 @@ signals:
// KDE Includes
#include <KBookmarkMenu>
-
/**
* This class represent the rekonq bookmarks menu.
* It's just a simple class inherited from KBookmarkMenu
@@ -143,13 +147,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 +206,7 @@ public:
*/
void setupBookmarkBar(KToolBar *);
+ void removeToolBar(KToolBar*);
/**
* @short Get action by name
@@ -209,7 +224,16 @@ 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 +260,18 @@ public slots:
*/
void slotBookmarksChanged(const QString &group, const QString &caller);
+
private:
KAction *fillBookmarkBar(const KBookmark &bookmark);
+ 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..0caf0f31 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)
+ , 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");
@@ -85,19 +84,20 @@ void BookmarksPanel::setup()
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);
@@ -106,8 +106,114 @@ void BookmarksPanel::setup()
BookmarksTreeModel *model = new BookmarksTreeModel( this );
BookmarksProxy *proxy = new BookmarksProxy(ui);
proxy->setSourceModel( model );
- treeView->setModel( proxy );
+ 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..90597c73 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,24 @@
#ifndef BOOKMARKSPANEL_H
#define BOOKMARKSPANEL_H
+
+// Local Includes
+#include "rekonqprivate_export.h"
+#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 +55,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..7fa34b3f 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
diff --git a/src/bookmarks/bookmarksproxy.h b/src/bookmarks/bookmarksproxy.h
index 99483331..2bf1d63a 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
+
+// Local Includes
+#include "rekonqprivate_export.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..836401a6 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,94 +33,112 @@
#include "application.h"
#include "bookmarksmanager.h"
+// Qt Includes
+#include <QMimeData>
+
// KDE includes
#include <KBookmarkGroup>
#include <KLocalizedString>
-class BookmarksTreeModel::BtmItem
+BtmItem::BtmItem(const KBookmark &bm)
+ : m_parent(0)
+ , m_kbm(bm)
{
-public:
- 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;
+}
// -------------------------------------------------------------------------------------
@@ -129,8 +148,9 @@ BookmarksTreeModel::BookmarksTreeModel(QObject *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()) );
}
@@ -178,8 +198,17 @@ 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;
}
@@ -255,32 +284,10 @@ QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const
}
-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();
}
@@ -321,3 +328,100 @@ void BookmarksTreeModel::populate( BtmItem *node, KBookmarkGroup bmg)
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);
+
+ 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..b312ab2d 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>
+
+// Local Includes
+#include "rekonqprivate_export.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..76637975 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
@@ -56,6 +31,7 @@
// KDE Includes
#include <KLocalizedString>
+#include <KDebug>
// Qt Includes
#include <QWebFrame>
@@ -114,39 +90,51 @@ void ClickToFlash::load()
elements.append(docElement.findAll(selector.arg(QLatin1String("object"))));
elements.append(docElement.findAll(selector.arg(QLatin1String("embed"))));
- bool isRightElement = false;
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..186b5836 100644
--- a/src/clicktoflash.h
+++ b/src/clicktoflash.h
@@ -1,69 +1,52 @@
-/*
- * 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
+
+// Local Includes
+#include "rekonqprivate_export.h"
+
+// Qt Includes
#include <QWidget>
#include <QUrl>
+#include <QWebElement>
-
+// Forward Declarations
class WebPluginFactory;
-class ClickToFlash : public QWidget
+
+class REKONQ_TESTS_EXPORT ClickToFlash : public QWidget
{
Q_OBJECT
+
public:
- ClickToFlash(QUrl pluginUrl, QWidget *parent = 0);
+ explicit ClickToFlash(QUrl pluginUrl, QWidget *parent = 0);
signals:
void signalLoadClickToFlash(bool);
@@ -72,6 +55,8 @@ 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..b0f8f2e3 100644
--- a/src/data/rekonq.desktop
+++ b/src/data/rekonq.desktop
@@ -1,17 +1,35 @@
[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[pl]=rekonq
+Name[pt]=rekonq
+Name[pt_BR]=rekonq
Name[sv]=Rekonq
-Name[tr]=Rekonq
+Name[uk]=rekonq
Name[x-test]=xxrekonqxx
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[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
Icon=rekonq
Type=Application
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..f94b7810 100644
--- a/src/filterurljob.cpp
+++ b/src/filterurljob.cpp
@@ -31,9 +31,6 @@
#include <KUriFilter>
#include <KUriFilterData>
-// Qt Includes
-#include <QUrl>
-
FilterUrlJob::FilterUrlJob(WebView *view, const QString &urlString, QObject *parent)
: Job(parent)
@@ -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..9be058e3 100644
--- a/src/filterurljob.h
+++ b/src/filterurljob.h
@@ -28,6 +28,7 @@
#define FILTER_URL_JOB_H
// Local Includes
+#include "rekonqprivate_export.h"
#include "webview.h"
// KDE Includes
@@ -41,7 +42,7 @@
using namespace ThreadWeaver;
-class FilterUrlJob : public Job
+class REKONQ_TESTS_EXPORT FilterUrlJob : public Job
{
public:
FilterUrlJob(WebView *view, const QString &urlString, QObject *parent = 0);
diff --git a/src/findbar.cpp b/src/findbar.cpp
index bd1a5137..48a3c4e0 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
@@ -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,6 +69,7 @@ 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);
@@ -77,22 +83,30 @@ 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();
@@ -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();
@@ -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..78615f9a 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
@@ -29,46 +29,44 @@
#define FINDBAR_H
+// Local Includes
+#include "rekonqprivate_export.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..1bfd5c9e 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
@@ -52,7 +52,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 +94,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..c4c9045b 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
@@ -29,6 +29,9 @@
#define AUTOSAVER_H
+// Local Includes
+#include "rekonqprivate_export.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..097f9ee2 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
@@ -69,10 +69,9 @@ HistoryManager::HistoryManager(QObject *parent)
, m_historyModel(0)
, m_historyFilterModel(0)
, m_historyTreeModel(0)
- , m_completion(0)
+ , m_completion(new KCompletion)
{
// take care of the completion object
- m_completion = new KCompletion;
m_completion->setOrder( KCompletion::Weighted );
m_expiredTimer.setSingleShot(true);
@@ -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..9a844672 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
@@ -30,6 +30,9 @@
#define HISTORY_H
+// Local Includes
+#include "rekonqprivate_export.h"
+
// KDE Includes
#include <KUrl>
@@ -54,7 +57,10 @@ public:
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..736dbcd7 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
@@ -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();
}
diff --git a/src/history/historymodels.h b/src/history/historymodels.h
index 08f3f63e..c2b1ede1 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
@@ -31,6 +31,7 @@
// Local Includes
+#include "rekonqprivate_export.h"
#include "historymanager.h"
// KDE Includes
@@ -45,7 +46,7 @@
#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..8c36dfa8 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
@@ -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)
+ , m_treeView(new PanelTreeView(this))
{
setup();
setShown(ReKonfig::showHistoryPanel());
@@ -70,11 +74,11 @@ void HistoryPanel::setup()
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);
+ 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..a4dfaf64 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
@@ -29,6 +29,11 @@
#define HISTORYPANEL_H
+// Local Includes
+#include "rekonqprivate_export.h"
+#include "application.h"
+#include "paneltreeview.h"
+
// Qt Includes
#include <QDockWidget>
@@ -38,7 +43,7 @@ class QWidget;
class QModelIndex;
-class HistoryPanel : public QDockWidget
+class REKONQ_TESTS_EXPORT HistoryPanel : public QDockWidget
{
Q_OBJECT
@@ -47,13 +52,17 @@ public:
~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..0be5a7ee 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
@@ -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",
@@ -91,6 +86,11 @@ extern "C" KDE_EXPORT int kdemain( int argc, char **argv )
"");
// --------------- 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",
diff --git a/src/mainview.cpp b/src/mainview.cpp
index b26e7466..cb2e3b11 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
@@ -60,17 +61,21 @@
#include <QWidget>
#include <QVBoxLayout>
+// Defines
+#define QL1S(x) QLatin1String(x)
+
MainView::MainView(MainWindow *parent)
- : KTabWidget(parent)
- , m_urlBar(new UrlBar(this))
- , m_tabBar(new TabBar(this))
- , m_addTabButton(new QToolButton(this))
- , m_currentTabIndex(0)
- , m_parentWindow(parent)
+ : KTabWidget(parent)
+ , _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);
@@ -79,17 +84,18 @@ MainView::MainView(MainWindow *parent)
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(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(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(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(m_tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(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)));
@@ -117,12 +123,10 @@ 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)
{
@@ -142,14 +146,13 @@ void MainView::updateTabButtonPosition()
// detecting X position
int newPosX = tabBarWidth;
- int tabWidthHint = m_tabBar->tabSizeHint(0).width();
+ 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);
}
}
@@ -163,13 +166,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
+QWidget *MainView::urlBarWidget() const
{
- return m_urlBar;
+ return _bars;
}
@@ -181,13 +191,13 @@ WebTab *MainView::currentWebTab() const
void MainView::updateTabBar()
{
- if (ReKonfig::alwaysShowTabBar())
+ if( ReKonfig::alwaysShowTabBar() )
{
if (!isTabBarHidden())
{
- if (m_tabBar->isHidden())
+ if (tabBar()->isHidden())
{
- m_tabBar->show();
+ tabBar()->show();
m_addTabButton->show();
}
updateTabButtonPosition();
@@ -195,16 +205,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())
+ else if( !isTabBarHidden() )
{
- if (m_tabBar->isHidden())
+ if ( tabBar()->isHidden() )
{
- m_tabBar->show();
+ tabBar()->show();
m_addTabButton->show();
}
updateTabButtonPosition();
@@ -235,17 +245,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)
{
@@ -273,42 +272,41 @@ void MainView::currentChanged(int 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&)));
disconnect(oldTab->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)),
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();
}
@@ -328,7 +326,8 @@ 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()));
connect(tab->view(), SIGNAL(loadFinished(bool)), this, SLOT(webViewLoadFinished(bool)));
@@ -341,10 +340,15 @@ WebTab *MainView::newWebTab(bool focused, bool nearParent)
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)
@@ -368,7 +372,7 @@ void MainView::newTab()
w->load( KUrl("about:home") );
break;
case 1: // blank page
- urlBar()->setUrl(KUrl(""));
+ urlBar()->clear();
break;
case 2: // homepage
w->load( KUrl(ReKonfig::homePage()) );
@@ -376,7 +380,7 @@ void MainView::newTab()
default:
break;
}
- urlBar()->setFocus();
+ _bars->currentWidget()->setFocus();
}
@@ -458,12 +462,12 @@ void MainView::closeTab(int index)
if (count() == 1)
{
WebView *w = currentWebTab()->view();
- urlBar()->setUrl(KUrl(""));
switch(ReKonfig::newTabsBehaviour())
{
case 0: // new tab page
case 1: // blank page
w->load( KUrl("about:home") );
+ urlBar()->setFocus();
break;
case 2: // homepage
w->load( KUrl(ReKonfig::homePage()) );
@@ -471,7 +475,6 @@ void MainView::closeTab(int index)
default:
break;
}
- urlBar()->setFocus();
return;
}
@@ -480,43 +483,40 @@ 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( 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);
+ }
- 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!!
+ tab->deleteLater(); // tab is scheduled for deletion.
- if (hasFocus && count() > 0)
- {
- currentWebTab()->setFocus();
- }
- }
+ QWidget *urlbar = _bars->widget(index);
+ _bars->removeWidget(urlbar);
+ urlbar->deleteLater();
+
+ emit tabsChanged();
}
@@ -533,11 +533,10 @@ void MainView::webViewLoadStarted()
}
}
- emit browserTabLoading(true);
-
if (index != currentIndex())
return;
+ emit browserTabLoading(true);
emit showStatusBarMessage(i18n("Loading..."));
}
@@ -579,14 +578,12 @@ void MainView::webViewIconChanged()
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();
}
}
@@ -606,7 +603,7 @@ void MainView::webViewTitleChanged(const QString &title)
}
if (currentIndex() == index)
{
- emit setCurrentTitle(tabTitle);
+ emit currentTitle(tabTitle);
}
Application::historyManager()->updateHistoryEntry(view->url(), tabTitle);
}
@@ -618,7 +615,7 @@ void MainView::webViewUrlChanged(const QUrl &url)
int index = indexOf( view->parentWidget() );
if (-1 != index)
{
- m_tabBar->setTabData(index, url);
+ tabBar()->setTabData(index, url);
}
emit tabsChanged();
}
@@ -647,7 +644,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 +656,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;
}
@@ -690,3 +687,11 @@ void MainView::detachTab(int index)
Application::instance()->loadUrl(url, Rekonq::NewWindow);
}
+
+
+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..272cf82e 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
@@ -43,6 +44,7 @@
// Qt Includes
#include <QtGui/QToolButton>
+#include <QStackedWidget>
// Forward Declarations
class QUrl;
@@ -68,8 +70,7 @@ public:
MainView(MainWindow *parent);
~MainView();
-public:
-
+ QWidget *urlBarWidget() const;
UrlBar *urlBar() const;
WebTab *webTab(int index) const;
@@ -86,7 +87,6 @@ public:
void setTabBarHidden(bool hide);
QToolButton *addTabButton() const;
- void clear();
/**
* This function creates a new empty tab
@@ -106,7 +106,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);
@@ -147,7 +147,7 @@ private slots:
void windowCloseRequested();
void postLaunch();
-
+ void movedTab(int,int);
protected:
virtual void resizeEvent(QResizeEvent *event);
@@ -167,8 +167,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 df600c05..cb90f818 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
@@ -70,13 +71,14 @@
#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>
@@ -102,8 +104,8 @@ MainWindow::MainWindow()
, 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_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) )
@@ -159,6 +161,7 @@ MainWindow::MainWindow()
MainWindow::~MainWindow()
{
+ Application::bookmarkProvider()->removeToolBar(m_bmBar);
Application::instance()->removeMainWindow(this);
delete m_popup;
}
@@ -167,8 +170,6 @@ MainWindow::~MainWindow()
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->addSeparator();
@@ -177,18 +178,31 @@ void MainWindow::setupToolbars()
// location bar
KAction *urlBarAction = new KAction(this);
- urlBarAction->setDefaultWidget(m_view->urlBar());
+ urlBarAction->setDefaultWidget(m_view->urlBarWidget());
m_mainBar->addAction( urlBarAction );
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);
+ }
}
@@ -202,7 +216,7 @@ void MainWindow::postLaunch()
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
@@ -252,7 +266,7 @@ void MainWindow::setupActions()
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()));
+ connect(a, SIGNAL(triggered(bool)), Application::instance(), SLOT(newWindow()));
// Standard Actions
KStandardAction::open(this, SLOT(fileOpen()), actionCollection());
@@ -261,23 +275,27 @@ 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));
@@ -298,20 +316,20 @@ void MainWindow::setupActions()
// ============================= 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()));
-
- a = new KAction(KIcon("zoom-original"), i18n("&Normal Font"), this);
+ actionCollection()->addAction(QLatin1String("zoom_in"), a);
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(zoomIn()));
+
+ 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(QLatin1String("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(QLatin1String("zoom_out"), a);
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(zoomOut()));
// =============================== Tools Actions =================================
a = new KAction(i18n("Page S&ource"), this);
@@ -329,14 +347,16 @@ void MainWindow::setupActions()
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);
@@ -409,13 +429,41 @@ void MainWindow::setupTools()
toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::SaveAs)));
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(QLatin1String("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(QLatin1String("zoom_in")));
+ zoomIn->setAutoRaise(true);
+
+ QToolButton *zoomNormal = new QToolButton(zoomWidget);
+ zoomNormal->setDefaultAction(actionByName(QLatin1String("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")));
@@ -432,7 +480,7 @@ void MainWindow::setupTools()
toolsMenu->addAction(actionByName(QLatin1String("bm_bar")));
toolsMenu->addAction(actionByName(QLatin1String("show_history_panel")));
- toolsMenu->addAction(actionByName(QLatin1String("show_bookmarks_panel")));
+ toolsMenu->addAction(actionByName(QLatin1String("show_bookmarks_panel")));
toolsMenu->addAction(actionByName(KStandardAction::name(KStandardAction::FullScreen)));
toolsMenu->addSeparator();
@@ -453,28 +501,30 @@ void MainWindow::setupPanels()
// 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);
// 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);
@@ -549,7 +599,10 @@ void MainWindow::updateConfiguration()
// 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());
+ 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();
@@ -559,13 +612,6 @@ void MainWindow::updateConfiguration()
}
-void MainWindow::updateBrowser()
-{
- updateConfiguration();
- mainView()->reloadAllTabs();
-}
-
-
void MainWindow::openLocation()
{
m_view->urlBar()->selectAll();
@@ -602,7 +648,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&)), this, SLOT(updateConfiguration()));
s->exec();
delete s;
@@ -626,7 +672,7 @@ void MainWindow::updateWindowTitle(const QString &title)
{
if(settings->testAttribute(QWebSettings::PrivateBrowsingEnabled))
{
- setWindowTitle("rekonq (" + i18n("Private Browsing") + ")");
+ setWindowTitle(i18nc("Window title when private browsing is activated", "rekonq (Private Browsing)"));
}
else
{
@@ -637,11 +683,11 @@ void MainWindow::updateWindowTitle(const QString &title)
{
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));
}
}
}
@@ -704,7 +750,7 @@ void MainWindow::privateBrowsing(bool enable)
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
{
@@ -714,10 +760,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();
}
}
@@ -728,57 +773,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::viewTextSmaller()
+void MainWindow::zoomOut()
{
- if (!currentTab())
+ m_zoomSlider->setValue(m_zoomSlider->value() - 1);
+}
+
+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);
}
@@ -859,9 +958,12 @@ void MainWindow::viewPageSource()
}
-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()) );
}
@@ -902,19 +1004,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();
+ }
}
@@ -924,6 +1048,7 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
if (event->key() == Qt::Key_Escape)
{
m_findBar->hide();
+ currentTab()->setFocus(); // give focus to web pages
return;
}
@@ -960,7 +1085,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
}
@@ -1009,27 +1134,33 @@ void MainWindow::notifyMessage(const QString &msg, Rekonq::Notify status)
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();
@@ -1041,22 +1172,32 @@ void MainWindow::notifyMessage(const QString &msg, Rekonq::Notify status)
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())
{
Application::historyManager()->clear();
}
-
+
+ if(clearWidget.clearDownloads->isChecked())
+ {
+ Application::historyManager()->clearDownloadsHistory();
+ }
+
if(clearWidget.clearCookies->isChecked())
{
QDBusInterface kcookiejar("org.kde.kded", "/modules/kcookiejar", "org.kde.KCookieServer");
@@ -1065,7 +1206,8 @@ void MainWindow::clearPrivateData()
if(clearWidget.clearCachedPages->isChecked())
{
- // TODO implement me!
+ KProcess::startDetached(KStandardDirs::findExe("kio_http_cache_cleaner"),
+ QStringList(QLatin1String("--clear-all")));
}
if(clearWidget.clearWebIcons->isChecked())
@@ -1086,6 +1228,8 @@ void MainWindow::clearPrivateData()
}
}
}
+
+ dialog->deleteLater();
}
@@ -1109,7 +1253,7 @@ void MainWindow::aboutToShowBackMenu()
QWebHistoryItem item = historyList.at(i);
KAction *action = new KAction(this);
action->setData(i + offset);
- QIcon icon = Application::icon( item.url() );
+ KIcon icon = Application::icon( item.url() );
action->setIcon( icon );
action->setText( item.title() );
m_historyBackMenu->addAction(action);
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 7083591d..d1509066 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
@@ -31,7 +33,9 @@
// Local Includes
+#include "rekonqprivate_export.h"
#include "application.h"
+#include "previewselectorbar.h"
// KDE Includes
#include <KMainWindow>
@@ -41,6 +45,7 @@
// Forward Declarations
class QWebFrame;
+class QSlider;
class KAction;
class KPassivePopup;
@@ -58,7 +63,7 @@ class MainView;
* It handles the menus, toolbars, and status bars.
*
*/
-class MainWindow : public KMainWindow
+class REKONQ_TESTS_EXPORT MainWindow : public KMainWindow
{
Q_OBJECT
@@ -72,7 +77,9 @@ public:
virtual QSize sizeHint() const;
virtual KActionCollection *actionCollection () const;
void setWidgetsVisible(bool makeFullScreen);
-
+
+ void setZoomSliderFactor(qreal factor);
+
private:
void setupActions();
void setupTools();
@@ -80,8 +87,7 @@ private:
void setupPanels();
public slots:
- void updateBrowser();
- void homePage();
+ void homePage(Qt::MouseButtons = Qt::LeftButton, Qt::KeyboardModifiers = Qt::NoModifier);
/**
* Notifies a message in a popup
@@ -116,18 +122,21 @@ private slots:
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();
@@ -152,7 +161,7 @@ private slots:
private:
MainView *m_view;
FindBar *m_findBar;
-
+
HistoryPanel *m_historyPanel;
BookmarksPanel *m_bookmarksPanel;
WebInspectorPanel *m_webInspectorPanel;
@@ -163,6 +172,8 @@ private:
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..99337206 100644
--- a/src/networkaccessmanager.cpp
+++ b/src/networkaccessmanager.cpp
@@ -3,7 +3,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) 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
@@ -31,22 +32,56 @@
// Local Includes
#include "application.h"
#include "adblockmanager.h"
+#include "webpage.h"
+
+// KDE Includes
#include <KDebug>
+
NetworkAccessManager::NetworkAccessManager(QObject *parent)
: AccessManager(parent)
+ , _parentPage( qobject_cast<WebPage *>(parent) )
{
}
QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData)
{
- // Adblock
- if (op == QNetworkAccessManager::GetOperation)
+ QNetworkReply *reply = 0;
+
+ switch(op)
{
- QNetworkReply *reply = Application::adblockManager()->block(req);
+ case QNetworkAccessManager::HeadOperation:
+ kDebug() << "HEAD OPERATION";
+// if(outgoingData)
+// {
+// QByteArray outgoingDataByteArray = outgoingData->peek(1024 * 1024);
+// kDebug() << outgoingDataByteArray;
+// }
+ break;
+
+ case QNetworkAccessManager::GetOperation:
+ kDebug() << "GET OPERATION";
+ reply = Application::adblockManager()->block(req, _parentPage);
if (reply)
return reply;
+ break;
+
+ case QNetworkAccessManager::PutOperation:
+ kDebug() << "PUT OPERATION";
+ break;
+
+ case QNetworkAccessManager::PostOperation:
+ kDebug() << "POST OPERATION";
+ break;
+
+ case QNetworkAccessManager::DeleteOperation:
+ kDebug() << "DELETE OPERATION";
+ break;
+
+ default:
+ kDebug() << "UNKNOWN OPERATION";
+ break;
}
return AccessManager::createRequest(op,req,outgoingData);
diff --git a/src/networkaccessmanager.h b/src/networkaccessmanager.h
index 5c34ebd7..352f67d6 100644
--- a/src/networkaccessmanager.h
+++ b/src/networkaccessmanager.h
@@ -3,7 +3,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) 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
@@ -28,6 +29,10 @@
#define NETWORKACCESSMANAGER_H
+// Local Includes
+#include "rekonqprivate_export.h"
+#include "webpage.h"
+
// KDE Includes
#include <kio/accessmanager.h>
@@ -35,15 +40,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);
+
+private:
+ WebPage *_parentPage;
};
#endif // NETWORKACCESSMANAGER_H
diff --git a/src/newtabpage.cpp b/src/newtabpage.cpp
new file mode 100644
index 00000000..b709375a
--- /dev/null
+++ b/src/newtabpage.cpp
@@ -0,0 +1,596 @@
+/* ============================================================
+*
+* 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 <KDebug>
+#include <KConfig>
+#include <KConfigGroup>
+#include <KDialog>
+#include <KCalendarSystem>
+
+// Qt Includes
+#include <QFile>
+
+// Defines
+#define QL1S(x) QLatin1String(x)
+
+
+NewTabPage::NewTabPage(QWebFrame *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 = urls.at(i);
+ QWebElement prev;
+
+ if(url.isEmpty())
+ prev = emptyPreview(i);
+ else if(!QFile::exists(WebSnap::fileForUrl(url).toLocalFile()))
+ 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);
+
+ new WebSnap(url, m_root.webFrame(), index);
+
+ return prev;
+}
+
+
+QWebElement NewTabPage::validPreview(int index, const KUrl &url, const QString &title)
+{
+ QWebElement prev = markup(".thumbnail");
+ KUrl previewPath = WebSnap::fileForUrl(url);
+ QString iString = QVariant(index).toString();
+
+ prev.findFirst(".preview img").setAttribute("src" , previewPath.toMimeDataString());
+ prev.findFirst("a").setAttribute("href", url.toMimeDataString());
+ prev.findFirst("span a").setAttribute("href", url.toMimeDataString());
+ 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(int index, const KUrl &url, const QString &title)
+{
+ // Update title if necessary
+ QStringList urls = ReKonfig::previewUrls();
+ if(KUrl(urls.at(index)) == url)
+ {
+ QStringList names = ReKonfig::previewNames();
+ names.replace(index, title);
+ ReKonfig::setPreviewNames(names);
+
+ ReKonfig::self()->writeConfig();
+ }
+
+ // 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;
+
+ QWebElement prev = m_root.findFirst("#preview" + QVariant(index).toString());
+ if(KUrl(prev.findFirst("a").attribute("href")) == url)
+ {
+ QWebElement newPrev = validPreview(index, 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;
+ else if(!QFile::exists(WebSnap::fileForUrl(item.url).toLocalFile()))
+ prev = loadingPreview(i, item.url);
+ else
+ prev = validPreview(i, item.url, item.title);
+
+ 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/rekonqpage/newtabpage.h b/src/newtabpage.h
index 003aa84e..6604e4df 100644
--- a/src/rekonqpage/newtabpage.h
+++ b/src/newtabpage.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
@@ -28,58 +29,91 @@
#define REKONQ_NEW_TAB_PAGE
-// rekonq Includes
-#include <webpage.h>
+// Local Includes
+#include "rekonqprivate_export.h"
// KDE Includes
#include <KUrl>
// Qt Includes
-#include <QtCore/QObject>
-#include <QtCore/QString>
+#include <QObject>
+#include <QString>
#include <QWebElement>
// Forward Includes
class KBookmark;
+class WebPage;
-class NewTabPage
+class REKONQ_TESTS_EXPORT NewTabPage : public QObject
{
-
+Q_OBJECT
+
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
+ * This method takes an about: url and loads
+ * the corresponding part of the new tab page
*/
void generate(const KUrl &url = KUrl("about:home"));
+
+ void snapFinished(int index, const KUrl &url, const QString &title);
+
-protected: // these are the function to build the new tab page
+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();
- //QString lastVisitedPage();
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);
-private:
+ 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(QString selector)
+ /**
+ * 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);
- QString m_html;
+private:
+ QString m_html;
QWebElement m_root;
};
diff --git a/src/paneltreeview.cpp b/src/paneltreeview.cpp
new file mode 100644
index 00000000..c13caf4d
--- /dev/null
+++ b/src/paneltreeview.cpp
@@ -0,0 +1,196 @@
+/* ============================================================
+*
+* 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"
+
+// Qt Includes
+#include <QMouseEvent>
+#include <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 = QApplication::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..93d7a33e
--- /dev/null
+++ b/src/paneltreeview.h
@@ -0,0 +1,69 @@
+/* ============================================================
+*
+* 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
+
+// Local Includes
+#include "application.h"
+
+// Qt Includes
+#include <QTreeView>
+
+
+class 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..924a5439
--- /dev/null
+++ b/src/previewselectorbar.cpp
@@ -0,0 +1,152 @@
+/* ============================================================
+*
+* 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"
+
+// Local Include
+#include "rekonq.h"
+#include "websnap.h"
+#include "application.h"
+#include "mainwindow.h"
+#include "webtab.h"
+
+// KDE Includes
+#include <KIcon>
+#include <KLocalizedString>
+
+// Qt Includes
+#include <QToolButton>
+#include <QHBoxLayout>
+#include <QString>
+
+
+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/previewselectorbar.h b/src/previewselectorbar.h
new file mode 100644
index 00000000..bb9f26c4
--- /dev/null
+++ b/src/previewselectorbar.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>
+* 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/>.
+*
+* ============================================================ */
+
+
+#ifndef PREVIEWSELECTORBAR_H
+#define PREVIEWSELECTORBAR_H
+
+// Local Includes
+#include "rekonqprivate_export.h"
+#include "webpage.h"
+
+// Qt Includes
+#include <QWidget>
+#include <QPushButton>
+#include <QLabel>
+
+
+class REKONQ_TESTS_EXPORT PreviewSelectorBar : public QWidget
+{
+Q_OBJECT
+
+public:
+ PreviewSelectorBar(int index, QWidget *parent);
+ ~PreviewSelectorBar();
+
+private slots:
+ void clicked();
+
+ void loadProgress();
+ void loadFinished();
+
+ void verifyUrl();
+
+ void destroy();
+
+private:
+ QPushButton *m_button;
+ QLabel *m_label;
+
+ int m_previewIndex;
+};
+
+#endif // PREVIEWSELECTORBAR_H
diff --git a/src/protocolhandler.cpp b/src/protocolhandler.cpp
index c90afd19..c97bc475 100644
--- a/src/protocolhandler.cpp
+++ b/src/protocolhandler.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
* modify it under the terms of the GNU General Public License as
@@ -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>
@@ -51,6 +53,7 @@
#include <KFileItem>
#include <KJob>
#include <kio/udsentry.h>
+#include <KMessageBox>
// Qt Includes
#include <QLatin1String>
@@ -60,13 +63,15 @@
#include <QFile>
#include <QDateTime>
+// Defines
+#define QL1S(x) QLatin1String(x)
+
ProtocolHandler::ProtocolHandler(QObject *parent)
: QObject(parent)
- , _lister(new KDirLister)
+ , _lister(0)
, _frame(0)
{
- connect( _lister, SIGNAL(newItems(const KFileItemList &)), this, SLOT(showResults(const KFileItemList &)));
}
@@ -80,18 +85,16 @@ bool ProtocolHandler::preHandling(const QNetworkRequest &request, QWebFrame *fra
_url = request.url();
_frame = frame;
- kDebug() << "URL PROTOCOL: " << _url;
-
+ // "http(s)" (fast) handling
+ if( _url.protocol() == QL1S("http") || _url.protocol() == QL1S("https") )
+ return false;
+
// relative urls
if(_url.isRelative())
return false;
-
- // "http(s)" (fast) handling
- if( _url.protocol() == QLatin1String("http") || _url.protocol() == QLatin1String("https") )
- return false;
-
+
// javascript handling
- if( _url.protocol() == QLatin1String("javascript") )
+ if( _url.protocol() == QL1S("javascript") )
{
QString scriptSource = _url.authority();
QVariant result = frame->evaluateJavaScript(scriptSource);
@@ -99,15 +102,28 @@ bool ProtocolHandler::preHandling(const QNetworkRequest &request, QWebFrame *fra
}
// "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") )
{
+ // let webkit manage the about:blank url...
+ if( _url == KUrl("about:blank") )
+ {
+ return false;
+ }
+
if( _url == KUrl("about:home") )
{
switch(ReKonfig::newTabStartPage())
@@ -118,26 +134,22 @@ 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;
@@ -152,12 +164,12 @@ bool ProtocolHandler::postHandling(const QNetworkRequest &request, QWebFrame *fr
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,7 +180,7 @@ 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*) ));
@@ -176,13 +188,15 @@ bool ProtocolHandler::postHandling(const QNetworkRequest &request, QWebFrame *fr
}
// "file" handling. This is quite trivial :)
- if(_url.protocol() == QLatin1String("file") )
+ if( _url.protocol() == QL1S("file") )
{
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;
}
}
@@ -193,6 +207,10 @@ bool ProtocolHandler::postHandling(const QNetworkRequest &request, QWebFrame *fr
QString ProtocolHandler::dirHandling(const KFileItemList &list)
{
+ if (!_lister)
+ {
+ return QString("rekonq error, sorry :(");
+ }
KFileItem mainItem = _lister->rootItem();
KUrl rootUrl = mainItem.url();
@@ -263,7 +281,7 @@ QString ProtocolHandler::dirHandling(const KFileItemList &list)
msg += "</table>";
- QString html = QString(QLatin1String(file.readAll()))
+ QString html = QString(QL1S(file.readAll()))
.arg(title)
.arg(msg)
;
@@ -281,14 +299,13 @@ void ProtocolHandler::showResults(const KFileItemList &list)
return;
}
- if ( list.isEmpty() )
- return;
-
QString html = dirHandling(list);
- _frame->setHtml(html);
+ _frame->setHtml( html, _url );
- Application::instance()->mainWindow()->mainView()->urlBar()->setUrl(_url);
+ Application::instance()->mainWindow()->currentTab()->setFocus();
Application::historyManager()->addHistoryEntry( _url.prettyUrl() );
+
+ delete _lister;
}
@@ -304,8 +321,66 @@ void ProtocolHandler::slotMostLocalUrlResult(KJob *job)
KIO::StatJob *statJob = static_cast<KIO::StatJob*>(job);
KIO::UDSEntry entry = statJob->statResult();
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..99aec70a 100644
--- a/src/protocolhandler.h
+++ b/src/protocolhandler.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
* modify it under the terms of the GNU General Public License as
@@ -27,6 +27,10 @@
#ifndef PROTOCOL_HANDLER_H
#define PROTOCOL_HANDLER_H
+
+// Local Includes
+#include "rekonqprivate_export.h"
+
// KDE Includes
#include <KDirLister>
@@ -41,7 +45,7 @@ class KUrl;
class KJob;
-class ProtocolHandler : public QObject
+class REKONQ_TESTS_EXPORT ProtocolHandler : public QObject
{
Q_OBJECT
@@ -70,7 +74,8 @@ private slots:
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..860809cd 100644
--- a/src/rekonq.kcfg
+++ b/src/rekonq.kcfg
@@ -7,17 +7,37 @@
<!-- 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>
+</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 +55,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 +110,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 -->
@@ -144,4 +155,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/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/sessionmanager.cpp b/src/sessionmanager.cpp
index f4e7cd3e..9e1f7baf 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
@@ -66,15 +66,15 @@ void SessionManager::saveSession()
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(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;
}
@@ -104,16 +104,17 @@ bool SessionManager::restoreSession()
line = in.readLine();
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..613b050f 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
+// Local Includes
+#include "rekonqprivate_export.h"
+
// Qt Includes
#include <QtCore/QObject>
#include <QtCore/QString>
@@ -38,7 +41,7 @@
/**
* Session Management
*/
-class SessionManager : public QObject
+class REKONQ_TESTS_EXPORT SessionManager : public QObject
{
Q_OBJECT
public:
diff --git a/src/settings/adblockwidget.cpp b/src/settings/adblockwidget.cpp
new file mode 100644
index 00000000..2f431c1e
--- /dev/null
+++ b/src/settings/adblockwidget.cpp
@@ -0,0 +1,193 @@
+/* ============================================================
+*
+* 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(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";
+ kDebug() << str;
+ 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/settings/adblockwidget.h b/src/settings/adblockwidget.h
new file mode 100644
index 00000000..7e641f3e
--- /dev/null
+++ b/src/settings/adblockwidget.h
@@ -0,0 +1,66 @@
+/* ============================================================
+*
+* 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/>.
+*
+* ============================================================ */
+
+
+#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();
+
+private:
+ void load();
+ void loadRules(QTreeWidgetItem *item);
+
+ bool _changed;
+};
+
+#endif // ADBLOCK_WIDGET_H
diff --git a/src/settings/networkwidget.cpp b/src/settings/networkwidget.cpp
new file mode 100644
index 00000000..54f6e068
--- /dev/null
+++ b/src/settings/networkwidget.cpp
@@ -0,0 +1,101 @@
+/* ============================================================
+*
+* 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>
+#include <KDebug>
+
+// 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/settings/networkwidget.h b/src/settings/networkwidget.h
new file mode 100644
index 00000000..efdd1807
--- /dev/null
+++ b/src/settings/networkwidget.h
@@ -0,0 +1,63 @@
+/* ============================================================
+*
+* 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/>.
+*
+* ============================================================ */
+
+
+#ifndef NETWORK_WIDGET_H
+#define NETWORK_WIDGET_H
+
+
+// KDE Includes
+#include <KCModuleProxy>
+
+// Qt Includes
+#include <QWidget>
+
+
+class NetworkWidget : public QWidget
+{
+Q_OBJECT
+
+public:
+ NetworkWidget(QWidget *parent = 0);
+ ~NetworkWidget();
+
+ void save();
+ bool changed();
+
+signals:
+ void changed(bool);
+
+private slots:
+ void hasChanged();
+
+private:
+ KCModuleProxy *_cacheModule;
+ KCModuleProxy *_cookiesModule;
+ KCModuleProxy *_proxyModule;
+
+ bool _changed;
+};
+
+#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 a4503d4a..00277133 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>
- </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>lycos</string>
</property>
</item>
<item>
<property name="text">
- <string>Closed Tabs</string>
+ <string>wikipedia</string>
</property>
</item>
<item>
<property name="text">
- <string>Bookmarks</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>History</string>
+ <string>wolfram</string>
</property>
</item>
</widget>
@@ -272,21 +224,21 @@
<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">
+ <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>Use KGet for downloading files</string>
+ <string>List links with KGet</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>
+ <widget class="QCheckBox" name="kcfg_kgetDownload">
<property name="text">
- <string>List links with KGet</string>
+ <string>Use KGet for downloading files</string>
</property>
</widget>
</item>
@@ -301,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..e424fd9c 100644
--- a/src/settings/settings_webkit.ui
+++ b/src/settings/settings_webkit.ui
@@ -148,13 +148,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 +213,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..35f753d3 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
@@ -37,6 +36,8 @@
#include "application.h"
#include "mainwindow.h"
#include "webtab.h"
+#include "adblockwidget.h"
+#include "networkwidget.h"
//Ui Includes
#include "ui_settings_general.h"
@@ -53,7 +54,6 @@
#include <KCModuleProxy>
// Qt Includes
-#include <QtCore/QPointer>
#include <QtGui/QWidget>
@@ -65,12 +65,12 @@ private:
Ui::tabs tabsUi;
Ui::fonts fontsUi;
Ui::webkit webkitUi;
+
+ AdBlockWidget *adBlockWidg;
+ NetworkWidget *networkWidg;
- KCModuleProxy *proxyModule;
KCModuleProxy *ebrowsingModule;
- KCModuleProxy *cookiesModule;
- KCModuleProxy *cacheModule;
- KCModuleProxy *adblockModule;
+
KShortcutsEditor *shortcutsEditor;
Private(SettingsDialog *parent);
@@ -101,21 +101,6 @@ Private::Private(SettingsDialog *parent)
widget->layout()->setMargin(0);
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);
@@ -125,10 +110,15 @@ 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"));
@@ -139,8 +129,8 @@ Private::Private(SettingsDialog *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!!
+ // WARNING remember wheh changing here that the smallest netbooks
+ // have a 1024x576 resolution. So DON'T bother that limits!!
parent->setMinimumSize(700,525);
}
@@ -153,23 +143,23 @@ 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();
}
@@ -209,24 +199,26 @@ 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();
+
+ 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->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..54494a00 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
@@ -30,6 +29,9 @@
#define SETTINGS_DIALOG_H
+// Local Includes
+#include "rekonqprivate_export.h"
+
// KDE Includes
#include <KConfigDialog>
@@ -38,7 +40,7 @@ class QWidget;
class Private;
-class SettingsDialog : public KConfigDialog
+class REKONQ_TESTS_EXPORT SettingsDialog : public KConfigDialog
{
Q_OBJECT
diff --git a/src/sslinfodialog_p.h b/src/sslinfodialog_p.h
new file mode 100644
index 00000000..44d3ab7c
--- /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 460a2464..f8da57b1 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
@@ -93,13 +93,13 @@ QSize TabBar::tabSizeHint(int index) const
int minWidth = view->sizeHint().width()/MIN_WIDTH_DIVISOR;
int w;
- if (baseWidth*count()<tabBarWidth)
+ if (baseWidth*count() < tabBarWidth)
{
w = baseWidth;
}
else
{
- if (count() > 0 && tabBarWidth/count()>minWidth)
+ if (count() > 0 && tabBarWidth/count() > minWidth)
{
w = tabBarWidth/count();
}
@@ -150,40 +150,49 @@ 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, true) );
+
+ 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
@@ -208,9 +217,9 @@ void TabBar::mouseMoveEvent(QMouseEvent *event)
//if current tab or not found then hide previous tab preview
if (tab==currentIndex() || tab==-1)
{
- if ( m_previewPopup)
+ if ( !m_previewPopup.isNull() )
{
- m_previewPopup->hide();
+ m_previewPopup.data()->hide();
}
m_currentTabPreview = -1;
}
@@ -225,9 +234,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,6 +247,15 @@ 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;
@@ -278,3 +296,26 @@ void TabBar::emptyAreaContextMenu(const QPoint &pos)
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..97c320fc 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
@@ -35,7 +35,7 @@
#include "rekonqprivate_export.h"
// Qt Includes
-#include <QPointer>
+#include <QWeakPointer>
// KDE Includes
#include <KTabBar>
@@ -80,6 +80,8 @@ protected:
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();
@@ -99,7 +101,7 @@ private:
*/
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..a79f44a2
--- /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..596ac4e1 100644
--- a/src/tests/mainview_test.cpp
+++ b/src/tests/mainview_test.cpp
@@ -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,8 +43,6 @@ class MainViewTest : public QObject
public slots:
void initTestCase();
void cleanupTestCase();
- void init();
- void cleanup();
private slots:
void tabwidget_data();
@@ -75,38 +74,29 @@ private slots:
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..d3ab6bef
--- /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..ac6cf89e
--- /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..a3c78c2f
--- /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..e3e1b329
--- /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..560f2c9b 100644
--- a/src/tests/tabbar_test.cpp
+++ b/src/tests/tabbar_test.cpp
@@ -24,116 +24,115 @@
#include <QtCore>
#include <QtGui>
-#include "../tabbar.h"
+#include "mainwindow.h"
+#include "mainview.h"
+#include "tabbar.h"
-class TabBarTest : public QObject
-{
- Q_OBJECT
-
-public slots:
- void initTestCase();
- void cleanupTestCase();
- void init();
- void cleanup();
-
-private slots:
- void tabbar_data();
- void tabbar();
-
- void tabSizeHint_data();
- void tabSizeHint();
-};
-
-
-// Subclass that exposes the protected functions.
+/**
+ * Subclass that exposes the protected functions.
+ */
class SubTabBar : public TabBar
{
public:
- void call_cloneTab(int index)
- { return SubTabBar::cloneTab(index); }
-
- void call_closeOtherTabs(int index)
- { return SubTabBar::closeOtherTabs(index); }
-
- void call_closeTab(int index)
- { return SubTabBar::closeTab(index); }
+
+ SubTabBar(QWidget *parent) : TabBar(parent) {};
+ QSize call_tabSizeHint(int index) const
+ { return SubTabBar::tabSizeHint(index); }
+
void call_mouseMoveEvent(QMouseEvent* event)
{ return SubTabBar::mouseMoveEvent(event); }
-
+
+ void call_leaveEvent(QEvent* event)
+ { return SubTabBar::leaveEvent(event); }
+
void call_mousePressEvent(QMouseEvent* event)
{ return SubTabBar::mousePressEvent(event); }
+
+ void call_mouseReleaseEvent(QMouseEvent* event)
+ { return SubTabBar::mouseReleaseEvent(event); }
+};
- void call_reloadAllTabs()
- { return SubTabBar::reloadAllTabs(); }
- void call_reloadTab(int index)
- { return SubTabBar::reloadTab(index); }
+// ------------------------------------------------------------------
- QSize call_tabSizeHint(int index) const
- { return SubTabBar::tabSizeHint(index); }
- void call_showTabPreview(int tab)
- { return SubTabBar::showTabPreview(tab); }
+class TabBarTest : public QObject
+{
+ Q_OBJECT
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+
+private slots:
+ void tabSizeHint_data();
+ void tabSizeHint();
+
+ void mousePress_data();
+ void mousePress();
+
+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..7a1fb40b
--- /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..ec9c3559
--- /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..3051b8bf
--- /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..53fc1d4f
--- /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..2c6edf35
--- /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..11d1a46c
--- /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..8307940b
--- /dev/null
+++ b/src/urlbar/completionwidget.cpp
@@ -0,0 +1,314 @@
+/* ============================================================
+*
+* 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"
+
+// KDE Includes
+#include <KGlobalSettings>
+#include <KDebug>
+#include <KUrl>
+
+// Qt Includes
+#include <QPoint>
+#include <QSize>
+#include <QVBoxLayout>
+#include <QString>
+#include <QEvent>
+#include <QKeyEvent>
+
+// Defines
+#define QL1S(x) QLatin1String(x)
+
+
+CompletionWidget::CompletionWidget(QWidget *parent)
+ : QFrame(parent, Qt::ToolTip)
+ , _parent(parent)
+ , _currentIndex(-1)
+ , _searchEngine( defaultSearchEngine() )
+{
+ 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(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();
+ }
+}
+
+
+QString CompletionWidget::defaultSearchEngine()
+{
+ 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 engine;
+}
diff --git a/src/urlbar/completionwidget.h b/src/urlbar/completionwidget.h
new file mode 100644
index 00000000..e9851484
--- /dev/null
+++ b/src/urlbar/completionwidget.h
@@ -0,0 +1,82 @@
+/* ============================================================
+*
+* 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
+
+
+// Local Includes
+#include "application.h"
+#include "listitem.h"
+
+// KDE Includes
+#include <KLineEdit>
+
+// 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);
+
+ QString searchEngine() { return _searchEngine; };
+ void setCurrentEngine(const QString &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:
+ QString defaultSearchEngine();
+
+ void insertSearchList(const UrlSearchList &list, const QString& text);
+ void popup();
+ void clear();
+
+ void sizeAndPosition();
+ void up();
+ void down();
+
+ QWidget *_parent;
+
+ UrlSearchList _list;
+ int _currentIndex;
+
+ QString _searchEngine;
+};
+
+#endif // COMPLETION_WIDGET_H
diff --git a/src/urlbar/lineedit.cpp b/src/urlbar/lineedit.cpp
index f3c93e8e..6236512f 100644
--- a/src/urlbar/lineedit.cpp
+++ b/src/urlbar/lineedit.cpp
@@ -30,24 +30,64 @@
#include "lineedit.h"
#include "lineedit.moc"
+// KDE Includes
+#include <klocalizedstring.h>
+#include <KDebug>
+#include <KStandardDirs>
+#include <KIconLoader>
+
// Qt Includes
#include <QtGui/QContextMenuEvent>
#include <QtGui/QFocusEvent>
#include <QtGui/QKeyEvent>
+#include <QStyleOptionFrameV2>
+#include <QPainter>
+
+
+IconButton::IconButton(QWidget *parent)
+ : QToolButton(parent)
+{
+ setToolButtonStyle(Qt::ToolButtonIconOnly);
+ setStyleSheet("IconButton { background-color:transparent; border: none; padding: 0px}");
+ setCursor(Qt::ArrowCursor);
+}
+
+
+// -----------------------------------------------------------------------------------------------------------
LineEdit::LineEdit(QWidget* parent)
- : KLineEdit(parent)
+ : KLineEdit(parent)
+ , _icon( new IconButton(this) )
{
+ // cosmetic
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
setMinimumWidth(200);
+ setMinimumHeight(26);
+
+ // initial style
+ setStyleSheet( QString("LineEdit { padding: 0 0 0 %1px;} ").arg(_icon->sizeHint().width()) );
+
+ // doesn't show the clear button
+ setClearButtonShown(false);
+
+ // trap Key_Enter & Key_Return events, while emitting the returnPressed signal
+ setTrapReturnKey(true);
+
+ // insert decoded URLs
+ setUrlDropsEnabled(true);
+
+ // accept focus, via tabbing, clicking & wheeling
setFocusPolicy(Qt::WheelFocus);
- setHandleSignals(true);
- setClearButtonShown(true);
+
+ // disable completion object (we have our own :) )
+ setCompletionObject(0);
}
LineEdit::~LineEdit()
{
+ delete _icon;
}
@@ -67,3 +107,87 @@ void LineEdit::mouseDoubleClickEvent(QMouseEvent *)
{
selectAll();
}
+
+
+IconButton *LineEdit::iconButton() const
+{
+ return _icon;
+}
+
+
+void LineEdit::paintEvent(QPaintEvent *event)
+{
+ // you need this before our code to draw inside the line edit..
+ KLineEdit::paintEvent(event);
+
+ if (text().isEmpty())
+ {
+ 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("Search Bookmarks, History, Web.. just start typing here!")
+ );
+ }
+}
+
+
+IconButton *LineEdit::addRightIcon(LineEdit::icon ic)
+{
+ IconButton *rightIcon = new IconButton(this);
+
+ switch(ic)
+ {
+ case LineEdit::KGet:
+ rightIcon->setIcon( KIcon("download") );
+ rightIcon->setToolTip( i18n("List all links with KGet") );
+ break;
+ case LineEdit::RSS:
+ rightIcon->setIcon( KIcon("application-rss+xml") );
+ rightIcon->setToolTip( i18n("List all available RSS feeds") );
+ break;
+ case LineEdit::SSL:
+ rightIcon->setIcon( KIcon("object-locked") );
+ rightIcon->setToolTip( i18n("Show SSL Infos") );
+ break;
+ default:
+ kDebug() << "ERROR.. default non extant case!!";
+ break;
+ }
+
+ _rightIconsList << rightIcon;
+ int iconsCount = _rightIconsList.count();
+ rightIcon->move( width() - 23*iconsCount, 6);
+ rightIcon->show();
+
+ return rightIcon;
+}
+
+
+void LineEdit::clearRightIcons()
+{
+ qDeleteAll(_rightIconsList);
+ _rightIconsList.clear();
+}
+
+
+void LineEdit::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 );
+ }
+
+ KLineEdit::resizeEvent(event);
+
+}
diff --git a/src/urlbar/lineedit.h b/src/urlbar/lineedit.h
index 67ded052..68cdc7d1 100644
--- a/src/urlbar/lineedit.h
+++ b/src/urlbar/lineedit.h
@@ -32,11 +32,32 @@
// KDE Includes
#include <KLineEdit>
+#include <KIcon>
+
+// Qt Includes
+#include <QToolButton>
// Forward Declarations
class QContextMenuEvent;
class QFocusEvent;
class QKeyEvent;
+class QStyleOptionFrameV2;
+
+
+class IconButton : public QToolButton
+{
+ Q_OBJECT
+
+public:
+ IconButton(QWidget *parent = 0);
+};
+
+
+// ------------------------------------------------------------------------------------
+
+
+// Definitions
+typedef QList<IconButton *> IconButtonPointerList;
class LineEdit : public KLineEdit
@@ -44,12 +65,33 @@ class LineEdit : public KLineEdit
Q_OBJECT
public:
+
+ enum icon
+ {
+ KGet = 0x00000001,
+ RSS = 0x00000010,
+ SSL = 0x00000100,
+ };
+
explicit LineEdit(QWidget *parent = 0);
virtual ~LineEdit();
+
+ IconButton *iconButton() const;
protected:
- virtual void keyPressEvent(QKeyEvent*);
+ virtual void keyPressEvent(QKeyEvent *);
virtual void mouseDoubleClickEvent(QMouseEvent *);
+ virtual void paintEvent(QPaintEvent *);
+ virtual void resizeEvent(QResizeEvent *);
+
+ IconButton *addRightIcon(LineEdit::icon );
+
+private slots:
+ void clearRightIcons();
+
+private:
+ IconButton *_icon;
+ IconButtonPointerList _rightIconsList;
};
#endif // LINEEDIT_H
diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp
new file mode 100644
index 00000000..a182c1a2
--- /dev/null
+++ b/src/urlbar/listitem.cpp
@@ -0,0 +1,437 @@
+/* ============================================================
+*
+* 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"
+
+// KDE Includes
+#include <KIcon>
+#include <KStandardDirs>
+#include <KDebug>
+#include <QActionGroup>
+#include <KConfigGroup>
+#include <KIcon>
+
+// Qt Includes
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QSizePolicy>
+#include <QPixmap>
+#include <QStylePainter>
+#include <QMouseEvent>
+#include <QWebSettings>
+#include <QFile>
+
+// Defines
+#define QL1S(x) QLatin1String(x)
+
+
+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);
+
+ QHBoxLayout *hLayout = new QHBoxLayout(this);
+ hLayout->setSpacing(4);
+ setLayout(hLayout);
+
+ 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(this);
+ 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)
+{
+ 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);
+ layout()->addWidget(previewLabelIcon);
+
+ QVBoxLayout *vLayout = new QVBoxLayout(this);
+ vLayout->setMargin(0);
+ vLayout->addWidget( new TextLabel(item.title, text, this) );
+ vLayout->addWidget( new TextLabel("<i>" + item.url.url() + "</i>", text, this) );
+ ((QHBoxLayout *)layout())->addLayout(vLayout);
+
+ layout()->addWidget( new TypeIconLabel(item.type, this) );
+}
+
+
+// ---------------------------------------------------------------
+
+
+PreviewLabel::PreviewLabel(const QString &url, int width, int height, QWidget *parent)
+ : QLabel(parent)
+{
+ setFixedSize(width, height);
+ setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
+
+ KUrl u = WebSnap::fileForUrl( QUrl(url) );
+ QString path = u.pathOrUrl();
+ if(QFile::exists(path))
+ {
+ QPixmap preview;
+ preview.load(path);
+ 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)
+{
+ CompletionWidget *w = qobject_cast<CompletionWidget *>(parent);
+ QString currentEngine = w->searchEngine();
+ kDebug() << currentEngine;
+
+ m_iconLabel = new IconLabel("edit-find", this); //TODO: get the default engine icon
+ m_titleLabel = new TextLabel( searchItemTitle(currentEngine, text), QString(), this);
+ m_engineBar = new EngineBar(text, currentEngine, parent);
+
+ // without this it will not work :)
+ m_url = m_engineBar->url();
+
+ layout()->addWidget( m_iconLabel );
+ layout()->addWidget( m_titleLabel );
+ layout()->addWidget( new QLabel( i18n("Engines: "), this ) );
+ layout()->addWidget( m_engineBar );
+ layout()->addWidget( new TypeIconLabel(item.type, this) );
+
+ connect(m_engineBar, SIGNAL(searchEngineChanged(QString, QString)), this, SLOT(changeSearchEngine(QString, QString)));
+}
+
+
+QString SearchListItem::searchItemTitle(QString engine, QString text)
+{
+ return QString("Search "+ engine +" for <b>"+text+"</b>");
+}
+
+
+void SearchListItem::changeSearchEngine(QString url, QString engine)
+{
+ m_titleLabel->setText(searchItemTitle(engine,m_text));
+ m_iconLabel->setPixmap(Application::icon( KUrl(url) ).pixmap(16));
+ QString url2 = url.replace( QL1S("\\{@}"), m_text);
+ m_url = KUrl(url2);
+
+ CompletionWidget *w = qobject_cast<CompletionWidget *>(parent());
+ w->setCurrentEngine( engine );
+}
+
+
+void SearchListItem::nextItemSubChoice()
+{
+ m_engineBar->selectNextEngine();
+}
+
+
+// -----------------------------------------------------------------------------------------------
+
+
+EngineBar::EngineBar(const QString &text, const QString &selectedEngine, QWidget *parent)
+ : KToolBar(parent)
+{
+ setIconSize(QSize(16,16));
+ setToolButtonStyle(Qt::ToolButtonIconOnly);
+
+ m_engineGroup = new QActionGroup(this);
+ m_engineGroup->setExclusive(true);
+
+ KConfig config("kuriikwsfilterrc"); //Share with konqueror
+ KConfigGroup cg = config.group("General");
+ QStringList favoriteEngines;
+ favoriteEngines << "wikipedia" << "google"; //defaults
+ favoriteEngines = cg.readEntry("FavoriteSearchEngines", favoriteEngines);
+
+ // default engine
+ CompletionWidget *w = qobject_cast<CompletionWidget *>(parent);
+ QString defaultEngine = w->searchEngine();
+ KService::Ptr service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(defaultEngine));
+
+ m_engineGroup->addAction(newEngineAction(service, selectedEngine));
+
+ // set url;
+ QString url = service->property("Query").toString();
+ url = url.replace("\\{@}",text);
+ m_url = KUrl(url);
+
+ Q_FOREACH(const QString &engine, favoriteEngines)
+ {
+ if(!engine.isEmpty())
+ {
+ service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(engine));
+ if(service && service->desktopEntryName() != defaultEngine)
+ {
+ m_engineGroup->addAction(newEngineAction(service, selectedEngine));
+ }
+ }
+ }
+
+ addActions(m_engineGroup->actions());
+}
+
+
+KAction *EngineBar::newEngineAction(KService::Ptr service, QString selectedEngine)
+{
+ KAction *a = new KAction(Application::icon(m_url), service->name(), this);
+ a->setCheckable(true);
+ if (service->name()==selectedEngine)
+ a->setChecked(true);
+
+ QString url = service->property("Query").toString();
+
+ a->setData( QStringList() << url << service->desktopEntryName() );
+ connect(a, SIGNAL(triggered(bool)), this, SLOT(changeSearchEngine()));
+
+ return a;
+}
+
+
+void EngineBar::changeSearchEngine()
+{
+ KAction *a = qobject_cast<KAction*>(sender());
+ QStringList list = a->data().toStringList();
+ emit searchEngineChanged(list.first(), list.last());
+}
+
+
+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;
+ layout()->addWidget( new IconLabel(item.url.url(), this) );
+ layout()->addWidget( new TextLabel( QL1S("Browse <i>http://<b>") + url.remove("http://") + QL1S("</b></i>"), QString(), this) );
+ layout()->addWidget( new TypeIconLabel(item.type, this) );
+}
+
+
+// ---------------------------------------------------------------
+
+
+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..de42fd03
--- /dev/null
+++ b/src/urlbar/listitem.h
@@ -0,0 +1,221 @@
+/* ============================================================
+*
+* 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
+
+
+// Local Includes
+#include "urlresolver.h"
+
+// KDE Includes
+#include <KToolBar>
+#include <KAction>
+#include <KService>
+
+// Qt Includes
+#include <QWidget>
+#include <QLayout>
+#include <QStyleOptionViewItemV4>
+#include <QLabel>
+
+// Forward Declarations
+class UrlSearchItem;
+
+
+class ListItem : public QWidget
+{
+ Q_OBJECT
+
+public:
+ 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:
+ 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:
+ EngineBar(const QString &text, const QString &selectedEngine, QWidget *parent = 0);
+
+ void selectNextEngine();
+ KUrl url() { return m_url; };
+
+signals:
+ void searchEngineChanged(QString url, QString engine);
+
+private slots:
+ void changeSearchEngine();
+
+private:
+ KAction *newEngineAction(KService::Ptr service, QString selectedEngine);
+
+ QActionGroup *m_engineGroup;
+ KUrl m_url;
+};
+
+
+// -------------------------------------------------------------------------
+
+
+class SearchListItem : public ListItem
+{
+ Q_OBJECT
+
+public:
+ SearchListItem(const UrlSearchItem &item, const QString &text, QWidget *parent = 0);
+
+public slots:
+ virtual void nextItemSubChoice();
+
+private slots:
+ void changeSearchEngine(QString url, QString engine);
+
+private:
+ QString searchItemTitle(QString engine, QString text);
+
+ TextLabel* m_titleLabel;
+ IconLabel* m_iconLabel;
+ EngineBar* m_engineBar;
+
+ QString m_text;
+};
+
+
+// -------------------------------------------------------------------------
+
+
+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/urlbar.cpp b/src/urlbar/urlbar.cpp
index adeba6ae..6d1b19c9 100644
--- a/src/urlbar/urlbar.cpp
+++ b/src/urlbar/urlbar.cpp
@@ -31,12 +31,16 @@
#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 "webview.h"
-#include "historymanager.h"
+#include "completionwidget.h"
// KDE Includes
#include <KDebug>
@@ -48,299 +52,219 @@
#include <QPaintEvent>
#include <QPalette>
#include <QTimer>
+#include <QVBoxLayout>
-
-QColor UrlBar::s_defaultBaseColor;
+// Defines
+#define QL1S(x) QLatin1String(x)
UrlBar::UrlBar(QWidget *parent)
- : KHistoryComboBox(true, parent)
- , m_lineEdit(new LineEdit)
- , m_progress(0)
+ : LineEdit(parent)
+ , _tab(0)
+ , _privateMode(false)
{
- setUrlDropsEnabled(true);
- setAutoDeleteCompletionObject(true);
-
- //cosmetic
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- setMinimumWidth(180);
+ _tab = qobject_cast<WebTab *>(parent);
- 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()));
-
- // setup completion box
- setCompletionObject( Application::historyManager()->completionObject() );
+ 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()));
- // set dropdown list background
- QPalette p = view()->palette();
- p.setColor(QPalette::Base, palette().color(QPalette::Base));
- view()->setPalette(p);
+ // load typed urls
+ connect(this, SIGNAL(returnPressed(const QString &)), this, SLOT(loadTyped(const QString &)));
- // load urls on activated urlbar signal
- connect(this, SIGNAL(activated(const KUrl&)), Application::instance(), SLOT(loadUrl(const KUrl&)));
+ activateSuggestions(true);
}
UrlBar::~UrlBar()
{
+ activateSuggestions(false);
+ _box.clear();
}
-void UrlBar::selectAll() const
-{
- lineEdit()->selectAll();
-}
-
-
-KUrl UrlBar::url() const
-{
- return m_currentUrl;
-}
-
-
-KLineEdit *UrlBar::lineEdit() const
-{
- return m_lineEdit;
-}
-
-
-void UrlBar::setupLineEdit()
-{
- // 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();
-}
-
-
-void UrlBar::setUrl(const QUrl& url)
+void UrlBar::setQUrl(const QUrl& url)
{
- if(url.scheme() == "about")
+ if(url.scheme() == QL1S("about") )
{
- m_currentUrl = KUrl();
- updateUrl(); // updateUrl before setFocus
+ iconButton()->setIcon( KIcon("arrow-right") );
+ clear();
setFocus();
}
else
{
- m_currentUrl = KUrl(url);
- updateUrl();
+ clearFocus();
+ LineEdit::setUrl(url);
+ setCursorPosition(0);
+ iconButton()->setIcon( Application::icon(url) );
}
-
}
-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())
- {
- kDebug() << "Don't change my typed url...";
- return;
- }
-
- KIcon icon;
- if(m_currentUrl.isEmpty())
- {
- icon = KIcon("arrow-right");
- }
- else
- {
- icon = Application::icon(m_currentUrl);
- }
-
- if (count())
+ QColor backgroundColor;
+ if( _privateMode )
{
- changeUrl(0, icon, m_currentUrl);
+ backgroundColor = QColor(220, 220, 220); // light gray
}
else
{
- insertUrl(0, icon, m_currentUrl);
+ backgroundColor = Application::palette().color(QPalette::Base);
}
+
+ // set background color of UrlBar
+ QPalette p = palette();
- setCurrentIndex(0);
-
- // important security consideration: always display the beginning
- // of the url rather than its end to prevent spoofing attempts.
- // Must be AFTER setCurrentIndex
- if (!hasFocus())
+ int progr = _tab->progress();
+ if (progr == 0)
+ {
+ if( _tab->url().scheme() == QL1S("https") )
+ {
+ backgroundColor = QColor(255, 255, 171); // light yellow
+ }
+ p.setBrush(QPalette::Base, backgroundColor);
+ }
+ else
{
- lineEdit()->setCursorPosition(0);
+ 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);
+
+ LineEdit::paintEvent(event);
}
-void UrlBar::activated(const QString& urlString)
-{
- if (urlString.isEmpty())
- return;
-
- setUrl(urlString);
- emit activated(m_currentUrl);
-}
-
-
-void UrlBar::cleared()
-{
- // clear the history on user's request from context menu
- clear();
-}
-
-
-void UrlBar::loadFinished(bool)
-{
- // reset progress bar after small delay
- m_progress = 0;
- QTimer::singleShot(200, this, SLOT(repaint()));
-}
-
-
-void UrlBar::updateProgress(int progress)
-{
- m_progress = progress;
- repaint();
-}
-
-
-void UrlBar::paintEvent(QPaintEvent *event)
+void UrlBar::keyPressEvent(QKeyEvent *event)
{
- // set background color of UrlBar
- QPalette p = palette();
- p.setColor(QPalette::Base, s_defaultBaseColor);
- setPalette(p);
-
- KHistoryComboBox::paintEvent(event);
-
- if (!hasFocus())
+ // this handles the Modifiers + Return key combinations
+ QString currentText = text().trimmed();
+ if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
+ && !currentText.startsWith(QLatin1String("http://"), Qt::CaseInsensitive))
{
- QPainter painter(this);
-
- QColor loadingColor;
- if (m_currentUrl.scheme() == QLatin1String("https"))
+ QString append;
+ if (event->modifiers() == Qt::ControlModifier)
+ {
+ append = QLatin1String(".com");
+ }
+ else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))
{
- loadingColor = QColor(248, 248, 100);
+ append = QLatin1String(".org");
}
- else
+ else if (event->modifiers() == Qt::ShiftModifier)
+ {
+ append = QLatin1String(".net");
+ }
+
+ QUrl url(QLatin1String("http://www.") + currentText);
+ QString host = url.host();
+ if (!host.endsWith(append, Qt::CaseInsensitive))
{
- loadingColor = QColor(116, 192, 250);
+ host += append;
+ url.setHost(host);
+ setText(url.toString());
}
- 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();
}
+
+ LineEdit::keyPressEvent(event);
}
-QSize UrlBar::sizeHint() const
+void UrlBar::focusInEvent(QFocusEvent *event)
{
- return lineEdit()->sizeHint();
+ activateSuggestions(true);
+
+ LineEdit::focusInEvent(event);
}
-QLinearGradient UrlBar::generateGradient(const QColor &color, int height)
+void UrlBar::setPrivateMode(bool on)
{
- 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;
+ _privateMode = on;
}
-void UrlBar::setBackgroundColor(QColor c)
+void UrlBar::dropEvent(QDropEvent *event)
{
- s_defaultBaseColor = c;
- repaint();
+ LineEdit::dropEvent(event);
+ activated(text());
}
-bool UrlBar::isLoading()
+void UrlBar::loadFinished()
{
- if(m_progress == 0)
+ if(_tab->progress() != 0)
+ return;
+
+ if(_tab->url().scheme() == QL1S("about") )
+ {
+ update();
+ return;
+ }
+
+ // show KGet downloads??
+ if(ReKonfig::kgetList())
+ {
+ IconButton *bt = addRightIcon(LineEdit::KGet);
+ connect(bt, SIGNAL(clicked()), _tab->page(), SLOT(downloadAllContentsWithKGet()));
+ }
+
+ // show RSS
+ if(_tab->hasRSSInfo())
+ {
+ IconButton *bt = addRightIcon(LineEdit::RSS);
+ connect(bt, SIGNAL(clicked()), _tab, SLOT(showRSSInfo()));
+ }
+
+ // show SSL
+ if(_tab->url().scheme() == QL1S("https") )
{
- return false;
+ IconButton *bt = addRightIcon(LineEdit::SSL);
+ connect(bt, SIGNAL(clicked()), _tab->page(), SLOT(showSSLInfo()));
}
- return true;
+
+ update();
}
-void UrlBar::keyPressEvent(QKeyEvent *event)
+void UrlBar::loadTyped(const QString &text)
{
- QString currentText = m_lineEdit->text().trimmed();
- if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return)
+ activated(KUrl(text));
+}
+
+
+void UrlBar::activateSuggestions(bool b)
+{
+ if(b)
{
- if( !currentText.startsWith(QLatin1String("http://"), Qt::CaseInsensitive) )
+ if(_box.isNull())
{
- 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");
- }
-
- 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());
- }
- }
- else
- {
- // fill lineEdit with its stripped contents to remove trailing spaces
- m_lineEdit->setText(currentText);
+ _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 &)));
}
}
-
- KHistoryComboBox::keyPressEvent(event);
+ else
+ {
+ removeEventFilter(_box.data());
+ _box.data()->deleteLater();
+ }
}
diff --git a/src/urlbar/urlbar.h b/src/urlbar/urlbar.h
index 8d267b2c..28afc21e 100644
--- a/src/urlbar/urlbar.h
+++ b/src/urlbar/urlbar.h
@@ -32,22 +32,24 @@
// Local Includes
+#include "rekonqprivate_export.h"
#include "lineedit.h"
+#include "application.h"
// KDE Includes
#include <KUrl>
-#include <KHistoryComboBox>
// Qt Includes
-#include <QUrl>
+#include <QWeakPointer>
// Forward Declarations
class QLinearGradient;
class QWidget;
-class KCompletion;
+class CompletionWidget;
+class WebTab;
-class UrlBar : public KHistoryComboBox
+class REKONQ_TESTS_EXPORT UrlBar : public LineEdit
{
Q_OBJECT
@@ -55,44 +57,27 @@ public:
UrlBar(QWidget *parent = 0);
~UrlBar();
- void selectAll() const;
- KUrl url() const;
- QSize sizeHint() const;
- void setBackgroundColor(QColor);
- bool isLoading();
-
- void setProgress(int progress);
-
-signals:
- void activated(const KUrl&);
+ void setPrivateMode(bool on);
-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 activated(const KUrl& url, Rekonq::OpenType = Rekonq::CurrentTab);
+ void setQUrl(const QUrl &url);
+ void loadFinished();
+ void loadTyped(const QString &);
+
protected:
virtual void paintEvent(QPaintEvent *event);
virtual void keyPressEvent(QKeyEvent *event);
+ virtual void focusInEvent(QFocusEvent *event);
+ virtual void dropEvent(QDropEvent *event);
private:
- void setupLineEdit();
-
- KLineEdit *lineEdit() const;
-
- static QLinearGradient generateGradient(const QColor &color, int height);
-
- static QColor s_defaultBaseColor;
-
- LineEdit *m_lineEdit;
-
- KUrl m_currentUrl;
- int m_progress;
+ void activateSuggestions(bool);
+
+ QWeakPointer<CompletionWidget> _box;
+ WebTab *_tab;
+ bool _privateMode;
};
#endif
diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp
new file mode 100644
index 00000000..5b4b1625
--- /dev/null
+++ b/src/urlbar/urlresolver.cpp
@@ -0,0 +1,230 @@
+/* ============================================================
+*
+* 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 <KDebug>
+#include <KService>
+#include <KConfig>
+#include <KConfigGroup>
+
+// Qt Includes
+#include <QString>
+#include <QByteArray>
+#include <QUrl>
+
+// 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==(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 << webSearchesResolution();
+
+ if (_typedString.length() >= 2)
+ {
+ list << qurlFromUserInputResolution();
+
+ 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 (UrlSearchItem i, common)
+ {
+ list << i;
+ }
+
+ foreach (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("http://")
+ || _typedString.startsWith("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())
+ {
+ KUrl gUrl(urlFromUserInput);
+ QString gTitle = i18n("Browse");
+ UrlSearchItem gItem(UrlSearchItem::Browse, gUrl, gTitle);
+ list << gItem;
+ }
+
+ return list;
+}
+
+
+// STEP 2 = Web Searches
+UrlSearchList UrlResolver::webSearchesResolution()
+{
+ UrlSearchList list;
+
+ if(KUrl(_typedString).isRelative())
+ {
+ UrlSearchItem gItem(UrlSearchItem::Search, KUrl(), QString() ); // others will find this url..
+ list << gItem;
+ }
+
+ return list;
+}
+
+
+// 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..22a9de4f
--- /dev/null
+++ b/src/urlbar/urlresolver.h
@@ -0,0 +1,85 @@
+/* ============================================================
+*
+* 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
+
+// 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==(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..5b911585 100644
--- a/src/walletbar.cpp
+++ b/src/walletbar.cpp
@@ -28,6 +28,9 @@
#include "walletbar.h"
#include "walletbar.moc"
+// Auto Includes
+#include "rekonq.h"
+
// KDE Includes
#include <klocalizedstring.h>
#include <KIcon>
@@ -85,7 +88,11 @@ 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();
}
diff --git a/src/walletbar.h b/src/walletbar.h
index d2e39373..efb28a8f 100644
--- a/src/walletbar.h
+++ b/src/walletbar.h
@@ -24,10 +24,13 @@
* ============================================================ */
-#ifndef WALLET_WIDGET_H
-#define WALLET_WIDGET_H
+#ifndef WALLET_BAR_H
+#define WALLET_BAR_H
+// Local Includes
+#include "rekonqprivate_export.h"
+
// Qt Includes
#include <QWidget>
#include <QString>
@@ -35,7 +38,7 @@
#include <QLabel>
-class WalletBar : public QWidget
+class REKONQ_TESTS_EXPORT WalletBar : public QWidget
{
Q_OBJECT
@@ -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..6f8e48a0 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
@@ -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
diff --git a/src/webinspectorpanel.h b/src/webinspectorpanel.h
index 8f65b48a..bb196b5c 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
@@ -29,6 +29,9 @@
// Local Includes
+#include "rekonqprivate_export.h"
+
+// Local Includes
#include "mainwindow.h"
// Qt Includes
@@ -38,7 +41,7 @@
Docked web inspector
behaviour : hide/show by tab, not globally
*/
-class WebInspectorPanel : public QDockWidget
+class REKONQ_TESTS_EXPORT WebInspectorPanel : public QDockWidget
{
Q_OBJECT
public:
diff --git a/src/webpage.cpp b/src/webpage.cpp
index b2bedffc..a75272cd 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
@@ -44,6 +45,8 @@
#include "networkaccessmanager.h"
#include "adblockmanager.h"
+#include "sslinfodialog_p.h"
+
// KDE Includes
#include <KStandardDirs>
#include <KUrl>
@@ -68,32 +71,72 @@
#include <QtGui/QMouseEvent>
#include <QtGui/QClipboard>
#include <QtGui/QKeyEvent>
+#include <QWebFrame>
+
+// Defines
+#define QL1S(x) QLatin1String(x)
+#define QL1C(x) QLatin1Char(x)
+
+
+// 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...
+
+ while (u1List.count() > 2)
+ u1List.removeFirst();
+
+ while (u2List.count() > 2)
+ u2List.removeFirst();
+
+ return (u1List == u2List);
+}
+
+
+// ---------------------------------------------------------------------------------
-WebPage::WebPage(QObject *parent)
- : KWebPage(parent, KWalletIntegration)
+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);
+ manager->setCache(0); // disable QtWebKit cache to just use KIO one..
- // disable QtWebKit cache to just use KIO one..
- manager->setCache(0);
-
+ // set cookieJar window ID..
+ if (parent && parent->window())
+ manager->setCookieJarWindowId(parent->window()->winId());
+
setNetworkAccessManager(manager);
- // Web Plugin Factory
- setPluginFactory(new WebPluginFactory(this));
+ // activate ssl warnings
+ setSessionMetaData("ssl_activate_warnings", "TRUE");
-
- connect(networkAccessManager(), SIGNAL(finished(QNetworkReply*)), this, SLOT(manageNetworkErrors(QNetworkReply*)));
+ // 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());
- connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), this, SLOT(handleUnsupportedContent(QNetworkReply *)));
+ // ----- Web Plugin Factory
+ setPluginFactory(new WebPluginFactory(this));
+
+ // ----- 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 +148,66 @@ WebPage::~WebPage()
bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
{
- // advise users on resubmitting data
- if(type == QWebPage::NavigationTypeFormResubmitted)
+ 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;
+ }
+
+ 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");
+ }
}
-
- m_requestedUrl = request.url();
-
return KWebPage::acceptNavigationRequest(frame, request, type);
}
@@ -137,7 +223,7 @@ WebPage *WebPage::createWindow(QWebPage::WebWindowType type)
WebTab *w = 0;
if(ReKonfig::openTabNoWindow())
{
- w = Application::instance()->mainWindow()->mainView()->newWebTab(!ReKonfig::openTabsBack());
+ w = Application::instance()->mainWindow()->mainView()->newWebTab(!ReKonfig::openTabsBack(), ReKonfig::openTabsNearCurrent());
}
else
{
@@ -160,7 +246,12 @@ void WebPage::handleUnsupportedContent(QNetworkReply *reply)
if( offer.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;
}
@@ -171,18 +262,35 @@ void WebPage::handleUnsupportedContent(QNetworkReply *reply)
switch ( dlg.askEmbedOrSave() )
{
case KParts::BrowserOpenOrSaveQuestion::Save:
- downloadRequested(reply->request());
- return;
+ kDebug() << "service handling: download!";
+ downloadRequest( reply->request() );
+ return;
+
case KParts::BrowserOpenOrSaveQuestion::Cancel:
- return;
+ return;
+
default: // non extant case
break;
}
}
// case KParts::BrowserRun::Embed
- KUrl::List list;
- list.append(url);
- KRun::run(*offer,url,0);
+ 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);
+ return;
}
}
@@ -191,53 +299,80 @@ void WebPage::loadFinished(bool)
{
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;
-
- if(m_protHandler.postHandling( reply->request(), mainFrame() ))
- return;
-
- // don't bother on adblocked urls
- if( reply->error() == QNetworkReply::ContentAccessDenied )
- return;
-
- if( reply->url() != m_requestedUrl ) // prevent favicon loading
- return;
+ Q_ASSERT(reply);
+ WebView *v = 0;
+ QWebFrame* frame = qobject_cast<QWebFrame *>(reply->request().originatingObject());
+ const bool isMainFrameRequest = (frame == mainFrame());
- 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::UnknownNetworkError: // unknown network-related error detected
+
+ if( _protHandler.postHandling(reply->request(), mainFrame()) )
+ 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::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
+
+ // don't bother on elements loading errors:
+ // we'll manage just main url page ones
+ v = qobject_cast<WebView *>(view());
+ if( reply->url() != v->url() )
+ break;
+
+ mainFrame()->setHtml( errorPage(reply), reply->url() );
+ break;
+
+ default:
+ kDebug() << "Nothing to do here..";
+ break;
+
}
}
@@ -275,68 +410,97 @@ QString WebPage::errorPage(QNetworkReply *reply)
}
+// 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;
-
- do
- {
- destUrl = KFileDialog::getSaveFileName(srcUrl.fileName(), QString(), view());
-
- if (destUrl.isLocalFile())
- {
- 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();
- }
- }
- }
- while (result == KIO::R_CANCEL && destUrl.isValid());
-
- if (result == KIO::R_OVERWRITE && destUrl.isValid())
+ KUrl destUrl;
+ KUrl srcUrl (request.url());
+ int result = KIO::R_OVERWRITE;
+
+ do
+ {
+ destUrl = KFileDialog::getSaveFileName(srcUrl.fileName(), QString(), view());
+
+ if (destUrl.isLocalFile())
+ {
+ QFileInfo finfo( destUrl.toLocalFile() );
+ if ( finfo.exists() )
+ {
+ 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() );
+
+ if ( result == KIO::R_OVERWRITE && destUrl.isValid() )
+ {
+ // now store data
+ // now, destUrl, srcUrl
+ Application::historyManager()->addDownload( srcUrl.pathOrUrl() , destUrl.pathOrUrl() );
+
+ if ( ReKonfig::kgetDownload() )
{
- //*End of copy code
-
//KGet integration:
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 KWebPage::downloadRequest(request);
+
+ // 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);
+ }
}
void WebPage::downloadAllContentsWithKGet()
{
- 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"))
@@ -344,5 +508,46 @@ void WebPage::downloadAllContentsWithKGet()
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()
+{
+ 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")
+ );
+ }
}
diff --git a/src/webpage.h b/src/webpage.h
index 9169ad60..9583cc22 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
@@ -33,7 +34,10 @@
// Local Includes
+#include "rekonqprivate_export.h"
#include "protocolhandler.h"
+#include "newtabpage.h"
+#include "websslinfo.h"
// KDE Includes
#include <KWebPage>
@@ -46,18 +50,18 @@ 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();
+
protected:
WebPage *createWindow(WebWindowType type);
@@ -69,13 +73,15 @@ protected Q_SLOTS:
virtual void handleUnsupportedContent(QNetworkReply *reply);
private slots:
+ void manageNetworkErrors(QNetworkReply *reply);
void loadFinished(bool);
-
+ void showSSLInfo();
+
private:
QString errorPage(QNetworkReply *);
-
- QUrl m_requestedUrl;
- ProtocolHandler m_protHandler;
+
+ ProtocolHandler _protHandler;
+ WebSslInfo _sslInfo;
};
#endif
diff --git a/src/webpluginfactory.cpp b/src/webpluginfactory.cpp
index aec4e18d..79a36aa0 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
@@ -32,7 +33,6 @@
#include "rekonq.h"
#include "application.h"
#include "mainwindow.h"
-#include "previewimage.h"
#include "clicktoflash.h"
// KDE Includes
@@ -41,21 +41,15 @@
WebPluginFactory::WebPluginFactory(QObject *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;
}
@@ -66,61 +60,36 @@ QObject *WebPluginFactory::create(const QString &mimeType,
{
kDebug() << "loading mimeType: " << mimeType;
- if(mimeType == QString("application/image-preview") )
+ switch( ReKonfig::pluginsEnabled() )
{
- 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
- {
- 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;
+
+ default:
+ kDebug() << "oh oh.. this should NEVER happen..";
+ break;
}
- 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);
}
-
-
-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;
-}
diff --git a/src/webpluginfactory.h b/src/webpluginfactory.h
index c1e4c28f..85122d56 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
@@ -28,6 +29,9 @@
#define WEB_PLUGIN_FACTORY_H
+// Local Includes
+#include "rekonqprivate_export.h"
+
// KDE Includes
#include <KWebPluginFactory>
@@ -36,23 +40,19 @@
#include <QtGui/QWidget>
-class WebPluginFactory : public KWebPluginFactory
+class REKONQ_TESTS_EXPORT WebPluginFactory : public KWebPluginFactory
{
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:
@@ -63,7 +63,7 @@ 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..612fdf4e 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
@@ -29,6 +30,9 @@
#include "websnap.h"
#include "websnap.moc"
+// Local Includes
+#include "newtabpage.h"
+
// KDE Includes
#include <KDebug>
#include <KStandardDirs>
@@ -42,15 +46,12 @@
#include <QFile>
-#define WIDTH 200
-#define HEIGHT 150
-
-
-WebSnap::WebSnap(const QUrl &url)
+WebSnap::WebSnap(const QUrl& url, QWebFrame *frame, int index)
: QObject()
+ , m_url(url)
+ , m_frame(frame)
+ , m_previewIndex(index)
{
- m_url = url;
-
// this to not register websnap history
m_page.settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
@@ -59,46 +60,40 @@ WebSnap::WebSnap(const QUrl &url)
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()
-{
-}
-
-
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, bool save)
{
// 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::Vertical, Qt::ScrollBarAlwaysOff);
page.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
- page.mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
-
+ QSize oldSize = page.viewportSize();
+
// find the best size
QSize size;
- if (page.viewportSize().width() && page.viewportSize().height())
+ int width = page.mainFrame()->contentsSize().width();
+ if (width < 640)
{
- size = page.viewportSize();
- }
- else
- {
- 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);
@@ -107,42 +102,75 @@ QPixmap WebSnap::renderPreview(const QWebPage &page,int w, int h)
// 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);
+ page.setViewportSize(oldSize);
+
+ QPixmap pm = QPixmap::fromImage(pageImage);
+ if(save)
+ {
+ KUrl url( page.mainFrame()->url() );
+ kDebug() << "saving preview";
+ QFile::remove( fileForUrl(url).toLocalFile() );
+ pm.save(fileForUrl(url).toLocalFile());
+ }
+
+ return pm;
+}
+
- return QPixmap::fromImage(pageImage);
+KUrl WebSnap::fileForUrl(KUrl url)
+{
+ QString filePath = KStandardDirs::locateLocal("cache", QString("thumbs/") + WebSnap::guessNameFromUrl(url) + ".png", true);
+ return KUrl(filePath);
+}
+
+
+QString WebSnap::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 WebSnap::saveResult(bool ok)
{
+ QPixmap image = QPixmap();
+
// crude error-checking
if (!ok)
{
kDebug() << "Error loading site..";
- return;
+ m_snapTitle = "Error...";
+
}
-
- m_image = renderPreview(m_page, WIDTH, HEIGHT);
- emit finished();
+ else
+ {
+ image = renderPreview(m_page, WIDTH, HEIGHT);
+ m_snapTitle = m_page.mainFrame()->title();
+ }
+ QFile::remove(fileForUrl(m_url).toLocalFile());
+ image.save(fileForUrl(m_url).toLocalFile());
+
+ NewTabPage p( m_frame );
+ p.snapFinished(m_previewIndex, m_url, m_snapTitle);
+
+ this->deleteLater();
}
-
QString WebSnap::snapTitle()
{
return m_page.mainFrame()->title();
}
-
-
-QUrl WebSnap::snapUrl()
-{
- return m_url;
-}
-
-
-QPixmap WebSnap::previewImage()
-{
- return m_image;
-}
diff --git a/src/websnap.h b/src/websnap.h
index 6c5b4af9..9773b4cc 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
@@ -28,6 +29,9 @@
#ifndef WEB_SNAP_H
#define WEB_SNAP_H
+// Local Includes
+#include "rekonqprivate_export.h"
+
// KDE Includes
#include <KUrl>
@@ -37,39 +41,49 @@
#include <QImage>
#include <QWebPage>
+#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 WITHOUT saving an image)
+ * - NewTabPage class: to show the favorites page "preview" (given an url, you show AND save an image)
+ * - PreviewSelector class: to save new favorite selection (given a page, 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);
+ WebSnap(const QUrl &url, QWebFrame *frame, int index);
+
+ static QPixmap renderPreview(const QWebPage &page, int w = WIDTH, int h = HEIGHT, bool save = true);
+
+ static KUrl fileForUrl(KUrl url);
+ static QString guessNameFromUrl(QUrl url);
QString snapTitle();
- QUrl snapUrl();
-
-signals:
- void finished();
private slots:
void load();
- void saveResult(bool ok);
+ void saveResult(bool ok = true);
private:
QWebPage m_page;
- QPixmap m_image;
QUrl m_url;
QString m_snapTitle;
+
+ QWebFrame *m_frame;
+ int m_previewIndex;
};
#endif // WEB_SNAP_H
diff --git a/src/websslinfo.cpp b/src/websslinfo.cpp
new file mode 100644
index 00000000..ffc4918f
--- /dev/null
+++ b/src/websslinfo.cpp
@@ -0,0 +1,211 @@
+/*
+ * 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..433cf053
--- /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..6bafd04a 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
@@ -39,6 +39,7 @@
#include "webpage.h"
#include "bookmarksmanager.h"
#include "walletbar.h"
+#include "previewselectorbar.h"
// KDE Includes
#include <KService>
@@ -48,6 +49,7 @@
#include <KActionMenu>
#include <KWebView>
#include <kwebwallet.h>
+#include <KDE/KMessageBox>
// Qt Includes
#include <QContextMenuEvent>
@@ -58,28 +60,34 @@
#include <QAction>
#include <QVBoxLayout>
+// Defines
+#define QL1S(x) QLatin1String(x)
-WebTab::WebTab(QWidget* parent)
+
+WebTab::WebTab(QWidget *parent)
: QWidget(parent)
- , m_view( new WebView(this) )
, 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);
- 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();
+ 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)
{
@@ -87,34 +95,32 @@ WebTab::WebTab(QWidget* parent)
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());
+KUrl WebTab::url()
+{
+ return KUrl( view()->url() );
}
@@ -124,18 +130,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,7 +143,13 @@ 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();
@@ -162,3 +162,60 @@ 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()
+{
+ _rssList.clear();
+ QWebElementCollection col = page()->mainFrame()->findAllElements("link");
+ foreach(QWebElement el, col)
+ {
+ if( el.attribute("type") == QL1S("application/rss+xml") || el.attribute("type") == QL1S("application/rss+xml") )
+ {
+ if( el.attribute("href").startsWith( QL1S("http") ) )
+ {
+ _rssList << KUrl( 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") ))
+ _rssList << u;
+ }
+ }
+ }
+
+ return !_rssList.isEmpty();
+}
+
+
+void WebTab::showRSSInfo()
+{
+ QString urlList = QString("Here are the rss link found: <br /><br />");
+ foreach(const KUrl &url, _rssList)
+ {
+ urlList += QString("<a href=\"") + url.url() + QString("\">") + url.url() + QString("</a><br />");
+ }
+ urlList += QString("<br />Enough for now.. waiting for some cool akonadi based feeds management :)");
+
+ KMessageBox::information( view(),
+ urlList,
+ "RSS Management"
+ );
+}
diff --git a/src/webtab.h b/src/webtab.h
index ecf8e5b3..9054a7c1 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
@@ -29,16 +29,21 @@
#define WEBTAB_H
+// Local Includes
+#include "rekonqprivate_export.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,24 @@ 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();
private:
- WebView *const m_view;
int m_progress;
- QString m_statusBarText;
+
+ KUrl::List _rssList;
};
#endif
diff --git a/src/webview.cpp b/src/webview.cpp
index 232a2633..f48afffb 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
@@ -62,16 +62,21 @@
WebView::WebView(QWidget* parent)
: KWebView(parent, false)
- , m_page( new WebPage(this) )
- , m_mousePos(QPoint(0,0))
+ , _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 &)));
+ 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 &)),
@@ -80,12 +85,24 @@ WebView::WebView(QWidget* parent)
// loadUrl signal
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;
}
@@ -164,7 +181,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
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->setIcon( Application::icon( data.uri() ) );
a->setData(searchProviderPrefix);
connect(a, SIGNAL(triggered(bool)), this, SLOT(search()));
searchMenu->addAction(a);
@@ -306,24 +323,60 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
void WebView::mousePressEvent(QMouseEvent *event)
{
+ 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:
triggerPageAction(KWebPage::Back);
break;
+
case Qt::XButton2:
triggerPageAction(KWebPage::Forward);
break;
+
+ case Qt::MidButton:
+ if(_canEnableAutoScroll && !_isAutoScrollEnabled)
+ {
+ setCursor( KIcon("transform-move").pixmap(32) );
+ _clickPos = event->pos();
+ _isAutoScrollEnabled = true;
+ }
+ break;
+
default:
- KWebView::mousePressEvent(event);
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)
@@ -341,7 +394,7 @@ void WebView::mouseMoveEvent(QMouseEvent *event)
QPoint WebView::mousePos()
{
- return m_mousePos;
+ return _mousePos;
}
@@ -397,18 +450,73 @@ void WebView::openLinkInNewTab()
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->modifiers() == Qt::ControlModifier) && (event->key() == Qt::Key_A))
+ if ( event->key() == Qt::Key_A )
+ {
+ triggerPageAction(KWebPage::SelectAll);
+ return;
+ }
+ }
+
+ 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);
}
@@ -418,6 +526,7 @@ void WebView::inspect()
QAction *a = Application::instance()->mainWindow()->actionByName("web_inspector");
if(a && !a->isChecked())
a->trigger();
+ pageAction(QWebPage::InspectElement)->trigger();
}
@@ -425,3 +534,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..c6ca2688 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
@@ -29,6 +29,7 @@
#define WEBVIEW_H
// Local Includes
+#include "rekonqprivate_export.h"
#include "application.h"
// KDE Includes
@@ -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);
@@ -67,12 +68,20 @@ private slots:
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