From 7a1aaf4d1e86d45691e981e92d99a817849240fd Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Tue, 1 Feb 2011 17:32:57 +0100 Subject: User Agent Switcher. This patch should implement the UA switcher ability for rekonq. This is a first implementation, but it seems working quite well. It is based on KDE UA management and should be fully compatible with konqueror's one i.e. it should be possible using alternatively rekonq and konqueror sharing the same setting. Anyway, this is a different implementation from the konqueror's one. Simpler and based on the idea of a future moving to a plugin. --- src/CMakeLists.txt | 5 + src/application.cpp | 2 +- src/mainwindow.cpp | 90 ++++++++++++++++++ src/mainwindow.h | 7 ++ src/useragent/useragentinfo.cpp | 188 +++++++++++++++++++++++++++++++++++++ src/useragent/useragentinfo.h | 78 +++++++++++++++ src/useragent/useragentsettings.ui | 72 ++++++++++++++ src/useragent/useragentwidget.cpp | 101 ++++++++++++++++++++ src/useragent/useragentwidget.h | 53 +++++++++++ 9 files changed, 595 insertions(+), 1 deletion(-) create mode 100644 src/useragent/useragentinfo.cpp create mode 100644 src/useragent/useragentinfo.h create mode 100644 src/useragent/useragentsettings.ui create mode 100644 src/useragent/useragentwidget.cpp create mode 100644 src/useragent/useragentwidget.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6cf26517..7f9fe19f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,6 +81,9 @@ SET( rekonq_KDEINIT_SRCS opensearch/opensearchmanager.cpp opensearch/opensearchengine.cpp opensearch/suggestionparser.cpp + #---------------------------------------- + useragent/useragentinfo.cpp + useragent/useragentwidget.cpp ) @@ -91,6 +94,7 @@ KDE4_ADD_UI_FILES( rekonq_KDEINIT_SRCS settings/settings_webkit.ui settings/settings_adblock.ui cleardata.ui + useragent/useragentsettings.ui ) KDE4_ADD_KCFG_FILES( rekonq_KDEINIT_SRCS rekonq.kcfgc ) @@ -107,6 +111,7 @@ INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/rekonqpage ${CMAKE_CURRENT_SOURCE_DIR}/settings ${CMAKE_CURRENT_SOURCE_DIR}/urlbar + ${CMAKE_CURRENT_SOURCE_DIR}/useragent ${CMAKE_CURRENT_BINARY_DIR} ${KDE4_INCLUDES} ${QT4_INCLUDES} diff --git a/src/application.cpp b/src/application.cpp index f38832cf..6f8cd8b2 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -249,7 +249,7 @@ 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 ReKonfig::setRecoverOnCrash(ReKonfig::recoverOnCrash() + 1); saveConfiguration(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ece11cc3..a93157a6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -52,6 +52,8 @@ #include "webpage.h" #include "webtab.h" #include "zoombar.h" +#include "useragentinfo.h" +#include "useragentwidget.h" // Ui Includes #include "ui_cleardata.h" @@ -71,6 +73,7 @@ #include #include #include +#include #include #include @@ -102,6 +105,7 @@ MainWindow::MainWindow() , m_analyzerPanel(0) , m_historyBackMenu(0) , m_encodingMenu(new KMenu(this)) + , m_userAgentMenu(new KMenu(this)) , m_bookmarksBar(0) , m_popup(new KPassivePopup(this)) , m_hidePopup(new QTimer(this)) @@ -243,6 +247,7 @@ void MainWindow::updateToolsMenu() m_toolsMenu->addAction(action); m_toolsMenu->addAction(actionByName(QL1S("encodings"))); + m_toolsMenu->addAction(actionByName(QL1S("useragent"))); m_toolsMenu->addSeparator(); @@ -524,6 +529,16 @@ void MainWindow::setupActions() a->setMenu(m_encodingMenu); connect(m_encodingMenu, SIGNAL(aboutToShow()), this, SLOT(populateEncodingMenu())); connect(m_encodingMenu, SIGNAL(triggered(QAction *)), this, SLOT(setEncoding(QAction *))); + + // --- User Agent + a = new KAction(KIcon("preferences-web-browser-identification"), i18n("Browser Identification"), this); + actionCollection()->addAction(QL1S("useragent"), a); + a->setMenu(m_userAgentMenu); + connect(m_userAgentMenu, SIGNAL(aboutToShow()), this, SLOT(populateUserAgentMenu())); + + a = new KAction(KIcon("preferences-web-browser-identification"), i18n("Browser Identification"), this); + actionCollection()->addAction(QL1S("UserAgentSettings"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(showUserAgentSettings())); } @@ -1344,6 +1359,22 @@ void MainWindow::setEncoding(QAction *qa) } +void MainWindow::setUserAgent() +{ + QAction *sender = static_cast(QObject::sender()); + + QString info; + QString desc = sender->text(); + int uaIndex = sender->data().toInt(); + + KUrl url = currentTab()->url(); + UserAgentInfo uaInfo; + kDebug() << "SETTING USER AGENT"; + uaInfo.setUserAgentForHost(uaIndex, url.host()); + currentTab()->page()->triggerAction(QWebPage::Reload); +} + + void MainWindow::populateEncodingMenu() { QStringList codecs; @@ -1402,6 +1433,51 @@ void MainWindow::populateEncodingMenu() } +void MainWindow::populateUserAgentMenu() +{ + kDebug() << "populating user agent menu..."; + bool defaultUA = true; + KUrl url = currentTab()->url(); + + QAction *a, *defaultAction; + + m_userAgentMenu->clear(); + + defaultAction = new QAction( i18nc("Default rekonq user agent", "Default"), this); + defaultAction->setData(-1); + defaultAction->setCheckable(true); + connect(defaultAction, SIGNAL(triggered(bool)), this, SLOT(setUserAgent())); + + m_userAgentMenu->addAction(defaultAction); + m_userAgentMenu->addSeparator(); + + UserAgentInfo uaInfo; + QStringList UAlist = uaInfo.availableUserAgents(); + int uaIndex = uaInfo.uaIndexForHost(currentTab()->url().host()); + + for (int i = 0; i < UAlist.count(); ++i) + { + QString uaDesc = UAlist.at(i); + + a = new QAction(uaDesc, this); + a->setData(i); + a->setCheckable(true); + connect(a, SIGNAL(triggered(bool)), this, SLOT(setUserAgent())); + + if(i == uaIndex) + { + a->setChecked(true); + defaultUA = false; + } + m_userAgentMenu->addAction(a); + } + defaultAction->setChecked(defaultUA); + + m_userAgentMenu->addSeparator(); + m_userAgentMenu->addAction( actionByName("UserAgentSettings") ); +} + + void MainWindow::enableNetworkAnalysis(bool b) { currentTab()->page()->enableNetworkAnalyzer(b); @@ -1474,3 +1550,17 @@ void MainWindow::setupBookmarksAndToolsShortcuts() connect(actionByName(QL1S("rekonq_tools")), SIGNAL(triggered()), toolsButton, SLOT(showMenu())); } } + + +void MainWindow::showUserAgentSettings() +{ + QPointer dialog = new KDialog(this); + dialog->setCaption(i18nc("@title:window", "User Agent Settings")); + dialog->setButtons(KDialog::Ok); + + UserAgentWidget widget; + dialog->setMainWidget(&widget); + dialog->exec(); + + dialog->deleteLater(); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index c915934b..3a918879 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -166,6 +166,11 @@ private Q_SLOTS: void setEncoding(QAction *); void populateEncodingMenu(); + // user agent + void setUserAgent(); + void populateUserAgentMenu(); + void showUserAgentSettings(); + void enableNetworkAnalysis(bool); void initBookmarkBar(); @@ -186,6 +191,8 @@ private: KMenu *m_encodingMenu; KMenu *m_tabListMenu; + KMenu *m_userAgentMenu; + BookmarkToolBar *m_bookmarksBar; QString m_lastSearch; diff --git a/src/useragent/useragentinfo.cpp b/src/useragent/useragentinfo.cpp new file mode 100644 index 00000000..94dab139 --- /dev/null +++ b/src/useragent/useragentinfo.cpp @@ -0,0 +1,188 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (c) 2001 by Dawit Alemayehu +* Copyright (C) 2010 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +// Self Includes +#include "useragentinfo.h" + +// Standard Includes +#include +#include + +// KDE Includes +#include +#include + +#include +#include + +#include + + +UserAgentInfo::UserAgentInfo() +{ +/* KService::List m_providers = KServiceTypeTrader::self()->query("UserAgentStrings");*/ + + // NOTE: limiting User Agent Numbers + m_providers << KService::serviceByDesktopName("firefox36oncurrent"); + m_providers << KService::serviceByDesktopName("ie70onwinnt51"); + m_providers << KService::serviceByDesktopName("ie60oncurrent"); + m_providers << KService::serviceByDesktopName("chrome50oncurrent"); + m_providers << KService::serviceByDesktopName("safari40"); + m_providers << KService::serviceByDesktopName("op962oncurrent"); + m_providers << KService::serviceByDesktopName("ns71oncurrent"); + m_providers << KService::serviceByDesktopName("android10"); + m_providers << KService::serviceByDesktopName("googlebot"); +} + + +QString UserAgentInfo::userAgentString(int i) +{ + if(i<0) + { + kDebug() << "oh oh... negative index on the user agent choice!"; + return QL1S("Default"); + } + + QString tmp = m_providers.at(i)->property("X-KDE-UA-FULL").toString(); + + struct utsname utsn; + uname( &utsn ); + + tmp.replace( QL1S("appSysName"), QString(utsn.sysname) ); + tmp.replace( QL1S("appSysRelease"), QString(utsn.release) ); + tmp.replace( QL1S("appMachineType"), QString(utsn.machine) ); + + QStringList languageList = KGlobal::locale()->languageList(); + if ( languageList.count() ) + { + int ind = languageList.indexOf( QL1S("C") ); + if( ind >= 0 ) + { + if( languageList.contains( QL1S("en") ) ) + languageList.removeAt( ind ); + else + languageList.value(ind) = QL1S("en"); + } + } + + tmp.replace( QL1S("appLanguage"), QString("%1").arg(languageList.join(", ")) ); + tmp.replace( QL1S("appPlatform"), QL1S("X11") ); + + return tmp; +} + + +QString UserAgentInfo::userAgentName(int i) +{ + if(i<0) + { + kDebug() << "oh oh... negative index on the user agent choice!"; + return QL1S("Default"); + } + + return m_providers.at(i)->property("X-KDE-UA-NAME").toString(); +} + + +QString UserAgentInfo::userAgentVersion(int i) +{ + if(i<0) + { + kDebug() << "oh oh... negative index on the user agent choice!"; + return QL1S("Default"); + } + + return m_providers.at(i)->property("X-KDE-UA-VERSION").toString(); +} + + +QString UserAgentInfo::userAgentDescription(int i) +{ + if(i<0) + { + kDebug() << "oh oh... negative index on the user agent choice!"; + return QL1S("Default"); + } + + QString tmp = m_providers.at(i)->property("Name").toString(); + tmp.remove( QL1S("UADescription (") ); + tmp.remove( QL1C(')') ); + return tmp; +} + + +QStringList UserAgentInfo::availableUserAgents() +{ + QStringList UAs; + int n = m_providers.count(); + for(int i = 0; i +* Copyright (C) 2010 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + + +#ifndef USER_AGENT_INFO_H +#define USER_AGENT_INFO_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include + +// Qt Includes +#include + + +class UserAgentInfo +{ +public: + UserAgentInfo(); + + /** + * Lists all available User Agents + * + * @returns the list of the UA descriptions + */ + QStringList availableUserAgents(); + + /** + * Set User Agent for host + * + * @param uaIndex the index of the UA description. @see availableUserAgents() + * @param host the host to se the UA + */ + bool setUserAgentForHost(int uaIndex, const QString &host); + + /** + * @returns the index of the UA set for the @p host + */ + int uaIndexForHost(const QString &); + +private: + QString userAgentString(int); + QString userAgentName(int); + QString userAgentVersion(int); + QString userAgentDescription(int); + +private: + KService::List m_providers; +}; + +#endif // USER_AGENT_INFO_H diff --git a/src/useragent/useragentsettings.ui b/src/useragent/useragentsettings.ui new file mode 100644 index 00000000..77887060 --- /dev/null +++ b/src/useragent/useragentsettings.ui @@ -0,0 +1,72 @@ + + + UserAgent + + + + 0 + 0 + 609 + 496 + + + + Form + + + + + + false + + + true + + + + Host + + + + + Identification + + + + + + + + + + Delete + + + + + + + Delete All + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/src/useragent/useragentwidget.cpp b/src/useragent/useragentwidget.cpp new file mode 100644 index 00000000..8fb278b8 --- /dev/null +++ b/src/useragent/useragentwidget.cpp @@ -0,0 +1,101 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +// Self Includes +#include "useragentwidget.h" +#include "useragentwidget.moc" + +// KDE Includes +#include + + +UserAgentWidget::UserAgentWidget(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteUserAgent())); + connect(deleteAllButton, SIGNAL(clicked()), this, SLOT(deleteAll())); + + KConfig config("kio_httprc", KConfig::NoGlobals); + + QStringList hosts = config.groupList(); + kDebug() << "HOSTS" << hosts; + Q_FOREACH(const QString &host, hosts) + { + QStringList tmp; + tmp << host; + + KConfigGroup hostGroup(&config, host); + tmp << hostGroup.readEntry( QL1S("UserAgent"), QString()); + + kDebug() << "TMP: " << tmp; + QTreeWidgetItem *item = new QTreeWidgetItem(sitePolicyTreeWidget, tmp); + sitePolicyTreeWidget->addTopLevelItem(item); + } +} + + +void UserAgentWidget::deleteUserAgent() +{ + QTreeWidgetItem *item = sitePolicyTreeWidget->currentItem(); + if(!item) + return; + + sitePolicyTreeWidget->takeTopLevelItem( sitePolicyTreeWidget->indexOfTopLevelItem(item) ); + + QString host = item->text(0); + kDebug() << "HOST: " << host; + + KConfig config("kio_httprc", KConfig::NoGlobals); + KConfigGroup group(&config, host); + if(group.exists()) + { + group.deleteGroup(); + KProtocolManager::reparseConfiguration(); + } +} + + +void UserAgentWidget::deleteAll() +{ + sitePolicyTreeWidget->clear(); + + KConfig config("kio_httprc", KConfig::NoGlobals); + + QStringList list = config.groupList(); + Q_FOREACH(const QString &groupName, list) + { + kDebug() << "HOST: " << groupName; + + KConfigGroup group(&config, groupName); + group.deleteGroup(); + } + KConfigGroup group(&config, QString()); + group.deleteGroup(); + + KProtocolManager::reparseConfiguration(); +} diff --git a/src/useragent/useragentwidget.h b/src/useragent/useragentwidget.h new file mode 100644 index 00000000..d878a080 --- /dev/null +++ b/src/useragent/useragentwidget.h @@ -0,0 +1,53 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Andrea Diamantini +* +* +* 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 . +* +* ============================================================ */ + + +#ifndef USER_AGENT_WIDGET_H +#define USER_AGENT_WIDGET_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include + +// Ui Includes +#include "ui_useragentsettings.h" + + +class UserAgentWidget : public QWidget, private Ui::UserAgent +{ + Q_OBJECT + +public: + UserAgentWidget(QWidget *parent = 0); + +private Q_SLOTS: + void deleteUserAgent(); + void deleteAll(); +}; + +#endif -- cgit v1.2.1