From 9461c52f07a2bf8b9bc25f037b17805cda51b2b0 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Sun, 10 Mar 2013 19:02:12 +0100 Subject: Supporting panel (again) :) - Move to a pure QWidget base window (instead of TabWidget one) (this to properly store panels position) - Restoring && rewamping panels code - Restoring actions to activate/deactivate them BUG: 312354 --- src/CMakeLists.txt | 11 +- src/application.cpp | 121 ++--- src/application.h | 12 +- src/bookmarks/bookmarkowner.cpp | 11 +- src/bookmarks/bookmarkstreemodel.cpp | 406 ++++++++++++++++ src/bookmarks/bookmarkstreemodel.h | 116 +++++ src/history/historymodels.cpp | 6 +- src/history/historymodels.h | 4 +- src/icons/iconmanager.cpp | 4 +- src/main.cpp | 14 +- src/panels/bookmarkspanel.cpp | 170 +++++++ src/panels/bookmarkspanel.h | 93 ++++ src/panels/historypanel.cpp | 214 +++++++++ src/panels/historypanel.h | 63 +++ src/panels/paneltreeview.cpp | 186 ++++++++ src/panels/paneltreeview.h | 69 +++ src/panels/urlfilterproxymodel.cpp | 59 +++ src/panels/urlfilterproxymodel.h | 59 +++ src/panels/urlpanel.cpp | 111 +++++ src/panels/urlpanel.h | 81 ++++ src/rekonq.kcfg | 6 + src/rekonqpage/newtabpage.cpp | 9 +- src/sessionmanager.cpp | 43 +- src/sessionmanager.h | 7 +- src/settings/generalwidget.cpp | 5 +- src/tabwindow/rekonqwindow.cpp | 461 ++++-------------- src/tabwindow/rekonqwindow.h | 130 ++--- src/tabwindow/rwindow.cpp | 397 +++++++++++++++ src/tabwindow/rwindow.h | 131 +++++ src/tabwindow/tabbar.cpp | 19 +- src/tabwindow/tabwidget.cpp | 900 +++++++++++++++++++++++++++++++++++ src/tabwindow/tabwidget.h | 146 ++++++ src/tabwindow/tabwindow.cpp | 831 -------------------------------- src/tabwindow/tabwindow.h | 140 ------ src/urlbar/rsswidget.cpp | 5 +- src/webwindow/rekonqui.rc | 9 +- src/webwindow/webwindow.cpp | 6 +- 37 files changed, 3502 insertions(+), 1553 deletions(-) create mode 100644 src/bookmarks/bookmarkstreemodel.cpp create mode 100644 src/bookmarks/bookmarkstreemodel.h create mode 100644 src/panels/bookmarkspanel.cpp create mode 100644 src/panels/bookmarkspanel.h create mode 100644 src/panels/historypanel.cpp create mode 100644 src/panels/historypanel.h create mode 100644 src/panels/paneltreeview.cpp create mode 100644 src/panels/paneltreeview.h create mode 100644 src/panels/urlfilterproxymodel.cpp create mode 100644 src/panels/urlfilterproxymodel.h create mode 100644 src/panels/urlpanel.cpp create mode 100644 src/panels/urlpanel.h create mode 100644 src/tabwindow/rwindow.cpp create mode 100644 src/tabwindow/rwindow.h create mode 100644 src/tabwindow/tabwidget.cpp create mode 100644 src/tabwindow/tabwidget.h delete mode 100644 src/tabwindow/tabwindow.cpp delete mode 100644 src/tabwindow/tabwindow.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0984c93..6833f27f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,7 @@ set(rekonq_KDEINIT_SRCS bookmarks/bookmarkscontextmenu.cpp bookmarks/bookmarksmenu.cpp bookmarks/bookmarkstoolbar.cpp + bookmarks/bookmarkstreemodel.cpp bookmarks/bookmarkowner.cpp #---------------------------------------- download/downloaditem.cpp @@ -41,6 +42,12 @@ set(rekonq_KDEINIT_SRCS icons/iconmanager.cpp icons/webicon.cpp #---------------------------------------- + panels/bookmarkspanel.cpp + panels/historypanel.cpp + panels/paneltreeview.cpp + panels/urlfilterproxymodel.cpp + panels/urlpanel.cpp + #---------------------------------------- rekonqpage/newtabpage.cpp rekonqpage/thumbupdater.cpp #---------------------------------------- @@ -66,11 +73,12 @@ set(rekonq_KDEINIT_SRCS sync/syncgooglesettingswidget.cpp sync/syncoperasettingswidget.cpp #---------------------------------------- + tabwindow/rwindow.cpp tabwindow/rekonqwindow.cpp tabwindow/tabbar.cpp tabwindow/tabhighlighteffect.cpp tabwindow/tabpreviewpopup.cpp - tabwindow/tabwindow.cpp + tabwindow/tabwidget.cpp #---------------------------------------- urlbar/urlbar.cpp urlbar/completionwidget.cpp @@ -170,6 +178,7 @@ INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/download ${CMAKE_CURRENT_SOURCE_DIR}/history ${CMAKE_CURRENT_SOURCE_DIR}/icons + ${CMAKE_CURRENT_SOURCE_DIR}/panels ${CMAKE_CURRENT_SOURCE_DIR}/rekonqpage ${CMAKE_CURRENT_SOURCE_DIR}/settings ${CMAKE_CURRENT_SOURCE_DIR}/sync diff --git a/src/application.cpp b/src/application.cpp index 0c96d986..dfcfc59a 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -38,7 +38,7 @@ #include "searchengine.h" #include "tabbar.h" -#include "tabwindow.h" +#include "rekonqwindow.h" #include "webwindow.h" #include "webtab.h" @@ -73,6 +73,7 @@ #include #include #include +#include Application::Application() @@ -194,7 +195,7 @@ int Application::newInstance() } // first argument: 99% of the time we have just that... - if (isFirstLoad || m_tabWindows.count() == 0) + if (isFirstLoad || m_rekonqWindows.count() == 0) { // No windows in the current desktop? No windows at all? // Create a new one and load there sites... @@ -218,8 +219,8 @@ int Application::newInstance() loadUrl(urlList.at(0), Rekonq::NewWindow); } - if (!tabWindow()->isActiveWindow()) - KWindowSystem::demandAttention(tabWindow()->winId(), true); + if (!rekonqWindow()->isActiveWindow()) + KWindowSystem::demandAttention(rekonqWindow()->winId(), true); } // following arguments: what's best behavior here? @@ -282,7 +283,7 @@ int Application::newInstance() break; } default: - newTabWindow()->newTab(); + newWindow()->tabWidget()->newTab(); break; } } @@ -312,8 +313,8 @@ int Application::newInstance() { if (hasToBeRecoveredFromCrash && !incognito) { - if (tabWindow() && tabWindow()->currentWebWindow()) - QTimer::singleShot(1000, tabWindow()->currentWebWindow(), SLOT(showCrashMessageBar())); + if (rekonqWindow() && rekonqWindow()->currentWebWindow()) + QTimer::singleShot(1000, rekonqWindow()->currentWebWindow(), SLOT(showCrashMessageBar())); } else { @@ -321,7 +322,7 @@ int Application::newInstance() } if (ReKonfig::checkDefaultSearchEngine() && !hasToBeRecoveredFromCrash && SearchEngine::defaultEngine().isNull()) - QTimer::singleShot(2000, tabWindow()->currentWebWindow()->tabView(), SLOT(showSearchEngineBar())); + QTimer::singleShot(2000, rekonqWindow()->currentWebWindow()->tabView(), SLOT(showSearchEngineBar())); // updating rekonq configuration updateConfiguration(); @@ -354,21 +355,21 @@ void Application::saveConfiguration() const } -TabWindow *Application::tabWindow() +RekonqWindow *Application::rekonqWindow() { - TabWindow *active = qobject_cast(QApplication::activeWindow()); + RekonqWindow *active = qobject_cast(QApplication::activeWindow()); if (!active) { - if (m_tabWindows.isEmpty()) + if (m_rekonqWindows.isEmpty()) return 0; - Q_FOREACH(const QWeakPointer &pointer, m_tabWindows) + Q_FOREACH(const QWeakPointer &pointer, m_rekonqWindows) { if (KWindowInfo(pointer.data()->effectiveWinId(), NET::WMDesktop, 0).isOnCurrentDesktop()) return pointer.data(); } - return m_tabWindows.at(0).data(); + return m_rekonqWindows.at(0).data(); } return active; } @@ -390,39 +391,39 @@ void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type) if (url.url().contains("about:") && url.url().contains("/")) newType = Rekonq::CurrentTab; - TabWindow *w = 0; + RekonqWindow *w = 0; if (newType == Rekonq::NewPrivateWindow) { - w = newTabWindow(true, true); + w = newWindow(true, true); newType = Rekonq::CurrentTab; } else if (newType == Rekonq::NewWindow - || ((newType == Rekonq::NewTab || newType == Rekonq::NewFocusedTab) && tabWindowList().count() == 0)) + || ((newType == Rekonq::NewTab || newType == Rekonq::NewFocusedTab) && rekonqWindowList().count() == 0)) { - w = newTabWindow(); + w = newWindow(); newType = Rekonq::CurrentTab; } else { - w = tabWindow(); + w = rekonqWindow(); } w->loadUrl(url, newType); } -TabWindow *Application::newTabWindow(bool withTab, bool PrivateBrowsingMode) +RekonqWindow *Application::newWindow(bool withTab, bool PrivateBrowsingMode) { - TabWindow *w = new TabWindow(withTab, PrivateBrowsingMode); + RekonqWindow *w = new RekonqWindow(withTab, PrivateBrowsingMode); // set object name - int n = m_tabWindows.count() + 1; + int n = m_rekonqWindows.count() + 1; w->setObjectName(QL1S("win") + QString::number(n)); // This is used to track which window was activated most recently w->installEventFilter(this); - m_tabWindows.prepend(w); + m_rekonqWindows.prepend(w); w->show(); return w; @@ -442,9 +443,9 @@ WebTab *Application::newWebApp() } -TabWindowList Application::tabWindowList() +RekonqWindowList Application::rekonqWindowList() { - return m_tabWindows; + return m_rekonqWindows; } @@ -460,16 +461,16 @@ bool Application::eventFilter(QObject* watched, QEvent* event) // (e.g. when another application opens a link) if (event->type() == QEvent::WindowActivate) { - TabWindow *window = qobject_cast(watched); + RekonqWindow *window = qobject_cast(watched); if (window) { - if (!m_tabWindows.isEmpty() - && m_tabWindows.at(0) - && m_tabWindows.at(0).data() != window) + if (!m_rekonqWindows.isEmpty() + && m_rekonqWindows.at(0) + && m_rekonqWindows.at(0).data() != window) { - int index = m_tabWindows.indexOf(QWeakPointer(window)); + int index = m_rekonqWindows.indexOf(QWeakPointer(window)); Q_ASSERT(index != -1); - m_tabWindows.prepend(m_tabWindows.takeAt(index)); + m_rekonqWindows.prepend(m_rekonqWindows.takeAt(index)); } } } @@ -478,14 +479,14 @@ bool Application::eventFilter(QObject* watched, QEvent* event) // when we close one of them, remove from tab window list and check if it was last... if (event->type() == QEvent::Close) { - TabWindow *window = qobject_cast(watched); + RekonqWindow *window = qobject_cast(watched); if (window) - m_tabWindows.removeOne(window); + m_rekonqWindows.removeOne(window); WebTab *webApp = qobject_cast(watched); m_webApps.removeOne(webApp); - if (m_tabWindows.count() == 0 && m_webApps.count() == 0) + if (m_rekonqWindows.count() == 0 && m_webApps.count() == 0) quit(); } @@ -497,7 +498,7 @@ void Application::updateConfiguration() { // ============== Tabs ================== bool b = ReKonfig::closeTabSelectPrevious(); - Q_FOREACH(const QWeakPointer &w, m_tabWindows) + Q_FOREACH(const QWeakPointer &w, m_rekonqWindows) { if (b) w.data()->tabBar()->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); @@ -519,9 +520,9 @@ void Application::updateConfiguration() // compute font size // (I have to admit I know nothing about these DPI questions..: copied from kwebkitpart, as someone suggested) // font size in pixels = font size in inches × screen dpi - if (tabWindow() && tabWindow()->currentWebWindow()) + if (rekonqWindow() && rekonqWindow()->currentWebWindow()) { - int logDpiY = tabWindow()->currentWebWindow()->logicalDpiY(); + int logDpiY = rekonqWindow()->currentWebWindow()->logicalDpiY(); float toPix = (logDpiY < 96.0) ? 96.0 / 72.0 : logDpiY / 72.0 ; @@ -580,13 +581,13 @@ void Application::updateConfiguration() defaultSettings = 0; - if (!tabWindow()) + if (!rekonqWindow()) return; // FIXME What about this? // ReKonfig::useFavicon() -// ? tabWindow()->changeWindowIcon(tabWindow()->mainView()->currentIndex()) -// : tabWindow()->setWindowIcon(KIcon("rekonq")) +// ? rekonqWindow()->changeWindowIcon(rekonqWindow()->mainView()->currentIndex()) +// : rekonqWindow()->setWindowIcon(KIcon("rekonq")) // ; // // hovering unfocused tabs options @@ -594,23 +595,23 @@ void Application::updateConfiguration() { case 0: // tab previews case 3: // nothing - for (int i = 0; i < tabWindow()->tabBar()->count(); i++) + for (int i = 0; i < rekonqWindow()->tabBar()->count(); i++) { - tabWindow()->tabBar()->setTabToolTip(i, QL1S("")); + rekonqWindow()->tabBar()->setTabToolTip(i, QL1S("")); } break; case 1: // title previews - for (int i = 0; i < tabWindow()->tabBar()->count(); i++) + for (int i = 0; i < rekonqWindow()->tabBar()->count(); i++) { - tabWindow()->tabBar()->setTabToolTip(i, tabWindow()->tabText(i).remove('&')); + rekonqWindow()->tabBar()->setTabToolTip(i, rekonqWindow()->tabWidget()->tabText(i).remove('&')); } break; case 2: // url previews - for (int i = 0; i < tabWindow()->tabBar()->count(); i++) + for (int i = 0; i < rekonqWindow()->tabBar()->count(); i++) { - tabWindow()->tabBar()->setTabToolTip(i, tabWindow()->webWindow(i)->url().toMimeDataString()); + rekonqWindow()->tabBar()->setTabToolTip(i, rekonqWindow()->tabWidget()->webWindow(i)->url().toMimeDataString()); } break; @@ -626,14 +627,14 @@ void Application::queryQuit() { if (m_webApps.count() > 0) { - tabWindow()->close(); + rekonqWindow()->close(); return; } - if (tabWindowList().count() > 1) + if (rekonqWindowList().count() > 1) { int answer = KMessageBox::questionYesNoCancel( - tabWindow(), + rekonqWindow(), i18n("Do you want to close the window or the whole application?"), i18n("Application/Window closing..."), KGuiItem(i18n("C&lose Current Window"), @@ -646,7 +647,7 @@ void Application::queryQuit() switch (answer) { case KMessageBox::Yes: - tabWindow()->close(); + rekonqWindow()->close(); return; case KMessageBox::No: @@ -664,7 +665,7 @@ void Application::queryQuit() void Application::clearPrivateData() { - QPointer dialog = new KDialog(tabWindow()); + QPointer dialog = new KDialog(rekonqWindow()); dialog->setCaption(i18nc("@title:window", "Clear Private Data")); dialog->setButtons(KDialog::Ok | KDialog::Cancel); @@ -741,10 +742,10 @@ void Application::clearPrivateData() void Application::createWebAppShortcut() { - KUrl u = tabWindow()->currentWebWindow()->url(); + KUrl u = rekonqWindow()->currentWebWindow()->url(); QString h = u.host(); - QPointer dialog = new KDialog(tabWindow()); + QPointer dialog = new KDialog(rekonqWindow()); dialog->setCaption(i18nc("@title:window", "Create Application Shortcut")); dialog->setButtons(KDialog::Ok | KDialog::Cancel); dialog->button(KDialog::Ok)->setText(i18n("Create")); @@ -755,7 +756,7 @@ void Application::createWebAppShortcut() QWidget widget; wAppWidget.setupUi(&widget); - QString webAppTitle = tabWindow()->currentWebWindow()->title().remove('&'); + QString webAppTitle = rekonqWindow()->currentWebWindow()->title().remove('&'); wAppWidget.nameLineEdit->setText(webAppTitle); wAppWidget.kcfg_createDesktopAppShortcut->setChecked(ReKonfig::createDesktopAppShortcut()); wAppWidget.kcfg_createMenuAppShortcut->setChecked(ReKonfig::createMenuAppShortcut()); @@ -848,26 +849,26 @@ void Application::newPrivateBrowsingWindow() void Application::pageCreated(WebPage *pg) { - if (m_tabWindows.isEmpty()) + if (m_rekonqWindows.isEmpty()) { - // NOTE: This is "adjusted" from newTabWindow() code... - TabWindow *w = new TabWindow(pg); + // NOTE: This is "adjusted" from newRekonqWindow() code... + RekonqWindow *w = new RekonqWindow(pg); // set object name - int n = m_tabWindows.count() + 1; + int n = m_rekonqWindows.count() + 1; w->setObjectName(QL1S("win") + QString::number(n)); // This is used to track which window was activated most recently w->installEventFilter(this); - m_tabWindows.prepend(w); + m_rekonqWindows.prepend(w); w->show(); return; } - TabWindow *tw = tabWindow(); - tw->newTab(pg); + RekonqWindow *tw = rekonqWindow(); + tw->tabWidget()->newTab(pg); tw->activateWindow(); tw->raise(); diff --git a/src/application.h b/src/application.h index e7153831..5db6b424 100644 --- a/src/application.h +++ b/src/application.h @@ -39,13 +39,13 @@ #include // Forward Declarations -class TabWindow; +class RekonqWindow; class WebWindow; class WebTab; class WebPage; -typedef QList< QWeakPointer > TabWindowList; +typedef QList< QWeakPointer > RekonqWindowList; typedef QList WebAppList; // --------------------------------------------------------------------------------------------------------------- @@ -67,8 +67,8 @@ public: int newInstance(); static Application *instance(); - TabWindow *tabWindow(); - TabWindowList tabWindowList(); + RekonqWindow *rekonqWindow(); + RekonqWindowList rekonqWindowList(); WebAppList webAppList(); @@ -92,7 +92,7 @@ public Q_SLOTS: const Rekonq::OpenType& type = Rekonq::CurrentTab ); - TabWindow *newTabWindow(bool withTab = true, bool PrivateBrowsingMode = false); + RekonqWindow *newWindow(bool withTab = true, bool PrivateBrowsingMode = false); WebTab *newWebApp(); @@ -118,7 +118,7 @@ private Q_SLOTS: void pageCreated(WebPage *); private: - TabWindowList m_tabWindows; + RekonqWindowList m_rekonqWindows; WebAppList m_webApps; }; diff --git a/src/bookmarks/bookmarkowner.cpp b/src/bookmarks/bookmarkowner.cpp index 11c3585d..b7fe443b 100644 --- a/src/bookmarks/bookmarkowner.cpp +++ b/src/bookmarks/bookmarkowner.cpp @@ -35,7 +35,8 @@ #include "bookmarkmanager.h" #include "application.h" -#include "tabwindow.h" +#include "rekonqwindow.h" +#include "tabwidget.h" #include "webwindow.h" // KDE Includes @@ -119,20 +120,20 @@ KAction* BookmarkOwner::createAction(const KBookmark &bookmark, const BookmarkAc QString BookmarkOwner::currentTitle() const { - return rApp->tabWindow()->currentWebWindow()->title(); + return rApp->rekonqWindow()->currentWebWindow()->title(); } QString BookmarkOwner::currentUrl() const { - return rApp->tabWindow()->currentWebWindow()->url().url(); + return rApp->rekonqWindow()->currentWebWindow()->url().url(); } QList< QPair > BookmarkOwner::currentBookmarkList() const { QList< QPair > bkList; - TabWindow *view = rApp->tabWindow(); + TabWidget *view = rApp->rekonqWindow()->tabWidget(); int tabNumber = view->count(); for (int i = 0; i < tabNumber; ++i) @@ -165,7 +166,7 @@ void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bkGoup) if (urlList.length() > 8) { if (KMessageBox::warningContinueCancel( - rApp->tabWindow(), + rApp->rekonqWindow(), i18ncp("%1=Number of tabs. Value is always >=8", "You are about to open %1 tabs.\nAre you sure?", "You are about to open %1 tabs.\nAre you sure?", urlList.length())) diff --git a/src/bookmarks/bookmarkstreemodel.cpp b/src/bookmarks/bookmarkstreemodel.cpp new file mode 100644 index 00000000..8a74e3e6 --- /dev/null +++ b/src/bookmarks/bookmarkstreemodel.cpp @@ -0,0 +1,406 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Nils Weigel +* Copyright (C) 2010-2013 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 "bookmarkstreemodel.h" +#include "bookmarkstreemodel.moc" + +// Local Includes +#include "bookmarkmanager.h" +#include "iconmanager.h" + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include + + +BtmItem::BtmItem(const KBookmark &bm) + : m_parent(0) + , m_kbm(bm) +{ +} + + +BtmItem::~BtmItem() +{ + qDeleteAll(m_children); +} + + +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) + { + // NOTE + // this should be: + // return KIcon(m_kbm.icon()); + // but I cannot let it work :( + // I really cannot understand how let this work properly... + if (m_kbm.isGroup() || m_kbm.isSeparator()) + return KIcon(m_kbm.icon()); + else + return IconManager::self()->iconForUrl(KUrl(m_kbm.url())); + } + + if (role == Qt::UserRole) + return m_kbm.url(); + + if (role == Qt::ToolTipRole) + { + QString tooltip = m_kbm.fullText(); + if (m_kbm.isGroup()) + tooltip += i18ncp("%1=Number of items in bookmark folder", " (1 item)", " (%1 items)", childCount()); + + QString url = m_kbm.url().url(); + if (!url.isEmpty()) + { + if (!tooltip.isEmpty()) + tooltip += '\n'; + tooltip += url; + } + + if (!m_kbm.description().isEmpty()) + { + if (!tooltip.isEmpty()) + tooltip += '\n'; + tooltip += m_kbm.description(); + } + + return tooltip; + } + + return QVariant(); +} + + +int BtmItem::row() const +{ + if (m_parent) + return m_parent->m_children.indexOf(const_cast< BtmItem* >(this)); + return 0; +} + + +int BtmItem::childCount() const +{ + return m_children.count(); +} + + +BtmItem* BtmItem::child(int n) +{ + Q_ASSERT(n >= 0); + Q_ASSERT(n < childCount()); + + return m_children.at(n); +} + + +BtmItem* BtmItem::parent() const +{ + return m_parent; +} + + +void BtmItem::appendChild(BtmItem *child) +{ + if (!child) + return; + + child->m_parent = this; + m_children << child; +} + + +void BtmItem::clear() +{ + qDeleteAll(m_children); + m_children.clear(); +} + +KBookmark BtmItem::getBkm() const +{ + return m_kbm; +} + + +// ------------------------------------------------------------------------------------- + + +BookmarksTreeModel::BookmarksTreeModel(QObject *parent) + : QAbstractItemModel(parent) + , m_root(0) +{ + resetModel(); + connect(BookmarkManager::self()->manager(), SIGNAL(changed(QString, QString)), + this, SLOT(bookmarksChanged(QString))); +} + + +BookmarksTreeModel::~BookmarksTreeModel() +{ + delete m_root; +} + + +int BookmarksTreeModel::rowCount(const QModelIndex &parent) const +{ + BtmItem *parentItem = 0; + if (!parent.isValid()) + { + parentItem = m_root; + } + else + { + parentItem = static_cast(parent.internalPointer()); + } + + return parentItem->childCount(); +} + + +int BookmarksTreeModel::columnCount(const QModelIndex& /*parent*/) const +{ + return 1; +} + + +Qt::ItemFlags BookmarksTreeModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + + if (!index.isValid()) + return flags | Qt::ItemIsDropEnabled; + + flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; + + if (bookmarkForIndex(index).isGroup()) + flags |= Qt::ItemIsDropEnabled; + + return flags; +} + + +QModelIndex BookmarksTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + BtmItem *parentItem; + + if (!parent.isValid()) + parentItem = m_root; + else + parentItem = static_cast(parent.internalPointer()); + + BtmItem *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + + return QModelIndex(); +} + + +QModelIndex BookmarksTreeModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + BtmItem *childItem = static_cast(index.internalPointer()); + BtmItem *parentItem = childItem->parent(); + + if (parentItem == m_root) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + + +QVariant BookmarksTreeModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + BtmItem *node = static_cast(index.internalPointer()); + if (node && node == m_root) + { + if (role == Qt::DisplayRole) + return i18n("Bookmarks"); + if (role == Qt::DecorationRole) + return KIcon("bookmarks"); + } + else + { + if (node) + return node->data(role); + } + + return QVariant(); +} + + +QStringList BookmarksTreeModel::mimeTypes() const +{ + return QStringList(BookmarkManager::bookmark_mime_type()); +} + + +bool BookmarksTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + if (action != Qt::MoveAction || !data->hasFormat(BookmarkManager::bookmark_mime_type())) + return false; + + QByteArray addresses = data->data(BookmarkManager::bookmark_mime_type()); + KBookmark bookmark = BookmarkManager::self()->findByAddress(QString::fromLatin1(addresses.data())); + + KBookmarkGroup root; + if (parent.isValid()) + root = bookmarkForIndex(parent).toGroup(); + else + root = BookmarkManager::self()->rootGroup(); + + QModelIndex destIndex = index(row, column, parent); + + if (destIndex.isValid() && row != -1) + { + root.moveBookmark(bookmark, root.previous(bookmarkForIndex(destIndex))); + } + else + { + root.deleteBookmark(bookmark); + root.addBookmark(bookmark); + } + + BookmarkManager::self()->emitChanged(); + + return true; +} + + +Qt::DropActions BookmarksTreeModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + + +QMimeData* BookmarksTreeModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData; + + QByteArray address = bookmarkForIndex(indexes.first()).address().toLatin1(); + mimeData->setData(BookmarkManager::bookmark_mime_type(), address); + bookmarkForIndex(indexes.first()).populateMimeData(mimeData); + + return mimeData; +} + + +void BookmarksTreeModel::bookmarksChanged(const QString &groupAddress) +{ + if (groupAddress.isEmpty()) + { + resetModel(); + } + else + { + beginResetModel(); + BtmItem *node = m_root; + QModelIndex nodeIndex; + + QStringList indexChain(groupAddress.split('/', QString::SkipEmptyParts)); + bool ok; + int i; + Q_FOREACH(const QString & sIndex, indexChain) + { + i = sIndex.toInt(&ok); + if (!ok) + break; + + if (i < 0 || i >= node->childCount()) + break; + + node = node->child(i); + nodeIndex = index(i, 0, nodeIndex); + } + populate(node, BookmarkManager::self()->findByAddress(groupAddress).toGroup()); + endResetModel(); + } + + emit bookmarksUpdated(); +} + + +void BookmarksTreeModel::resetModel() +{ + setRoot(BookmarkManager::self()->rootGroup()); +} + + +void BookmarksTreeModel::setRoot(KBookmarkGroup bmg) +{ + beginResetModel(); + delete m_root; + m_root = new BtmItem(KBookmark()); + populate(m_root, bmg); + endResetModel(); +} + + +void BookmarksTreeModel::populate(BtmItem *node, KBookmarkGroup bmg) +{ + node->clear(); + + if (bmg.isNull()) + return; + + KBookmark bm = bmg.first(); + while (!bm.isNull()) + { + BtmItem *newChild = new BtmItem(bm); + if (bm.isGroup()) + populate(newChild, bm.toGroup()); + + node->appendChild(newChild); + bm = bmg.next(bm); + } +} + + +KBookmark BookmarksTreeModel::bookmarkForIndex(const QModelIndex &index) const +{ + return static_cast(index.internalPointer())->getBkm(); +} diff --git a/src/bookmarks/bookmarkstreemodel.h b/src/bookmarks/bookmarkstreemodel.h new file mode 100644 index 00000000..d12c898d --- /dev/null +++ b/src/bookmarks/bookmarkstreemodel.h @@ -0,0 +1,116 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Nils Weigel +* Copyright (C) 2010-2013 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 BOOKMARKS_TREE_MODEL_H +#define BOOKMARKS_TREE_MODEL_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE includes +#include + +// Qt Includes +#include + + +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 + +public: + explicit BookmarksTreeModel(QObject *parent = 0); + virtual ~BookmarksTreeModel(); + + /** + * @return number of rows under the given parent. + */ + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + /** + * @return number of columns (always 1). + */ + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + + /** + * @return index in the model specified by the given row, column and parent. + */ + virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + /** + * @return parent of the given index. + */ + virtual QModelIndex parent(const QModelIndex &index) const; + 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 Q_SLOTS: + void bookmarksChanged(const QString &groupAddress); + +Q_SIGNALS: + void bookmarksUpdated(); + +private: + void resetModel(); + void setRoot(KBookmarkGroup bmg); + void populate(BtmItem *node, KBookmarkGroup bmg); + KBookmark bookmarkForIndex(const QModelIndex &index) const; + + BtmItem *m_root; +}; + +#endif // BOOKMARKS_TREE_MODEL_H diff --git a/src/history/historymodels.cpp b/src/history/historymodels.cpp index 4e1ca01f..76b504d3 100644 --- a/src/history/historymodels.cpp +++ b/src/history/historymodels.cpp @@ -748,20 +748,20 @@ void HistoryTreeModel::sourceRowsRemoved(const QModelIndex &parent, int start, i // ---------------------------------------------------------------------------------------------------------- -UrlFilterProxyModel::UrlFilterProxyModel(QObject *parent) +SortFilterProxyModel::SortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent) { setFilterCaseSensitivity(Qt::CaseInsensitive); } -bool UrlFilterProxyModel::filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const +bool SortFilterProxyModel::filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const { return recursiveMatch(sourceModel()->index(source_row, 0, source_parent)); } -bool UrlFilterProxyModel::recursiveMatch(const QModelIndex &index) const +bool SortFilterProxyModel::recursiveMatch(const QModelIndex &index) const { if (index.data().toString().contains(filterRegExp())) return true; diff --git a/src/history/historymodels.h b/src/history/historymodels.h index be0cb442..598c8de3 100644 --- a/src/history/historymodels.h +++ b/src/history/historymodels.h @@ -186,12 +186,12 @@ private: * If a url matches the filter it'll be shown, * even if it's parent doesn't match it. */ -class UrlFilterProxyModel : public QSortFilterProxyModel +class SortFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - explicit UrlFilterProxyModel(QObject *parent = 0); + explicit SortFilterProxyModel(QObject *parent = 0); protected: virtual bool filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const; diff --git a/src/icons/iconmanager.cpp b/src/icons/iconmanager.cpp index e0408577..c8775ed3 100644 --- a/src/icons/iconmanager.cpp +++ b/src/icons/iconmanager.cpp @@ -74,7 +74,7 @@ IconManager::IconManager(QObject *parent) KIcon IconManager::iconForUrl(const KUrl &url) { // first things first.. avoid infinite loop at startup - if (url.isEmpty() || (rApp->tabWindowList().isEmpty() && rApp->webAppList().isEmpty())) + if (url.isEmpty() || (rApp->rekonqWindowList().isEmpty() && rApp->webAppList().isEmpty())) return KIcon("text-html"); QByteArray encodedUrl = url.toEncoded(); @@ -192,7 +192,7 @@ void IconManager::saveDesktopIconForUrl(const KUrl &u) QString IconManager::iconPathForUrl(const KUrl &url) { // first things first.. avoid infinite loop at startup - if (url.isEmpty() || rApp->tabWindowList().isEmpty()) + if (url.isEmpty() || rApp->rekonqWindowList().isEmpty()) { QString icon = QL1S("file://") + KGlobal::dirs()->findResource("icon", "oxygen/16x16/mimetypes/text-html.png"); return icon; diff --git a/src/main.cpp b/src/main.cpp index eabbfde5..0d4527c4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,7 +30,7 @@ // Local Includes #include "application.h" #include "sessionmanager.h" -#include "tabwindow.h" +#include "rekonqwindow.h" #include "urlresolver.h" // KDE Includes @@ -230,12 +230,14 @@ extern "C" KDE_EXPORT int kdemain(int argc, char **argv) QCoreApplication::setApplicationVersion(REKONQ_VERSION); if (app.isSessionRestored()) - for (int i = 1; TabWindow::canBeRestored(i); i++) + { + for (int i = 1; RekonqWindow::canBeRestored(i); i++) { - TabWindow * newTabWindow = app.newTabWindow(false); - if (newTabWindow->restore(i)) - SessionManager::self()->restoreTabWindow(newTabWindow); + RekonqWindow * newRekonqWindow = app.newWindow(false); + if (newRekonqWindow->restore(i)) + SessionManager::self()->restoreWindow(newRekonqWindow); } - + } + return app.exec(); } diff --git a/src/panels/bookmarkspanel.cpp b/src/panels/bookmarkspanel.cpp new file mode 100644 index 00000000..57796a23 --- /dev/null +++ b/src/panels/bookmarkspanel.cpp @@ -0,0 +1,170 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Nils Weigel +* Copyright (C) 2010-2013 by Andrea Diamantini +* Copyright (C) 2010 by Yoann Laissus +* +* 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 "bookmarkspanel.h" +#include "bookmarkspanel.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "bookmarkmanager.h" +#include "bookmarkstreemodel.h" +#include "bookmarkscontextmenu.h" +#include "bookmarkowner.h" + +#include "paneltreeview.h" +#include "urlfilterproxymodel.h" + + +BookmarksPanel::BookmarksPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) + : UrlPanel(title, parent, flags) + , _bkTreeModel(new BookmarksTreeModel(this)) + , _loadingState(false) +{ + setObjectName("bookmarksPanel"); + setVisible(ReKonfig::showBookmarksPanel()); + + panelTreeView()->setDragEnabled(true); + panelTreeView()->setAcceptDrops(true); + connect(_bkTreeModel, SIGNAL(bookmarksUpdated()), this, SLOT(loadFoldedState())); +} + + +BookmarksPanel::~BookmarksPanel() +{ + ReKonfig::setShowBookmarksPanel(!isHidden()); +} + + +void BookmarksPanel::loadFoldedState() +{ + _loadingState = true; + loadFoldedState(QModelIndex()); + _loadingState = false; +} + + +void BookmarksPanel::contextMenu(const QPoint &pos) +{ + if (_loadingState) + return; + + BookmarksContextMenu menu(bookmarkForIndex(panelTreeView()->indexAt(pos)), + BookmarkManager::self()->manager(), + BookmarkManager::self()->owner() + ); + + menu.exec(panelTreeView()->mapToGlobal(pos)); +} + + +void BookmarksPanel::deleteBookmark() +{ + QModelIndex index = panelTreeView()->currentIndex(); + if (_loadingState || !index.isValid()) + return; + + BookmarkManager::self()->owner()->deleteBookmark(bookmarkForIndex(index)); +} + + +void BookmarksPanel::onCollapse(const QModelIndex &index) +{ + if (_loadingState) + return; + + bookmarkForIndex(index).internalElement().setAttribute("folded", "yes"); + emit expansionChanged(); +} + + +void BookmarksPanel::onExpand(const QModelIndex &index) +{ + if (_loadingState) + return; + + bookmarkForIndex(index).internalElement().setAttribute("folded", "no"); + emit expansionChanged(); +} + + +void BookmarksPanel::setup() +{ + UrlPanel::setup(); + + connect(panelTreeView(), SIGNAL(delKeyPressed()), this, SLOT(deleteBookmark())); + connect(panelTreeView(), SIGNAL(collapsed(QModelIndex)), this, SLOT(onCollapse(QModelIndex))); + connect(panelTreeView(), SIGNAL(expanded(QModelIndex)), this, SLOT(onExpand(QModelIndex))); + + loadFoldedState(); +} + + +void BookmarksPanel::loadFoldedState(const QModelIndex &root) +{ + QAbstractItemModel *model = panelTreeView()->model(); + if (!model) + return; + + int count = model->rowCount(root); + QModelIndex index; + + for (int i = 0; i < count; ++i) + { + index = model->index(i, 0, root); + if (index.isValid()) + { + KBookmark bm = bookmarkForIndex(index); + if (bm.isGroup()) + { + panelTreeView()->setExpanded(index, bm.toGroup().isOpen()); + loadFoldedState(index); + } + } + } +} + + +KBookmark BookmarksPanel::bookmarkForIndex(const QModelIndex &index) +{ + if (!index.isValid()) + return KBookmark(); + + const UrlFilterProxyModel *proxyModel = static_cast(index.model()); + QModelIndex originalIndex = proxyModel->mapToSource(index); + + BtmItem *node = static_cast(originalIndex.internalPointer()); + return node->getBkm(); +} + + +QAbstractItemModel* BookmarksPanel::model() +{ + return _bkTreeModel; +} diff --git a/src/panels/bookmarkspanel.h b/src/panels/bookmarkspanel.h new file mode 100644 index 00000000..8c827c65 --- /dev/null +++ b/src/panels/bookmarkspanel.h @@ -0,0 +1,93 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Nils Weigel +* Copyright (C) 2010-2013 by Andrea Diamantini +* Copyright (C) 2010 by Yoann Laissus +* +* +* 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 BOOKMARKS_PANEL_H +#define BOOKMARKS_PANEL_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Local Includes +#include "urlpanel.h" + +// Forward Declarations +class BookmarksTreeModel; + +class KBookmark; +class QModelIndex; + + +class REKONQ_TESTS_EXPORT BookmarksPanel : public UrlPanel +{ + Q_OBJECT + +public: + explicit BookmarksPanel(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~BookmarksPanel(); + +public Q_SLOTS: + void loadFoldedState(); + +Q_SIGNALS: + void expansionChanged(); + +private Q_SLOTS: + void contextMenu(const QPoint &pos); + + virtual void contextMenuItem(const QPoint &pos) + { + contextMenu(pos); + } + virtual void contextMenuGroup(const QPoint &pos) + { + contextMenu(pos); + } + virtual void contextMenuEmpty(const QPoint &pos) + { + contextMenu(pos); + } + + void deleteBookmark(); + void onCollapse(const QModelIndex &index); + void onExpand(const QModelIndex &index); + +private: + virtual void setup(); + + void loadFoldedState(const QModelIndex &root); + + KBookmark bookmarkForIndex(const QModelIndex &index); + + virtual QAbstractItemModel* model(); + + BookmarksTreeModel *_bkTreeModel; + bool _loadingState; +}; + +#endif // BOOKMARKS_PANEL_H diff --git a/src/panels/historypanel.cpp b/src/panels/historypanel.cpp new file mode 100644 index 00000000..30d2cb6b --- /dev/null +++ b/src/panels/historypanel.cpp @@ -0,0 +1,214 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Domrachev Alexandr +* Copyright (C) 2009-2011 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 "historypanel.h" +#include "historypanel.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "paneltreeview.h" + +#include "historymanager.h" +#include "historymodels.h" +#include "urlfilterproxymodel.h" + +// KDE Includes +#include +#include +#include +#include + +// Qt Includes +#include + + +HistoryPanel::HistoryPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) + : UrlPanel(title, parent, flags) +{ + setObjectName("historyPanel"); + setVisible(ReKonfig::showHistoryPanel()); +} + + +HistoryPanel::~HistoryPanel() +{ + ReKonfig::setShowHistoryPanel(!isHidden()); +} + + +void HistoryPanel::contextMenuItem(const QPoint &pos) +{ + KMenu menu; + KAction* action; + + action = new KAction(KIcon("tab-new"), i18n("Open"), this); + connect(action, SIGNAL(triggered()), panelTreeView(), SLOT(openInCurrentTab())); + menu.addAction(action); + + action = new KAction(KIcon("tab-new"), i18n("Open in New Tab"), this); + connect(action, SIGNAL(triggered()), panelTreeView(), SLOT(openInNewTab())); + menu.addAction(action); + + action = new KAction(KIcon("window-new"), i18n("Open in New Window"), this); + connect(action, SIGNAL(triggered()), panelTreeView(), SLOT(openInNewWindow())); + menu.addAction(action); + + action = new KAction(KIcon("edit-copy"), i18n("Copy Link Address"), this); + connect(action, SIGNAL(triggered()), panelTreeView(), SLOT(copyToClipboard())); + menu.addAction(action); + + action = new KAction(KIcon("edit-clear"), i18n("Remove Entry"), this); + connect(action, SIGNAL(triggered()), this, SLOT(deleteEntry())); + menu.addAction(action); + + action = new KAction(KIcon("edit-clear"), i18n("Remove all occurrences"), this); + connect(action, SIGNAL(triggered()), this, SLOT(forgetSite())); + menu.addAction(action); + + menu.exec(panelTreeView()->mapToGlobal(pos)); +} + + +void HistoryPanel::contextMenuGroup(const QPoint &pos) +{ + KMenu menu; + KAction* action; + + action = new KAction(KIcon("tab-new"), i18n("Open Folder in Tabs"), this); + connect(action, SIGNAL(triggered()), this, SLOT(openAll())); + menu.addAction(action); + + action = new KAction(KIcon("edit-clear"), i18n("Remove Folder"), this); + connect(action, SIGNAL(triggered()), this, SLOT(deleteGroup())); + menu.addAction(action); + + menu.exec(panelTreeView()->mapToGlobal(pos)); +} + + +void HistoryPanel::contextMenuEmpty(const QPoint& /*pos*/) +{ +} + + +void HistoryPanel::openAll() +{ + QModelIndex index = panelTreeView()->currentIndex(); + if (!index.isValid()) + return; + + QList allChild; + + for (int i = 0; i < index.model()->rowCount(index); i++) + allChild << qVariantValue(index.child(i, 0).data(Qt::UserRole)); + + if (allChild.length() > 8) + { + if (!(KMessageBox::warningContinueCancel(this, + i18ncp("%1=Number of tabs. Value is always >=8", + "You are about to open %1 tabs.\nAre you sure?", + "You are about to open %1 tabs.\nAre you sure?", + allChild.length())) == KMessageBox::Continue) + ) + return; + } + + for (int i = 0; i < allChild.length(); i++) + emit openUrl(allChild.at(i).url(), Rekonq::NewTab); +} + + +void HistoryPanel::deleteGroup() +{ + QModelIndex index = panelTreeView()->currentIndex(); + if (!index.isValid()) + return; + + //Getting all URLs of sub items. + QList allChild; + for (int i = 0; i < index.model()->rowCount(index); i++) + allChild << qVariantValue(index.child(i, 0).data(Qt::UserRole)); + + for (int i = 0; i < allChild.length(); i++) + HistoryManager::self()->removeHistoryEntry(allChild.at(i)); + +} + + +void HistoryPanel::setup() +{ + UrlPanel::setup(); + + panelTreeView()->header()->hideSection(1); + + const UrlFilterProxyModel *proxy = static_cast(panelTreeView()->model()); + panelTreeView()->expand(proxy->index(0, 0)); +} + + +void HistoryPanel::deleteEntry() +{ + QModelIndex index = panelTreeView()->currentIndex(); + if (!index.isValid()) + return; + removedFolderIndex = index.parent().row(); + + HistoryManager::self()->removeHistoryEntry(qVariantValue< KUrl >(index.data(Qt::UserRole))); + + QModelIndex expandItem = panelTreeView()->model()->index(removedFolderIndex, 0); + if (expandItem.isValid()) + panelTreeView()->expand(expandItem); +} + + +void HistoryPanel::forgetSite() +{ + QModelIndex index = panelTreeView()->currentIndex(); + if (!index.isValid()) + return; + removedFolderIndex = index.row(); + + QString site = qVariantValue< KUrl >(index.data(Qt::UserRole)).host(); + QList toRemove = HistoryManager::self()->find(site); + for (int i = 0; i < toRemove.length(); i++) + { + HistoryManager::self()->removeHistoryEntry(KUrl(toRemove.at(i).url)); + } + + QModelIndex expandItem = panelTreeView()->model()->index(removedFolderIndex, 0); + if (expandItem.isValid()) + panelTreeView()->expand(expandItem); +} + + +QAbstractItemModel* HistoryPanel::model() +{ + return HistoryManager::self()->historyTreeModel(); +} diff --git a/src/panels/historypanel.h b/src/panels/historypanel.h new file mode 100644 index 00000000..bae55d76 --- /dev/null +++ b/src/panels/historypanel.h @@ -0,0 +1,63 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Domrachev Alexandr +* Copyright (C) 2009-2013 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 HISTORYPANEL_H +#define HISTORYPANEL_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Local Includes +#include "urlpanel.h" + + +class REKONQ_TESTS_EXPORT HistoryPanel : public UrlPanel +{ + Q_OBJECT + +public: + explicit HistoryPanel(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); + virtual ~HistoryPanel(); + +private Q_SLOTS: + virtual void contextMenuItem(const QPoint &pos); + virtual void contextMenuGroup(const QPoint &pos); + virtual void contextMenuEmpty(const QPoint &pos); + + void openAll(); + void deleteEntry(); + void deleteGroup(); + void forgetSite(); + +private: + virtual void setup(); + virtual QAbstractItemModel* model(); + int removedFolderIndex; +}; + +#endif // HISTORYPANEL_H diff --git a/src/panels/paneltreeview.cpp b/src/panels/paneltreeview.cpp new file mode 100644 index 00000000..722ba8a9 --- /dev/null +++ b/src/panels/paneltreeview.cpp @@ -0,0 +1,186 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Yoann Laissus +* Copyright (C) 2012-2013 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 "paneltreeview.h" +#include "paneltreeview.moc" + +// Local Includes +#include "application.h" + +// KDE Includes +#include + +// Qt Includes +#include +#include + + +PanelTreeView::PanelTreeView(QWidget *parent) + : QTreeView(parent) +{ + connect(this, SIGNAL(itemHovered(QString)), parent, SIGNAL(itemHovered(QString))); + connect(this, SIGNAL(openUrl(KUrl, Rekonq::OpenType)), parent, SIGNAL(openUrl(KUrl, Rekonq::OpenType))); + + setMouseTracking(true); + setExpandsOnDoubleClick(false); +} + + +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) + emit openUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::NewTab); + + else if (event->button() == Qt::LeftButton) + { + if (model()->rowCount(index) == 0) + emit openUrl(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) + openUrl(qVariantValue< KUrl >(index.data(Qt::UserRole))); + else + setExpanded(index, !isExpanded(index)); + } + + else if (event->key() == Qt::Key_Delete) + { + emit delKeyPressed(); + } +} + + +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; + + emit openUrl(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; + + emit openUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::NewTab); +} + + +void PanelTreeView::openInNewWindow() +{ + QModelIndex index = currentIndex(); + if (!index.isValid()) + return; + + emit openUrl(qVariantValue< KUrl >(index.data(Qt::UserRole)), Rekonq::NewWindow); +} diff --git a/src/panels/paneltreeview.h b/src/panels/paneltreeview.h new file mode 100644 index 00000000..ee8c51d0 --- /dev/null +++ b/src/panels/paneltreeview.h @@ -0,0 +1,69 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010-2011 by Yoann Laissus +* Copyright (C) 2012-2013 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 PANELTREEVIEW_H +#define PANELTREEVIEW_H + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include + +// Forward Declarations +class KUrl; + + +class REKONQ_TESTS_EXPORT PanelTreeView : public QTreeView +{ + Q_OBJECT + +public: + PanelTreeView(QWidget *parent = 0); + +Q_SIGNALS: + void openUrl(const KUrl &, const Rekonq::OpenType & = Rekonq::CurrentTab); + void itemHovered(const QString &); + void delKeyPressed(); + void contextMenuItemRequested(const QPoint &pos); + void contextMenuGroupRequested(const QPoint &pos); + void contextMenuEmptyRequested(const QPoint &pos); + +public Q_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); +}; + +#endif // PANELTREEVIEW_H diff --git a/src/panels/urlfilterproxymodel.cpp b/src/panels/urlfilterproxymodel.cpp new file mode 100644 index 00000000..aa9ac7a6 --- /dev/null +++ b/src/panels/urlfilterproxymodel.cpp @@ -0,0 +1,59 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Nils Weigel +* Copyright (C) 2010-2011 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 "urlfilterproxymodel.h" +#include "urlfilterproxymodel.moc" + + +UrlFilterProxyModel::UrlFilterProxyModel(QObject *parent) + : QSortFilterProxyModel(parent) +{ + setFilterCaseSensitivity(Qt::CaseInsensitive); +} + + +bool UrlFilterProxyModel::filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const +{ + return recursiveMatch(sourceModel()->index(source_row, 0, source_parent)); +} + + +bool UrlFilterProxyModel::recursiveMatch(const QModelIndex &index) const +{ + if (index.data().toString().contains(filterRegExp())) + return true; + + int numChildren = sourceModel()->rowCount(index); + for (int childRow = 0; childRow < numChildren; ++childRow) + { + if (recursiveMatch(sourceModel()->index(childRow, 0, index))) + return true; + } + + return false; +} diff --git a/src/panels/urlfilterproxymodel.h b/src/panels/urlfilterproxymodel.h new file mode 100644 index 00000000..6cb8574e --- /dev/null +++ b/src/panels/urlfilterproxymodel.h @@ -0,0 +1,59 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Nils Weigel +* Copyright (C) 2010-2011 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 URLFILTERPROXYMODEL_H +#define URLFILTERPROXYMODEL_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include + + +/** + * QSortFilterProxyModel hides all children which parent doesn't + * match the filter. This class is used to change this behavior. + * If a url matches the filter it'll be shown, + * even if it's parent doesn't match it. + */ +class REKONQ_TESTS_EXPORT UrlFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + explicit UrlFilterProxyModel(QObject *parent = 0); + +protected: + virtual bool filterAcceptsRow(const int source_row, const QModelIndex &source_parent) const; + + // returns true if index or any of his children match the filter + bool recursiveMatch(const QModelIndex &index) const; +}; + +#endif // URLFILTERPROXYMODEL_H diff --git a/src/panels/urlpanel.cpp b/src/panels/urlpanel.cpp new file mode 100644 index 00000000..7fb75087 --- /dev/null +++ b/src/panels/urlpanel.cpp @@ -0,0 +1,111 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Domrachev Alexandr +* Copyright (C) 2009-2013 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 "urlpanel.h" +#include "urlpanel.moc" + +// Local Includes +#include "paneltreeview.h" +#include "urlfilterproxymodel.h" + +// KDE Includes +#include +#include + +// Qt Includes +#include +#include +#include + + +UrlPanel::UrlPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) + : QDockWidget(title, parent, flags) + , _treeView(new PanelTreeView(this)) + , _loaded(false) +{ + setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + connect(this, SIGNAL(visibilityChanged(bool)), this, SLOT(showing(bool))); +} + + +void UrlPanel::showing(bool b) +{ + if (!_loaded && b) + { + setup(); + _loaded = true; + } +} + + +void UrlPanel::setup() +{ + QWidget *ui = new QWidget(this); + + // setup search bar + QHBoxLayout *searchLayout = new QHBoxLayout; + searchLayout->setContentsMargins(5, 0, 0, 0); + QLabel *searchLabel = new QLabel(i18n("&Search:")); + searchLayout->addWidget(searchLabel); + KLineEdit *search = new KLineEdit; + search->setClearButtonShown(true); + searchLayout->addWidget(search); + searchLabel->setBuddy(search); + + // setup tree view + _treeView->setUniformRowHeights(true); + _treeView->header()->hide(); + + // put everything together + QVBoxLayout *vBoxLayout = new QVBoxLayout; + vBoxLayout->setContentsMargins(0, 0, 0, 0); + vBoxLayout->addLayout(searchLayout); + vBoxLayout->addWidget(_treeView); + + // add it to the UI + ui->setLayout(vBoxLayout); + setWidget(ui); + + UrlFilterProxyModel *proxy = new UrlFilterProxyModel(this); + proxy->setSourceModel(model()); + _treeView->setModel(proxy); + + connect(search, SIGNAL(textChanged(QString)), proxy, SLOT(setFilterFixedString(QString))); + connect(search, SIGNAL(textChanged(QString)), this, SLOT(expandTreeView())); + + connect(_treeView, SIGNAL(contextMenuItemRequested(QPoint)), this, SLOT(contextMenuItem(QPoint))); + connect(_treeView, SIGNAL(contextMenuGroupRequested(QPoint)), this, SLOT(contextMenuGroup(QPoint))); + connect(_treeView, SIGNAL(contextMenuEmptyRequested(QPoint)), this, SLOT(contextMenuEmpty(QPoint))); +} + + +void UrlPanel::expandTreeView() +{ + _treeView->expandAll(); +} diff --git a/src/panels/urlpanel.h b/src/panels/urlpanel.h new file mode 100644 index 00000000..72393c9e --- /dev/null +++ b/src/panels/urlpanel.h @@ -0,0 +1,81 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Domrachev Alexandr +* Copyright (C) 2009-2013 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 URLPANEL_H +#define URLPANEL_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include + +// Forward Declarations +class PanelTreeView; + +class QAbstractItemModel; + + +class REKONQ_TESTS_EXPORT UrlPanel : public QDockWidget +{ + Q_OBJECT + +public: + explicit UrlPanel(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); + +Q_SIGNALS: + void openUrl(const KUrl &, const Rekonq::OpenType &); + void itemHovered(const QString &); + +public Q_SLOTS: + void showing(bool); + +protected: + virtual void setup(); + virtual QAbstractItemModel* model() = 0; + + PanelTreeView* panelTreeView() const + { + return _treeView; + } + +protected Q_SLOTS: + virtual void contextMenuItem(const QPoint &pos) = 0; + virtual void contextMenuGroup(const QPoint &pos) = 0; + virtual void contextMenuEmpty(const QPoint &pos) = 0; + +private Q_SLOTS: + void expandTreeView(); + +private: + PanelTreeView *_treeView; + bool _loaded; +}; + + +#endif // URLPANEL_H diff --git a/src/rekonq.kcfg b/src/rekonq.kcfg index 3e8e07ff..3997587d 100644 --- a/src/rekonq.kcfg +++ b/src/rekonq.kcfg @@ -57,6 +57,12 @@ + + false + + + false + diff --git a/src/rekonqpage/newtabpage.cpp b/src/rekonqpage/newtabpage.cpp index c1a1f248..48b567de 100644 --- a/src/rekonqpage/newtabpage.cpp +++ b/src/rekonqpage/newtabpage.cpp @@ -34,7 +34,8 @@ // Local Includes #include "application.h" -#include "tabwindow.h" +#include "rekonqwindow.h" +#include "tabwidget.h" #include "previewselectorbar.h" #include "thumbupdater.h" @@ -181,7 +182,7 @@ void NewTabPage::generate(const KUrl &url) { const int tabIndex = url.queryItem(QL1S("tab")).toInt(); - rApp->tabWindow()->restoreClosedTab(tabIndex, false); + rApp->rekonqWindow()->tabWidget()->restoreClosedTab(tabIndex, false); return; } } @@ -430,7 +431,7 @@ void NewTabPage::historyPage(const QString & filter) m_root.document().findFirst(QL1S("#actions")).appendInside(clearHistory); HistoryTreeModel *model = HistoryManager::self()->historyTreeModel(); - UrlFilterProxyModel *proxy = new UrlFilterProxyModel(this); + SortFilterProxyModel *proxy = new SortFilterProxyModel(this); proxy->setSourceModel(model); bool filterIsEmpty = filter.isEmpty(); @@ -563,7 +564,7 @@ void NewTabPage::closedTabsPage() { m_root.addClass(QL1S("closedTabs")); - QList links = rApp->tabWindow()->recentlyClosedTabs(); + QList links = rApp->rekonqWindow()->tabWidget()->recentlyClosedTabs(); if (links.isEmpty()) { diff --git a/src/sessionmanager.cpp b/src/sessionmanager.cpp index e9ea5bf5..c4927cbc 100644 --- a/src/sessionmanager.cpp +++ b/src/sessionmanager.cpp @@ -35,7 +35,7 @@ #include "autosaver.h" #include "tabhistory.h" -#include "tabwindow.h" +#include "rekonqwindow.h" #include "tabbar.h" #include "webwindow.h" @@ -74,7 +74,7 @@ bool readSessionDocument(QDomDocument & document, const QString & sessionFilePat } -int loadTabs(TabWindow *tw, QDomElement & window, bool useFirstTab, bool justThePinnedOnes = false) +int loadTabs(RekonqWindow *tw, QDomElement & window, bool useFirstTab, bool justThePinnedOnes = false) { int currentTab = 0; @@ -191,38 +191,39 @@ void SessionManager::save() kDebug() << "Unable to open session file" << sessionFile.fileName(); return; } - TabWindowList wl = rApp->tabWindowList(); + RekonqWindowList wl = rApp->rekonqWindowList(); QDomDocument document("session"); QDomElement session = document.createElement("session"); document.appendChild(session); - Q_FOREACH(const QWeakPointer &w, wl) + Q_FOREACH(const QWeakPointer &w, wl) { QDomElement window = document.createElement("window"); int tabInserted = 0; window.setAttribute("name", w.data()->objectName()); - - for (signed int tabNo = 0; tabNo < w.data()->count(); tabNo++) + + TabWidget *tw = w.data()->tabWidget(); + for (signed int tabNo = 0; tabNo < tw->count(); tabNo++) { - KUrl u = w.data()->webWindow(tabNo)->url(); + KUrl u = tw->webWindow(tabNo)->url(); tabInserted++; QDomElement tab = document.createElement("tab"); - tab.setAttribute("title", w.data()->webWindow(tabNo)->title()); // redundant, but needed for closedSites() + tab.setAttribute("title", tw->webWindow(tabNo)->title()); // redundant, but needed for closedSites() // as there's not way to read out the historyData tab.setAttribute("url", u.url()); - if (w.data()->currentIndex() == tabNo) + if (tw->currentIndex() == tabNo) { tab.setAttribute("currentTab", 1); } - if (w.data()->tabBar()->tabData(tabNo).toBool()) // pinned tab info + if (tw->tabBar()->tabData(tabNo).toBool()) // pinned tab info { tab.setAttribute("pinned", 1); } QByteArray history; QDataStream historyStream(&history, QIODevice::ReadWrite); - historyStream << *(w.data()->webWindow(tabNo)->page()->history()); + historyStream << *(tw->webWindow(tabNo)->page()->history()); QDomCDATASection historySection = document.createCDATASection(history.toBase64()); tab.appendChild(historySection); @@ -252,11 +253,11 @@ bool SessionManager::restoreSessionFromScratch() { QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); - TabWindow *tw = rApp->newTabWindow(); + RekonqWindow *tw = rApp->newWindow(); int currentTab = loadTabs(tw, window, true, false); - tw->setCurrentIndex(currentTab); + tw->tabWidget()->setCurrentIndex(currentTab); } return true; @@ -279,11 +280,11 @@ bool SessionManager::restoreJustThePinnedTabs() continue; done = true; - TabWindow *tw = rApp->newTabWindow(false); + RekonqWindow *tw = rApp->newWindow(false); int currentTab = loadTabs(tw, window, false, true); - tw->setCurrentIndex(currentTab); + tw->tabWidget()->setCurrentIndex(currentTab); } return done; @@ -301,22 +302,22 @@ void SessionManager::restoreCrashedSession() { QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); - TabWindow *tw = (winNo == 0) - ? rApp->tabWindow() - : rApp->newTabWindow(); + RekonqWindow *tw = (winNo == 0) + ? rApp->rekonqWindow() + : rApp->newWindow(); KUrl u = tw->currentWebWindow()->url(); bool useCurrentTab = (u.isEmpty() || u.protocol() == QL1S("about")); int currentTab = loadTabs(tw, window, useCurrentTab); - tw->setCurrentIndex(currentTab); + tw->tabWidget()->setCurrentIndex(currentTab); } setSessionManagementEnabled(true); } -bool SessionManager::restoreTabWindow(TabWindow* window) +bool SessionManager::restoreWindow(RekonqWindow* window) { QDomDocument document("session"); @@ -334,7 +335,7 @@ bool SessionManager::restoreTabWindow(TabWindow* window) int currentTab = loadTabs(window, savedWindowElement, false); - window->setCurrentIndex(currentTab); + window->tabWidget()->setCurrentIndex(currentTab); return true; } diff --git a/src/sessionmanager.h b/src/sessionmanager.h index 344f3b8a..1cd2ba71 100644 --- a/src/sessionmanager.h +++ b/src/sessionmanager.h @@ -41,7 +41,8 @@ // Forward Declarations class AutoSaver; class TabHistory; -class TabWindow; + +class RekonqWindow; /** @@ -67,8 +68,8 @@ public: QList closedSitesForWindow(const QString &); - // This method restores a single TabWindow - bool restoreTabWindow(TabWindow * window); + // This method restores a single Window + bool restoreWindow(RekonqWindow * window); private: explicit SessionManager(QObject *parent = 0); diff --git a/src/settings/generalwidget.cpp b/src/settings/generalwidget.cpp index ae08a01f..d64fd8d3 100644 --- a/src/settings/generalwidget.cpp +++ b/src/settings/generalwidget.cpp @@ -33,7 +33,7 @@ // Local Includes #include "application.h" -#include "tabwindow.h" +#include "rekonqwindow.h" #include "webwindow.h" //KDE Includes @@ -91,8 +91,7 @@ void GeneralWidget::hasChanged() void GeneralWidget::setHomeToCurrentPage() { - TabWindow *tw = rApp->tabWindow(); - WebWindow *tab = tw->currentWebWindow(); + WebWindow *tab = rApp->rekonqWindow()->currentWebWindow(); if (tab) { kcfg_homePage->setText(tab->url().url()); diff --git a/src/tabwindow/rekonqwindow.cpp b/src/tabwindow/rekonqwindow.cpp index ee37eba9..a14dcf15 100644 --- a/src/tabwindow/rekonqwindow.cpp +++ b/src/tabwindow/rekonqwindow.cpp @@ -2,7 +2,7 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2012 by Andrea Diamantini +* Copyright (C) 2013 by Andrea Diamantini * * * This program is free software; you can redistribute it and/or @@ -27,422 +27,163 @@ // Self Includes #include "rekonqwindow.h" #include "rekonqwindow.moc" -#include - -// KDE Includes -#include -#include -#include - -// Qt Includes -#include -#include - - -static bool s_no_query_exit = false; - - -class KRWSessionManager : public KSessionManager -{ - -public: - KRWSessionManager() - { - } - - ~KRWSessionManager() - { - } - - bool dummyInit() - { - return true; - } - - bool saveState(QSessionManager&) - { - KConfig* config = KApplication::kApplication()->sessionConfig(); - int n = 0; - Q_FOREACH(RekonqWindow * rw, RekonqWindow::windowList()) - { - n++; - rw->savePropertiesInternal(config, n); - } - - KConfigGroup group(config, "Number"); - group.writeEntry("NumberOfWindows", n); - return true; - } - - bool commitData(QSessionManager& sm) - { - // not really a fast method but the only compatible one - if (sm.allowsInteraction()) - { - bool canceled = false; - ::s_no_query_exit = true; - - Q_FOREACH(RekonqWindow * window, RekonqWindow::windowList()) - { - if (!window->testAttribute(Qt::WA_WState_Hidden)) - { - QCloseEvent e; - QApplication::sendEvent(window, &e); - canceled = !e.isAccepted(); - if (canceled) - break; - } - } - ::s_no_query_exit = false; - if (canceled) - return false; - - return true; - } - - // the user wants it, the user gets it - return true; - } -}; +// Auto Includes +#include "rekonq.h" -K_GLOBAL_STATIC(KRWSessionManager, ktwsm) -K_GLOBAL_STATIC(QList, sWindowList) +// Local Includes +#include "application.h" +#include "tabwidget.h" +#include "tabbar.h" -// ---------------------------------------------------------------------------------------------------- +#include "webpage.h" +#include "webwindow.h" +// KDE Includes +#include +#include -RekonqWindow::RekonqWindow(QWidget* parent) - : KTabWidget(parent) -{ - // This has to be a window... - setWindowFlags(Qt::Window); - - // Setting attributes (just to be sure...) - setAttribute(Qt::WA_DeleteOnClose, true); - setAttribute(Qt::WA_QuitOnClose, true); - - ktwsm->dummyInit(); - sWindowList->append(this); - - QString geometry; - KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); - if (args && args->isSet("geometry")) - geometry = args->getOption("geometry"); - - if (geometry.isNull()) // if there is no geometry, it doesn't matter - { - KSharedConfig::Ptr cf = KGlobal::config(); - KConfigGroup cg(cf, QL1S("TabWindow")); - restoreWindowSize(cg); - } - else - { - parseGeometry(); - } - - setWindowTitle(KGlobal::caption()); -} - - -RekonqWindow::~RekonqWindow() -{ - sWindowList->removeAll(this); - - KSharedConfig::Ptr cf = KGlobal::config(); - KConfigGroup cg(cf, QL1S("TabWindow")); - saveWindowSize(cg); -} - +// Qt Includes +#include +#include -QSize RekonqWindow::sizeHint() const -{ - QRect desktopRect = QApplication::desktop()->screenGeometry(); - QSize size = desktopRect.size() * 0.8; - return size; -} -QList RekonqWindow::windowList() +RekonqWindow::RekonqWindow(bool withTab, bool privateBrowsingMode, QWidget *parent) + : RWindow(parent) + , _tabWidget(new TabWidget(withTab, privateBrowsingMode, this)) + , _splitter(new QSplitter(this)) { - return *sWindowList; + init(); } -void RekonqWindow::savePropertiesInternal(KConfig *config, int number) +RekonqWindow::RekonqWindow(WebPage *pg, QWidget *parent) + : RWindow(parent) + , _tabWidget(new TabWidget(pg, this)) + , _splitter(new QSplitter(this)) { - QString s; - s.setNum(number); - s.prepend(QL1S("WindowProperties")); - KConfigGroup cg(config, s); - - // store objectName, className, Width and Height for later restoring - // (Only useful for session management) - cg.writeEntry(QL1S("ObjectName"), objectName()); - cg.writeEntry(QL1S("ClassName"), metaObject()->className()); - - saveWindowSize(cg); - - s.setNum(number); - cg = KConfigGroup(config, s); - saveProperties(cg); + init(); } -bool RekonqWindow::readPropertiesInternal(KConfig *config, int number) +RekonqWindow::~RekonqWindow() { - // in order they are in toolbar list - QString s; - s.setNum(number); - s.prepend(QL1S("WindowProperties")); - - KConfigGroup cg(config, s); - - // restore the object name (window role) - if (cg.hasKey(QL1S("ObjectName"))) - setObjectName(cg.readEntry("ObjectName").toLatin1()); // latin1 is right here - - restoreWindowSize(cg); - - s.setNum(number); - KConfigGroup grp(config, s); - readProperties(grp); - - return true; } -void RekonqWindow::restoreWindowSize(const KConfigGroup & _cg) +void RekonqWindow::init() { - int scnum = QApplication::desktop()->screenNumber(window()); - QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - KConfigGroup cg(_cg); + QVBoxLayout *l = new QVBoxLayout(this); + l->setMargin(0); + l->setSpacing(0); - QString geometryKey = QString::fromLatin1("geometry-%1-%2").arg(desktopRect.width()).arg(desktopRect.height()); - QByteArray geometry = cg.readEntry(geometryKey, QByteArray()); + if (ReKonfig::showBookmarksPanel()) + showBookmarksPanel(true); + + if (ReKonfig::showHistoryPanel()) + showHistoryPanel(true); - // if first time run, center window: resize && move.. - if (!restoreGeometry(QByteArray::fromBase64(geometry))) - { - QSize defaultSize = desktopRect.size() * 0.8; - resize(defaultSize); + _splitter->addWidget(_tabWidget); + _tabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - move((desktopRect.width() - width()) / 2, (desktopRect.height() - height()) / 2); - } + l->addWidget(_splitter); - checkPosition(); + + // fix focus handling + setFocusProxy(_tabWidget); } - -void RekonqWindow::saveWindowSize(const KConfigGroup & _cg) const -{ - int scnum = QApplication::desktop()->screenNumber(window()); - QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); - - int w, h; - if (isMaximized()) - { - w = desktopRect.width() + 1; - h = desktopRect.height() + 1; - } - else - { - w = width(); - h = height(); - } - - KConfigGroup cg(_cg); - - QString widthString = QString::fromLatin1("Width %1").arg(desktopRect.width()); - cg.writeEntry(widthString, w); - - QString heightString = QString::fromLatin1("Height %1").arg(desktopRect.height()); - cg.writeEntry(heightString, h); - - // geometry is saved separately for each resolution - QString geometryKey = QString::fromLatin1("geometry-%1-%2").arg(desktopRect.width()).arg(desktopRect.height()); - QByteArray geometry = saveGeometry(); - cg.writeEntry(geometryKey, geometry.toBase64()); -} +// -------------------------------------------------------------------------------------------------- -void RekonqWindow::parseGeometry() +TabWidget *RekonqWindow::tabWidget() { - QString cmdlineGeometry; - KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); - if (args->isSet("geometry")) - cmdlineGeometry = args->getOption("geometry"); - - Q_ASSERT(!cmdlineGeometry.isNull()); - -// #if defined Q_WS_X11 -// int x, y; -// int w, h; -// int m = XParseGeometry( cmdlineGeometry.toLatin1(), &x, &y, (unsigned int*)&w, (unsigned int*)&h); -// if (parsewidth) { -// const QSize minSize = minimumSize(); -// const QSize maxSize = maximumSize(); -// if ( !(m & WidthValue) ) -// w = width(); -// if ( !(m & HeightValue) ) -// h = height(); -// w = qMin(w,maxSize.width()); -// h = qMin(h,maxSize.height()); -// w = qMax(w,minSize.width()); -// h = qMax(h,minSize.height()); -// resize(w, h); -// } else { -// if ( (m & XNegative) ) -// x = KApplication::desktop()->width() + x - w; -// else if ( (m & XValue) ) -// x = geometry().x(); -// if ( (m & YNegative) ) -// y = KApplication::desktop()->height() + y - h; -// else if ( (m & YValue) ) -// y = geometry().y(); -// -// move(x, y); -// } -// #endif + return _tabWidget; } -void RekonqWindow::resizeEvent(QResizeEvent *event) +TabBar *RekonqWindow::tabBar() { - if (!isFullScreen()) - saveAutoSaveSettings(); - KTabWidget::resizeEvent(event); + return _tabWidget->tabBar(); } -void RekonqWindow::saveAutoSaveSettings() +WebWindow *RekonqWindow::currentWebWindow() const { - kDebug() << "AUTO SAVING SETTINGS..."; - - KSharedConfig::Ptr cf = KGlobal::config(); - KConfigGroup cg(cf, QL1S("TabWindow")); - saveWindowSize(cg); + return _tabWidget->currentWebWindow(); } -bool RekonqWindow::canBeRestored(int number) -{ - if (!qApp->isSessionRestored()) - return false; - KConfig *config = kapp->sessionConfig(); - if (!config) - return false; - - KConfigGroup group(config, "Number"); - const int n = group.readEntry("NumberOfWindows", 1); - return number >= 1 && number <= n; -} +// -------------------------------------------------------------------------------------------------- -bool RekonqWindow::restore(int number, bool show) +void RekonqWindow::loadUrl(const KUrl &url, Rekonq::OpenType type, TabHistory *history) { - if (!canBeRestored(number)) - return false; - KConfig *config = kapp->sessionConfig(); - if (readPropertiesInternal(config, number)) + switch (type) { - if (show) - RekonqWindow::show(); - return true; - } - return false; -} - - -// NOTE: For internal purpose only ------------------------------------------------------ - - -int RekonqWindow::addTab(QWidget *page, const QString &label) -{ - setUpdatesEnabled(false); - int i = KTabWidget::addTab(page, label); - setUpdatesEnabled(true); - - return i; -} - - -int RekonqWindow::addTab(QWidget *page, const QIcon &icon, const QString &label) -{ - setUpdatesEnabled(false); - int i = KTabWidget::addTab(page, icon, label); - setUpdatesEnabled(true); - - return i; -} - - -int RekonqWindow::insertTab(int index, QWidget *page, const QString &label) -{ - if (! ReKonfig::openNewTabsNextToCurrent()) - index = -1; - setUpdatesEnabled(false); - int i = KTabWidget::insertTab(index, page, label); - setUpdatesEnabled(true); + case Rekonq::NewWindow: + case Rekonq::NewPrivateWindow: + rApp->loadUrl(url, type); + return; - return i; + case Rekonq::NewTab: + case Rekonq::NewBackGroundTab: + case Rekonq::NewFocusedTab: + case Rekonq::CurrentTab: + default: + _tabWidget->loadUrl(url, type, history); + break; + }; } -int RekonqWindow::insertTab(int index, QWidget *page, const QIcon &icon, const QString &label) +void RekonqWindow::showBookmarksPanel(bool on) { - if (! ReKonfig::openNewTabsNextToCurrent()) - index = -1; - setUpdatesEnabled(false); - int i = KTabWidget::insertTab(index, page, icon, label); - setUpdatesEnabled(true); + if (on) + { + if (_bookmarksPanel.isNull()) + { + _bookmarksPanel = new BookmarksPanel(i18n("Bookmarks Panel"), this); + connect(_bookmarksPanel.data(), SIGNAL(openUrl(KUrl, Rekonq::OpenType)), this, SLOT(loadUrl(KUrl, Rekonq::OpenType))); - return i; + QAction *a = _tabWidget->actionByName(QL1S("show_bookmarks_panel")); + connect(_bookmarksPanel.data(), SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool))); + } + _splitter->insertWidget(0, _bookmarksPanel.data()); + _bookmarksPanel.data()->show(); + } + else + { + _bookmarksPanel.data()->hide(); + delete _bookmarksPanel.data(); + _bookmarksPanel.clear(); + } } -// -------------------------------------------------------------------------------------- - - -void RekonqWindow::checkPosition() +void RekonqWindow::showHistoryPanel(bool on) { - // no need to check trivial positions... - if (isMaximized()) - return; - - QList wList = RekonqWindow::windowList(); - int wNumber = wList.count(); - - // no need to check first window... - if (wNumber <= 1) - return; - - int div = wNumber % 4; - - int scnum = QApplication::desktop()->screenNumber(window()); - QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); + if (on) + { + if (_historyPanel.isNull()) + { + _historyPanel = new HistoryPanel(i18n("History Panel"), this); + connect(_historyPanel.data(), SIGNAL(openUrl(KUrl, Rekonq::OpenType)), this, SLOT(loadUrl(KUrl, Rekonq::OpenType))); + + QAction *a = _tabWidget->actionByName(QL1S("show_history_panel")); + connect(_historyPanel.data(), SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool))); - switch (div) + } + _splitter->insertWidget(0, _historyPanel.data()); + _historyPanel.data()->show(); + } + else { - case 2: - // left down - move(desktopRect.width() - width(), desktopRect.height() - height()); - break; - case 3: - // right down - move(0, desktopRect.height() - height()); - break; - case 0: - // left top - move(desktopRect.width() - width(), 0); - break; - case 1: - // right top - move(0, 0); - break; - default: - kDebug() << "OOPS...THIS SHOULD NEVER HAPPEN!!"; - break; + _historyPanel.data()->hide(); + delete _historyPanel.data(); + _historyPanel.clear(); } } diff --git a/src/tabwindow/rekonqwindow.h b/src/tabwindow/rekonqwindow.h index ed018e4a..1d46faeb 100644 --- a/src/tabwindow/rekonqwindow.h +++ b/src/tabwindow/rekonqwindow.h @@ -2,7 +2,7 @@ * * This file is a part of the rekonq project * -* Copyright (C) 2012 by Andrea Diamantini +* Copyright (C) 2013 by Andrea Diamantini * * * This program is free software; you can redistribute it and/or @@ -32,109 +32,55 @@ // Rekonq Includes #include "rekonq_defines.h" -// KDE Includes -#include -#include -#include +// Local Includes +#include "rwindow.h" +#include "tabwidget.h" + +#include "bookmarkspanel.h" +#include "historypanel.h" // Qt Includes -#include - -/** - * This is rekonq (re)implementation of KMainWindow, - * given that we'd like to NOT use a "real" xMainWindow - * but a widget with the nice mainwindow properties - * (eg: session management, auto save dimension, etc) but - * NOT its peculiar containers (eg: toolbars, menubar, statusbar, - * central widget...) - * - */ -class RekonqWindow : public KTabWidget -{ - friend class KRWSessionManager; +#include +#include + +// Forward Declarations +class TabBar; + +class WebPage; +class WebWindow; + +class RekonqWindow : public RWindow +{ Q_OBJECT public: - explicit RekonqWindow(QWidget* parent = 0); + explicit RekonqWindow(bool withTab = true, bool PrivateBrowsingMode = false, QWidget *parent = 0); + explicit RekonqWindow(WebPage *pg, QWidget *parent = 0); virtual ~RekonqWindow(); - QSize sizeHint() const; - - /** - * List of members of RekonqWindow class. - */ - static QList windowList(); - - /** - * If the session did contain so high a @p number, @p true is returned, - * else @p false. - * @see restore() - **/ - static bool canBeRestored(int number); - - /** - * Try to restore the toplevel widget as defined by @p number (1..X). - * - * You should call canBeRestored() first. - * - **/ - bool restore(int number, bool show = true); - - // NOTE: For internal purpose only ------------------------------------------------------ - int addTab(QWidget *page, const QString &label); - int addTab(QWidget *page, const QIcon &icon, const QString &label); - - int insertTab(int index, QWidget *page, const QString &label); - int insertTab(int index, QWidget *page, const QIcon &icon, const QString &label); - // -------------------------------------------------------------------------------------- - -protected: - /** - * Save your instance-specific properties. The function is - * invoked when the session manager requests your application - * to save its state. - * - * Please reimplement these function in childclasses. - * - * Note: No user interaction is allowed - * in this function! - * - */ - virtual void saveProperties(KConfigGroup &) {} - - /** - * Read your instance-specific properties. - * - * Is called indirectly by restore(). - */ - virtual void readProperties(const KConfigGroup &) {} - - void savePropertiesInternal(KConfig*, int); - bool readPropertiesInternal(KConfig*, int); - - /** - * For inherited classes - */ - void saveWindowSize(const KConfigGroup &config) const; - /** - * For inherited classes - * Note that a -geometry on the command line has priority. - */ - void restoreWindowSize(const KConfigGroup & config); - - /// parse the geometry from the geometry command line argument - void parseGeometry(); - - virtual void resizeEvent(QResizeEvent *); + TabWidget *tabWidget(); + TabBar *tabBar(); + WebWindow *currentWebWindow() const; -private Q_SLOTS: - void saveAutoSaveSettings(); +private: + void init(); + +public Q_SLOTS: + void loadUrl(const KUrl &, Rekonq::OpenType type = Rekonq::CurrentTab, TabHistory *history = 0); +private Q_SLOTS: + void showBookmarksPanel(bool); + void showHistoryPanel(bool); + private: - /// This has been added to just fix window position && not let them be overlying - void checkPosition(); + TabWidget *_tabWidget; + + QSplitter *_splitter; + + QWeakPointer _historyPanel; + QWeakPointer _bookmarksPanel; }; #endif // REKONQ_WINDOW_H diff --git a/src/tabwindow/rwindow.cpp b/src/tabwindow/rwindow.cpp new file mode 100644 index 00000000..f7304da5 --- /dev/null +++ b/src/tabwindow/rwindow.cpp @@ -0,0 +1,397 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012-2013 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 "rwindow.h" +#include "rwindow.moc" + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include +#include + + +static bool s_no_query_exit = false; + + +class KRWSessionManager : public KSessionManager +{ + +public: + KRWSessionManager() + { + } + + ~KRWSessionManager() + { + } + + bool dummyInit() + { + return true; + } + + bool saveState(QSessionManager&) + { + KConfig* config = KApplication::kApplication()->sessionConfig(); + int n = 0; + Q_FOREACH(RWindow * rw, RWindow::windowList()) + { + n++; + rw->savePropertiesInternal(config, n); + } + + KConfigGroup group(config, "Number"); + group.writeEntry("NumberOfWindows", n); + return true; + } + + bool commitData(QSessionManager& sm) + { + // not really a fast method but the only compatible one + if (sm.allowsInteraction()) + { + bool canceled = false; + ::s_no_query_exit = true; + + Q_FOREACH(RWindow * window, RWindow::windowList()) + { + if (!window->testAttribute(Qt::WA_WState_Hidden)) + { + QCloseEvent e; + QApplication::sendEvent(window, &e); + canceled = !e.isAccepted(); + if (canceled) + break; + } + } + ::s_no_query_exit = false; + if (canceled) + return false; + + return true; + } + + // the user wants it, the user gets it + return true; + } +}; + + +K_GLOBAL_STATIC(KRWSessionManager, ktwsm) +K_GLOBAL_STATIC(QList, sWindowList) + + +// ---------------------------------------------------------------------------------------------------- + + +RWindow::RWindow(QWidget* parent) + : QWidget(parent) +{ + // This has to be a window... + setWindowFlags(Qt::Window); + + // Setting attributes (just to be sure...) + setAttribute(Qt::WA_DeleteOnClose, true); + setAttribute(Qt::WA_QuitOnClose, true); + + ktwsm->dummyInit(); + sWindowList->append(this); + + QString geometry; + KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); + if (args && args->isSet("geometry")) + geometry = args->getOption("geometry"); + + if (geometry.isNull()) // if there is no geometry, it doesn't matter + { + KSharedConfig::Ptr cf = KGlobal::config(); + KConfigGroup cg(cf, QL1S("RekonqWindow")); + restoreWindowSize(cg); + } + else + { + parseGeometry(); + } + + setWindowTitle(KGlobal::caption()); +} + + +RWindow::~RWindow() +{ + sWindowList->removeAll(this); + + KSharedConfig::Ptr cf = KGlobal::config(); + KConfigGroup cg(cf, QL1S("RekonqWindow")); + saveWindowSize(cg); +} + + +QSize RWindow::sizeHint() const +{ + QRect desktopRect = QApplication::desktop()->screenGeometry(); + QSize size = desktopRect.size() * 0.8; + return size; +} + +QList RWindow::windowList() +{ + return *sWindowList; +} + + +void RWindow::savePropertiesInternal(KConfig *config, int number) +{ + QString s; + s.setNum(number); + s.prepend(QL1S("WindowProperties")); + KConfigGroup cg(config, s); + + // store objectName, className, Width and Height for later restoring + // (Only useful for session management) + cg.writeEntry(QL1S("ObjectName"), objectName()); + cg.writeEntry(QL1S("ClassName"), metaObject()->className()); + + saveWindowSize(cg); + + s.setNum(number); + cg = KConfigGroup(config, s); + saveProperties(cg); +} + + +bool RWindow::readPropertiesInternal(KConfig *config, int number) +{ + // in order they are in toolbar list + QString s; + s.setNum(number); + s.prepend(QL1S("WindowProperties")); + + KConfigGroup cg(config, s); + + // restore the object name (window role) + if (cg.hasKey(QL1S("ObjectName"))) + setObjectName(cg.readEntry("ObjectName").toLatin1()); // latin1 is right here + + restoreWindowSize(cg); + + s.setNum(number); + KConfigGroup grp(config, s); + readProperties(grp); + + return true; +} + + +void RWindow::restoreWindowSize(const KConfigGroup & _cg) +{ + int scnum = QApplication::desktop()->screenNumber(window()); + QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); + + KConfigGroup cg(_cg); + + QString geometryKey = QString::fromLatin1("geometry-%1-%2").arg(desktopRect.width()).arg(desktopRect.height()); + QByteArray geometry = cg.readEntry(geometryKey, QByteArray()); + + // if first time run, center window: resize && move.. + if (!restoreGeometry(QByteArray::fromBase64(geometry))) + { + QSize defaultSize = desktopRect.size() * 0.8; + resize(defaultSize); + + move((desktopRect.width() - width()) / 2, (desktopRect.height() - height()) / 2); + } + + checkPosition(); +} + + +void RWindow::saveWindowSize(const KConfigGroup & _cg) const +{ + int scnum = QApplication::desktop()->screenNumber(window()); + QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); + + int w, h; + if (isMaximized()) + { + w = desktopRect.width() + 1; + h = desktopRect.height() + 1; + } + else + { + w = width(); + h = height(); + } + + KConfigGroup cg(_cg); + + QString widthString = QString::fromLatin1("Width %1").arg(desktopRect.width()); + cg.writeEntry(widthString, w); + + QString heightString = QString::fromLatin1("Height %1").arg(desktopRect.height()); + cg.writeEntry(heightString, h); + + // geometry is saved separately for each resolution + QString geometryKey = QString::fromLatin1("geometry-%1-%2").arg(desktopRect.width()).arg(desktopRect.height()); + QByteArray geometry = saveGeometry(); + cg.writeEntry(geometryKey, geometry.toBase64()); +} + + +void RWindow::parseGeometry() +{ + QString cmdlineGeometry; + KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); + if (args->isSet("geometry")) + cmdlineGeometry = args->getOption("geometry"); + + Q_ASSERT(!cmdlineGeometry.isNull()); + +// #if defined Q_WS_X11 +// int x, y; +// int w, h; +// int m = XParseGeometry( cmdlineGeometry.toLatin1(), &x, &y, (unsigned int*)&w, (unsigned int*)&h); +// if (parsewidth) { +// const QSize minSize = minimumSize(); +// const QSize maxSize = maximumSize(); +// if ( !(m & WidthValue) ) +// w = width(); +// if ( !(m & HeightValue) ) +// h = height(); +// w = qMin(w,maxSize.width()); +// h = qMin(h,maxSize.height()); +// w = qMax(w,minSize.width()); +// h = qMax(h,minSize.height()); +// resize(w, h); +// } else { +// if ( (m & XNegative) ) +// x = KApplication::desktop()->width() + x - w; +// else if ( (m & XValue) ) +// x = geometry().x(); +// if ( (m & YNegative) ) +// y = KApplication::desktop()->height() + y - h; +// else if ( (m & YValue) ) +// y = geometry().y(); +// +// move(x, y); +// } +// #endif +} + + +void RWindow::resizeEvent(QResizeEvent *event) +{ + if (!isFullScreen()) + saveAutoSaveSettings(); + QWidget::resizeEvent(event); +} + + +void RWindow::saveAutoSaveSettings() +{ + kDebug() << "AUTO SAVING SETTINGS..."; + + KSharedConfig::Ptr cf = KGlobal::config(); + KConfigGroup cg(cf, QL1S("RekonqWindow")); + saveWindowSize(cg); +} + + +bool RWindow::canBeRestored(int number) +{ + if (!qApp->isSessionRestored()) + return false; + KConfig *config = kapp->sessionConfig(); + if (!config) + return false; + + KConfigGroup group(config, "Number"); + const int n = group.readEntry("NumberOfWindows", 1); + return number >= 1 && number <= n; +} + + +bool RWindow::restore(int number, bool show) +{ + if (!canBeRestored(number)) + return false; + KConfig *config = kapp->sessionConfig(); + if (readPropertiesInternal(config, number)) + { + if (show) + RWindow::show(); + return true; + } + return false; +} + + +void RWindow::checkPosition() +{ + // no need to check trivial positions... + if (isMaximized()) + return; + + QList wList = RWindow::windowList(); + int wNumber = wList.count(); + + // no need to check first window... + if (wNumber <= 1) + return; + + int div = wNumber % 4; + + int scnum = QApplication::desktop()->screenNumber(window()); + QRect desktopRect = QApplication::desktop()->screenGeometry(scnum); + + switch (div) + { + case 2: + // left down + move(desktopRect.width() - width(), desktopRect.height() - height()); + break; + case 3: + // right down + move(0, desktopRect.height() - height()); + break; + case 0: + // left top + move(desktopRect.width() - width(), 0); + break; + case 1: + // right top + move(0, 0); + break; + default: + kDebug() << "OOPS...THIS SHOULD NEVER HAPPEN!!"; + break; + } +} diff --git a/src/tabwindow/rwindow.h b/src/tabwindow/rwindow.h new file mode 100644 index 00000000..871d3788 --- /dev/null +++ b/src/tabwindow/rwindow.h @@ -0,0 +1,131 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012-2013 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 R_WINDOW_H +#define R_WINDOW_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include +#include + +// Qt Includes +#include + +/** + * This is rekonq (re)implementation of KMainWindow, + * given that we'd like to NOT use a "real" xMainWindow + * but a widget with the nice mainwindow properties + * (eg: session management, auto save dimension, etc) but + * NOT its peculiar containers (eg: toolbars, menubar, statusbar, + * central widget...) + * + */ +class RWindow : public QWidget +{ + friend class KRWSessionManager; + + Q_OBJECT + +public: + explicit RWindow(QWidget* parent = 0); + + virtual ~RWindow(); + + QSize sizeHint() const; + + /** + * List of members of RekonqWindow class. + */ + static QList windowList(); + + /** + * If the session did contain so high a @p number, @p true is returned, + * else @p false. + * @see restore() + **/ + static bool canBeRestored(int number); + + /** + * Try to restore the toplevel widget as defined by @p number (1..X). + * + * You should call canBeRestored() first. + * + **/ + bool restore(int number, bool show = true); + +protected: + /** + * Save your instance-specific properties. The function is + * invoked when the session manager requests your application + * to save its state. + * + * Please reimplement these function in childclasses. + * + * Note: No user interaction is allowed + * in this function! + * + */ + virtual void saveProperties(KConfigGroup &) {} + + /** + * Read your instance-specific properties. + * + * Is called indirectly by restore(). + */ + virtual void readProperties(const KConfigGroup &) {} + + void savePropertiesInternal(KConfig*, int); + bool readPropertiesInternal(KConfig*, int); + + /** + * For inherited classes + */ + void saveWindowSize(const KConfigGroup &config) const; + /** + * For inherited classes + * Note that a -geometry on the command line has priority. + */ + void restoreWindowSize(const KConfigGroup & config); + + /// parse the geometry from the geometry command line argument + void parseGeometry(); + + virtual void resizeEvent(QResizeEvent *); + +private Q_SLOTS: + void saveAutoSaveSettings(); + +private: + /// This has been added to just fix window position && not let them be overlying + void checkPosition(); +}; + +#endif // R_WINDOW_H diff --git a/src/tabwindow/tabbar.cpp b/src/tabwindow/tabbar.cpp index bdd07573..7363d965 100644 --- a/src/tabwindow/tabbar.cpp +++ b/src/tabwindow/tabbar.cpp @@ -33,7 +33,8 @@ #include "rekonq.h" // Local Includes -#include "tabwindow.h" +#include "tabwidget.h" + #include "tabhighlighteffect.h" #include "tabpreviewpopup.h" #include "webwindow.h" @@ -186,7 +187,7 @@ void TabBar::detachTab() void TabBar::contextMenu(int tabIndex, const QPoint &pos) { - TabWindow *w = qobject_cast(parent()); + TabWidget *w = qobject_cast(parent()); QAction *a; @@ -262,7 +263,7 @@ void TabBar::contextMenu(int tabIndex, const QPoint &pos) void TabBar::emptyAreaContextMenu(const QPoint &pos) { - TabWindow *w = qobject_cast(parent()); + TabWidget *w = qobject_cast(parent()); QAction *a; @@ -355,7 +356,7 @@ void TabBar::tabInserted(int index) if (index < availableIndex) { - TabWindow *w = qobject_cast(parent()); + TabWidget *w = qobject_cast(parent()); w->moveTab(index, availableIndex); } @@ -446,7 +447,7 @@ void TabBar::mouseReleaseEvent(QMouseEvent *event) { if (!tabData(i).toBool()) { - TabWindow *w = qobject_cast(parent()); + TabWidget *w = qobject_cast(parent()); w->moveTab(i, pinnedTabs); w->setCurrentIndex(pinnedTabs); } @@ -457,7 +458,7 @@ void TabBar::mouseReleaseEvent(QMouseEvent *event) { if (tabData(i).toBool()) { - TabWindow *w = qobject_cast(parent()); + TabWidget *w = qobject_cast(parent()); w->moveTab(i, pinnedTabs - 1); w->setCurrentIndex(pinnedTabs - 1); } @@ -482,7 +483,7 @@ void TabBar::showTabPreview() delete m_previewPopup.data(); m_previewPopup.clear(); - TabWindow *tabW = qobject_cast(parent()); + TabWidget *tabW = qobject_cast(parent()); WebWindow *indexedTab = tabW->webWindow(m_currentTabPreviewIndex); WebWindow *currentTab = tabW->webWindow(currentIndex()); @@ -546,7 +547,7 @@ void TabBar::pinTab() } } - TabWindow *w = qobject_cast(parent()); + TabWidget *w = qobject_cast(parent()); w->moveTab(index, availableIndex); index = availableIndex; @@ -593,7 +594,7 @@ void TabBar::unpinTab() } } - TabWindow *w = qobject_cast(parent()); + TabWidget *w = qobject_cast(parent()); w->moveTab(index, availableIndex); index = availableIndex; diff --git a/src/tabwindow/tabwidget.cpp b/src/tabwindow/tabwidget.cpp new file mode 100644 index 00000000..bb62ca27 --- /dev/null +++ b/src/tabwindow/tabwidget.cpp @@ -0,0 +1,900 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 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 "tabwidget.h" +#include "tabwidget.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "application.h" +#include "rekonqwindow.h" + +#include "webpage.h" +#include "webwindow.h" +#include "tabbar.h" + +#include "tabhistory.h" + +#include "bookmarkmanager.h" +#include "iconmanager.h" +#include "sessionmanager.h" + +// KDE Includes +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +// Qt Includes +#include +#include +#include +#include +#include +#include +#include +#include + + +TabWidget::TabWidget(bool withTab, bool PrivateBrowsingMode, QWidget *parent) + : KTabWidget(parent) + , _addTabButton(new QToolButton(this)) + , _openedTabsCounter(0) + , _isPrivateBrowsing(PrivateBrowsingMode) + , _ac(new KActionCollection(this)) +{ + init(); + + // NOTE: we usually create TabWidget with AT LEAST one tab, but + // in one important case... + if (withTab) + { + WebWindow *tab = prepareNewTab(); + addTab(tab, i18n("new tab")); + setCurrentWidget(tab); + } +} + + +TabWidget::TabWidget(WebPage *pg, QWidget *parent) + : KTabWidget(parent) + , _addTabButton(new QToolButton(this)) + , _openedTabsCounter(0) + , _isPrivateBrowsing(false) + , _ac(new KActionCollection(this)) +{ + init(); + + WebWindow *tab = prepareNewTab(pg); + addTab(tab, i18n("new tab")); + setCurrentWidget(tab); +} + + +void TabWidget::init() +{ + setContentsMargins(0, 0, 0, 0); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + // set mouse tracking for tab previews + setMouseTracking(true); + + // setting tabbar + TabBar *tabBar = new TabBar(this); + setTabBar(tabBar); + + // sets document mode; this removes the frame around the tabs + setDocumentMode(true); + + // connecting tabbar signals + connect(tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); + connect(tabBar, SIGNAL(mouseMiddleClick(int)), this, SLOT(closeTab(int))); + + connect(tabBar, SIGNAL(newTabRequest()), this, SLOT(newTab())); + + connect(tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int))); + connect(tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); + connect(tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int))); + connect(tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); + connect(tabBar, SIGNAL(detachTab(int)), this, SLOT(detachTab(int))); + + connect(tabBar, SIGNAL(tabLayoutChanged()), this, SLOT(updateNewTabButtonPosition())); + + // ============================== Tab Window Actions ==================================== + _ac->addAssociatedWidget(this); + + KAction* a; + + a = new KAction(KIcon("tab-new"), i18n("New &Tab"), this); + a->setShortcut(KShortcut(Qt::CTRL + Qt::Key_T)); + actionCollection()->addAction(QL1S("new_tab"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(newTab())); + + a = new KAction(KIcon("tab-new"), i18n("Open Last Closed Tab"), this); + a->setShortcut(KShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_T)); + actionCollection()->addAction(QL1S("open_last_closed_tab"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(restoreLastClosedTab())); + + a = new KAction(KIcon("tab-close"), i18n("&Close Tab"), this); + a->setShortcuts(KStandardShortcut::close()); + actionCollection()->addAction(QL1S("close_tab"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(closeTab())); + + a = new KAction(i18n("Show Next Tab"), this); + a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabPrev() : KStandardShortcut::tabNext()); + actionCollection()->addAction(QL1S("show_next_tab"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(nextTab())); + + a = new KAction(i18n("Show Previous Tab"), this); + a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabNext() : KStandardShortcut::tabPrev()); + actionCollection()->addAction(QL1S("show_prev_tab"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(previousTab())); + + a = KStandardAction::fullScreen(this, SLOT(setFullScreen(bool)), this, actionCollection()); + KShortcut fullScreenShortcut = KStandardShortcut::fullScreen(); + fullScreenShortcut.setAlternate(Qt::Key_F11); + a->setShortcut(fullScreenShortcut); + + a = new KAction(KIcon("bookmarks"), i18n("Bookmark all tabs"), this); + actionCollection()->addAction(QL1S("bookmark_all_tabs"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(bookmarkAllTabs())); + + // ---------------------------------------------------------------------------------------------- + // Add Tab Button + _addTabButton->setDefaultAction(actionByName(QL1S("new_tab"))); + _addTabButton->setAutoRaise(true); + _addTabButton->raise(); + _addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + + connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); + + // ---------------------------------------------------------------------------------------------- + RekonqWindow *rw = qobject_cast(parent()); + // setup bookmarks panel action + a = new KAction(KIcon("bookmarks-organize"), i18n("Bookmarks Panel"), this); + a->setShortcut(KShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_B)); + actionCollection()->addAction(QL1S("show_bookmarks_panel"), a); + a->setCheckable(true); + connect(a, SIGNAL(triggered(bool)), rw, SLOT(showBookmarksPanel(bool))); + + // setup history panel action + a = new KAction(KIcon("view-history"), i18n("History Panel"), this); + a->setShortcut(KShortcut(Qt::CTRL + Qt::Key_H)); + actionCollection()->addAction(QL1S("show_history_panel"), a); + a->setCheckable(true); + connect(a, SIGNAL(triggered(bool)), rw, SLOT(showHistoryPanel(bool))); + + // ---------------------------------------------------------------------------------------------- + // shortcuts for quickly switching to a tab + QSignalMapper *tabSignalMapper = new QSignalMapper(this); + for (int i = 0; i < 9; i++) + { + a = new KAction(i18n("Switch to Tab %1", i+1), this); + a->setShortcut(KShortcut(QString("Alt+%1").arg(i+1))); + actionCollection()->addAction(QL1S(QString("switch_tab_" + QString::number(i+1)).toAscii()), a); + connect(a, SIGNAL(triggered(bool)), tabSignalMapper, SLOT(map())); + tabSignalMapper->setMapping(a, i); + } + connect(tabSignalMapper, SIGNAL(mapped(int)), this, SLOT(setCurrentIndex(int))); + + // shortcuts for loading favorite pages + QSignalMapper *favoritesSignalMapper = new QSignalMapper(this); + for (int i = 1; i <= 9; ++i) + { + a = new KAction(i18n("Switch to Favorite Page %1", i), this); + a->setShortcut(KShortcut(QString("Ctrl+%1").arg(i))); + actionCollection()->addAction(QL1S(QString("switch_favorite_" + QString::number(i)).toAscii()), a); + connect(a, SIGNAL(triggered(bool)), favoritesSignalMapper, SLOT(map())); + favoritesSignalMapper->setMapping(a, i); + } + connect(favoritesSignalMapper, SIGNAL(mapped(int)), this, SLOT(loadFavorite(int))); + + _ac->readSettings(); + + // ---------------------------------------------------------------------------------------------- + int n = rApp->rekonqWindowList().count() + 1; + QList list = SessionManager::self()->closedSitesForWindow( QL1S("win") + QString::number(n) ); + Q_FOREACH(const TabHistory & tab, list) + { + if (tab.url.startsWith(QL1S("about"))) + continue; + m_recentlyClosedTabs.removeAll(tab); + m_recentlyClosedTabs.prepend(tab); + } +} + + +// ---------------------------------------------------------------------------------------------------- + + +KActionCollection *TabWidget::actionCollection() const +{ + return _ac; +} + + +QAction *TabWidget::actionByName(const QString &name) +{ + return actionCollection()->action(name); +} + + +TabBar *TabWidget::tabBar() const +{ + TabBar *tabBar = qobject_cast(QTabWidget::tabBar()); + return tabBar; +} + + +WebWindow *TabWidget::currentWebWindow() const +{ + return webWindow(currentIndex()); +} + + +WebWindow *TabWidget::webWindow(int index) const +{ + WebWindow *tab = qobject_cast(this->widget(index)); + if (tab) + { + return tab; + } + + kDebug() << "WebWindow with index " << index << "not found. Returning NULL." ; + return 0; +} + + +QList TabWidget::recentlyClosedTabs() +{ + return m_recentlyClosedTabs; +} + + +void TabWidget::newTab(WebPage *page) +{ + WebWindow *tab = prepareNewTab(page); + addTab(tab, i18n("new tab")); + setCurrentWidget(tab); + + // no need to load an url if we already have a page... + if (page) + return; + + switch (ReKonfig::newTabsBehaviour()) + { + case 0: // new tab page + tab->load(KUrl("about:home")); + break; + case 2: // homepage + tab->load(KUrl(ReKonfig::homePage())); + break; + case 1: // blank page + default: + tab->load(KUrl("about:blank")); + break; + } +} + + +WebWindow *TabWidget::prepareNewTab(WebPage *page) +{ + WebWindow *tab = new WebWindow(this, _isPrivateBrowsing, page); + + connect(tab, SIGNAL(titleChanged(QString)), this, SLOT(tabTitleChanged(QString))); + connect(tab, SIGNAL(urlChanged(QUrl)), this, SLOT(tabUrlChanged(QUrl))); + connect(tab, SIGNAL(iconChanged()), this, SLOT(tabIconChanged())); + + connect(tab, SIGNAL(loadStarted()), this, SLOT(tabLoadStarted())); + connect(tab, SIGNAL(loadFinished(bool)), this, SLOT(tabLoadFinished(bool))); + + connect(tab, SIGNAL(pageCreated(WebPage*)), this, SLOT(pageCreated(WebPage*))); + + connect(tab, SIGNAL(setFullScreen(bool)), this, SLOT(setFullScreen(bool))); + + return tab; +} + + +void TabWidget::loadUrl(const KUrl &url, Rekonq::OpenType type, TabHistory *history) +{ + WebWindow *tab = 0; + switch (type) + { + case Rekonq::NewTab: + tab = prepareNewTab(); + _openedTabsCounter++; + insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); + if (ReKonfig::openNewTabsInForeground()) + { + setCurrentWidget(tab); + } + break; + case Rekonq::NewBackGroundTab: + tab = prepareNewTab(); + _openedTabsCounter++; + insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); + break; + + case Rekonq::NewFocusedTab: + tab = prepareNewTab(); + _openedTabsCounter++; + insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); + setCurrentWidget(tab); + break; + + case Rekonq::NewWindow: + case Rekonq::NewPrivateWindow: + rApp->loadUrl(url, type); + return; + + case Rekonq::CurrentTab: + default: + tab = currentWebWindow(); + break; + }; + + tab->load(url); + + if (history) + { + history->applyHistory(tab->page()->history()); + } +} + + +void TabWidget::pageCreated(WebPage *page) +{ + WebWindow *tab = prepareNewTab(page); + + // Now, the dirty jobs... + _openedTabsCounter++; + insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); + + setCurrentWidget(tab); +} + + +void TabWidget::currentChanged(int newIndex) +{ + _openedTabsCounter = 0; + + tabBar()->setTabHighlighted(newIndex, false); + + // update window title & icon + WebWindow* tab = webWindow(newIndex); + if (!tab) + return; + + QString t = tab->title(); + + (t.isEmpty() || t == QL1S("rekonq")) + ? setWindowTitle(QL1S("rekonq")) + : setWindowTitle(t + QL1S(" - rekonq")); + + tab->checkFocus(); +} + + +void TabWidget::updateNewTabButtonPosition() +{ + if (isFullScreen()) + return; + + setUpdatesEnabled(false); + + int tabWidgetWidth = frameSize().width(); + int tabBarWidth = tabBar()->sizeHint().width(); + + if (tabBarWidth + _addTabButton->width() > tabWidgetWidth) + { + setCornerWidget(_addTabButton); + } + else + { + setCornerWidget(0); + _addTabButton->move(tabBarWidth, 0); + } + + _addTabButton->show(); + setUpdatesEnabled(true); +} + + +void TabWidget::tabTitleChanged(const QString &title) +{ + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + QString tabTitle = title.isEmpty() ? tab->title() : title; + tabTitle.replace('&', "&&"); + + int index = indexOf(tab); + + if (-1 != index && !tabBar()->tabData(index).toBool()) + { + setTabText(index, tabTitle); + } + + if (currentIndex() != index) + { + tabBar()->setTabHighlighted(index, true); + } + else + { + setWindowTitle(tabTitle + QL1S(" - rekonq")); + } + + if (ReKonfig::hoveringTabOption() == 1) + tabBar()->setTabToolTip(index, tabTitle.remove('&')); +} + + +void TabWidget::tabUrlChanged(const QUrl &url) +{ + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + int index = indexOf(tab); + if (ReKonfig::hoveringTabOption() == 2) + tabBar()->setTabToolTip(index, url.toString()); +} + + +void TabWidget::tabIconChanged() +{ + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + if (tab->isLoading()) + return; + + int index = indexOf(tab); + + if (-1 == index) + return; + + QLabel *label = qobject_cast(tabBar()->tabButton(index, QTabBar::LeftSide)); + if (!label) + { + label = new QLabel(this); + tabBar()->setTabButton(index, QTabBar::LeftSide, 0); + tabBar()->setTabButton(index, QTabBar::LeftSide, label); + } + + KIcon ic = IconManager::self()->iconForUrl(tab->url()); + label->setPixmap(ic.pixmap(16, 16)); +} + + +void TabWidget::tabLoadStarted() +{ + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + int index = indexOf(tab); + if (index != -1) + { + QLabel *label = qobject_cast(tabBar()->tabButton(index, QTabBar::LeftSide)); + if (!label) + { + label = new QLabel(this); + } + + if (!label->movie()) + { + static QString loadingGitPath = KStandardDirs::locate("appdata" , "pics/loading.mng"); + + QMovie *movie = new QMovie(loadingGitPath, QByteArray(), label); + movie->setSpeed(50); + label->setMovie(movie); + movie->start(); + } + + tabBar()->setTabButton(index, QTabBar::LeftSide, 0); + tabBar()->setTabButton(index, QTabBar::LeftSide, label); + + if (!tabBar()->tabData(index).toBool()) + tabBar()->setTabText(index, i18n("Loading...")); + else + { + tabBar()->tabButton(index, QTabBar::RightSide)->hide(); // NOTE: not really good this, but..."Repetita iuvant"!!! + } + } +} + + +void TabWidget::tabLoadFinished(bool ok) +{ + Q_UNUSED(ok); + + WebWindow *tab = qobject_cast(sender()); + if (!tab) + return; + + int index = indexOf(tab); + + if (-1 == index) + return; + + QLabel *label = qobject_cast(tabBar()->tabButton(index, QTabBar::LeftSide)); + if (!label) + { + label = new QLabel(this); + tabBar()->setTabButton(index, QTabBar::LeftSide, 0); + tabBar()->setTabButton(index, QTabBar::LeftSide, label); + } + + QMovie *movie = label->movie(); + if (movie) + { + movie->stop(); + delete movie; + } + + label->setMovie(0); + + KIcon ic = IconManager::self()->iconForUrl(tab->url()); + label->setPixmap(ic.pixmap(16, 16)); + + if (!tabBar()->tabData(index).toBool()) + { + setTabText(index, tab->title()); + } + else + { + setTabText(index, QString()); + } + + if (index == currentIndex()) + tab->checkFocus(); +} + + +void TabWidget::cloneTab(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + QUrl u = webWindow(index)->url(); + QWebHistory* history = webWindow(index)->page()->history(); + TabHistory clonedHistory(history); + + loadUrl(u, Rekonq::NewTab, &clonedHistory); +} + + +void TabWidget::closeTab(int index, bool del) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + WebWindow *tabToClose = webWindow(index); + if (!tabToClose) + return; + + // what to do if there is just one tab... + if (count() == 1) + { + kDebug() << "CANNOT CLOSE WINDOW FROM HERE..."; + currentWebWindow()->load(KUrl("about:home")); + return; + } + + if (!tabToClose->url().isEmpty() + && tabToClose->url().scheme() != QL1S("about") + && !tabToClose->page()->settings()->testAttribute(QWebSettings::PrivateBrowsingEnabled) + ) + { + const int recentlyClosedTabsLimit = 8; + TabHistory history(tabToClose->page()->history()); + history.title = tabToClose->title(); + history.url = tabToClose->url().url(); + history.position = index; + + m_recentlyClosedTabs.removeAll(history); + if (m_recentlyClosedTabs.count() == recentlyClosedTabsLimit) + m_recentlyClosedTabs.removeLast(); + m_recentlyClosedTabs.prepend(history); + } + + removeTab(index); + + if (del) + { + tabToClose->deleteLater(); + } +} + + +void TabWidget::closeOtherTabs(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + for (int i = count() - 1; i > index; --i) + { + closeTab(i); + } + + for (int i = index - 1; i >= 0; --i) + { + closeTab(i); + } +} + + +void TabWidget::detachTab(int index, RekonqWindow *toWindow) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + WebWindow *tab = webWindow(index); + KUrl u = tab->url(); + if (u.scheme() == QL1S("about")) + { + closeTab(index); + loadUrl(u, Rekonq::NewWindow); + return; + } + // else + + closeTab(index, false); + + RekonqWindow *w = 0; + w = (toWindow == 0) + ? new RekonqWindow(false) + : toWindow; + + TabWidget *hostTabWidget = w->tabWidget(); + + hostTabWidget->addTab(tab, tab->title()); + hostTabWidget->setCurrentWidget(tab); + + // disconnect signals from old tabwindow + // WARNING: Code copied from prepareNewTab method. + // Any new changes there should be applied here... + disconnect(tab, SIGNAL(titleChanged(QString)), this, SLOT(tabTitleChanged(QString))); + disconnect(tab, SIGNAL(iconChanged()), this, SLOT(tabIconChanged())); + disconnect(tab, SIGNAL(loadStarted()), this, SLOT(tabLoadStarted())); + disconnect(tab, SIGNAL(loadFinished(bool)), this, SLOT(tabLoadFinished(bool))); + disconnect(tab, SIGNAL(pageCreated(WebPage*)), this, SLOT(pageCreated(WebPage*))); + + // reconnect signals to new tabwindow + // WARNING: Code copied from prepareNewTab method. + // Any new changes there should be applied here... + connect(tab, SIGNAL(titleChanged(QString)), hostTabWidget, SLOT(tabTitleChanged(QString))); + connect(tab, SIGNAL(iconChanged()), hostTabWidget, SLOT(tabIconChanged())); + connect(tab, SIGNAL(loadStarted()), hostTabWidget, SLOT(tabLoadStarted())); + connect(tab, SIGNAL(loadFinished(bool)), hostTabWidget, SLOT(tabLoadFinished(bool))); + connect(tab, SIGNAL(pageCreated(WebPage*)), hostTabWidget, SLOT(pageCreated(WebPage*))); + + w->show(); +} + + +void TabWidget::reloadTab(int index) +{ + // When index is -1 index chooses the current tab + if (index < 0) + index = currentIndex(); + + if (index < 0 || index >= count()) + return; + + WebWindow *reloadingTab = webWindow(index); + QAction *action = reloadingTab->page()->action(QWebPage::Reload); + action->trigger(); +} + + +void TabWidget::reloadAllTabs() +{ + for (int i = 0; i < count(); ++i) + { + reloadTab(i); + } +} + + +void TabWidget::bookmarkAllTabs() +{ + KBookmarkGroup rGroup = BookmarkManager::self()->rootGroup(); + KBookmarkGroup folderGroup = rGroup.createNewFolder(i18n("Bookmarked tabs: ") + QDate::currentDate().toString()); + for (int i = 0; i < count(); ++i) + { + WebWindow *tab = webWindow(i); + KBookmark bk = folderGroup.addBookmark(tab->title(), tab->url()); + } +} + + +void TabWidget::restoreLastClosedTab() +{ + restoreClosedTab(0); +} + + +void TabWidget::restoreClosedTab(int index, bool inNewTab) +{ + if (m_recentlyClosedTabs.isEmpty()) + return; + + if (index >= m_recentlyClosedTabs.count()) + return; + + TabHistory history = m_recentlyClosedTabs.takeAt(index); + + QUrl u = QUrl(history.url); + + int restorePosition = history.position; + + WebWindow *tab; + + if (inNewTab) + { + tab = prepareNewTab(); + if (restorePosition < count()) + insertTab(restorePosition, tab, i18n("restored tab")); + else + addTab(tab, i18n("restored tab")); + + setCurrentWidget(tab); + } + else + { + tab = currentWebWindow(); + } + + tab->load(u); + + // just to get sure... + m_recentlyClosedTabs.removeAll(history); +} + + +void TabWidget::nextTab() +{ + int next = currentIndex() + 1; + if (next == count()) + next = 0; + setCurrentIndex(next); +} + + +void TabWidget::previousTab() +{ + int next = currentIndex() - 1; + if (next < 0) + next = count() - 1; + setCurrentIndex(next); +} + + +void TabWidget::setFullScreen(bool makeFullScreen) +{ + tabBar()->setVisible(!makeFullScreen); + _addTabButton->setVisible(!makeFullScreen); + + KToggleFullScreenAction::setFullScreen(this, makeFullScreen); + + for (int i = 0; i < count(); i++) + webWindow(i)->setWidgetsHidden(makeFullScreen); +} + + +bool TabWidget::isPrivateBrowsingWindowMode() +{ + return _isPrivateBrowsing; +} + + +void TabWidget::loadFavorite(const int index) +{ + QStringList urls = ReKonfig::previewUrls(); + if (index < 0 || index > urls.length()) + return; + + KUrl url = KUrl(urls.at(index - 1)); + loadUrl(url); + currentWebWindow()->setFocus(); +} + + +// NOTE: For internal purpose only ------------------------------------------------------ + + +int TabWidget::addTab(QWidget *page, const QString &label) +{ + setUpdatesEnabled(false); + int i = KTabWidget::addTab(page, label); + setUpdatesEnabled(true); + + return i; +} + + +int TabWidget::addTab(QWidget *page, const QIcon &icon, const QString &label) +{ + setUpdatesEnabled(false); + int i = KTabWidget::addTab(page, icon, label); + setUpdatesEnabled(true); + + return i; +} + + +int TabWidget::insertTab(int index, QWidget *page, const QString &label) +{ + if (! ReKonfig::openNewTabsNextToCurrent()) + index = -1; + setUpdatesEnabled(false); + int i = KTabWidget::insertTab(index, page, label); + setUpdatesEnabled(true); + + return i; +} + + +int TabWidget::insertTab(int index, QWidget *page, const QIcon &icon, const QString &label) +{ + if (! ReKonfig::openNewTabsNextToCurrent()) + index = -1; + setUpdatesEnabled(false); + int i = KTabWidget::insertTab(index, page, icon, label); + setUpdatesEnabled(true); + + return i; +} + + +// -------------------------------------------------------------------------------------- diff --git a/src/tabwindow/tabwidget.h b/src/tabwindow/tabwidget.h new file mode 100644 index 00000000..9c79df11 --- /dev/null +++ b/src/tabwindow/tabwidget.h @@ -0,0 +1,146 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2012 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 TAB_WIDGET +#define TAB_WIDGET + + +// Rekonq Includes +#include "rekonq_defines.h" + +// KDE Includes +#include +#include + +// Forward Declarations +class KUrl; + +class QLabel; +class QToolButton; +class QWebHistory; + +class TabHistory; + +class TabBar; +class WebPage; +class WebWindow; + +class RekonqWindow; + +// -------------------------------------------------------------------------------------- + + +class TabWidget : public KTabWidget +{ + Q_OBJECT + +public: + explicit TabWidget(bool withTab = true, bool PrivateBrowsingMode = false, QWidget *parent = 0); + explicit TabWidget(WebPage *pg, QWidget *parent = 0); + + WebWindow* currentWebWindow() const; + WebWindow* webWindow(int index) const; + + TabBar* tabBar() const; + + bool isPrivateBrowsingWindowMode(); + + virtual KActionCollection *actionCollection() const; + QAction *actionByName(const QString &name); + + QList recentlyClosedTabs(); + void restoreClosedTab(int index, bool inNewTab = true); + + // NOTE: For internal purpose only ------------------------------------------------------ + int addTab(QWidget *page, const QString &label); + int addTab(QWidget *page, const QIcon &icon, const QString &label); + + int insertTab(int index, QWidget *page, const QString &label); + int insertTab(int index, QWidget *page, const QIcon &icon, const QString &label); + // -------------------------------------------------------------------------------------- + +public Q_SLOTS: + void loadUrl(const KUrl &, Rekonq::OpenType type = Rekonq::CurrentTab, TabHistory *history = 0); + void newTab(WebPage *page = 0); + +private: + /** + * Prepares the new WebWindow to be open + */ + WebWindow *prepareNewTab(WebPage *page = 0); + + void init(); + +private Q_SLOTS: + /** + * Updates new tab button position + */ + void updateNewTabButtonPosition(); + + void tabTitleChanged(const QString &); + void tabUrlChanged(const QUrl &); + void tabIconChanged(); + + void tabLoadStarted(); + void tabLoadFinished(bool); + + void pageCreated(WebPage *); + + void currentChanged(int); + + // Indexed slots + void cloneTab(int index = -1); + void closeTab(int index = -1, bool del = true); + void closeOtherTabs(int index = -1); + void detachTab(int index = -1, RekonqWindow *toWindow = 0); + void reloadTab(int index = -1); + + void reloadAllTabs(); + void bookmarkAllTabs(); + + void nextTab(); + void previousTab(); + + void restoreLastClosedTab(); + + void setFullScreen(bool); + + void loadFavorite(const int); + +private: + // the new tab button + QToolButton *_addTabButton; + + int _openedTabsCounter; + + QList m_recentlyClosedTabs; + + bool _isPrivateBrowsing; + + KActionCollection *_ac; +}; + +#endif // TAB_WIDGET diff --git a/src/tabwindow/tabwindow.cpp b/src/tabwindow/tabwindow.cpp deleted file mode 100644 index 2ade757b..00000000 --- a/src/tabwindow/tabwindow.cpp +++ /dev/null @@ -1,831 +0,0 @@ -/* ============================================================ -* -* This file is a part of the rekonq project -* -* Copyright (C) 2012 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 "tabwindow.h" -#include "tabwindow.moc" - -// Auto Includes -#include "rekonq.h" - -// Local Includes -#include "application.h" -#include "webpage.h" -#include "webwindow.h" -#include "tabbar.h" - -#include "tabhistory.h" - -#include "bookmarkmanager.h" -#include "iconmanager.h" -#include "sessionmanager.h" - -// KDE Includes -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -// Qt Includes -#include -#include -#include -#include -#include -#include -#include -#include - - -TabWindow::TabWindow(bool withTab, bool PrivateBrowsingMode, QWidget *parent) - : RekonqWindow(parent) - , _addTabButton(new QToolButton(this)) - , _openedTabsCounter(0) - , _isPrivateBrowsing(PrivateBrowsingMode) - , _ac(new KActionCollection(this)) -{ - init(); - - // NOTE: we usually create TabWindow with AT LEAST one tab, but - // in one important case... - if (withTab) - { - WebWindow *tab = prepareNewTab(); - addTab(tab, i18n("new tab")); - setCurrentWidget(tab); - } -} - - -TabWindow::TabWindow(WebPage *pg, QWidget *parent) - : RekonqWindow(parent) - , _addTabButton(new QToolButton(this)) - , _openedTabsCounter(0) - , _isPrivateBrowsing(false) - , _ac(new KActionCollection(this)) -{ - init(); - - WebWindow *tab = prepareNewTab(pg); - addTab(tab, i18n("new tab")); - setCurrentWidget(tab); -} - - -void TabWindow::init() -{ - setContentsMargins(0, 0, 0, 0); - - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - // set mouse tracking for tab previews - setMouseTracking(true); - - // setting tabbar - TabBar *tabBar = new TabBar(this); - setTabBar(tabBar); - - // sets document mode; this removes the frame around the tabs - setDocumentMode(true); - - // connecting tabbar signals - connect(tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); - connect(tabBar, SIGNAL(mouseMiddleClick(int)), this, SLOT(closeTab(int))); - - connect(tabBar, SIGNAL(newTabRequest()), this, SLOT(newTab())); - - connect(tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int))); - connect(tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); - connect(tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int))); - connect(tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); - connect(tabBar, SIGNAL(detachTab(int)), this, SLOT(detachTab(int))); - - connect(tabBar, SIGNAL(tabLayoutChanged()), this, SLOT(updateNewTabButtonPosition())); - - // ============================== Tab Window Actions ==================================== - _ac->addAssociatedWidget(this); - - KAction* a; - - a = new KAction(KIcon("tab-new"), i18n("New &Tab"), this); - a->setShortcut(KShortcut(Qt::CTRL + Qt::Key_T)); - actionCollection()->addAction(QL1S("new_tab"), a); - connect(a, SIGNAL(triggered(bool)), this, SLOT(newTab())); - - a = new KAction(KIcon("tab-new"), i18n("Open Last Closed Tab"), this); - a->setShortcut(KShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_T)); - actionCollection()->addAction(QL1S("open_last_closed_tab"), a); - connect(a, SIGNAL(triggered(bool)), this, SLOT(restoreLastClosedTab())); - - a = new KAction(KIcon("tab-close"), i18n("&Close Tab"), this); - a->setShortcuts(KStandardShortcut::close()); - actionCollection()->addAction(QL1S("close_tab"), a); - connect(a, SIGNAL(triggered(bool)), this, SLOT(closeTab())); - - a = new KAction(i18n("Show Next Tab"), this); - a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabPrev() : KStandardShortcut::tabNext()); - actionCollection()->addAction(QL1S("show_next_tab"), a); - connect(a, SIGNAL(triggered(bool)), this, SLOT(nextTab())); - - a = new KAction(i18n("Show Previous Tab"), this); - a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabNext() : KStandardShortcut::tabPrev()); - actionCollection()->addAction(QL1S("show_prev_tab"), a); - connect(a, SIGNAL(triggered(bool)), this, SLOT(previousTab())); - - a = KStandardAction::fullScreen(this, SLOT(setFullScreen(bool)), this, actionCollection()); - KShortcut fullScreenShortcut = KStandardShortcut::fullScreen(); - fullScreenShortcut.setAlternate(Qt::Key_F11); - a->setShortcut(fullScreenShortcut); - - a = new KAction(KIcon("bookmarks"), i18n("Bookmark all tabs"), this); - actionCollection()->addAction(QL1S("bookmark_all_tabs"), a); - connect(a, SIGNAL(triggered(bool)), this, SLOT(bookmarkAllTabs())); - - // ---------------------------------------------------------------------------------------------- - // Add Tab Button - _addTabButton->setDefaultAction(actionByName(QL1S("new_tab"))); - _addTabButton->setAutoRaise(true); - _addTabButton->raise(); - _addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); - - connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); - - // ---------------------------------------------------------------------------------------------- - // shortcuts for quickly switching to a tab - QSignalMapper *tabSignalMapper = new QSignalMapper(this); - for (int i = 0; i < 9; i++) - { - a = new KAction(i18n("Switch to Tab %1", i+1), this); - a->setShortcut(KShortcut(QString("Alt+%1").arg(i+1))); - actionCollection()->addAction(QL1S(QString("switch_tab_" + QString::number(i+1)).toAscii()), a); - connect(a, SIGNAL(triggered(bool)), tabSignalMapper, SLOT(map())); - tabSignalMapper->setMapping(a, i); - } - connect(tabSignalMapper, SIGNAL(mapped(int)), this, SLOT(setCurrentIndex(int))); - - // shortcuts for loading favorite pages - QSignalMapper *favoritesSignalMapper = new QSignalMapper(this); - for (int i = 1; i <= 9; ++i) - { - a = new KAction(i18n("Switch to Favorite Page %1", i), this); - a->setShortcut(KShortcut(QString("Ctrl+%1").arg(i))); - actionCollection()->addAction(QL1S(QString("switch_favorite_" + QString::number(i)).toAscii()), a); - connect(a, SIGNAL(triggered(bool)), favoritesSignalMapper, SLOT(map())); - favoritesSignalMapper->setMapping(a, i); - } - connect(favoritesSignalMapper, SIGNAL(mapped(int)), this, SLOT(loadFavorite(int))); - - _ac->readSettings(); - - // ---------------------------------------------------------------------------------------------- - int n = rApp->tabWindowList().count() + 1; - QList list = SessionManager::self()->closedSitesForWindow( QL1S("win") + QString::number(n) ); - Q_FOREACH(const TabHistory & tab, list) - { - if (tab.url.startsWith(QL1S("about"))) - continue; - m_recentlyClosedTabs.removeAll(tab); - m_recentlyClosedTabs.prepend(tab); - } -} - - -// ---------------------------------------------------------------------------------------------------- - - -KActionCollection *TabWindow::actionCollection() const -{ - return _ac; -} - - -QAction *TabWindow::actionByName(const QString &name) -{ - return actionCollection()->action(name); -} - - -TabBar *TabWindow::tabBar() const -{ - TabBar *tabBar = qobject_cast(QTabWidget::tabBar()); - return tabBar; -} - - -WebWindow *TabWindow::currentWebWindow() const -{ - return webWindow(currentIndex()); -} - - -WebWindow *TabWindow::webWindow(int index) const -{ - WebWindow *tab = qobject_cast(this->widget(index)); - if (tab) - { - return tab; - } - - kDebug() << "WebWindow with index " << index << "not found. Returning NULL." ; - return 0; -} - - -QList TabWindow::recentlyClosedTabs() -{ - return m_recentlyClosedTabs; -} - - -WebWindow *TabWindow::prepareNewTab(WebPage *page) -{ - WebWindow *tab = new WebWindow(this, _isPrivateBrowsing, page); - - connect(tab, SIGNAL(titleChanged(QString)), this, SLOT(tabTitleChanged(QString))); - connect(tab, SIGNAL(urlChanged(QUrl)), this, SLOT(tabUrlChanged(QUrl))); - connect(tab, SIGNAL(iconChanged()), this, SLOT(tabIconChanged())); - - connect(tab, SIGNAL(loadStarted()), this, SLOT(tabLoadStarted())); - connect(tab, SIGNAL(loadFinished(bool)), this, SLOT(tabLoadFinished(bool))); - - connect(tab, SIGNAL(pageCreated(WebPage*)), this, SLOT(pageCreated(WebPage*))); - - connect(tab, SIGNAL(setFullScreen(bool)), this, SLOT(setFullScreen(bool))); - - return tab; -} - - -void TabWindow::loadUrl(const KUrl &url, Rekonq::OpenType type, TabHistory *history) -{ - WebWindow *tab = 0; - switch (type) - { - case Rekonq::NewTab: - tab = prepareNewTab(); - _openedTabsCounter++; - insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); - if (ReKonfig::openNewTabsInForeground()) - { - setCurrentWidget(tab); - } - break; - case Rekonq::NewBackGroundTab: - tab = prepareNewTab(); - _openedTabsCounter++; - insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); - break; - - case Rekonq::NewFocusedTab: - tab = prepareNewTab(); - _openedTabsCounter++; - insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); - setCurrentWidget(tab); - break; - - case Rekonq::NewWindow: - case Rekonq::NewPrivateWindow: - rApp->loadUrl(url, type); - return; - - case Rekonq::CurrentTab: - default: - tab = currentWebWindow(); - break; - }; - - tab->load(url); - - if (history) - { - history->applyHistory(tab->page()->history()); - } -} - - -void TabWindow::newTab(WebPage *page) -{ - WebWindow *tab = prepareNewTab(page); - addTab(tab, i18n("new tab")); - setCurrentWidget(tab); - - // no need to load an url if we already have a page... - if (page) - return; - - switch (ReKonfig::newTabsBehaviour()) - { - case 0: // new tab page - tab->load(KUrl("about:home")); - break; - case 2: // homepage - tab->load(KUrl(ReKonfig::homePage())); - break; - case 1: // blank page - default: - tab->load(KUrl("about:blank")); - break; - } - -} - - -void TabWindow::pageCreated(WebPage *page) -{ - WebWindow *tab = prepareNewTab(page); - - // Now, the dirty jobs... - _openedTabsCounter++; - insertTab(currentIndex() + _openedTabsCounter, tab, i18n("new tab")); - - setCurrentWidget(tab); -} - - -void TabWindow::currentChanged(int newIndex) -{ - _openedTabsCounter = 0; - - tabBar()->setTabHighlighted(newIndex, false); - - // update window title & icon - WebWindow* tab = webWindow(newIndex); - if (!tab) - return; - - QString t = tab->title(); - - (t.isEmpty() || t == QL1S("rekonq")) - ? setWindowTitle(QL1S("rekonq")) - : setWindowTitle(t + QL1S(" - rekonq")); - - tab->checkFocus(); -} - - -void TabWindow::updateNewTabButtonPosition() -{ - if (isFullScreen()) - return; - - setUpdatesEnabled(false); - - int tabWidgetWidth = frameSize().width(); - int tabBarWidth = tabBar()->sizeHint().width(); - - if (tabBarWidth + _addTabButton->width() > tabWidgetWidth) - { - setCornerWidget(_addTabButton); - } - else - { - setCornerWidget(0); - _addTabButton->move(tabBarWidth, 0); - } - - _addTabButton->show(); - setUpdatesEnabled(true); -} - - -void TabWindow::tabTitleChanged(const QString &title) -{ - WebWindow *tab = qobject_cast(sender()); - if (!tab) - return; - - QString tabTitle = title.isEmpty() ? tab->title() : title; - tabTitle.replace('&', "&&"); - - int index = indexOf(tab); - - if (-1 != index && !tabBar()->tabData(index).toBool()) - { - setTabText(index, tabTitle); - } - - if (currentIndex() != index) - { - tabBar()->setTabHighlighted(index, true); - } - else - { - setWindowTitle(tabTitle + QL1S(" - rekonq")); - } - - if (ReKonfig::hoveringTabOption() == 1) - tabBar()->setTabToolTip(index, tabTitle.remove('&')); -} - - -void TabWindow::tabUrlChanged(const QUrl &url) -{ - WebWindow *tab = qobject_cast(sender()); - if (!tab) - return; - - int index = indexOf(tab); - if (ReKonfig::hoveringTabOption() == 2) - tabBar()->setTabToolTip(index, url.toString()); -} - - -void TabWindow::tabIconChanged() -{ - WebWindow *tab = qobject_cast(sender()); - if (!tab) - return; - - if (tab->isLoading()) - return; - - int index = indexOf(tab); - - if (-1 == index) - return; - - QLabel *label = qobject_cast(tabBar()->tabButton(index, QTabBar::LeftSide)); - if (!label) - { - label = new QLabel(this); - tabBar()->setTabButton(index, QTabBar::LeftSide, 0); - tabBar()->setTabButton(index, QTabBar::LeftSide, label); - } - - KIcon ic = IconManager::self()->iconForUrl(tab->url()); - label->setPixmap(ic.pixmap(16, 16)); -} - - -void TabWindow::tabLoadStarted() -{ - WebWindow *tab = qobject_cast(sender()); - if (!tab) - return; - - int index = indexOf(tab); - if (index != -1) - { - QLabel *label = qobject_cast(tabBar()->tabButton(index, QTabBar::LeftSide)); - if (!label) - { - label = new QLabel(this); - } - - if (!label->movie()) - { - static QString loadingGitPath = KStandardDirs::locate("appdata" , "pics/loading.mng"); - - QMovie *movie = new QMovie(loadingGitPath, QByteArray(), label); - movie->setSpeed(50); - label->setMovie(movie); - movie->start(); - } - - tabBar()->setTabButton(index, QTabBar::LeftSide, 0); - tabBar()->setTabButton(index, QTabBar::LeftSide, label); - - if (!tabBar()->tabData(index).toBool()) - tabBar()->setTabText(index, i18n("Loading...")); - else - { - tabBar()->tabButton(index, QTabBar::RightSide)->hide(); // NOTE: not really good this, but..."Repetita iuvant"!!! - } - } -} - - -void TabWindow::tabLoadFinished(bool ok) -{ - Q_UNUSED(ok); - - WebWindow *tab = qobject_cast(sender()); - if (!tab) - return; - - int index = indexOf(tab); - - if (-1 == index) - return; - - QLabel *label = qobject_cast(tabBar()->tabButton(index, QTabBar::LeftSide)); - if (!label) - { - label = new QLabel(this); - tabBar()->setTabButton(index, QTabBar::LeftSide, 0); - tabBar()->setTabButton(index, QTabBar::LeftSide, label); - } - - QMovie *movie = label->movie(); - if (movie) - { - movie->stop(); - delete movie; - } - - label->setMovie(0); - - KIcon ic = IconManager::self()->iconForUrl(tab->url()); - label->setPixmap(ic.pixmap(16, 16)); - - if (!tabBar()->tabData(index).toBool()) - { - setTabText(index, tab->title()); - } - else - { - setTabText(index, QString()); - } - - if (index == currentIndex()) - tab->checkFocus(); -} - - -void TabWindow::cloneTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - QUrl u = webWindow(index)->url(); - QWebHistory* history = webWindow(index)->page()->history(); - TabHistory clonedHistory(history); - - loadUrl(u, Rekonq::NewTab, &clonedHistory); -} - - -void TabWindow::closeTab(int index, bool del) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - WebWindow *tabToClose = webWindow(index); - if (!tabToClose) - return; - - // what to do if there is just one tab... - if (count() == 1) - { - kDebug() << "CANNOT CLOSE WINDOW FROM HERE..."; - currentWebWindow()->load(KUrl("about:home")); - return; - } - - if (!tabToClose->url().isEmpty() - && tabToClose->url().scheme() != QL1S("about") - && !tabToClose->page()->settings()->testAttribute(QWebSettings::PrivateBrowsingEnabled) - ) - { - const int recentlyClosedTabsLimit = 8; - TabHistory history(tabToClose->page()->history()); - history.title = tabToClose->title(); - history.url = tabToClose->url().url(); - history.position = index; - - m_recentlyClosedTabs.removeAll(history); - if (m_recentlyClosedTabs.count() == recentlyClosedTabsLimit) - m_recentlyClosedTabs.removeLast(); - m_recentlyClosedTabs.prepend(history); - } - - removeTab(index); - - if (del) - { - tabToClose->deleteLater(); - } -} - - -void TabWindow::closeOtherTabs(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - for (int i = count() - 1; i > index; --i) - { - closeTab(i); - } - - for (int i = index - 1; i >= 0; --i) - { - closeTab(i); - } -} - - -void TabWindow::detachTab(int index, TabWindow *toWindow) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - WebWindow *tab = webWindow(index); - KUrl u = tab->url(); - if (u.scheme() == QL1S("about")) - { - closeTab(index); - loadUrl(u, Rekonq::NewWindow); - return; - } - // else - - closeTab(index, false); - - TabWindow *w = 0; - w = (toWindow == 0) - ? new TabWindow(false) - : toWindow; - - w->addTab(tab, tab->title()); - w->setCurrentWidget(tab); - - // disconnect signals from old tabwindow - // WARNING: Code copied from prepareNewTab method. - // Any new changes there should be applied here... - disconnect(tab, SIGNAL(titleChanged(QString)), this, SLOT(tabTitleChanged(QString))); - disconnect(tab, SIGNAL(iconChanged()), this, SLOT(tabIconChanged())); - disconnect(tab, SIGNAL(loadStarted()), this, SLOT(tabLoadStarted())); - disconnect(tab, SIGNAL(loadFinished(bool)), this, SLOT(tabLoadFinished(bool))); - disconnect(tab, SIGNAL(pageCreated(WebPage*)), this, SLOT(pageCreated(WebPage*))); - - // reconnect signals to new tabwindow - // WARNING: Code copied from prepareNewTab method. - // Any new changes there should be applied here... - connect(tab, SIGNAL(titleChanged(QString)), w, SLOT(tabTitleChanged(QString))); - connect(tab, SIGNAL(iconChanged()), w, SLOT(tabIconChanged())); - connect(tab, SIGNAL(loadStarted()), w, SLOT(tabLoadStarted())); - connect(tab, SIGNAL(loadFinished(bool)), w, SLOT(tabLoadFinished(bool))); - connect(tab, SIGNAL(pageCreated(WebPage*)), w, SLOT(pageCreated(WebPage*))); - - w->show(); -} - - -void TabWindow::reloadTab(int index) -{ - // When index is -1 index chooses the current tab - if (index < 0) - index = currentIndex(); - - if (index < 0 || index >= count()) - return; - - WebWindow *reloadingTab = webWindow(index); - QAction *action = reloadingTab->page()->action(QWebPage::Reload); - action->trigger(); -} - - -void TabWindow::reloadAllTabs() -{ - for (int i = 0; i < count(); ++i) - { - reloadTab(i); - } -} - - -void TabWindow::bookmarkAllTabs() -{ - KBookmarkGroup rGroup = BookmarkManager::self()->rootGroup(); - KBookmarkGroup folderGroup = rGroup.createNewFolder(i18n("Bookmarked tabs: ") + QDate::currentDate().toString()); - for (int i = 0; i < count(); ++i) - { - WebWindow *tab = webWindow(i); - KBookmark bk = folderGroup.addBookmark(tab->title(), tab->url()); - } -} - - -void TabWindow::restoreLastClosedTab() -{ - restoreClosedTab(0); -} - - -void TabWindow::restoreClosedTab(int index, bool inNewTab) -{ - if (m_recentlyClosedTabs.isEmpty()) - return; - - if (index >= m_recentlyClosedTabs.count()) - return; - - TabHistory history = m_recentlyClosedTabs.takeAt(index); - - QUrl u = QUrl(history.url); - - int restorePosition = history.position; - - WebWindow *tab; - - if (inNewTab) - { - tab = prepareNewTab(); - if (restorePosition < count()) - insertTab(restorePosition, tab, i18n("restored tab")); - else - addTab(tab, i18n("restored tab")); - - setCurrentWidget(tab); - } - else - { - tab = currentWebWindow(); - } - - tab->load(u); - - // just to get sure... - m_recentlyClosedTabs.removeAll(history); -} - - -void TabWindow::nextTab() -{ - int next = currentIndex() + 1; - if (next == count()) - next = 0; - setCurrentIndex(next); -} - - -void TabWindow::previousTab() -{ - int next = currentIndex() - 1; - if (next < 0) - next = count() - 1; - setCurrentIndex(next); -} - - -void TabWindow::setFullScreen(bool makeFullScreen) -{ - tabBar()->setVisible(!makeFullScreen); - _addTabButton->setVisible(!makeFullScreen); - - KToggleFullScreenAction::setFullScreen(this, makeFullScreen); - - for (int i = 0; i < count(); i++) - webWindow(i)->setWidgetsHidden(makeFullScreen); -} - - -bool TabWindow::isPrivateBrowsingWindowMode() -{ - return _isPrivateBrowsing; -} - - -void TabWindow::loadFavorite(const int index) -{ - QStringList urls = ReKonfig::previewUrls(); - if (index < 0 || index > urls.length()) - return; - - KUrl url = KUrl(urls.at(index - 1)); - loadUrl(url); - currentWebWindow()->setFocus(); -} diff --git a/src/tabwindow/tabwindow.h b/src/tabwindow/tabwindow.h deleted file mode 100644 index c72c252b..00000000 --- a/src/tabwindow/tabwindow.h +++ /dev/null @@ -1,140 +0,0 @@ -/* ============================================================ -* -* This file is a part of the rekonq project -* -* Copyright (C) 2012 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 TAB_WINDOW -#define TAB_WINDOW - - -// Rekonq Includes -#include "rekonq_defines.h" - -// Local Includes -#include "rekonqwindow.h" - -// KDE Includes -#include -#include - -// Forward Declarations -class KUrl; - -class QLabel; -class QToolButton; -class QWebHistory; - -class TabHistory; - -class TabBar; -class WebPage; -class WebWindow; - - -// -------------------------------------------------------------------------------------- - - -class TabWindow : public RekonqWindow -{ - Q_OBJECT - -public: - explicit TabWindow(bool withTab = true, bool PrivateBrowsingMode = false, QWidget *parent = 0); - explicit TabWindow(WebPage *pg, QWidget *parent = 0); - - WebWindow* currentWebWindow() const; - WebWindow* webWindow(int index) const; - - TabBar* tabBar() const; - - bool isPrivateBrowsingWindowMode(); - - virtual KActionCollection *actionCollection() const; - QAction *actionByName(const QString &name); - - QList recentlyClosedTabs(); - void restoreClosedTab(int index, bool inNewTab = true); - -public Q_SLOTS: - void loadUrl(const KUrl &, Rekonq::OpenType type = Rekonq::CurrentTab, TabHistory *history = 0); - void newTab(WebPage *page = 0); - -private: - /** - * Prepares the new WebWindow to be open - */ - WebWindow *prepareNewTab(WebPage *page = 0); - - void init(); - -private Q_SLOTS: - /** - * Updates new tab button position - */ - void updateNewTabButtonPosition(); - - void tabTitleChanged(const QString &); - void tabUrlChanged(const QUrl &); - void tabIconChanged(); - - void tabLoadStarted(); - void tabLoadFinished(bool); - - void pageCreated(WebPage *); - - void currentChanged(int); - - // Indexed slots - void cloneTab(int index = -1); - void closeTab(int index = -1, bool del = true); - void closeOtherTabs(int index = -1); - void detachTab(int index = -1, TabWindow *toWindow = 0); - void reloadTab(int index = -1); - - void reloadAllTabs(); - void bookmarkAllTabs(); - - void nextTab(); - void previousTab(); - - void restoreLastClosedTab(); - - void setFullScreen(bool); - - void loadFavorite(const int); - -private: - // the new tab button - QToolButton *_addTabButton; - - int _openedTabsCounter; - - QList m_recentlyClosedTabs; - - bool _isPrivateBrowsing; - - KActionCollection *_ac; -}; - -#endif // TAB_WINDOW diff --git a/src/urlbar/rsswidget.cpp b/src/urlbar/rsswidget.cpp index 0d142d19..aeed6218 100644 --- a/src/urlbar/rsswidget.cpp +++ b/src/urlbar/rsswidget.cpp @@ -30,7 +30,8 @@ // Local includes #include "application.h" -#include "tabwindow.h" +#include "rekonqwindow.h" + #include "iconmanager.h" // KDE Includes @@ -132,7 +133,7 @@ void RSSWidget::accept() void RSSWidget::addWithGoogleReader(const QString &url) { KUrl toLoad = KUrl("http://www.google.com/ig/add?feedurl=" + url); - rApp->tabWindow()->loadUrl(toLoad); + rApp->rekonqWindow()->loadUrl(toLoad); } diff --git a/src/webwindow/rekonqui.rc b/src/webwindow/rekonqui.rc index 190111d9..90c5c192 100644 --- a/src/webwindow/rekonqui.rc +++ b/src/webwindow/rekonqui.rc @@ -1,6 +1,6 @@ - + @@ -45,6 +45,13 @@ + + + &Panels + + + + diff --git a/src/webwindow/webwindow.cpp b/src/webwindow/webwindow.cpp index 864c79b5..ab002459 100644 --- a/src/webwindow/webwindow.cpp +++ b/src/webwindow/webwindow.cpp @@ -31,7 +31,9 @@ #include "rekonq.h" #include "application.h" -#include "tabwindow.h" +#include "rekonqwindow.h" + +#include "tabwidget.h" #include "adblockmanager.h" #include "bookmarkmanager.h" @@ -994,7 +996,7 @@ void WebWindow::keyBindings() QPointer dialog = new KShortcutsDialog(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this); dialog->addCollection(actionCollection(), i18n("web window")); - TabWindow *tw = rApp->tabWindow(); + TabWidget *tw = rApp->rekonqWindow()->tabWidget(); if (tw) { dialog->addCollection(tw->actionCollection(), i18n("tab window")); -- cgit v1.2.1