From a34f7ad76fe02227cc59143d91dabb891c2e3605 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Wed, 13 Mar 2013 17:50:00 +0100 Subject: Support Activities Open links in new tab only if there is a window in the current activity/on the current desktop This code has been written by Jonathan Verner and reviewed (a bit) by me. Hope everyone will be happy now... BUG: 316322 REVIEWED-BY: adjam --- CMakeLists.txt | 17 ++++++ config-kactivities.h.cmake | 1 + src/CMakeLists.txt | 7 +++ src/application.cpp | 130 ++++++++++++++++++++++++++++++++------------- src/application.h | 35 +++++++++++- 5 files changed, 152 insertions(+), 38 deletions(-) create mode 100644 config-kactivities.h.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ae8bddb..5bfaaf4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,14 @@ MACRO_BOOL_TO_01(QTOAUTH_FOUND HAVE_QTOAUTH) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-qtoauth.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/src/config-qtoauth.h ) +# ================================================================================== +# optional KActivities requirements + +MACRO_OPTIONAL_FIND_PACKAGE(KActivities 6.1.0) +MACRO_BOOL_TO_01(KActivities_FOUND HAVE_KACTIVITIES) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config-kactivities.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/src/config-kactivities.h ) + # ================================================================================== # Log messages @@ -171,6 +179,15 @@ IF(REKONQ_CAN_BE_COMPILED) MESSAGE(STATUS " Rekonq will be compiled WITHOUT support for opera sync handler") ENDIF(HAVE_QCA2 AND HAVE_QTOAUTH) + # KActivities + + IF(HAVE_KACTIVITIES) + MESSAGE(STATUS " KActivities Libraries................. YES") + MESSAGE(STATUS " Rekonq will be compiled with support for activities") + ELSE(HAVE_KACTIVITIES) + MESSAGE(STATUS " KActivities Libraries................. NO") + MESSAGE(STATUS " Rekonq will be compiled WITHOUT support for activities") + ENDIF(HAVE_KACTIVITIES) MESSAGE(STATUS "") MESSAGE(STATUS "-----------------------------------------------------------------------") diff --git a/config-kactivities.h.cmake b/config-kactivities.h.cmake new file mode 100644 index 00000000..e136858c --- /dev/null +++ b/config-kactivities.h.cmake @@ -0,0 +1 @@ +#cmakedefine HAVE_KACTIVITIES diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6833f27f..4bb6a1d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -252,6 +252,13 @@ IF(NepomukCore_FOUND) ) ENDIF(NepomukCore_FOUND) +# KActivities optional target link libraries +IF(HAVE_KACTIVITIES) + TARGET_LINK_LIBRARIES( kdeinit_rekonq + ${KACTIVITIES_LIBRARY} + ) +ENDIF(HAVE_KACTIVITIES) + # Opera sync optional link libraries IF(HAVE_QCA2 AND HAVE_QTOAUTH) TARGET_LINK_LIBRARIES( kdeinit_rekonq diff --git a/src/application.cpp b/src/application.cpp index dfcfc59a..002f19d1 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -69,6 +69,11 @@ #include +#include +#ifdef HAVE_KACTIVITIES +#include +#endif + // Qt Includes #include #include @@ -79,6 +84,9 @@ Application::Application() : KUniqueApplication() { +#ifdef HAVE_KACTIVITIES + m_activityConsumer = new KActivities::Consumer(); +#endif } @@ -89,6 +97,10 @@ Application::~Application() ReKonfig::setRecoverOnCrash(0); saveConfiguration(); +#ifdef HAVE_KACTIVITIES + delete m_activityConsumer; +#endif + kDebug() << "Bye bye (k)baby..."; } @@ -355,63 +367,55 @@ void Application::saveConfiguration() const } -RekonqWindow *Application::rekonqWindow() +// -------------------------------------------------------------------------------------------------------------------- + + +RekonqWindow *Application::rekonqWindow(const QString & activityID) { RekonqWindow *active = qobject_cast(QApplication::activeWindow()); if (!active) { - if (m_rekonqWindows.isEmpty()) - return 0; + RekonqWindowList wList = m_rekonqWindows; - Q_FOREACH(const QWeakPointer &pointer, m_rekonqWindows) +#ifdef HAVE_KACTIVITIES + wList = tabsForActivity(activityID); +#endif + + if (wList.isEmpty()) + return 0; + + Q_FOREACH(const QWeakPointer &pointer, wList) { if (KWindowInfo(pointer.data()->effectiveWinId(), NET::WMDesktop, 0).isOnCurrentDesktop()) return pointer.data(); } - return m_rekonqWindows.at(0).data(); + return wList.at(0).data(); } return active; } -void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type) +RekonqWindowList Application::tabsForActivity(const QString & activityID) { - if (url.isEmpty()) - return; - - if (!url.isValid()) - { - KMessageBox::error(0, i18n("Malformed URL:\n%1", url.url(KUrl::RemoveTrailingSlash))); - return; - } - - Rekonq::OpenType newType = type; - // Don't open useless tabs or windows for actions in about: pages - if (url.url().contains("about:") && url.url().contains("/")) - newType = Rekonq::CurrentTab; +#ifdef HAVE_KACTIVITIES + QString id = activityID; + if ( id.isEmpty() ) + id = m_activityConsumer->currentActivity(); + return m_activityRekonqWindowsMap[id]; +#else + return m_rekonqWindows; +#endif +} - RekonqWindow *w = 0; - if (newType == Rekonq::NewPrivateWindow) - { - w = newWindow(true, true); - newType = Rekonq::CurrentTab; - } - else if (newType == Rekonq::NewWindow - || ((newType == Rekonq::NewTab || newType == Rekonq::NewFocusedTab) && rekonqWindowList().count() == 0)) - { - w = newWindow(); - newType = Rekonq::CurrentTab; - } - else - { - w = rekonqWindow(); - } - w->loadUrl(url, newType); +bool Application::haveWindowsForActivity(const QString & activityID) +{ + return (!tabsForActivity(activityID).isEmpty()); } + RekonqWindow *Application::newWindow(bool withTab, bool PrivateBrowsingMode) { RekonqWindow *w = new RekonqWindow(withTab, PrivateBrowsingMode); @@ -424,6 +428,12 @@ RekonqWindow *Application::newWindow(bool withTab, bool PrivateBrowsingMode) w->installEventFilter(this); m_rekonqWindows.prepend(w); + +#ifdef HAVE_KACTIVITIES + QString currentActivity = m_activityConsumer->currentActivity(); + m_activityRekonqWindowsMap[currentActivity].prepend(w); +#endif + w->show(); return w; @@ -455,6 +465,9 @@ WebAppList Application::webAppList() } +// ------------------------------------------------------------------------------------------------------------------ + + bool Application::eventFilter(QObject* watched, QEvent* event) { // Track which window was activated most recently to prefer it on window choosing @@ -481,8 +494,14 @@ bool Application::eventFilter(QObject* watched, QEvent* event) { RekonqWindow *window = qobject_cast(watched); if (window) + { m_rekonqWindows.removeOne(window); - +#ifdef HAVE_KACTIVITIES + QString currentActivity = m_activityConsumer->currentActivity(); + m_activityRekonqWindowsMap[currentActivity].removeOne(window); +#endif + } + WebTab *webApp = qobject_cast(watched); m_webApps.removeOne(webApp); @@ -494,6 +513,43 @@ bool Application::eventFilter(QObject* watched, QEvent* event) } +void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type) +{ + if (url.isEmpty()) + return; + + if (!url.isValid()) + { + KMessageBox::error(0, i18n("Malformed URL:\n%1", url.url(KUrl::RemoveTrailingSlash))); + return; + } + + Rekonq::OpenType newType = type; + // Don't open useless tabs or windows for actions in about: pages + if (url.url().contains("about:") && url.url().contains("/")) + newType = Rekonq::CurrentTab; + + RekonqWindow *w = 0; + if (newType == Rekonq::NewPrivateWindow) + { + w = newWindow(true, true); + newType = Rekonq::CurrentTab; + } + else if (newType == Rekonq::NewWindow + || ((newType == Rekonq::NewTab || newType == Rekonq::NewFocusedTab) && !haveWindowsForActivity())) + { + w = newWindow(); + newType = Rekonq::CurrentTab; + } + else + { + w = rekonqWindow(); + } + + w->loadUrl(url, newType); +} + + void Application::updateConfiguration() { // ============== Tabs ================== diff --git a/src/application.h b/src/application.h index 5db6b424..e1801345 100644 --- a/src/application.h +++ b/src/application.h @@ -45,9 +45,22 @@ class WebWindow; class WebTab; class WebPage; +#include + +#ifdef HAVE_KACTIVITIES +namespace KActivities { + class Consumer; +} +#endif + typedef QList< QWeakPointer > RekonqWindowList; typedef QList WebAppList; +#ifdef HAVE_KACTIVITIES +typedef QHash< QString, RekonqWindowList > ActivityTabsMap; +#endif + + // --------------------------------------------------------------------------------------------------------------- @@ -67,9 +80,23 @@ public: int newInstance(); static Application *instance(); - RekonqWindow *rekonqWindow(); + RekonqWindow *rekonqWindow(const QString & activityID = QString()); RekonqWindowList rekonqWindowList(); + /** + * @returns the list of windows associated with activity whose id is @param activityID + * @param activityID the ID of the activity (if empty, it is interpreted as the current activity) + * @note If activities are disabled, returns the function returns the list of all tabs. + */ + RekonqWindowList tabsForActivity(const QString & activityID = QString()); + + /** + * @returns the true if there are windows associated with activity whose id is @param activityID + * @param activityID the ID of the activity (if empty, it is interpreted as the current activity) + * @note If activities are disabled, returns true if there are any tabs. + */ + bool haveWindowsForActivity(const QString & activityID = QString()); + WebAppList webAppList(); void bookmarksToolbarToggled(bool); @@ -120,6 +147,12 @@ private Q_SLOTS: private: RekonqWindowList m_rekonqWindows; WebAppList m_webApps; + +#ifdef HAVE_KACTIVITIES + ActivityTabsMap m_activityRekonqWindowsMap; + KActivities::Consumer *m_activityConsumer; +#endif + }; #endif // APPLICATION_H -- cgit v1.2.1