From 6cf7ab65f009f07cdc0ded9ec377665c124a84ac Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Thu, 8 Jan 2009 02:35:46 +0100 Subject: Created mainview! Other minor adjs.. --- src/CMakeLists.txt | 4 +- src/browserapplication.cpp | 2 +- src/findbar.cpp | 6 +- src/findbar.h | 2 +- src/mainview.cpp | 704 ++++++++++++++++++++++++++++++++++++ src/mainview.h | 178 ++++++++++ src/mainwindow.cpp | 6 +- src/mainwindow.h | 6 +- src/tabbar.cpp | 207 +++++++++++ src/tabbar.h | 74 ++++ src/tabwidget.cpp | 863 --------------------------------------------- src/tabwidget.h | 218 ------------ src/webview.cpp | 2 +- 13 files changed, 1179 insertions(+), 1093 deletions(-) create mode 100644 src/mainview.cpp create mode 100644 src/mainview.h create mode 100644 src/tabbar.cpp create mode 100644 src/tabbar.h delete mode 100644 src/tabwidget.cpp delete mode 100644 src/tabwidget.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 938c98cd..83297551 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,7 +2,8 @@ SET( rekonq_SRCS autosaver.cpp browserapplication.cpp mainwindow.cpp -# rekonqview.cpp + mainview.cpp + tabbar.cpp cookiejar.cpp downloadmanager.cpp edittableview.cpp @@ -16,7 +17,6 @@ SET( rekonq_SRCS searchbar.cpp settings.cpp squeezelabel.cpp - tabwidget.cpp webview.cpp main.cpp ) diff --git a/src/browserapplication.cpp b/src/browserapplication.cpp index 696b2cd8..bc29d64e 100644 --- a/src/browserapplication.cpp +++ b/src/browserapplication.cpp @@ -27,7 +27,7 @@ #include "downloadmanager.h" #include "history.h" #include "networkaccessmanager.h" -#include "tabwidget.h" +#include "mainview.h" #include "webview.h" // KDE Includes diff --git a/src/findbar.cpp b/src/findbar.cpp index 6df09de1..a1c867c2 100644 --- a/src/findbar.cpp +++ b/src/findbar.cpp @@ -17,9 +17,11 @@  *  * ============================================================ */ +// Self Includes #include "findbar.h" -#include "moc_findbar.cpp" +#include "findbar.moc" +// KDE Includes #include #include #include @@ -27,8 +29,10 @@ #include #include +// Qt Includes #include + FindBar::FindBar(KXmlGuiWindow *parent) : KToolBar( "Find Bar" , parent, Qt::BottomToolBarArea, true, false, false) , m_lineEdit(0) diff --git a/src/findbar.h b/src/findbar.h index 4c73767c..d70a9de1 100644 --- a/src/findbar.h +++ b/src/findbar.h @@ -20,9 +20,9 @@ #ifndef FINDBAR_H #define FINDBAR_H +// KDE Includes #include #include - #include class FindBar : public KToolBar diff --git a/src/mainview.cpp b/src/mainview.cpp new file mode 100644 index 00000000..79cb865d --- /dev/null +++ b/src/mainview.cpp @@ -0,0 +1,704 @@ +/* ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2007-2008 Trolltech ASA. All rights reserved + * Copyright (C) 2008 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * ============================================================ */ + + +// Local Includes +#include "mainview.h" + +#include "tabbar.h" +#include "browserapplication.h" +#include "mainwindow.h" +#include "history.h" +#include "urlbar.h" +#include "webview.h" + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include +#include + + + + +WebActionMapper::WebActionMapper(KAction *root, QWebPage::WebAction webAction, QObject *parent) + : QObject(parent) + , m_currentParent(0) + , m_root(root) + , m_webAction(webAction) +{ + if ( !m_root ) + { + return; + } + connect(m_root, SIGNAL( triggered() ), this, SLOT( rootTriggered() ) ); + connect(root, SIGNAL( destroyed(QObject *) ), this, SLOT( rootDestroyed() ) ); + + root->setEnabled(false); +} + + +void WebActionMapper::rootDestroyed() +{ + m_root = 0; +} + + +void WebActionMapper::currentDestroyed() +{ + updateCurrent(0); +} + + +void WebActionMapper::addChild(KAction *action) +{ + if ( !action ) + { + return; + } + connect(action, SIGNAL( changed() ), this, SLOT( childChanged() ) ); +} + +QWebPage::WebAction WebActionMapper::webAction() const +{ + return m_webAction; +} + + +void WebActionMapper::rootTriggered() +{ + if (m_currentParent) + { + KAction *gotoAction = new KAction( m_currentParent->action(m_webAction) ); + gotoAction->trigger(); + } +} + + +void WebActionMapper::childChanged() +{ + if (KAction *source = qobject_cast(sender())) + { + if (m_root + && m_currentParent + && source->parent() == m_currentParent) + { + m_root->setChecked(source->isChecked()); + m_root->setEnabled(source->isEnabled()); + } + } +} + + +void WebActionMapper::updateCurrent(QWebPage *currentParent) +{ + if (m_currentParent) + disconnect(m_currentParent, SIGNAL(destroyed(QObject *)), + this, SLOT(currentDestroyed())); + + m_currentParent = currentParent; + if (!m_root) + { + return; + } + if (!m_currentParent) + { + m_root->setEnabled(false); + m_root->setChecked(false); + return; + } + KAction *source = new KAction( m_currentParent->action(m_webAction) ); + m_root->setChecked(source->isChecked()); + m_root->setEnabled(source->isEnabled()); + connect(m_currentParent, SIGNAL( destroyed(QObject *) ), this, SLOT( currentDestroyed() ) ); +} + + +// ---------------------------------------------------------------------------------------------------------- + + +MainView::MainView(QWidget *parent) + : KTabWidget(parent) + , m_recentlyClosedTabsAction(0) + , m_newTabAction(0) + , m_closeTabAction(0) + , m_nextTabAction(0) + , m_previousTabAction(0) + , m_recentlyClosedTabsMenu(0) + , m_lineEditCompleter(0) + , m_lineEdits(0) + , m_tabBar(new TabBar(this)) +{ + setElideMode(Qt::ElideRight); + + connect(m_tabBar, SIGNAL(newTab()), this, SLOT(newTab())); + connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); + connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int))); + connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int))); + connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); + connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs())); + connect(m_tabBar, SIGNAL(tabMoveRequested(int, int)), this, SLOT(moveTab(int, int))); + setTabBar(m_tabBar); + + // Actions + m_newTabAction = new KAction( KIcon("tab-new"), i18n("New &Tab"), this); + m_newTabAction->setShortcut( KShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_N, Qt::CTRL + Qt::Key_T) ); + m_newTabAction->setIconVisibleInMenu(false); + connect(m_newTabAction, SIGNAL(triggered()), this, SLOT(newTab())); + + m_closeTabAction = new KAction(KIcon("tab-close"), i18n("&Close Tab"), this); + m_closeTabAction->setShortcut( KShortcut( Qt::CTRL + Qt::Key_W ) ); + m_closeTabAction->setIconVisibleInMenu(false); + connect(m_closeTabAction, SIGNAL(triggered()), this, SLOT(closeTab())); + + m_nextTabAction = new KAction(i18n("Show Next Tab"), this); + m_nextTabAction->setShortcuts( QApplication::isRightToLeft() ? KStandardShortcut::tabPrev() : KStandardShortcut::tabNext() ); + connect(m_nextTabAction, SIGNAL(triggered()), this, SLOT(nextTab())); + + m_previousTabAction = new KAction(i18n("Show Previous Tab"), this); + m_previousTabAction->setShortcuts( QApplication::isRightToLeft() ? KStandardShortcut::tabNext() : KStandardShortcut::tabPrev() ); + connect(m_previousTabAction, SIGNAL(triggered()), this, SLOT(previousTab())); + + m_recentlyClosedTabsMenu = new KMenu(this); + connect(m_recentlyClosedTabsMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentTabsMenu())); + connect(m_recentlyClosedTabsMenu, SIGNAL(triggered(QAction *)), this, SLOT(aboutToShowRecentTriggeredAction(QAction *))); + m_recentlyClosedTabsAction = new KAction(i18n("Recently Closed Tabs"), this); + m_recentlyClosedTabsAction->setMenu(m_recentlyClosedTabsMenu); + m_recentlyClosedTabsAction->setEnabled(false); + + // corner buttons + QToolButton *addTabButton = new QToolButton(this); + addTabButton->setDefaultAction(m_newTabAction); + addTabButton->setAutoRaise(true); + addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + setCornerWidget(addTabButton, Qt::TopLeftCorner); + + QToolButton *closeTabButton = new QToolButton(this); + closeTabButton->setDefaultAction(m_closeTabAction); + closeTabButton->setAutoRaise(true); + closeTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); + setCornerWidget(closeTabButton, Qt::TopRightCorner); + + connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); + + m_lineEdits = new QStackedWidget(this); +} + + +MainView::~MainView() +{ + delete m_lineEditCompleter; + delete m_recentlyClosedTabsMenu; +} + + +void MainView::clear() +{ + // clear the recently closed tabs + m_recentlyClosedTabs.clear(); + // clear the line edit history + for (int i = 0; i < m_lineEdits->count(); ++i) + { + QLineEdit *qLineEdit = lineEdit(i); + qLineEdit->setText(qLineEdit->text()); + } +} + + +void MainView::moveTab(int fromIndex, int toIndex) +{ + disconnect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); + + QWidget *tabWidget = widget(fromIndex); + QIcon icon = tabIcon(fromIndex); + QString text = tabText(fromIndex); + QVariant data = m_tabBar->tabData(fromIndex); + removeTab(fromIndex); + insertTab(toIndex, tabWidget, icon, text); + m_tabBar->setTabData(toIndex, data); + connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); + setCurrentIndex(toIndex); +} + + +// When index is -1 index chooses the current tab +void MainView::reloadTab(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + QWidget *widget = this->widget(index); + if (WebView *tab = qobject_cast(widget)) + tab->reload(); +} + + +void MainView::addWebAction(KAction *action, QWebPage::WebAction webAction) +{ + if (!action) + return; + m_webActionList.append(new WebActionMapper(action, webAction, this)); +} + + +void MainView::currentChanged(int index) +{ + WebView *webView = this->webView(index); + if (!webView) + return; + + Q_ASSERT( m_lineEdits->count() == count() ); + + WebView *oldWebView = this->webView(m_lineEdits->currentIndex()); + if (oldWebView) + { + disconnect(oldWebView, SIGNAL(statusBarMessage(const QString&)), this, SIGNAL(showStatusBarMessage(const QString&))); + disconnect(oldWebView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), this, SIGNAL(linkHovered(const QString&))); + disconnect(oldWebView, SIGNAL(loadProgress(int)), this, SIGNAL(loadProgress(int))); + } + + connect(webView, SIGNAL(statusBarMessage(const QString&)), this, SIGNAL(showStatusBarMessage(const QString&))); + connect(webView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), this, SIGNAL(linkHovered(const QString&))); + connect(webView, SIGNAL(loadProgress(int)), this, SIGNAL(loadProgress(int))); + + for (int i = 0; i < m_webActionList.count(); ++i) + { + WebActionMapper *mapper = m_webActionList[i]; + mapper->updateCurrent(webView->page()); + } + emit setCurrentTitle(webView->title()); + m_lineEdits->setCurrentIndex(index); + emit loadProgress(webView->progress()); + emit showStatusBarMessage(webView->lastStatusBarText()); + + // set focus to the current webview + webView->setFocus(); +} + + +KAction *MainView::newTabAction() const +{ + return m_newTabAction; +} + + +KAction *MainView::closeTabAction() const +{ + return m_closeTabAction; +} + + +KAction *MainView::recentlyClosedTabsAction() const +{ + return m_recentlyClosedTabsAction; +} + + +KAction *MainView::nextTabAction() const +{ + return m_nextTabAction; +} + + +KAction *MainView::previousTabAction() const +{ + return m_previousTabAction; +} + + +QWidget *MainView::lineEditStack() const +{ + return m_lineEdits; +} + + +QLineEdit *MainView::currentLineEdit() const +{ + return lineEdit(m_lineEdits->currentIndex()); +} + + +WebView *MainView::currentWebView() const +{ + return webView(currentIndex()); +} + + +QLineEdit *MainView::lineEdit(int index) const +{ + UrlBar *urlLineEdit = qobject_cast(m_lineEdits->widget(index)); + if (urlLineEdit) + return urlLineEdit->lineEdit(); + return 0; +} + + +WebView *MainView::webView(int index) const +{ + QWidget *widget = this->widget(index); + if (WebView *webView = qobject_cast(widget)) + { + return webView; + } + else + { + // optimization to delay creating the first webview + if (count() == 1) + { + MainView *that = const_cast(this); + that->setUpdatesEnabled(false); + that->newTab(); + that->closeTab(0); + that->setUpdatesEnabled(true); + return currentWebView(); + } + } + return 0; +} + + +int MainView::webViewIndex(WebView *webView) const +{ + int index = indexOf(webView); + return index; +} + + +WebView *MainView::newTab(bool makeCurrent) +{ + // line edit + UrlBar *urlLineEdit = new UrlBar; + QLineEdit *lineEdit = urlLineEdit->lineEdit(); + if (!m_lineEditCompleter && count() > 0) + { + HistoryCompletionModel *completionModel = new HistoryCompletionModel(this); + completionModel->setSourceModel(BrowserApplication::historyManager()->historyFilterModel()); + m_lineEditCompleter = new QCompleter(completionModel, this); + // Should this be in Qt by default? + QAbstractItemView *popup = m_lineEditCompleter->popup(); + QListView *listView = qobject_cast(popup); + if (listView) + { + listView->setUniformItemSizes(true); + } + } + lineEdit->setCompleter(m_lineEditCompleter); + connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(lineEditReturnPressed())); + m_lineEdits->addWidget(urlLineEdit); + m_lineEdits->setSizePolicy(lineEdit->sizePolicy()); + + // optimization to delay creating the more expensive WebView, history, etc + if (count() == 0) + { + QWidget *emptyWidget = new QWidget; + QPalette p = emptyWidget->palette(); + p.setColor(QPalette::Window, palette().color(QPalette::Base)); + emptyWidget->setPalette(p); + emptyWidget->setAutoFillBackground(true); + disconnect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); + addTab(emptyWidget, i18n("(Untitled)")); + connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); + return 0; + } + + // webview + WebView *webView = new WebView; + urlLineEdit->setWebView(webView); + + connect(webView, SIGNAL(loadStarted()), this, SLOT(webViewLoadStarted())); + connect(webView, SIGNAL(loadFinished(bool)), this, SLOT(webViewIconChanged())); + connect(webView, SIGNAL(iconChanged()), this, SLOT(webViewIconChanged())); + connect(webView, SIGNAL(titleChanged(const QString &)), this, SLOT(webViewTitleChanged(const QString &))); + connect(webView, SIGNAL(urlChanged(const QUrl &)), this, SLOT(webViewUrlChanged(const QUrl &))); + connect(webView->page(), SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested())); + connect(webView->page(), SIGNAL(geometryChangeRequested(const QRect &)), this, SIGNAL(geometryChangeRequested(const QRect &))); + connect(webView->page(), SIGNAL(printRequested(QWebFrame *)), this, SIGNAL(printRequested(QWebFrame *))); + connect(webView->page(), SIGNAL(menuBarVisibilityChangeRequested(bool)), this, SIGNAL(menuBarVisibilityChangeRequested(bool))); + connect(webView->page(), SIGNAL(statusBarVisibilityChangeRequested(bool)), this, SIGNAL(statusBarVisibilityChangeRequested(bool))); + connect(webView->page(), SIGNAL(toolBarVisibilityChangeRequested(bool)), this, SIGNAL(toolBarVisibilityChangeRequested(bool))); + + connect(webView, SIGNAL( ctrlTabPressed() ), this, SLOT( nextTab() ) ); + connect(webView, SIGNAL( shiftCtrlTabPressed() ), this, SLOT( previousTab() ) ); + + addTab(webView, i18n("(Untitled)") ); + if (makeCurrent) + setCurrentWidget(webView); + + // webview actions + for (int i = 0; i < m_webActionList.count(); ++i) + { + WebActionMapper *mapper = m_webActionList[i]; + mapper->addChild( new KAction( webView->page()->action( mapper->webAction() ) ) ); + } + + if (count() == 1) + currentChanged(currentIndex()); + emit tabsChanged(); + return webView; +} + + +void MainView::reloadAllTabs() +{ + for (int i = 0; i < count(); ++i) + { + QWidget *tabWidget = widget(i); + if (WebView *tab = qobject_cast(tabWidget)) + { + tab->reload(); + } + } +} + + +void MainView::lineEditReturnPressed() +{ + if (QLineEdit *lineEdit = qobject_cast(sender())) + { + emit loadPage(lineEdit->text()); + if (m_lineEdits->currentWidget() == lineEdit) + currentWebView()->setFocus(); + } +} + + +void MainView::windowCloseRequested() +{ + WebPage *webPage = qobject_cast(sender()); + WebView *webView = qobject_cast(webPage->view()); + int index = webViewIndex(webView); + if (index >= 0) + { + if (count() == 1) + webView->webPage()->mainWindow()->close(); + else + closeTab(index); + } +} + + +void MainView::closeOtherTabs(int index) +{ + if (-1 == index) + return; + for (int i = count() - 1; i > index; --i) + closeTab(i); + for (int i = index - 1; i >= 0; --i) + closeTab(i); +} + + +// When index is -1 index chooses the current tab +void MainView::cloneTab(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + WebView *tab = newTab(false); + tab->setUrl( webView(index)->url() ); +} + + +// When index is -1 index chooses the current tab +void MainView::closeTab(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + bool hasFocus = false; + if (WebView *tab = webView(index)) + { + if (tab->isModified()) + { + int risp = KMessageBox::questionYesNo( this , + i18n("You have modified this page and when closing it you would lose the modification.\n" + "Do you really want to close this page?\n"), + i18n("Do you really want to close this page?"), + KStandardGuiItem::no() ); + if( risp == KMessageBox::No ) + return; + } + hasFocus = tab->hasFocus(); + + m_recentlyClosedTabsAction->setEnabled(true); + m_recentlyClosedTabs.prepend(tab->url()); + if (m_recentlyClosedTabs.size() >= MainView::m_recentlyClosedTabsSize) + m_recentlyClosedTabs.removeLast(); + } + QWidget *lineEdit = m_lineEdits->widget(index); + m_lineEdits->removeWidget(lineEdit); + lineEdit->deleteLater(); + QWidget *webView = widget(index); + removeTab(index); + webView->deleteLater(); + emit tabsChanged(); + if (hasFocus && count() > 0) + currentWebView()->setFocus(); + if (count() == 0) + emit lastTabClosed(); +} + + +void MainView::webViewLoadStarted() +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) + { + setTabIcon(index, KIcon("rekonq") ); + } +} + + +void MainView::webViewIconChanged() +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) + { + QIcon icon = BrowserApplication::instance()->icon(webView->url()); + setTabIcon(index, icon); + } +} + + +void MainView::webViewTitleChanged(const QString &title) +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) { + setTabText(index, title); + } + if (currentIndex() == index) + emit setCurrentTitle(title); + BrowserApplication::historyManager()->updateHistoryItem(webView->url(), title); +} + + +void MainView::webViewUrlChanged(const QUrl &url) +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) { + m_tabBar->setTabData(index, url); + } + emit tabsChanged(); +} + + +void MainView::aboutToShowRecentTabsMenu() +{ + m_recentlyClosedTabsMenu->clear(); + for (int i = 0; i < m_recentlyClosedTabs.count(); ++i) + { + KAction *action = new KAction(m_recentlyClosedTabsMenu); + action->setData(m_recentlyClosedTabs.at(i)); + QIcon icon = BrowserApplication::instance()->icon(m_recentlyClosedTabs.at(i)); + action->setIcon(icon); + action->setText( m_recentlyClosedTabs.at(i).prettyUrl() ); + m_recentlyClosedTabsMenu->addAction(action); + } +} + + +void MainView::aboutToShowRecentTriggeredAction(QAction *action) +{ + KUrl url = action->data().toUrl(); + loadUrlInCurrentTab(url); +} + + +void MainView::mouseDoubleClickEvent(QMouseEvent *event) +{ + if ( !childAt(event->pos() ) + // Remove the line below when QTabWidget does not have a one pixel frame + && event->pos().y() < (tabBar()->y() + tabBar()->height())) + { + newTab(); + return; + } + QTabWidget::mouseDoubleClickEvent(event); +} + + +void MainView::contextMenuEvent(QContextMenuEvent *event) +{ + if (!childAt(event->pos())) { + m_tabBar->contextMenuRequested(event->pos()); + return; + } + QTabWidget::contextMenuEvent(event); +} + + +void MainView::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::MidButton && !childAt(event->pos()) + // Remove the line below when QTabWidget does not have a one pixel frame + && event->pos().y() < (tabBar()->y() + tabBar()->height())) + { + KUrl url( QApplication::clipboard()->text(QClipboard::Selection) ); + if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) + { + WebView *webView = newTab(); + webView->setUrl(url); + } + } +} + + +void MainView::loadUrlInCurrentTab(const KUrl &url) +{ + WebView *webView = currentWebView(); + if (webView) + { + webView->loadUrl(url); + webView->setFocus(); + } +} + + +void MainView::nextTab() +{ + int next = currentIndex() + 1; + if (next == count()) + next = 0; + setCurrentIndex(next); +} + + +void MainView::previousTab() +{ + int next = currentIndex() - 1; + if (next < 0) + next = count() - 1; + setCurrentIndex(next); +} + + +// ---------------------------------------------------------------------------------------------------------------------------- diff --git a/src/mainview.h b/src/mainview.h new file mode 100644 index 00000000..3ffeef32 --- /dev/null +++ b/src/mainview.h @@ -0,0 +1,178 @@ +/* ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2007-2008 Trolltech ASA. All rights reserved + * Copyright (C) 2008 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * ============================================================ */ + + + +#ifndef TABWIDGET_H +#define TABWIDGET_H + +// KDE Includes +#include + +// Qt Includes +#include + +class WebView; +/** + * A proxy object that connects a single browser action + * to one child webpage action at a time. + * + * Example usage: used to keep the main window stop action in sync with + * the current tabs webview's stop action. + */ +class WebActionMapper : public QObject +{ + Q_OBJECT + +public: + WebActionMapper(KAction *root, QWebPage::WebAction webAction, QObject *parent); + QWebPage::WebAction webAction() const; + void addChild(KAction *action); + void updateCurrent(QWebPage *currentParent); + +private slots: + void rootTriggered(); + void childChanged(); + void rootDestroyed(); + void currentDestroyed(); + +private: + QWebPage *m_currentParent; + KAction *m_root; + QWebPage::WebAction m_webAction; +}; + + +// ---------------------------------------------------------------------------------------------------------------------------- + +// Local Includes +#include "tabbar.h" + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include + +QT_BEGIN_NAMESPACE +class QCompleter; +class QMenu; +class QStackedWidget; +QT_END_NAMESPACE + +/** + * TabWidget that contains WebViews and a stack widget of associated line edits. + * + * Connects up the current tab's signals to this class's signal and uses WebActionMapper + * to proxy the actions. + */ +class MainView : public KTabWidget +{ + Q_OBJECT + +public: + MainView(QWidget *parent = 0); + ~MainView(); + + +signals: + // tab widget signals + void loadPage(const QString &url); + void tabsChanged(); + void lastTabClosed(); + + // current tab signals + void setCurrentTitle(const QString &url); + void showStatusBarMessage(const QString &message); + void linkHovered(const QString &link); + void loadProgress(int progress); + void geometryChangeRequested(const QRect &geometry); + void menuBarVisibilityChangeRequested(bool visible); + void statusBarVisibilityChangeRequested(bool visible); + void toolBarVisibilityChangeRequested(bool visible); + void printRequested(QWebFrame *frame); + +public: + void clear(); + void addWebAction(KAction *action, QWebPage::WebAction webAction); + + KAction *newTabAction() const; + KAction *closeTabAction() const; + KAction *recentlyClosedTabsAction() const; + KAction *nextTabAction() const; + KAction *previousTabAction() const; + + QWidget *lineEditStack() const; + QLineEdit *currentLineEdit() const; + WebView *currentWebView() const; + WebView *webView(int index) const; + QLineEdit *lineEdit(int index) const; + int webViewIndex(WebView *webView) const; + +protected: + void mouseDoubleClickEvent(QMouseEvent *event); + void contextMenuEvent(QContextMenuEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + + +public slots: + void loadUrlInCurrentTab(const KUrl &url); + WebView *newTab(bool makeCurrent = true); + void cloneTab(int index = -1); + void closeTab(int index = -1); + void closeOtherTabs(int index); + void reloadTab(int index = -1); + void reloadAllTabs(); + void nextTab(); + void previousTab(); + +private slots: + void currentChanged(int index); + void aboutToShowRecentTabsMenu(); + void aboutToShowRecentTriggeredAction(QAction *action); // need QAction! + void webViewLoadStarted(); + void webViewIconChanged(); + void webViewTitleChanged(const QString &title); + void webViewUrlChanged(const QUrl &url); + void lineEditReturnPressed(); + void windowCloseRequested(); + void moveTab(int fromIndex, int toIndex); + +private: + KAction *m_recentlyClosedTabsAction; + KAction *m_newTabAction; + KAction *m_closeTabAction; + KAction *m_nextTabAction; + KAction *m_previousTabAction; + + KMenu *m_recentlyClosedTabsMenu; + static const int m_recentlyClosedTabsSize = 10; + QList m_recentlyClosedTabs; + QList m_webActionList; + + QCompleter *m_lineEditCompleter; + QStackedWidget *m_lineEdits; + TabBar *m_tabBar; +}; + +#endif // TABWIDGET_H + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9813cf1e..481bac96 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -21,13 +21,13 @@ // Self Includes #include "mainwindow.h" +#include "mainwindow.moc" // Local Includes #include "browserapplication.h" #include "downloadmanager.h" #include "history.h" #include "settings.h" -#include "tabwidget.h" #include "bookmarks.h" #include "webview.h" @@ -57,7 +57,7 @@ MainWindow::MainWindow() : KXmlGuiWindow() - , m_tabWidget( new TabWidget(this) ) + , m_tabWidget( new MainView(this) ) { // accept dnd setAcceptDrops(true); @@ -587,7 +587,7 @@ void MainWindow::loadPage(const QString &page) } -TabWidget *MainWindow::tabWidget() const +MainView *MainWindow::tabWidget() const { return m_tabWidget; } diff --git a/src/mainwindow.h b/src/mainwindow.h index aa8e3d65..8a13d7f9 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -25,6 +25,7 @@ // Local Includes #include "findbar.h" #include "searchbar.h" +#include "mainview.h" // KDE Includes #include @@ -37,7 +38,6 @@ class QWebFrame; -class TabWidget; class WebView; /** @@ -53,7 +53,7 @@ public: ~MainWindow(); static KUrl guessUrlFromString(const QString &url); - TabWidget *tabWidget() const; + MainView *tabWidget() const; WebView *currentTab() const; private: @@ -118,7 +118,7 @@ private: QString m_lastSearch; - TabWidget *m_tabWidget; + MainView *m_tabWidget; }; #endif // MAINWINDOW_H diff --git a/src/tabbar.cpp b/src/tabbar.cpp new file mode 100644 index 00000000..9aae3644 --- /dev/null +++ b/src/tabbar.cpp @@ -0,0 +1,207 @@ +/* ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2007-2008 Trolltech ASA. All rights reserved + * Copyright (C) 2008 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * ============================================================ */ + + +// Local Includes +#include "tabbar.h" + +#include "browserapplication.h" +#include "mainwindow.h" +#include "history.h" +#include "urlbar.h" +#include "webview.h" + +// KDE Includes +#include +#include +#include +#include + +// Qt Includes +#include +#include + + +TabBar::TabBar(QWidget *parent) + : KTabBar(parent) +{ + setElideMode(Qt::ElideRight); + setContextMenuPolicy(Qt::CustomContextMenu); + setAcceptDrops(true); + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenuRequested(const QPoint &))); + + QString alt = QLatin1String("Alt+%1"); + for (int i = 1; i <= 10; ++i) + { + int key = i; + if (key == 10) + { + key = 0; + } + QShortcut *shortCut = new QShortcut(alt.arg(key), this); + m_tabShortcuts.append(shortCut); + connect(shortCut, SIGNAL(activated()), this, SLOT(selectTabAction())); + } +} + + +TabBar::~TabBar() +{ +} + + +void TabBar::selectTabAction() +{ + if (QShortcut *shortCut = qobject_cast(sender())) + { + int index = m_tabShortcuts.indexOf(shortCut); + if (index == 0) + index = 10; + setCurrentIndex(index); + } +} + + +void TabBar::contextMenuRequested(const QPoint &position) +{ + // FIXME: use right actions + KMenu menu; + menu.addAction(i18n("New &Tab"), this, SIGNAL( newTab() ), QKeySequence::AddTab); + int index = tabAt(position); + if (-1 != index) + { + KAction *action = (KAction * ) menu.addAction(i18n("Clone Tab"), this, SLOT(cloneTab())); + action->setData(index); + + menu.addSeparator(); + + action = (KAction * ) menu.addAction(i18n("&Close Tab"), this, SLOT(closeTab()), QKeySequence::Close); + action->setData(index); + + action = (KAction * ) menu.addAction(i18n("Close &Other Tabs"), this, SLOT(closeOtherTabs())); + action->setData(index); + + menu.addSeparator(); + + action = (KAction * ) menu.addAction(i18n("Reload Tab"), this, SLOT(reloadTab()), QKeySequence::Refresh); + action->setData(index); + } + else + { + menu.addSeparator(); + } + menu.addAction(i18n("Reload All Tabs"), this, SIGNAL(reloadAllTabs())); + menu.exec(QCursor::pos()); +} + + +void TabBar::cloneTab() +{ + if (KAction *action = qobject_cast(sender())) + { + int index = action->data().toInt(); + emit cloneTab(index); + } +} + + +void TabBar::closeTab() +{ + if (KAction *action = qobject_cast(sender())) + { + int index = action->data().toInt(); + emit closeTab(index); + } +} + + +void TabBar::closeOtherTabs() +{ + if (KAction *action = qobject_cast(sender())) + { + int index = action->data().toInt(); + emit closeOtherTabs(index); + } +} + + +void TabBar::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + m_dragStartPos = event->pos(); + QTabBar::mousePressEvent(event); +} + + +void TabBar::mouseMoveEvent(QMouseEvent *event) +{ + if (event->buttons() == Qt::LeftButton && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance()) + { + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + QList urls; + int index = tabAt(event->pos()); + QUrl url = tabData(index).toUrl(); + urls.append(url); + mimeData->setUrls(urls); + mimeData->setText(tabText(index)); + mimeData->setData(QLatin1String("action"), "tab-reordering"); + drag->setMimeData(mimeData); + drag->exec(); + } + QTabBar::mouseMoveEvent(event); +} + + +void TabBar::dragEnterEvent(QDragEnterEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + QStringList formats = mimeData->formats(); + + if (formats.contains(QLatin1String("action")) && (mimeData->data(QLatin1String("action")) == "tab-reordering")) + { + event->acceptProposedAction(); + } + QTabBar::dragEnterEvent(event); +} + + +void TabBar::dropEvent(QDropEvent *event) +{ + int fromIndex = tabAt(m_dragStartPos); + int toIndex = tabAt(event->pos()); + if (fromIndex != toIndex) + { + emit tabMoveRequested(fromIndex, toIndex); + event->acceptProposedAction(); + } + QTabBar::dropEvent(event); +} + + +void TabBar::reloadTab() +{ + if (KAction *action = qobject_cast(sender())) + { + int index = action->data().toInt(); + emit reloadTab(index); + } +} + diff --git a/src/tabbar.h b/src/tabbar.h new file mode 100644 index 00000000..0692fcd6 --- /dev/null +++ b/src/tabbar.h @@ -0,0 +1,74 @@ +/* ============================================================ + * + * This file is a part of the rekonq project + * + * Copyright (C) 2007-2008 Trolltech ASA. All rights reserved + * Copyright (C) 2008 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, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * ============================================================ */ + + + +#ifndef TABBAR_H +#define TABBAR_H + +// KDE Includes +#include + +// Qt Includes +#include + +/** + * Tab bar with a few more features such as a context menu and shortcuts + */ +class TabBar : public KTabBar +{ + Q_OBJECT + +signals: + void newTab(); + void cloneTab(int index); + void closeTab(int index); + void closeOtherTabs(int index); + void reloadTab(int index); + void reloadAllTabs(); + void tabMoveRequested(int fromIndex, int toIndex); + +public: + TabBar(QWidget *parent = 0); + ~TabBar(); + +protected: + void mousePressEvent(QMouseEvent* event); + void mouseMoveEvent(QMouseEvent* event); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private slots: + void selectTabAction(); + void cloneTab(); + void closeTab(); + void closeOtherTabs(); + void reloadTab(); + void contextMenuRequested(const QPoint &position); + +private: + QList m_tabShortcuts; + friend class MainView; + + QPoint m_dragStartPos; + int m_dragCurrentIndex; +}; + +#endif diff --git a/src/tabwidget.cpp b/src/tabwidget.cpp deleted file mode 100644 index 4af3ef60..00000000 --- a/src/tabwidget.cpp +++ /dev/null @@ -1,863 +0,0 @@ -/* ============================================================ - * - * This file is a part of the rekonq project - * - * Copyright (C) 2007-2008 Trolltech ASA. All rights reserved - * Copyright (C) 2008 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, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * ============================================================ */ - - -// Local Includes -#include "tabwidget.h" - -#include "browserapplication.h" -#include "mainwindow.h" -#include "history.h" -#include "urlbar.h" -#include "webview.h" - -// KDE Includes -#include -#include -#include - -// Qt Includes -#include -#include - - -TabBar::TabBar(QWidget *parent) - : KTabBar(parent) -{ - setElideMode(Qt::ElideRight); - setContextMenuPolicy(Qt::CustomContextMenu); - setAcceptDrops(true); - connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenuRequested(const QPoint &))); - - QString alt = QLatin1String("Alt+%1"); - for (int i = 1; i <= 10; ++i) - { - int key = i; - if (key == 10) - key = 0; - QShortcut *shortCut = new QShortcut(alt.arg(key), this); - m_tabShortcuts.append(shortCut); - connect(shortCut, SIGNAL(activated()), this, SLOT(selectTabAction())); - } -} - - -TabBar::~TabBar() -{ -} - - -void TabBar::selectTabAction() -{ - if (QShortcut *shortCut = qobject_cast(sender())) - { - int index = m_tabShortcuts.indexOf(shortCut); - if (index == 0) - index = 10; - setCurrentIndex(index); - } -} - - -void TabBar::contextMenuRequested(const QPoint &position) -{ - KMenu menu; - menu.addAction(i18n("New &Tab"), this, SIGNAL( newTab() ), QKeySequence::AddTab); - int index = tabAt(position); - if (-1 != index) - { - KAction *action = (KAction * ) menu.addAction(i18n("Clone Tab"), this, SLOT(cloneTab())); - action->setData(index); - - menu.addSeparator(); - - action = (KAction * ) menu.addAction(i18n("&Close Tab"), this, SLOT(closeTab()), QKeySequence::Close); - action->setData(index); - - action = (KAction * ) menu.addAction(i18n("Close &Other Tabs"), this, SLOT(closeOtherTabs())); - action->setData(index); - - menu.addSeparator(); - - action = (KAction * ) menu.addAction(i18n("Reload Tab"), this, SLOT(reloadTab()), QKeySequence::Refresh); - action->setData(index); - } - else - { - menu.addSeparator(); - } - menu.addAction(i18n("Reload All Tabs"), this, SIGNAL(reloadAllTabs())); - menu.exec(QCursor::pos()); -} - - -void TabBar::cloneTab() -{ - if (KAction *action = qobject_cast(sender())) - { - int index = action->data().toInt(); - emit cloneTab(index); - } -} - - -void TabBar::closeTab() -{ - if (KAction *action = qobject_cast(sender())) - { - int index = action->data().toInt(); - emit closeTab(index); - } -} - - -void TabBar::closeOtherTabs() -{ - if (KAction *action = qobject_cast(sender())) - { - int index = action->data().toInt(); - emit closeOtherTabs(index); - } -} - - -void TabBar::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - m_dragStartPos = event->pos(); - QTabBar::mousePressEvent(event); -} - - -void TabBar::mouseMoveEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::LeftButton && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance()) - { - QDrag *drag = new QDrag(this); - QMimeData *mimeData = new QMimeData; - QList urls; - int index = tabAt(event->pos()); - QUrl url = tabData(index).toUrl(); - urls.append(url); - mimeData->setUrls(urls); - mimeData->setText(tabText(index)); - mimeData->setData(QLatin1String("action"), "tab-reordering"); - drag->setMimeData(mimeData); - drag->exec(); - } - QTabBar::mouseMoveEvent(event); -} - - -void TabBar::dragEnterEvent(QDragEnterEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - QStringList formats = mimeData->formats(); - - if (formats.contains(QLatin1String("action")) && (mimeData->data(QLatin1String("action")) == "tab-reordering")) - { - event->acceptProposedAction(); - } - QTabBar::dragEnterEvent(event); -} - - -void TabBar::dropEvent(QDropEvent *event) -{ - int fromIndex = tabAt(m_dragStartPos); - int toIndex = tabAt(event->pos()); - if (fromIndex != toIndex) - { - emit tabMoveRequested(fromIndex, toIndex); - event->acceptProposedAction(); - } - QTabBar::dropEvent(event); -} - - -void TabBar::reloadTab() -{ - if (KAction *action = qobject_cast(sender())) - { - int index = action->data().toInt(); - emit reloadTab(index); - } -} - - -// --------------------------------------------------------------------------------------------------------------------------- - - -TabWidget::TabWidget(QWidget *parent) - : KTabWidget(parent) - , m_recentlyClosedTabsAction(0) - , m_newTabAction(0) - , m_closeTabAction(0) - , m_nextTabAction(0) - , m_previousTabAction(0) - , m_recentlyClosedTabsMenu(0) - , m_lineEditCompleter(0) - , m_lineEdits(0) - , m_tabBar(new TabBar(this)) -{ - setElideMode(Qt::ElideRight); - - connect(m_tabBar, SIGNAL(newTab()), this, SLOT(newTab())); - connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); - connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int))); - connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int))); - connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); - connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs())); - connect(m_tabBar, SIGNAL(tabMoveRequested(int, int)), this, SLOT(moveTab(int, int))); - setTabBar(m_tabBar); - - // Actions - m_newTabAction = new KAction( KIcon("tab-new"), i18n("New &Tab"), this); - m_newTabAction->setShortcut( KShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_N, Qt::CTRL + Qt::Key_T) ); - m_newTabAction->setIconVisibleInMenu(false); - connect(m_newTabAction, SIGNAL(triggered()), this, SLOT(newTab())); - - m_closeTabAction = new KAction(KIcon("tab-close"), i18n("&Close Tab"), this); - m_closeTabAction->setShortcut( KShortcut( Qt::CTRL + Qt::Key_W ) ); - m_closeTabAction->setIconVisibleInMenu(false); - connect(m_closeTabAction, SIGNAL(triggered()), this, SLOT(closeTab())); - - m_nextTabAction = new KAction(i18n("Show Next Tab"), this); - m_nextTabAction->setShortcuts( QApplication::isRightToLeft() ? KStandardShortcut::tabPrev() : KStandardShortcut::tabNext() ); - connect(m_nextTabAction, SIGNAL(triggered()), this, SLOT(nextTab())); - - m_previousTabAction = new KAction(i18n("Show Previous Tab"), this); - m_previousTabAction->setShortcuts( QApplication::isRightToLeft() ? KStandardShortcut::tabNext() : KStandardShortcut::tabPrev() ); - connect(m_previousTabAction, SIGNAL(triggered()), this, SLOT(previousTab())); - - m_recentlyClosedTabsMenu = new KMenu(this); - connect(m_recentlyClosedTabsMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentTabsMenu())); - connect(m_recentlyClosedTabsMenu, SIGNAL(triggered(QAction *)), this, SLOT(aboutToShowRecentTriggeredAction(QAction *))); - m_recentlyClosedTabsAction = new KAction(i18n("Recently Closed Tabs"), this); - m_recentlyClosedTabsAction->setMenu(m_recentlyClosedTabsMenu); - m_recentlyClosedTabsAction->setEnabled(false); - - // corner buttons - QToolButton *addTabButton = new QToolButton(this); - addTabButton->setDefaultAction(m_newTabAction); - addTabButton->setAutoRaise(true); - addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); - setCornerWidget(addTabButton, Qt::TopLeftCorner); - - QToolButton *closeTabButton = new QToolButton(this); - closeTabButton->setDefaultAction(m_closeTabAction); - closeTabButton->setAutoRaise(true); - closeTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); - setCornerWidget(closeTabButton, Qt::TopRightCorner); - - connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); - - m_lineEdits = new QStackedWidget(this); -} - - -TabWidget::~TabWidget() -{ - delete m_lineEditCompleter; - delete m_recentlyClosedTabsMenu; -} - - -void TabWidget::clear() -{ - // clear the recently closed tabs - m_recentlyClosedTabs.clear(); - // clear the line edit history - for (int i = 0; i < m_lineEdits->count(); ++i) - { - QLineEdit *qLineEdit = lineEdit(i); - qLineEdit->setText(qLineEdit->text()); - } -} - - -void TabWidget::moveTab(int fromIndex, int toIndex) -{ - disconnect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); - - QWidget *tabWidget = widget(fromIndex); - QIcon icon = tabIcon(fromIndex); - QString text = tabText(fromIndex); - QVariant data = m_tabBar->tabData(fromIndex); - removeTab(fromIndex); - insertTab(toIndex, tabWidget, icon, text); - m_tabBar->setTabData(toIndex, data); - connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); - setCurrentIndex(toIndex); -} - - -// When index is -1 index chooses the current tab -void TabWidget::reloadTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - QWidget *widget = this->widget(index); - if (WebView *tab = qobject_cast(widget)) - tab->reload(); -} - - -void TabWidget::addWebAction(KAction *action, QWebPage::WebAction webAction) -{ - if (!action) - return; - m_actions.append(new WebActionMapper(action, webAction, this)); -} - - -void TabWidget::currentChanged(int index) -{ - WebView *webView = this->webView(index); - if (!webView) - return; - - Q_ASSERT( m_lineEdits->count() == count() ); - - WebView *oldWebView = this->webView(m_lineEdits->currentIndex()); - if (oldWebView) - { - disconnect(oldWebView, SIGNAL(statusBarMessage(const QString&)), this, SIGNAL(showStatusBarMessage(const QString&))); - disconnect(oldWebView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), this, SIGNAL(linkHovered(const QString&))); - disconnect(oldWebView, SIGNAL(loadProgress(int)), this, SIGNAL(loadProgress(int))); - } - - connect(webView, SIGNAL(statusBarMessage(const QString&)), this, SIGNAL(showStatusBarMessage(const QString&))); - connect(webView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), this, SIGNAL(linkHovered(const QString&))); - connect(webView, SIGNAL(loadProgress(int)), this, SIGNAL(loadProgress(int))); - - for (int i = 0; i < m_actions.count(); ++i) - { - WebActionMapper *mapper = m_actions[i]; - mapper->updateCurrent(webView->page()); - } - emit setCurrentTitle(webView->title()); - m_lineEdits->setCurrentIndex(index); - emit loadProgress(webView->progress()); - emit showStatusBarMessage(webView->lastStatusBarText()); - - // set focus to the current webview - webView->setFocus(); -} - - -KAction *TabWidget::newTabAction() const -{ - return m_newTabAction; -} - - -KAction *TabWidget::closeTabAction() const -{ - return m_closeTabAction; -} - - -KAction *TabWidget::recentlyClosedTabsAction() const -{ - return m_recentlyClosedTabsAction; -} - - -KAction *TabWidget::nextTabAction() const -{ - return m_nextTabAction; -} - - -KAction *TabWidget::previousTabAction() const -{ - return m_previousTabAction; -} - - -QWidget *TabWidget::lineEditStack() const -{ - return m_lineEdits; -} - - -QLineEdit *TabWidget::currentLineEdit() const -{ - return lineEdit(m_lineEdits->currentIndex()); -} - - -WebView *TabWidget::currentWebView() const -{ - return webView(currentIndex()); -} - - -QLineEdit *TabWidget::lineEdit(int index) const -{ - UrlBar *urlLineEdit = qobject_cast(m_lineEdits->widget(index)); - if (urlLineEdit) - return urlLineEdit->lineEdit(); - return 0; -} - - -WebView *TabWidget::webView(int index) const -{ - QWidget *widget = this->widget(index); - if (WebView *webView = qobject_cast(widget)) - { - return webView; - } - else - { - // optimization to delay creating the first webview - if (count() == 1) - { - TabWidget *that = const_cast(this); - that->setUpdatesEnabled(false); - that->newTab(); - that->closeTab(0); - that->setUpdatesEnabled(true); - return currentWebView(); - } - } - return 0; -} - - -int TabWidget::webViewIndex(WebView *webView) const -{ - int index = indexOf(webView); - return index; -} - - -WebView *TabWidget::newTab(bool makeCurrent) -{ - // line edit - UrlBar *urlLineEdit = new UrlBar; - QLineEdit *lineEdit = urlLineEdit->lineEdit(); - if (!m_lineEditCompleter && count() > 0) - { - HistoryCompletionModel *completionModel = new HistoryCompletionModel(this); - completionModel->setSourceModel(BrowserApplication::historyManager()->historyFilterModel()); - m_lineEditCompleter = new QCompleter(completionModel, this); - // Should this be in Qt by default? - QAbstractItemView *popup = m_lineEditCompleter->popup(); - QListView *listView = qobject_cast(popup); - if (listView) - listView->setUniformItemSizes(true); - } - lineEdit->setCompleter(m_lineEditCompleter); - connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(lineEditReturnPressed())); - m_lineEdits->addWidget(urlLineEdit); - m_lineEdits->setSizePolicy(lineEdit->sizePolicy()); - - // optimization to delay creating the more expensive WebView, history, etc - if (count() == 0) - { - QWidget *emptyWidget = new QWidget; - QPalette p = emptyWidget->palette(); - p.setColor(QPalette::Window, palette().color(QPalette::Base)); - emptyWidget->setPalette(p); - emptyWidget->setAutoFillBackground(true); - disconnect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); - addTab(emptyWidget, i18n("(Untitled)")); - connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); - return 0; - } - - // webview - WebView *webView = new WebView; - urlLineEdit->setWebView(webView); - - connect(webView, SIGNAL(loadStarted()), this, SLOT(webViewLoadStarted())); - connect(webView, SIGNAL(loadFinished(bool)), this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(iconChanged()), this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(titleChanged(const QString &)), this, SLOT(webViewTitleChanged(const QString &))); - connect(webView, SIGNAL(urlChanged(const QUrl &)), this, SLOT(webViewUrlChanged(const QUrl &))); - connect(webView->page(), SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested())); - connect(webView->page(), SIGNAL(geometryChangeRequested(const QRect &)), this, SIGNAL(geometryChangeRequested(const QRect &))); - connect(webView->page(), SIGNAL(printRequested(QWebFrame *)), this, SIGNAL(printRequested(QWebFrame *))); - connect(webView->page(), SIGNAL(menuBarVisibilityChangeRequested(bool)), this, SIGNAL(menuBarVisibilityChangeRequested(bool))); - connect(webView->page(), SIGNAL(statusBarVisibilityChangeRequested(bool)), this, SIGNAL(statusBarVisibilityChangeRequested(bool))); - connect(webView->page(), SIGNAL(toolBarVisibilityChangeRequested(bool)), this, SIGNAL(toolBarVisibilityChangeRequested(bool))); - - connect(webView, SIGNAL( ctrlTabPressed() ), this, SLOT( nextTab() ) ); - connect(webView, SIGNAL( shiftCtrlTabPressed() ), this, SLOT( previousTab() ) ); - - addTab(webView, i18n("(Untitled)") ); - if (makeCurrent) - setCurrentWidget(webView); - - // webview actions - for (int i = 0; i < m_actions.count(); ++i) - { - WebActionMapper *mapper = m_actions[i]; - mapper->addChild( new KAction( webView->page()->action( mapper->webAction() ) ) ); - } - - if (count() == 1) - currentChanged(currentIndex()); - emit tabsChanged(); - return webView; -} - - -void TabWidget::reloadAllTabs() -{ - for (int i = 0; i < count(); ++i) - { - QWidget *tabWidget = widget(i); - if (WebView *tab = qobject_cast(tabWidget)) - { - tab->reload(); - } - } -} - - -void TabWidget::lineEditReturnPressed() -{ - if (QLineEdit *lineEdit = qobject_cast(sender())) - { - emit loadPage(lineEdit->text()); - if (m_lineEdits->currentWidget() == lineEdit) - currentWebView()->setFocus(); - } -} - - -void TabWidget::windowCloseRequested() -{ - WebPage *webPage = qobject_cast(sender()); - WebView *webView = qobject_cast(webPage->view()); - int index = webViewIndex(webView); - if (index >= 0) - { - if (count() == 1) - webView->webPage()->mainWindow()->close(); - else - closeTab(index); - } -} - - -void TabWidget::closeOtherTabs(int index) -{ - if (-1 == index) - return; - for (int i = count() - 1; i > index; --i) - closeTab(i); - for (int i = index - 1; i >= 0; --i) - closeTab(i); -} - - -// When index is -1 index chooses the current tab -void TabWidget::cloneTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - WebView *tab = newTab(false); - tab->setUrl( webView(index)->url() ); -} - - -// When index is -1 index chooses the current tab -void TabWidget::closeTab(int index) -{ - if (index < 0) - index = currentIndex(); - if (index < 0 || index >= count()) - return; - - bool hasFocus = false; - if (WebView *tab = webView(index)) - { - if (tab->isModified()) - { - int risp = KMessageBox::questionYesNo( this , - i18n("You have modified this page and when closing it you would lose the modification.\n" - "Do you really want to close this page?\n"), - i18n("Do you really want to close this page?"), - KStandardGuiItem::no() ); - if( risp == KMessageBox::No ) - return; - } - hasFocus = tab->hasFocus(); - - m_recentlyClosedTabsAction->setEnabled(true); - m_recentlyClosedTabs.prepend(tab->url()); - if (m_recentlyClosedTabs.size() >= TabWidget::m_recentlyClosedTabsSize) - m_recentlyClosedTabs.removeLast(); - } - QWidget *lineEdit = m_lineEdits->widget(index); - m_lineEdits->removeWidget(lineEdit); - lineEdit->deleteLater(); - QWidget *webView = widget(index); - removeTab(index); - webView->deleteLater(); - emit tabsChanged(); - if (hasFocus && count() > 0) - currentWebView()->setFocus(); - if (count() == 0) - emit lastTabClosed(); -} - - -void TabWidget::webViewLoadStarted() -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) - { - setTabIcon(index, KIcon("rekonq") ); - } -} - - -void TabWidget::webViewIconChanged() -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) - { - QIcon icon = BrowserApplication::instance()->icon(webView->url()); - setTabIcon(index, icon); - } -} - - -void TabWidget::webViewTitleChanged(const QString &title) -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - setTabText(index, title); - } - if (currentIndex() == index) - emit setCurrentTitle(title); - BrowserApplication::historyManager()->updateHistoryItem(webView->url(), title); -} - - -void TabWidget::webViewUrlChanged(const QUrl &url) -{ - WebView *webView = qobject_cast(sender()); - int index = webViewIndex(webView); - if (-1 != index) { - m_tabBar->setTabData(index, url); - } - emit tabsChanged(); -} - - -void TabWidget::aboutToShowRecentTabsMenu() -{ - m_recentlyClosedTabsMenu->clear(); - for (int i = 0; i < m_recentlyClosedTabs.count(); ++i) - { - KAction *action = new KAction(m_recentlyClosedTabsMenu); - action->setData(m_recentlyClosedTabs.at(i)); - QIcon icon = BrowserApplication::instance()->icon(m_recentlyClosedTabs.at(i)); - action->setIcon(icon); - action->setText( m_recentlyClosedTabs.at(i).prettyUrl() ); - m_recentlyClosedTabsMenu->addAction(action); - } -} - - -void TabWidget::aboutToShowRecentTriggeredAction(QAction *action) -{ - KUrl url = action->data().toUrl(); - loadUrlInCurrentTab(url); -} - - -void TabWidget::mouseDoubleClickEvent(QMouseEvent *event) -{ - if ( !childAt(event->pos() ) - // Remove the line below when QTabWidget does not have a one pixel frame - && event->pos().y() < (tabBar()->y() + tabBar()->height())) - { - newTab(); - return; - } - QTabWidget::mouseDoubleClickEvent(event); -} - - -void TabWidget::contextMenuEvent(QContextMenuEvent *event) -{ - if (!childAt(event->pos())) { - m_tabBar->contextMenuRequested(event->pos()); - return; - } - QTabWidget::contextMenuEvent(event); -} - - -void TabWidget::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::MidButton && !childAt(event->pos()) - // Remove the line below when QTabWidget does not have a one pixel frame - && event->pos().y() < (tabBar()->y() + tabBar()->height())) - { - KUrl url( QApplication::clipboard()->text(QClipboard::Selection) ); - if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) - { - WebView *webView = newTab(); - webView->setUrl(url); - } - } -} - - -void TabWidget::loadUrlInCurrentTab(const KUrl &url) -{ - WebView *webView = currentWebView(); - if (webView) - { - webView->loadUrl(url); - webView->setFocus(); - } -} - - -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); -} - - -// ---------------------------------------------------------------------------------------------------------------------------- - - -WebActionMapper::WebActionMapper(KAction *root, QWebPage::WebAction webAction, QObject *parent) - : QObject(parent) - , m_currentParent(0) - , m_root(root) - , m_webAction(webAction) -{ - if ( !m_root ) - { - return; - } - connect(m_root, SIGNAL( triggered() ), this, SLOT( rootTriggered() ) ); - connect(root, SIGNAL( destroyed(QObject *) ), this, SLOT( rootDestroyed() ) ); - - root->setEnabled(false); -} - - -void WebActionMapper::rootDestroyed() -{ - m_root = 0; -} - - -void WebActionMapper::currentDestroyed() -{ - updateCurrent(0); -} - - -void WebActionMapper::addChild(KAction *action) -{ - if ( !action ) - { - return; - } - connect(action, SIGNAL( changed() ), this, SLOT( childChanged() ) ); -} - -QWebPage::WebAction WebActionMapper::webAction() const -{ - return m_webAction; -} - - -void WebActionMapper::rootTriggered() -{ - if (m_currentParent) - { - KAction *gotoAction = new KAction( m_currentParent->action(m_webAction) ); - gotoAction->trigger(); - } -} - - -void WebActionMapper::childChanged() -{ - if (KAction *source = qobject_cast(sender())) - { - if (m_root - && m_currentParent - && source->parent() == m_currentParent) - { - m_root->setChecked(source->isChecked()); - m_root->setEnabled(source->isEnabled()); - } - } -} - - -void WebActionMapper::updateCurrent(QWebPage *currentParent) -{ - if (m_currentParent) - disconnect(m_currentParent, SIGNAL(destroyed(QObject *)), - this, SLOT(currentDestroyed())); - - m_currentParent = currentParent; - if (!m_root) - { - return; - } - if (!m_currentParent) - { - m_root->setEnabled(false); - m_root->setChecked(false); - return; - } - KAction *source = new KAction( m_currentParent->action(m_webAction) ); - m_root->setChecked(source->isChecked()); - m_root->setEnabled(source->isEnabled()); - connect(m_currentParent, SIGNAL( destroyed(QObject *) ), this, SLOT( currentDestroyed() ) ); -} diff --git a/src/tabwidget.h b/src/tabwidget.h deleted file mode 100644 index 4edba9b9..00000000 --- a/src/tabwidget.h +++ /dev/null @@ -1,218 +0,0 @@ -/* ============================================================ - * - * This file is a part of the rekonq project - * - * Copyright (C) 2007-2008 Trolltech ASA. All rights reserved - * Copyright (C) 2008 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, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * ============================================================ */ - - - -#ifndef TABWIDGET_H -#define TABWIDGET_H - -#include -#include - -#include -/* - Tab bar with a few more features such as a context menu and shortcuts - */ -class TabBar : public KTabBar -{ - Q_OBJECT - -signals: - void newTab(); - void cloneTab(int index); - void closeTab(int index); - void closeOtherTabs(int index); - void reloadTab(int index); - void reloadAllTabs(); - void tabMoveRequested(int fromIndex, int toIndex); - -public: - TabBar(QWidget *parent = 0); - ~TabBar(); - -protected: - void mousePressEvent(QMouseEvent* event); - void mouseMoveEvent(QMouseEvent* event); - void dragEnterEvent(QDragEnterEvent *event); - void dropEvent(QDropEvent *event); - -private slots: - void selectTabAction(); - void cloneTab(); - void closeTab(); - void closeOtherTabs(); - void reloadTab(); - void contextMenuRequested(const QPoint &position); - -private: - QList m_tabShortcuts; - friend class TabWidget; - - QPoint m_dragStartPos; - int m_dragCurrentIndex; -}; - - -// ---------------------------------------------------------------------------------------------------------------------------- - - -#include - -class WebView; -/*! - A proxy object that connects a single browser action - to one child webpage action at a time. - - Example usage: used to keep the main window stop action in sync with - the current tabs webview's stop action. - */ -class WebActionMapper : public QObject -{ - Q_OBJECT - -public: - WebActionMapper(KAction *root, QWebPage::WebAction webAction, QObject *parent); - QWebPage::WebAction webAction() const; - void addChild(KAction *action); - void updateCurrent(QWebPage *currentParent); - -private slots: - void rootTriggered(); - void childChanged(); - void rootDestroyed(); - void currentDestroyed(); - -private: - QWebPage *m_currentParent; - KAction *m_root; - QWebPage::WebAction m_webAction; -}; - - -// ---------------------------------------------------------------------------------------------------------------------------- - -// KDE Includes -#include -#include -#include - -// Qt Includes -#include - -QT_BEGIN_NAMESPACE -class QCompleter; -class QMenu; -class QStackedWidget; -QT_END_NAMESPACE -/*! - TabWidget that contains WebViews and a stack widget of associated line edits. - - Connects up the current tab's signals to this class's signal and uses WebActionMapper - to proxy the actions. - */ -class TabWidget : public KTabWidget -{ - Q_OBJECT - -signals: - // tab widget signals - void loadPage(const QString &url); - void tabsChanged(); - void lastTabClosed(); - - // current tab signals - void setCurrentTitle(const QString &url); - void showStatusBarMessage(const QString &message); - void linkHovered(const QString &link); - void loadProgress(int progress); - void geometryChangeRequested(const QRect &geometry); - void menuBarVisibilityChangeRequested(bool visible); - void statusBarVisibilityChangeRequested(bool visible); - void toolBarVisibilityChangeRequested(bool visible); - void printRequested(QWebFrame *frame); - -public: - TabWidget(QWidget *parent = 0); - ~TabWidget(); - - void clear(); - void addWebAction(KAction *action, QWebPage::WebAction webAction); - - KAction *newTabAction() const; - KAction *closeTabAction() const; - KAction *recentlyClosedTabsAction() const; - KAction *nextTabAction() const; - KAction *previousTabAction() const; - - QWidget *lineEditStack() const; - QLineEdit *currentLineEdit() const; - WebView *currentWebView() const; - WebView *webView(int index) const; - QLineEdit *lineEdit(int index) const; - int webViewIndex(WebView *webView) const; - -protected: - void mouseDoubleClickEvent(QMouseEvent *event); - void contextMenuEvent(QContextMenuEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - - -public slots: - void loadUrlInCurrentTab(const KUrl &url); - WebView *newTab(bool makeCurrent = true); - void cloneTab(int index = -1); - void closeTab(int index = -1); - void closeOtherTabs(int index); - void reloadTab(int index = -1); - void reloadAllTabs(); - void nextTab(); - void previousTab(); - -private slots: - void currentChanged(int index); - void aboutToShowRecentTabsMenu(); - void aboutToShowRecentTriggeredAction(QAction *action); // need QAction! - void webViewLoadStarted(); - void webViewIconChanged(); - void webViewTitleChanged(const QString &title); - void webViewUrlChanged(const QUrl &url); - void lineEditReturnPressed(); - void windowCloseRequested(); - void moveTab(int fromIndex, int toIndex); - -private: - KAction *m_recentlyClosedTabsAction; - KAction *m_newTabAction; - KAction *m_closeTabAction; - KAction *m_nextTabAction; - KAction *m_previousTabAction; - - KMenu *m_recentlyClosedTabsMenu; - static const int m_recentlyClosedTabsSize = 10; - QList m_recentlyClosedTabs; - QList m_actions; - - QCompleter *m_lineEditCompleter; - QStackedWidget *m_lineEdits; - TabBar *m_tabBar; -}; - -#endif // TABWIDGET_H - diff --git a/src/webview.cpp b/src/webview.cpp index e17a961a..96167816 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -21,10 +21,10 @@ #include "browserapplication.h" #include "mainwindow.h" +#include "mainview.h" #include "cookiejar.h" #include "downloadmanager.h" #include "networkaccessmanager.h" -#include "tabwidget.h" #include "webview.h" #include -- cgit v1.2.1