summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/application.cpp12
-rw-r--r--src/data/CMakeLists.txt12
-rw-r--r--src/data/beolingus.xml8
-rw-r--r--src/data/db_opensearch.json67
-rw-r--r--src/data/de2en.xml8
-rw-r--r--src/data/dictfr.xml8
-rw-r--r--src/data/facebook.xml8
-rw-r--r--src/data/kde_techbase.xml8
-rw-r--r--src/data/kde_userbase.xml8
-rw-r--r--src/data/voila.xml8
-rw-r--r--src/data/wikia.xml8
-rw-r--r--src/data/wikipedia.xml4
-rw-r--r--src/data/wiktionary.xml8
-rw-r--r--src/data/wr_english.xml6
-rw-r--r--src/data/youtube.xml7
-rw-r--r--src/mainwindow.cpp8
-rw-r--r--src/opensearch/opensearchengine.cpp6
-rw-r--r--src/opensearch/opensearchmanager.cpp166
-rw-r--r--src/opensearch/opensearchmanager.h20
-rw-r--r--src/opensearch/suggestionparser.cpp25
-rw-r--r--src/settings/generalwidget.cpp4
-rw-r--r--src/settings/settingsdialog.cpp16
-rw-r--r--src/urlbar/listitem.cpp24
-rw-r--r--src/urlbar/listitem.h2
-rw-r--r--src/urlbar/urlbar.cpp18
-rw-r--r--src/urlbar/urlbar.h15
-rw-r--r--src/urlbar/urlresolver.cpp12
-rw-r--r--src/urlbar/webshortcutwidget.cpp184
-rw-r--r--src/urlbar/webshortcutwidget.h61
-rw-r--r--src/webtab.cpp71
-rw-r--r--src/webtab.h16
32 files changed, 727 insertions, 102 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f0310b4d..6cf26517 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -70,6 +70,7 @@ SET( rekonq_KDEINIT_SRCS
urlbar/listitem.cpp
urlbar/rsswidget.cpp
urlbar/bookmarkwidget.cpp
+ urlbar/webshortcutwidget.cpp
#----------------------------------------
analyzer/analyzerpanel.cpp
analyzer/networkanalyzer.cpp
diff --git a/src/application.cpp b/src/application.cpp
index 95aa9cf0..a7575b94 100644
--- a/src/application.cpp
+++ b/src/application.cpp
@@ -503,7 +503,7 @@ void Application::updateConfiguration()
// Enabling WebKit "Page Cache" feature: http://webkit.org/blog/427/webkit-page-cache-i-the-basics/
defaultSettings->setMaximumPagesInCache(3);
-
+
// ===== HTML 5 features WebKit support ======
defaultSettings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, ReKonfig::offlineStorageDatabaseEnabled());
defaultSettings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, ReKonfig::offlineWebApplicationCacheEnabled());
@@ -600,20 +600,20 @@ void Application::setPrivateBrowsingMode(bool b)
bool isJustEnabled = settings->testAttribute(QWebSettings::PrivateBrowsingEnabled);
if(isJustEnabled == b)
return; // uhm... something goes wrong...
-
+
if (b)
{
QString caption = i18n("Are you sure you want to turn on private browsing?");
QString text = i18n("<b>%1</b>"
"<p>rekonq will save your current tabs for when you'll stop private browsing the net..</p>", caption);
-
+
int button = KMessageBox::warningContinueCancel(mainWindow(), text, caption, KStandardGuiItem::cont(), KStandardGuiItem::cancel(), i18n("don't ask again") );
if (button != KMessageBox::Continue)
return;
-
+
settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
_privateBrowsingAction->setChecked(true);
-
+
Q_FOREACH(const QWeakPointer<MainWindow> &w, m_mainWindows)
{
w.data()->close();
@@ -629,7 +629,7 @@ void Application::setPrivateBrowsingMode(bool b)
settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false);
_privateBrowsingAction->setChecked(false);
-
+
loadUrl( KUrl("about:blank"), Rekonq::NewWindow);
if(!sessionManager()->restoreSession())
loadUrl( KUrl("about:home"), Rekonq::NewWindow);
diff --git a/src/data/CMakeLists.txt b/src/data/CMakeLists.txt
index 5f499941..f34936b4 100644
--- a/src/data/CMakeLists.txt
+++ b/src/data/CMakeLists.txt
@@ -31,7 +31,19 @@ INSTALL(
# opensearch engines
INSTALL(
FILES
+ beolingus.xml
+ de2en.xml
+ dictfr.xml
+ facebook.xml
google.xml
+ kde_techbase.xml
+ kde_userbase.xml
+ youtube.xml
+ voila.xml
+ wikia.xml
wikipedia.xml
+ wiktionary.xml
+ wr_english.xml
+ db_opensearch.json
DESTINATION ${DATA_INSTALL_DIR}/rekonq/opensearch
)
diff --git a/src/data/beolingus.xml b/src/data/beolingus.xml
new file mode 100644
index 00000000..60901163
--- /dev/null
+++ b/src/data/beolingus.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>De-En Beolingus</ShortName>
+ <Description>Beolingus: German-English Dictionary</Description>
+ <Url method="get" template="http://dict.tu-chemnitz.de/?query={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+json" template="http://dict.tu-chemnitz.de/sugg.php?json=1;s={searchTerms}"/>
+ <Image>http://dict.tu-chemnitz.de/pics/beo-de.png</Image>
+</OpenSearchDescription>
diff --git a/src/data/db_opensearch.json b/src/data/db_opensearch.json
new file mode 100644
index 00000000..16fc3f89
--- /dev/null
+++ b/src/data/db_opensearch.json
@@ -0,0 +1,67 @@
+[["http://www.7digital.com/osd.xml","7digital"],
+["http://dict.tu-chemnitz.de/de-en/opensearch.xml","beolingus"],
+["http://www.blip.tv/opensearch.xml","blip"],
+["http://b.static.ak.fbcdn.net/rsrc.php/zJ/r/H2SSvhJMJA-.xml","facebook"],
+["http://www.flickr.com/opensearch.xml","flickr"],
+["https://github.com/opensearch.xml","github"],
+["https://bugs.kde.org/search_plugin.cgi","bugft"],
+["http://st.pimg.net/tucs/opensearch.xml","cpan"],
+
+["http://citeseerx.ist.psu.edu/search_plugins/citeseerx_general.xml","citeseerx"],
+["http://citeseerx.ist.psu.edu/search_plugins/citeseerx_authorl.xml","citeseerx"],
+["http://citeseerx.ist.psu.edu/search_plugins/citeseerx_title.xml","citeseerx"],
+
+["http://identi.ca/opensearch/people","identica_people"],
+["http://identi.ca/opensearch/notice","identica_notices"],
+
+["http://www.cnrtl.fr/portail/opensearch.xml","dictfr"],
+
+["http://www.youtube.com/opensearch?locale=en_GB","youtube"],
+["http://static1.urbandictionary.com/osd.xml?1292027099","urbandictionary"],
+
+["http://www.wordreference.com/tools/OpenSearch/enes.xml","en2es"],
+["http://www.wordreference.com/tools/OpenSearch/esen.xml","es2en"],
+["http://www.wordreference.com/tools/OpenSearch/enfr.xml","en2fr"],
+["http://www.wordreference.com/tools/OpenSearch/fren.xml","fr2en"],
+["http://www.wordreference.com/tools/OpenSearch/enit.xml","en2it"],
+["http://www.wordreference.com/tools/OpenSearch/iten.xml","it2en"],
+["http://www.wordreference.com/tools/OpenSearch/definition.xml","wordref"],
+["http://dict.tu-chemnitz.de/de-en/opensearch.xml","de2en"],
+["http://www.dict.cc/opensearch.xml","en2de"],
+["http://dict.leo.org/plugins/Shared/Searches/leo_frde_de.xml","fr2de"],
+["http://dict.leo.org/plugins/Shared/Searches/leo_ende_de.xml","leo"],
+
+["http://opensearch.search.ke.voila.fr/voila.xml","voila"],
+["http://www.wikia.com/opensearch_desc.php","wikia"],
+
+["http://techbase.kde.org/opensearch_desc.php","kde_techbase"],
+["http://userbase.kde.org/opensearch_desc.php","kde_userbase"],
+
+["http://duckduckgo.com/opensearch.xml","duckduckgo"],
+
+["http://ecosia.org/_files/searchplugin.xml","ecosia"],
+
+["http://fr.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://en.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://it.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://de.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://es.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://nl.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://pl.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://ja.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://ru.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+["http://pt.wikipedia.org/w/opensearch_desc.php","wikipedia"],
+
+["http://fr.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://en.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://it.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://de.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://es.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://nl.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://pl.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://ja.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://ru.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+["http://pt.wiktionary.org/w/opensearch_desc.php","wiktionary"],
+
+["http://search.yippy.com/search?v:project=opensearch-desc&amp;v:frame=form&amp;","yippy"],
+["http://www.wolframalpha.com/searchDescription.xml","wolfram_alpha"]] \ No newline at end of file
diff --git a/src/data/de2en.xml b/src/data/de2en.xml
new file mode 100644
index 00000000..60901163
--- /dev/null
+++ b/src/data/de2en.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>De-En Beolingus</ShortName>
+ <Description>Beolingus: German-English Dictionary</Description>
+ <Url method="get" template="http://dict.tu-chemnitz.de/?query={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+json" template="http://dict.tu-chemnitz.de/sugg.php?json=1;s={searchTerms}"/>
+ <Image>http://dict.tu-chemnitz.de/pics/beo-de.png</Image>
+</OpenSearchDescription>
diff --git a/src/data/dictfr.xml b/src/data/dictfr.xml
new file mode 100644
index 00000000..64e90ea3
--- /dev/null
+++ b/src/data/dictfr.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>Portail Lexical - CNRTL</ShortName>
+ <Description>Cherche dans le TLF sur le portail lexical du CNRTL</Description>
+ <Url method="get" template="http://www.cnrtl.fr/definition/{searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+json" template="http://www.cnrtl.fr/utilities/OPEN?query={searchTerms}"/>
+ <Image>http://www.cnrtl.fr/favicon.ico</Image>
+</OpenSearchDescription>
diff --git a/src/data/facebook.xml b/src/data/facebook.xml
new file mode 100644
index 00000000..612e7cd0
--- /dev/null
+++ b/src/data/facebook.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>Facebook</ShortName>
+ <Description>Search Facebook</Description>
+ <Url method="get" template="http://www.facebook.com/search/?src=os&amp;q={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+xml" template="http://www.facebook.com/search/opensearch_typeahead.php?format=xml&amp;q={searchTerms}"/>
+ <Image>http://www.facebook.com/favicon.ico</Image>
+</OpenSearchDescription>
diff --git a/src/data/kde_techbase.xml b/src/data/kde_techbase.xml
new file mode 100644
index 00000000..25fc6e4c
--- /dev/null
+++ b/src/data/kde_techbase.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>KDE TechBase (en)</ShortName>
+ <Description>KDE TechBase (en)</Description>
+ <Url method="get" template="http://techbase.kde.org/index.php?title=Special:Search&amp;search={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+xml" template="http://techbase.kde.org/api.php?action=opensearch&amp;format=xml&amp;search={searchTerms}&amp;namespace=0"/>
+ <Image>http://techbase.kde.org/favicon.ico</Image>
+</OpenSearchDescription>
diff --git a/src/data/kde_userbase.xml b/src/data/kde_userbase.xml
new file mode 100644
index 00000000..64877019
--- /dev/null
+++ b/src/data/kde_userbase.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>KDE UserBase (en)</ShortName>
+ <Description>KDE UserBase (en)</Description>
+ <Url method="get" template="http://userbase.kde.org/index.php?title=Special:Search&amp;search={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+xml" template="http://userbase.kde.org/api.php?action=opensearch&amp;format=xml&amp;search={searchTerms}&amp;namespace=0"/>
+ <Image>http://userbase.kde.org/favicon.png</Image>
+</OpenSearchDescription>
diff --git a/src/data/voila.xml b/src/data/voila.xml
new file mode 100644
index 00000000..55780275
--- /dev/null
+++ b/src/data/voila.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>Voila</ShortName>
+ <Description>Moteur de recherche Voila</Description>
+ <Url method="get" template="http://rws.search.ke.voila.fr/RW/S/opensearch_voila?rdata={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+json" template="http://search.ke.voila.fr/fr/cmplopensearch/xml/fullxml?rdata={searchTerms}&amp;amp;id=1&amp;amp;dtd=2.0"/>
+ <Image>http://www.voila.fr/favicon.ico</Image>
+</OpenSearchDescription>
diff --git a/src/data/wikia.xml b/src/data/wikia.xml
new file mode 100644
index 00000000..0a1eac69
--- /dev/null
+++ b/src/data/wikia.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>Wikia (en)</ShortName>
+ <Description>Wikia (en)</Description>
+ <Url method="get" template="http://www.wikia.com/index.php?title=Special:Search&amp;search={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+json" template="http://www.wikia.com/api.php?action=opensearch&amp;search={searchTerms}&amp;namespace=1"/>
+ <Image>http://images.wikia.com/wikiaglobal/images/6/64/Favicon.ico</Image>
+</OpenSearchDescription>
diff --git a/src/data/wikipedia.xml b/src/data/wikipedia.xml
index 4e152087..9f9bdda4 100644
--- a/src/data/wikipedia.xml
+++ b/src/data/wikipedia.xml
@@ -2,7 +2,7 @@
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Wikipedia</ShortName>
<Description>Wikipedia</Description>
- <Url method="get" template="http://en.wikipedia.org/w/index.php?title=Sp%C3%A9cial:Recherche&amp;search={searchTerms}"/>
- <Url method="get" type="application/x-suggestions+xml" template="http://en.wikipedia.org/w/api.php?action=opensearch&amp;format=xml&amp;search={searchTerms}&amp;namespace=0"/>
+ <Url method="get" template="http://{country}.wikipedia.org/w/index.php?title=Sp%C3%A9cial:Recherche&amp;search={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+xml" template="http://{country}.wikipedia.org/w/api.php?action=opensearch&amp;format=xml&amp;search={searchTerms}&amp;namespace=0"/>
<Image>http://en.wikipedia.org/favicon.ico</Image>
</OpenSearchDescription>
diff --git a/src/data/wiktionary.xml b/src/data/wiktionary.xml
new file mode 100644
index 00000000..033f5b9e
--- /dev/null
+++ b/src/data/wiktionary.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>Wiktionary</ShortName>
+ <Description>Wiktionary</Description>
+ <Url method="get" template="http://{country}.wiktionary.org/w/index.php?title=Special:Search&amp;search={searchTerms}"/>
+ <Url method="get" type="application/x-suggestions+xml" template="http://{country}.wiktionary.org/w/api.php?action=opensearch&amp;format=xml&amp;search={searchTerms}&amp;namespace=0"/>
+ <Image>http://en.wiktionary.org/favicon.ico</Image>
+</OpenSearchDescription>
diff --git a/src/data/wr_english.xml b/src/data/wr_english.xml
new file mode 100644
index 00000000..30c9339b
--- /dev/null
+++ b/src/data/wr_english.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>WR English</ShortName>
+ <Description>WordReference monolingual English dictionary search</Description>
+ <Url method="get" template="http://www.wordreference.com/definition/{searchTerms}"/>
+</OpenSearchDescription>
diff --git a/src/data/youtube.xml b/src/data/youtube.xml
new file mode 100644
index 00000000..1fa8338a
--- /dev/null
+++ b/src/data/youtube.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+ <ShortName>Recherche de vidéos YouTube</ShortName>
+ <Description>Recherche de vidéos sur YouTube</Description>
+ <Url method="get" template="http://www.youtube.com/results?search_query={searchTerms}&amp;page={startPage?}&amp;utm_source=opensearch"/>
+ <Image>http://www.youtube.com/favicon.ico</Image>
+</OpenSearchDescription>
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 4159d451..938e6985 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -737,12 +737,12 @@ void MainWindow::printRequested(QWebFrame *frame)
connect(this, SIGNAL(triggerPartPrint()), ext, actionSlotMap->value("print"));
emit triggerPartPrint();
-
+
return;
}
}
}
-
+
QWebFrame *printFrame = 0;
if (frame == 0)
{
@@ -800,7 +800,7 @@ void MainWindow::findNext()
return;
}
}
-
+
if (m_findBar->isHidden())
{
QPoint previous_position = currentTab()->view()->page()->currentFrame()->scrollPosition();
@@ -1385,7 +1385,7 @@ bool MainWindow::queryClose()
// smooth private browsing mode
if(QWebSettings::globalSettings()->testAttribute(QWebSettings::PrivateBrowsingEnabled))
return true;
-
+
if (m_view->count() > 1)
{
int answer = KMessageBox::questionYesNoCancel(
diff --git a/src/opensearch/opensearchengine.cpp b/src/opensearch/opensearchengine.cpp
index 9d5e866f..37685fb5 100644
--- a/src/opensearch/opensearchengine.cpp
+++ b/src/opensearch/opensearchengine.cpp
@@ -57,12 +57,18 @@ QString OpenSearchEngine::parseTemplate(const QString &searchTerm, const QString
QString language = QLocale().name();
// Simple conversion to RFC 3066.
language = language.replace(QL1C('_'), QL1C('-'));
+ QString country = language;
+ country = (country.replace(0, country.indexOf("-")+1, "")).toLower();
+ const int firstDashPosition = country.indexOf(QL1C('-'));
+ if (firstDashPosition >= 0)
+ country = country.mid(firstDashPosition+1);
QString result = searchTemplate;
result.replace(QL1S("{count}"), QL1S("20"));
result.replace(QL1S("{startIndex}"), QL1S("0"));
result.replace(QL1S("{startPage}"), QL1S("0"));
result.replace(QL1S("{language}"), language);
+ result.replace(QL1S("{country}"), country.toLower());
result.replace(QL1S("{inputEncoding}"), QL1S("UTF-8"));
result.replace(QL1S("{outputEncoding}"), QL1S("UTF-8"));
result.replace(QL1S("{searchTerms}"), searchTerm);
diff --git a/src/opensearch/opensearchmanager.cpp b/src/opensearch/opensearchmanager.cpp
index e5afc144..4ee1de33 100644
--- a/src/opensearch/opensearchmanager.cpp
+++ b/src/opensearch/opensearchmanager.cpp
@@ -34,6 +34,7 @@
#include "opensearchengine.h"
#include "opensearchreader.h"
#include "opensearchwriter.h"
+#include "application.h"
// KDE Includes
#include <KDebug>
@@ -41,10 +42,17 @@
#include <KStandardDirs>
#include <KUrl>
#include <kio/scheduler.h>
+#include <KService>
+#include <KStandardDirs>
+#include <KDE/KMessageBox>
+#include <KUriFilterData>
+#include <KConfigGroup>
// Qt Includes
#include <QtCore/QFile>
-
+#include <QtCore/QFileInfo>
+#include <QDBusMessage>
+#include <QDBusConnection>
OpenSearchManager::OpenSearchManager(QObject *parent)
: QObject(parent)
@@ -52,13 +60,15 @@ OpenSearchManager::OpenSearchManager(QObject *parent)
, m_currentJob(0)
{
m_state = IDLE;
+ loadEngines();
}
OpenSearchManager::~OpenSearchManager()
{
- qDeleteAll(m_enginesMap.values());
- m_enginesMap.clear();
+ qDeleteAll(m_engineCache.values());
+ m_engineCache.clear();
+ m_engines.clear();
}
@@ -66,10 +76,10 @@ void OpenSearchManager::setSearchProvider(const QString &searchProvider)
{
m_activeEngine = 0;
- if (!m_enginesMap.contains(searchProvider))
+ if (!m_engineCache.contains(searchProvider))
{
- const QString fileName = KGlobal::dirs()->findResource("data", "rekonq/opensearch/" + searchProvider + ".xml");
- kDebug() << searchProvider << " file name path: " << fileName;
+ const QString fileName = KGlobal::dirs()->findResource("data", "rekonq/opensearch/" + trimmedEngineName(searchProvider) + ".xml");
+ kDebug() << searchProvider << " trimmed name: " << trimmedEngineName(searchProvider) << " file name path: " << fileName;
if (fileName.isEmpty())
{
kDebug() << "OpenSearch file name empty";
@@ -88,7 +98,7 @@ void OpenSearchManager::setSearchProvider(const QString &searchProvider)
if (engine)
{
- m_enginesMap.insert(searchProvider, engine);
+ m_engineCache.insert(searchProvider, engine);
}
else
{
@@ -96,7 +106,7 @@ void OpenSearchManager::setSearchProvider(const QString &searchProvider)
}
}
- m_activeEngine = m_enginesMap.value(searchProvider);
+ m_activeEngine = m_engineCache.value(searchProvider);
}
@@ -106,22 +116,24 @@ bool OpenSearchManager::isSuggestionAvailable()
}
-void OpenSearchManager::addOpenSearchEngine(const KUrl &url, const QString &title)
+void OpenSearchManager::addOpenSearchEngine(const KUrl &url, const QString &title, const QString &shortcut)
{
Q_UNUSED(title);
+ m_shortcut = shortcut;
+
if (m_state != IDLE)
{
idleJob();
}
m_currentJob = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo);
+ m_jobUrl = url;
m_state = REQ_DESCRIPTION;
connect(m_currentJob, SIGNAL(data(KIO::Job *, const QByteArray &)), this, SLOT(dataReceived(KIO::Job *, const QByteArray &)));
connect(m_currentJob, SIGNAL(result(KJob *)), this, SLOT(jobFinished(KJob *)));
}
-
void OpenSearchManager::requestSuggestion(const QString &searchText)
{
if (!m_activeEngine)
@@ -135,7 +147,7 @@ void OpenSearchManager::requestSuggestion(const QString &searchText)
// if we want in any case lets it finish its previous job we can just return here.
idleJob();
}
-
+
_typedText = searchText;
KUrl url = m_activeEngine->suggestionsUrl(searchText);
@@ -163,7 +175,7 @@ void OpenSearchManager::jobFinished(KJob *job)
m_state = IDLE;
return; // just silently return
}
-
+
if (m_state == REQ_SUGGESTION)
{
const ResponseList suggestionsList = m_activeEngine->parseSuggestion(m_jobData);
@@ -184,40 +196,144 @@ void OpenSearchManager::jobFinished(KJob *job)
OpenSearchEngine *engine = reader.read(m_jobData);
if (engine)
{
- m_enginesMap.insert(engine->name(), engine);
- QString path = KGlobal::dirs()->findResource("data", "rekonq/opensearch/");
- QString fileName = trimmedEngineName(engine->name());
- QFile file(path + fileName + ".xml");
- OpenSearchWriter writer;
- writer.write(&file, engine);
+ m_engineCache.insert(engine->name(), engine);
+ m_engines.insert(m_jobUrl, trimmedEngineName(engine->name()));
+ saveEngines();
+
+ QString path;
+ if (engine->providesSuggestions()) //save opensearch description only if it provides suggestions
+ {
+ OpenSearchWriter writer;
+ path = KGlobal::dirs()->findResource("data", "rekonq/opensearch/");
+ QFile file(path + trimmedEngineName(engine->name()) + ".xml");
+ writer.write(&file, engine);
+ }
QString searchUrl = OpenSearchEngine::parseTemplate("\\{@}", engine->searchUrlTemplate());
m_currentJob = NULL;
- emit openSearchEngineAdded(engine->name(), searchUrl, fileName);
+
+ path = KGlobal::mainComponent().dirs()->saveLocation("services", "searchproviders/");
+ KConfig _service(path + trimmedEngineName(engine->name()) + ".desktop", KConfig::SimpleConfig);
+ KConfigGroup service(&_service, "Desktop Entry");
+ service.writeEntry("Type", "Service");
+ service.writeEntry("ServiceTypes", "SearchProvider");
+ service.writeEntry("Name", engine->name());
+ service.writeEntry("Query", searchUrl);
+ service.writeEntry("Keys", m_shortcut);
+ // TODO charset
+ service.writeEntry("Charset", "" /* provider->charset() */);
+ // we might be overwriting a hidden entry
+ service.writeEntry("Hidden", false);
+ service.sync();
+
+ // Update filters in running applications...
+ QDBusMessage msg = QDBusMessage::createSignal("/", "org.kde.KUriFilterPlugin", "configure");
+ QDBusConnection::sessionBus().send(msg);
+
+ emit openSearchEngineAdded(engine->name(), searchUrl, m_shortcut);
}
else
{
kFatal() << "Error while adding new open search engine";
}
-
+
idleJob();
}
}
+void OpenSearchManager::loadEngines()
+{
+ QFile file(KStandardDirs::locate("appdata", "opensearch/db_opensearch.json"));
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ kDebug() << "opensearch db cannot be read";
+ return;
+ }
+
+ QString fileContent = QString::fromUtf8(file.readAll());
+ QScriptEngine reader;
+ if (!reader.canEvaluate(fileContent))
+ {
+ kDebug() << "opensearch db cannot be read";
+ return;
+ }
+
+ QScriptValue responseParts = reader.evaluate(fileContent);
+ QVariantList list;
+ qScriptValueToSequence(responseParts, list);
+ QStringList l;
+ Q_FOREACH(const QVariant &e, list)
+ {
+ l=e.toStringList();
+ m_engines.insert(KUrl(l.first()),l.last());
+ }
+ file.close();
+}
+
+
+void OpenSearchManager::saveEngines()
+{
+ QFile file(KStandardDirs::locate("appdata", "opensearch/db_opensearch.json"));
+ if (!file.open(QIODevice::WriteOnly))
+ {
+ kDebug() << "opensearch db cannot be writen";
+ return;
+ }
+ QTextStream out(&file);
+ out << "[";
+ int i=0;
+ QList<KUrl> urls = m_engines.keys();
+ Q_FOREACH(const KUrl &url, urls)
+ {
+ out << "[\"" << url.url() << "\",\"" << m_engines.value(url) << "\"]";
+ i++;
+ if (i != urls.size())
+ {
+ out << ",\n";
+ }
+ }
+ out << "]\n";
+ file.close();
+}
+
+
+void OpenSearchManager::removeDeletedEngines()
+{
+ KService::Ptr service;
+ Q_FOREACH(const KUrl &url, m_engines.keys())
+ {
+ service = KService::serviceByDesktopPath(QString("searchproviders/%1.desktop").arg(m_engines.value(url)));
+ if (!service)
+ {
+ QString path = KStandardDirs::locate("appdata", "opensearch/" + trimmedEngineName(m_engines.value(url)) + ".xml");
+ QFile::remove(path + trimmedEngineName(m_engines.value(url)) + ".xml");
+ m_engines.remove(url);
+ }
+ }
+ saveEngines();
+}
+
+
+bool OpenSearchManager::engineExists(const KUrl &url)
+{
+ return m_engines.contains(url);
+}
+
+
QString OpenSearchManager::trimmedEngineName(const QString &engineName) const
{
QString trimmed;
QString::ConstIterator constIter = engineName.constBegin();
- while (constIter != engineName.constEnd())
+ while (constIter != engineName.constEnd())
{
- if (constIter->isSpace())
+ if (constIter->isSpace())
{
- trimmed.append('-');
+ trimmed.append('_');
}
- else
+ else
{
- if (*constIter != '.')
+ if (*constIter != '.')
{
trimmed.append(constIter->toLower());
}
diff --git a/src/opensearch/opensearchmanager.h b/src/opensearch/opensearchmanager.h
index 4f42b4a8..df8e5367 100644
--- a/src/opensearch/opensearchmanager.h
+++ b/src/opensearch/opensearchmanager.h
@@ -39,6 +39,7 @@
// Qt Includes
#include <QtCore/QObject>
+#include <QFile>
// Forward Declarations
class OpenSearchEngine;
@@ -59,7 +60,7 @@ class OpenSearchManager : public QObject
REQ_DESCRIPTION,
IDLE
};
-
+
public:
/**
* Constructor
@@ -76,7 +77,7 @@ public:
*/
bool isSuggestionAvailable();
- void addOpenSearchEngine(const KUrl &url, const QString &title);
+ bool engineExists(const KUrl &url);
public Q_SLOTS:
/**
@@ -85,6 +86,8 @@ public Q_SLOTS:
* @param searchText the text to be queried to the suggestion service
*/
void requestSuggestion(const QString &searchText);
+ void addOpenSearchEngine(const KUrl &url, const QString &title, const QString &shortcut);
+ void removeDeletedEngines();
private Q_SLOTS:
void dataReceived(KIO::Job *job, const QByteArray &data);
@@ -96,18 +99,23 @@ Q_SIGNALS:
private:
QString trimmedEngineName(const QString &engineName) const;
-
+ void loadEngines();
+ void saveEngines();
void idleJob();
-
+
// QString substitutueSearchText(const QString &searchText, const QString &requestURL) const;
QByteArray m_jobData;
- QMap<QString, OpenSearchEngine*> m_enginesMap;
+ QMap<QString, OpenSearchEngine*> m_engineCache;
+ QMap<KUrl, QString> m_engines;
+
OpenSearchEngine *m_activeEngine;
STATE m_state;
-
+
KIO::TransferJob *m_currentJob;
+ KUrl m_jobUrl;
QString _typedText;
+ QString m_shortcut;
};
#endif // OPENSEARCHMANAGER_H
diff --git a/src/opensearch/suggestionparser.cpp b/src/opensearch/suggestionparser.cpp
index 4ed13e16..b2ecd009 100644
--- a/src/opensearch/suggestionparser.cpp
+++ b/src/opensearch/suggestionparser.cpp
@@ -35,7 +35,7 @@
ResponseList SuggestionParser::parse(const QByteArray &)
{
- return ResponseList();
+ return ResponseList();
}
@@ -47,7 +47,7 @@ SuggestionParser::~SuggestionParser()
ResponseList XMLParser::parse(const QByteArray &resp)
{
ResponseList rlist;
-
+
m_reader.clear();
m_reader.addData(resp);
@@ -73,16 +73,19 @@ ResponseList XMLParser::parse(const QByteArray &resp)
{
if(m_reader.isStartElement())
{
+
if (m_reader.name() == QL1S("Text"))
title = m_reader.readElementText();
if (m_reader.name() == QL1S("Url"))
url = m_reader.readElementText();
+
if (m_reader.name() == QL1S("Image"))
{
image = m_reader.attributes().value("source").toString();
image_width = m_reader.attributes().value("width").toString().toInt();
image_height = m_reader.attributes().value("height").toString().toInt();
}
+
if (m_reader.name() == QL1S("Description"))
description = m_reader.readElementText();
}
@@ -94,7 +97,7 @@ ResponseList XMLParser::parse(const QByteArray &resp)
m_reader.readNext();
}
-
+
return rlist;
}
@@ -103,23 +106,23 @@ ResponseList JSONParser::parse(const QByteArray &resp)
{
QString response = QString::fromLocal8Bit(resp);
response = response.trimmed();
-
- if (response.isEmpty())
+
+ if (response.isEmpty())
{
kDebug() << "RESPONSE IS EMPTY";
return ResponseList();
}
-
- if (!response.startsWith(QL1C('['))
+
+ if (!response.startsWith(QL1C('['))
|| !response.endsWith(QL1C(']'))
- )
+ )
{
kDebug() << "RESPONSE is NOT well FORMED";
return ResponseList();
}
// Evaluate the JSON response using QtScript.
- if (!m_reader.canEvaluate(response))
+ if (!m_reader.canEvaluate(response))
{
kDebug() << "m_reader cannot evaluate the response";
return ResponseList();
@@ -127,7 +130,7 @@ ResponseList JSONParser::parse(const QByteArray &resp)
QScriptValue responseParts = m_reader.evaluate(response);
- if (!responseParts.property(1).isArray())
+ if (!responseParts.property(1).isArray())
{
kDebug() << "RESPONSE is not an array";
return ResponseList();
@@ -141,6 +144,6 @@ ResponseList JSONParser::parse(const QByteArray &resp)
{
rlist << Response(s);
}
-
+
return rlist;
}
diff --git a/src/settings/generalwidget.cpp b/src/settings/generalwidget.cpp
index 642813ae..0128830c 100644
--- a/src/settings/generalwidget.cpp
+++ b/src/settings/generalwidget.cpp
@@ -48,9 +48,9 @@ GeneralWidget::GeneralWidget(QWidget *parent)
connect(setHomeToCurrentPageButton, SIGNAL(clicked()), this, SLOT(setHomeToCurrentPage()));
disableHomeSettings(ReKonfig::useNewTabPage());
-
+
connect(kcfg_useNewTabPage, SIGNAL(toggled(bool)), this, SLOT(disableHomeSettings(bool)));
-
+
checkKGetPresence();
}
diff --git a/src/settings/settingsdialog.cpp b/src/settings/settingsdialog.cpp
index a3b4f976..4a8776ad 100644
--- a/src/settings/settingsdialog.cpp
+++ b/src/settings/settingsdialog.cpp
@@ -37,6 +37,7 @@
#include "mainwindow.h"
#include "webtab.h"
#include "searchengine.h"
+#include "opensearchmanager.h"
// Widget Includes
#include "adblockwidget.h"
@@ -70,7 +71,7 @@ private:
WebKitWidget *webkitWidg;
NetworkWidget *networkWidg;
AdBlockWidget *adBlockWidg;
-
+
KCModuleProxy *ebrowsingModule;
KShortcutsEditor *shortcutsEditor;
@@ -94,13 +95,13 @@ Private::Private(SettingsDialog *parent)
tabsWidg->layout()->setMargin(0);
pageItem = parent->addPage(tabsWidg, i18n("Tabs"));
pageItem->setIcon(KIcon("tab-duplicate"));
-
+
// -- 3
appearanceWidg = new AppearanceWidget(parent);
appearanceWidg->layout()->setMargin(0);
pageItem = parent->addPage(appearanceWidg, i18n("Appearance"));
pageItem->setIcon(KIcon("preferences-desktop-font"));
-
+
// -- 4
webkitWidg = new WebKitWidget(parent);
webkitWidg->layout()->setMargin(0);
@@ -108,7 +109,7 @@ Private::Private(SettingsDialog *parent)
QString webkitIconPath = KStandardDirs::locate("appdata", "pics/webkit-icon.png");
KIcon webkitIcon = KIcon(QIcon(webkitIconPath));
pageItem->setIcon(webkitIcon);
-
+
// -- 5
networkWidg = new NetworkWidget(parent);
networkWidg->layout()->setMargin(0);
@@ -151,7 +152,7 @@ SettingsDialog::SettingsDialog(QWidget *parent)
setModal(true);
readConfig();
-
+
// update buttons
connect(d->generalWidg, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
connect(d->tabsWidg, SIGNAL(changed(bool)), this, SLOT(updateButtons()));
@@ -187,7 +188,7 @@ void SettingsDialog::saveSettings()
return;
ReKonfig::self()->writeConfig();
-
+
d->generalWidg->save();
d->tabsWidg->save();
d->appearanceWidg->save();
@@ -196,8 +197,9 @@ void SettingsDialog::saveSettings()
d->adBlockWidg->save();
d->shortcutsEditor->save();
d->ebrowsingModule->save();
-
+
SearchEngine::reload();
+ Application::opensearchManager()->removeDeletedEngines();
updateButtons();
emit settingsChanged("ReKonfig");
diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp
index f29a0e98..d82613f1 100644
--- a/src/urlbar/listitem.cpp
+++ b/src/urlbar/listitem.cpp
@@ -63,9 +63,9 @@ ListItem::ListItem(const UrlSearchItem &item, QWidget *parent)
: QWidget(parent)
, m_option()
, m_url(item.url)
-{
+{
m_option.initFrom(this);
- m_option.direction = Qt::LeftToRight;
+ m_option.direction = Qt::LeftToRight;
// use the same application palette (hence, the same colors)
// Qt docs says that using this cctor is possible & fast (qt:qpalette)
@@ -98,7 +98,7 @@ void ListItem::deactivate()
void ListItem::paintEvent(QPaintEvent *event)
{
- Q_UNUSED(event);
+ Q_UNUSED(event);
QWidget::paintEvent(event);
QPainter painter(this);
@@ -473,7 +473,7 @@ KAction *EngineBar::newEngineAction(KService::Ptr engine, KService::Ptr selected
{
QUrl u = engine->property("Query").toUrl();
KUrl url = KUrl( u.toString( QUrl::RemovePath | QUrl::RemoveQuery ) );
-
+
kDebug() << "Engine NAME: " << engine->name() << " URL: " << url;
KAction *a = new KAction(Application::iconManager()->iconForUrl(url), engine->name(), this);
a->setCheckable(true);
@@ -562,7 +562,7 @@ VisualSuggestionListItem::VisualSuggestionListItem(const UrlSearchItem &item, co
new IconLabel(item.url, previewLabelIcon);
}
- hLayout->addWidget(previewLabelIcon);
+ hLayout->addWidget(previewLabelIcon);
QVBoxLayout *vLayout = new QVBoxLayout;
vLayout->setMargin(0);
vLayout->addItem(new QSpacerItem(0,0,QSizePolicy::Expanding,QSizePolicy::MinimumExpanding));
@@ -608,31 +608,31 @@ BrowseListItem::BrowseListItem(const UrlSearchItem &item, const QString &text, Q
ListItem *ListItemFactory::create(const UrlSearchItem &item, const QString &text, QWidget *parent)
-{
+{
if (item.type & UrlSearchItem::Search)
{
kDebug() << "Search";
return new SearchListItem(item, text, parent);
}
-
+
if (item.type & UrlSearchItem::Browse)
{
kDebug() << "Browse";
return new BrowseListItem(item, text, parent);
}
-
+
if (item.type & UrlSearchItem::History)
{
kDebug() << "History";
return new PreviewListItem(item, text, parent);
}
-
+
if (item.type & UrlSearchItem::Bookmark)
{
kDebug() << "Bookmark";
return new PreviewListItem(item, text, parent);
}
-
+
if (item.type & UrlSearchItem::Suggestion)
{
kDebug() << "ITEM URL: " << item.url;
@@ -641,11 +641,11 @@ ListItem *ListItemFactory::create(const UrlSearchItem &item, const QString &text
kDebug() << "Suggestion";
return new SuggestionListItem(item, text, parent);
}
-
+
kDebug() << "Visual Suggestion";
return new VisualSuggestionListItem(item, text, parent);
}
-
+
kDebug() << "Undefined";
return new PreviewListItem(item, text, parent);
}
diff --git a/src/urlbar/listitem.h b/src/urlbar/listitem.h
index f5f11532..0d66a12c 100644
--- a/src/urlbar/listitem.h
+++ b/src/urlbar/listitem.h
@@ -63,7 +63,7 @@ public:
KUrl url();
virtual QString text();
-
+
public slots:
virtual void nextItemSubChoice();
diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp
index d93aeb75..f963be07 100644
--- a/src/urlbar/urlbar.cpp
+++ b/src/urlbar/urlbar.cpp
@@ -110,7 +110,10 @@ UrlBar::UrlBar(QWidget *parent)
connect(_tab->view(), SIGNAL(iconChanged()), this, SLOT(refreshFavicon()));
// bookmark icon
- connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(const QString &, const QString &)), this, SLOT(onBookmarksChanged()));
+ connect(Application::bookmarkProvider()->bookmarkManager(), SIGNAL(changed(const QString &, const QString &)), this, SLOT(updateRightIcons()));
+
+ // search icon
+ connect(Application::opensearchManager(), SIGNAL(openSearchEngineAdded(const QString &, const QString &, const QString &)), this, SLOT(updateRightIcons()));
_suggestionTimer->setSingleShot(true);
connect(_suggestionTimer, SIGNAL(timeout()), this, SLOT(suggest()));
@@ -335,6 +338,13 @@ void UrlBar::loadFinished()
connect(bt, SIGNAL(clicked(QPoint)), _tab->page(), SLOT(showSSLInfo(QPoint)));
}
+ // show add search engine
+ if (_tab->hasNewSearchEngine())
+ {
+ IconButton *bt = addRightIcon(UrlBar::SearchEngine);
+ connect(bt, SIGNAL(clicked(QPoint)), _tab, SLOT(showSearchEngine(QPoint)));
+ }
+
// we need to update urlbar after the right icon settings
// removing this code (where setStyleSheet automatically calls update) needs adding again
// an update call
@@ -367,7 +377,7 @@ void UrlBar::showBookmarkInfo(const QPoint &pos)
}
-void UrlBar::onBookmarksChanged()
+void UrlBar::updateRightIcons()
{
if (!_tab->isPageLoading())
{
@@ -442,6 +452,10 @@ IconButton *UrlBar::addRightIcon(UrlBar::icon ic)
rightIcon->setToolTip(i18n("Edit this bookmark"));
}
break;
+ case UrlBar::SearchEngine:
+ rightIcon->setIcon(KIcon("preferences-web-browser-shortcuts"));
+ rightIcon->setToolTip(i18n("Add search engine"));
+ break;
default:
kDebug() << "ERROR.. default non extant case!!";
break;
diff --git a/src/urlbar/urlbar.h b/src/urlbar/urlbar.h
index 67a693c0..964534cb 100644
--- a/src/urlbar/urlbar.h
+++ b/src/urlbar/urlbar.h
@@ -79,10 +79,11 @@ public:
enum icon
{
- KGet = 0x00000001,
- RSS = 0x00000010,
- SSL = 0x00000100,
- BK = 0x00001000
+ KGet = 0x00000001,
+ RSS = 0x00000010,
+ SSL = 0x00000100,
+ BK = 0x00001000,
+ SearchEngine = 0x00010000
};
explicit UrlBar(QWidget *parent = 0);
@@ -100,15 +101,15 @@ private slots:
void loadTyped(const QString &);
void clearRightIcons();
-
+ void updateRightIcons();
+
void detectTypedString(const QString &);
void suggest();
void showBookmarkInfo(const QPoint &pos);
- void onBookmarksChanged();
void refreshFavicon();
-
+
protected:
void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *event);
diff --git a/src/urlbar/urlresolver.cpp b/src/urlbar/urlresolver.cpp
index 57d6ca64..864eca04 100644
--- a/src/urlbar/urlresolver.cpp
+++ b/src/urlbar/urlresolver.cpp
@@ -412,16 +412,12 @@ void UrlResolver::suggestionsReceived(const QString &text, const ResponseList &s
Q_FOREACH(const Response &i, suggestions)
{
- QString urlString = i.url;
- if(urlString.isEmpty())
+ QString url = i.url;
+ if (url.isEmpty())
{
- QStringList list;
- list << QL1S("kuriikwsfilter");
- urlString = KUriFilter::self()->filteredUri(i.title, list);
+ url = SearchEngine::buildQuery(searchEngine(), i.title);
}
- kDebug() << "RESPONSE URL: " << i.url;
-
- UrlSearchItem gItem(UrlSearchItem::Suggestion, urlString, i.title, i.description, i.image, i.image_width, i.image_height);
+ UrlSearchItem gItem(UrlSearchItem::Suggestion, url, i.title, i.description, i.image, i.image_width, i.image_height);
sugList << gItem;
}
emit suggestionsReady(sugList, _typedString);
diff --git a/src/urlbar/webshortcutwidget.cpp b/src/urlbar/webshortcutwidget.cpp
new file mode 100644
index 00000000..843d528b
--- /dev/null
+++ b/src/urlbar/webshortcutwidget.cpp
@@ -0,0 +1,184 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2009 Fredy Yanardi <fyanardi@gmail.com>
+ * Copyright (C) 2010 Lionel Chauvin <megabigbug@yahoo.fr>
+ *
+ * This library 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 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 "webshortcutwidget.h"
+
+#include <QtCore/QTimer>
+#include <QtCore/QSet>
+#include <QtGui/QBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QPushButton>
+#include <QtGui/QFormLayout>
+
+
+#include <KGlobalSettings>
+#include <KIcon>
+#include <KLocale>
+#include <KServiceTypeTrader>
+
+WebShortcutWidget::WebShortcutWidget(QWidget *parent)
+ : QDialog(parent)
+{
+ QVBoxLayout *mainLayout = new QVBoxLayout();
+ QHBoxLayout *titleLayout = new QHBoxLayout();
+ mainLayout->addLayout(titleLayout);
+ QLabel *iconLabel = new QLabel(this);
+ KIcon wsIcon("preferences-web-browser-shortcuts");
+ iconLabel->setPixmap(wsIcon.pixmap(22, 22));
+ titleLayout->addWidget(iconLabel);
+ m_searchTitleLabel = new QLabel(i18n("Add Search Engine"), this);
+ QFont boldFont = KGlobalSettings::generalFont();
+ boldFont.setBold(true);
+ m_searchTitleLabel->setFont(boldFont);
+ titleLayout->addWidget(m_searchTitleLabel);
+ titleLayout->addStretch();
+
+ QFormLayout *formLayout = new QFormLayout();
+ mainLayout->addLayout(formLayout);
+
+ QFont smallFont = KGlobalSettings::smallestReadableFont();
+ m_nameLineEdit = new QLineEdit(this);
+ m_nameLineEdit->setEnabled(false);
+ m_nameLineEdit->setFont(smallFont);
+ QLabel *nameLabel = new QLabel(i18n("Name:"), this);
+ nameLabel->setFont(smallFont);
+ formLayout->addRow(nameLabel, m_nameLineEdit);
+
+ QLabel *shortcutsLabel = new QLabel(i18n("Shortcuts:"), this);
+ shortcutsLabel->setFont(smallFont);
+ m_wsLineEdit = new QLineEdit(this);
+ m_wsLineEdit->setMinimumWidth(100);
+ m_wsLineEdit->setFont(smallFont);
+ formLayout->addRow(shortcutsLabel, m_wsLineEdit);
+ connect(m_wsLineEdit, SIGNAL(textChanged(QString)), SLOT(shortcutsChanged(const QString&)));
+
+ m_noteLabel = new QLabel(this);
+ m_noteLabel->setFont(boldFont);
+ m_noteLabel->setWordWrap(true);
+ formLayout->addRow(m_noteLabel);
+ m_noteLabel->setVisible(false);
+
+ mainLayout->addStretch();
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout();
+ mainLayout->addLayout(buttonLayout);
+ buttonLayout->addStretch();
+ m_okButton = new QPushButton(i18n("Ok"), this);
+ m_okButton->setDefault(true);
+ buttonLayout->addWidget(m_okButton);
+ connect(m_okButton, SIGNAL(clicked()), this, SLOT(okClicked()));
+
+ QPushButton *cancelButton = new QPushButton(i18n("Cancel"), this);
+ buttonLayout->addWidget(cancelButton);
+ connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancelClicked()));
+
+ setLayout(mainLayout);
+
+ setMinimumWidth (250);
+
+ m_providers = KServiceTypeTrader::self()->query("SearchProvider");
+
+ QTimer::singleShot(0, m_wsLineEdit, SLOT(setFocus()));
+}
+
+
+void WebShortcutWidget::showAt(const QPoint &pos)
+{
+ adjustSize();
+
+ QPoint p;
+ p.setX(pos.x() - width());
+ p.setY(pos.y() + 10);
+
+ move(p);
+ QDialog::show();
+}
+
+
+void WebShortcutWidget::show(const KUrl &url, const QString &openSearchName, const QPoint &pos)
+{
+ m_wsLineEdit->clear();
+ m_nameLineEdit->setText(openSearchName);
+ m_url = url;
+ showAt(pos);
+}
+
+
+void WebShortcutWidget::okClicked()
+{
+ hide();
+ emit webShortcutSet(m_url, m_nameLineEdit->text(), m_wsLineEdit->text());
+}
+
+
+void WebShortcutWidget::cancelClicked()
+{
+ hide();
+}
+
+
+void WebShortcutWidget::shortcutsChanged(const QString& newShorthands)
+{
+ int savedCursorPosition = m_wsLineEdit->cursorPosition();
+ QString normalizedShorthands = QString(newShorthands).replace(" ", ",");
+ m_wsLineEdit->setText(normalizedShorthands);
+ m_wsLineEdit->setCursorPosition(savedCursorPosition);
+
+ QSet<QString> shorthands = normalizedShorthands.split(",").toSet();
+ QString contenderName = "";
+ QString contenderWS = "";
+
+ Q_FOREACH (const QString &shorthand, shorthands)
+ {
+ Q_FOREACH (KService::Ptr provider, m_providers)
+ {
+ if(provider->property("Keys").toStringList().contains(shorthand))
+ {
+ contenderName = provider->property("Name").toString();
+ contenderWS = shorthand;
+ break;
+ }
+ }
+ }
+
+ if (!contenderName.isEmpty())
+ {
+ m_okButton->setEnabled(false);
+ m_noteLabel->setText(i18n("The shortcut \"%1\" is already assigned to \"%2\".", contenderWS, contenderName));
+ m_noteLabel->setVisible(true);
+ resize(minimumSize().width(), minimumSizeHint().height()+15);
+ }
+ else
+ {
+ m_okButton->setEnabled(true);
+ m_noteLabel->clear();
+ bool noteIsVisible = m_noteLabel->isVisible();
+ m_noteLabel->setVisible(false);
+ if (noteIsVisible)
+ {
+ resize(minimumSize());
+ }
+ }
+}
+
+#include "webshortcutwidget.moc"
+
+
diff --git a/src/urlbar/webshortcutwidget.h b/src/urlbar/webshortcutwidget.h
new file mode 100644
index 00000000..02ddaf17
--- /dev/null
+++ b/src/urlbar/webshortcutwidget.h
@@ -0,0 +1,61 @@
+/* This file is part of the KDE project
+ * Copyright (C) 2009 Fredy Yanardi <fyanardi@gmail.com>
+ * Copyright (C) 2010 Lionel Chauvin <megabigbug@yahoo.fr>
+ *
+ * This library 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 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 WEBSHORTCUTWIDGET_H
+#define WEBSHORTCUTWIDGET_H
+
+#include <QtGui/QDialog>
+#include <KUrl>
+#include <KService>
+
+class QLabel;
+class QLineEdit;
+
+class WebShortcutWidget : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit WebShortcutWidget(QWidget *parent = 0);
+
+ void show(const KUrl &url, const QString &openSearchName, const QPoint &pos);
+
+private slots:
+ void okClicked();
+ void cancelClicked();
+ void shortcutsChanged(const QString& newShorthands);
+
+signals:
+ void webShortcutSet(const KUrl &url, const QString &openSearchName, const QString &webShortcut);
+
+private:
+ QLabel *m_searchTitleLabel;
+ QLineEdit *m_wsLineEdit;
+ QLineEdit *m_nameLineEdit;
+ QLabel *m_noteLabel;
+ QPushButton *m_okButton;
+
+ KService::List m_providers;
+ KUrl m_url;
+
+ void showAt(const QPoint &pos);
+};
+
+#endif // WEBSHORTCUTWIDGET_H
+
diff --git a/src/webtab.cpp b/src/webtab.cpp
index bac73fec..2641f9c9 100644
--- a/src/webtab.cpp
+++ b/src/webtab.cpp
@@ -28,7 +28,6 @@
// Self Includes
#include "webtab.h"
#include "webtab.moc"
-
// Auto Includes
#include "rekonq.h"
@@ -38,14 +37,22 @@
#include "rsswidget.h"
#include "walletbar.h"
#include "webpage.h"
+#include "webshortcutwidget.h"
+#include "application.h"
+#include "opensearchmanager.h"
// KDE Includes
#include <KWebWallet>
+#include <KStandardShortcut>
+#include <KMenu>
+#include <KActionMenu>
+#include <KWebView>
+#include <KDebug>
+#include <KBuildSycocaProgressDialog>
// Qt Includes
#include <QtGui/QVBoxLayout>
-
WebTab::WebTab(QWidget *parent)
: QWidget(parent)
, m_webView(new WebView(this))
@@ -95,7 +102,7 @@ KUrl WebTab::url()
kDebug() << "REKONQ PAGE. URL = " << page()->loadingUrl();
return page()->loadingUrl();
}
-
+
return view()->url();
}
@@ -178,7 +185,7 @@ bool WebTab::hasRSSInfo()
}
-void WebTab::showRSSInfo(QPoint pos)
+void WebTab::showRSSInfo(const QPoint &pos)
{
QWebElementCollection col = page()->mainFrame()->findAllElements("link[type=\"application/rss+xml\"]");
col.append(page()->mainFrame()->findAllElements("link[type=\"application/atom+xml\"]"));
@@ -228,10 +235,64 @@ void WebTab::setPart(KParts::ReadOnlyPart *p, const KUrl &u)
if(!m_part)
return;
-
+
// Part NO more exists. Let's clean up from webtab
m_webView->show();
qobject_cast<QVBoxLayout *>(layout())->removeWidget(m_part->widget());
delete m_part;
m_part = 0;
}
+
+
+KUrl WebTab::extractOpensearchUrl(QWebElement e)
+{
+ QString href = e.attribute(QLatin1String("href"));
+ KUrl url = KUrl(href);
+ if (!href.contains(":"))
+ {
+ KUrl docUrl = m_webView->url();
+ QString host = docUrl.scheme() + "://" + docUrl.host();
+ if (docUrl.port() != -1)
+ {
+ host += ":" + QString::number(docUrl.port());
+ }
+ url = KUrl(docUrl, href);
+ }
+ return url;
+}
+
+
+bool WebTab::hasNewSearchEngine()
+{
+ QWebElement e = page()->mainFrame()->findFirstElement(QLatin1String("head >link[rel=\"search\"][ type=\"application/opensearchdescription+xml\"]"));
+ return !e.isNull() && !Application::opensearchManager()->engineExists(extractOpensearchUrl(e));
+}
+
+
+void WebTab::showSearchEngine(const QPoint &pos)
+{
+ QWebElement e = page()->mainFrame()->findFirstElement(QLatin1String("head >link[rel=\"search\"][ type=\"application/opensearchdescription+xml\"]"));
+ QString title = e.attribute(QLatin1String("title"));
+ if (!title.isEmpty())
+ {
+ WebShortcutWidget *widget = new WebShortcutWidget(window());
+ widget->setWindowFlags(Qt::Popup);
+
+ connect(widget, SIGNAL(webShortcutSet(const KUrl &, const QString &, const QString &)),
+ Application::opensearchManager(), SLOT(addOpenSearchEngine(const KUrl &, const QString &, const QString &)));
+ connect(Application::opensearchManager(), SIGNAL(openSearchEngineAdded(const QString &, const QString &, const QString &)),
+ this, SLOT(openSearchEngineAdded()));
+
+ widget->show(extractOpensearchUrl(e), title, pos);
+ }
+}
+
+
+void WebTab::openSearchEngineAdded()
+{
+ // If the providers changed, tell sycoca to rebuild its database...
+ KBuildSycocaProgressDialog::rebuildKSycoca(this);
+
+ disconnect(Application::opensearchManager(), SIGNAL(openSearchEngineAdded(const QString &, const QString &, const QString &)),
+ this, SLOT(openSearchEngineAdded()));
+}
diff --git a/src/webtab.h b/src/webtab.h
index 12f528d9..7b7c3c7a 100644
--- a/src/webtab.h
+++ b/src/webtab.h
@@ -33,6 +33,7 @@
#include "rekonq_defines.h"
// Local Includes
+#include "webpage.h"
#include "webview.h"
// KDE Includes
@@ -46,6 +47,7 @@ class UrlBar;
class PreviewSelectorBar;
class WalletBar;
class NotificationBar;
+class QPoint;
class REKONQ_TESTS_EXPORT WebTab : public QWidget
@@ -66,26 +68,32 @@ public:
void insertBar(NotificationBar* bar);
bool hasRSSInfo();
+
bool isPageLoading();
+ bool hasNewSearchEngine();
KParts::ReadOnlyPart *part() { return m_part; }
void setPart(KParts::ReadOnlyPart *p, const KUrl &u);
-
+
private Q_SLOTS:
void updateProgress(int progress);
void loadFinished(bool);
void createWalletBar(const QString &, const QUrl &);
- void showRSSInfo(QPoint pos);
+ void showRSSInfo(const QPoint &pos);
+ void showSearchEngine(const QPoint &pos);
+ void openSearchEngineAdded();
Q_SIGNALS:
void loadProgressing();
void titleChanged(const QString &);
-
+
private:
+ KUrl extractOpensearchUrl(QWebElement e);
+
WebView *const m_webView;
UrlBar *const m_urlBar;
-
+
int m_progress;
QWeakPointer<WalletBar> m_walletBar;