From 09a1bec4676d30eff1fe906d4d034cc2b2980c06 Mon Sep 17 00:00:00 2001 From: nowrep Date: Mon, 13 May 2013 22:01:36 +0200 Subject: [PATCH] Added option to detach tabs into own window. Closes #441 --- CHANGELOG | 1 + src/lib/app/qupzilla.cpp | 15 +++++++++++-- src/lib/app/qupzilla.h | 3 +++ src/lib/webview/tabbar.cpp | 8 ++++++- src/lib/webview/tabbar.h | 2 ++ src/lib/webview/tabwidget.cpp | 41 ++++++++++++++++++++++++++++++++++- src/lib/webview/tabwidget.h | 2 ++ src/lib/webview/webtab.cpp | 18 +++++++++++---- src/lib/webview/webtab.h | 2 ++ 9 files changed, 84 insertions(+), 8 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index baa756ddd..4f3a5567d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Version 1.5.0 * development version * added support for Proxy Auto-Config (PAC) * added option to open another private window from private window + * added option to detach tabs from window * added delete action in edit context menu on page * added possibility to remove EasyList from AdBlock * added inline domain completion to urlbar diff --git a/src/lib/app/qupzilla.cpp b/src/lib/app/qupzilla.cpp index 9de41ac65..8e5c856e9 100644 --- a/src/lib/app/qupzilla.cpp +++ b/src/lib/app/qupzilla.cpp @@ -119,6 +119,7 @@ QupZilla::QupZilla(Qz::BrowserWindow type, QUrl startUrl) , m_isStarting(false) , m_startingUrl(startUrl) , m_windowType(type) + , m_startTab(0) , m_menuBookmarksAction(0) , m_actionPrivateBrowsing(0) , m_sideBarManager(new SideBarManager(this)) @@ -152,6 +153,11 @@ QupZilla::QupZilla(Qz::BrowserWindow type, QUrl startUrl) QTimer::singleShot(0, this, SLOT(postLaunch())); } +void QupZilla::openWithTab(WebTab* tab) +{ + m_startTab = tab; +} + void QupZilla::postLaunch() { #ifdef QZ_WS_X11 @@ -214,6 +220,11 @@ void QupZilla::postLaunch() addTab = true; } + if (m_startTab) { + addTab = false; + m_tabWidget->addView(m_startTab); + } + if (addTab) { QNetworkRequest request(startUrl); request.setRawHeader("X-QupZilla-UserLoadAction", QByteArray("1")); @@ -226,7 +237,7 @@ void QupZilla::postLaunch() } if (m_tabWidget->getTabBar()->normalTabsCount() <= 0 && m_windowType != Qz::BW_OtherRestoredWindow) { - //Something went really wrong .. add one tab + // Something went really wrong .. add one tab QNetworkRequest request(m_homepage); request.setRawHeader("X-QupZilla-UserLoadAction", QByteArray("1")); @@ -236,7 +247,7 @@ void QupZilla::postLaunch() aboutToHideEditMenu(); #ifdef Q_OS_MAC - // fill menus even if user don't call them + // Fill menus even if user don't call them if (m_windowType == Qz::BW_FirstAppWindow) { aboutToShowBookmarksMenu(); aboutToShowHistoryMostMenu(); diff --git a/src/lib/app/qupzilla.h b/src/lib/app/qupzilla.h index 46acea8cf..5a94a74f4 100644 --- a/src/lib/app/qupzilla.h +++ b/src/lib/app/qupzilla.h @@ -66,6 +66,8 @@ public: explicit QupZilla(Qz::BrowserWindow type, QUrl startUrl = QUrl()); ~QupZilla(); + void openWithTab(WebTab* tab); + void loadSettings(); void saveSideBarWidth(); @@ -268,6 +270,7 @@ private: QUrl m_startingUrl; QUrl m_homepage; Qz::BrowserWindow m_windowType; + WebTab* m_startTab; QVBoxLayout* m_mainLayout; QSplitter* m_mainSplitter; diff --git a/src/lib/webview/tabbar.cpp b/src/lib/webview/tabbar.cpp index 534bb6957..07e0f852e 100644 --- a/src/lib/webview/tabbar.cpp +++ b/src/lib/webview/tabbar.cpp @@ -134,6 +134,7 @@ void TabBar::contextMenuRequested(const QPoint &position) if (!webTab) { return; } + if (p_QupZilla->weView(m_clickedTab)->isLoading()) { menu.addAction(qIconProvider->standardIcon(QStyle::SP_BrowserStop), tr("&Stop Tab"), this, SLOT(stopTab())); } @@ -142,6 +143,11 @@ void TabBar::contextMenuRequested(const QPoint &position) } menu.addAction(QIcon::fromTheme("tab-duplicate"), tr("&Duplicate Tab"), this, SLOT(duplicateTab())); + + if (count() > 1 && !webTab->isPinned()) { + menu.addAction(QIcon::fromTheme("tab-detach"), tr("D&etach Tab"), this, SLOT(detachTab())); + } + menu.addAction(webTab->isPinned() ? tr("Un&pin Tab") : tr("&Pin Tab"), this, SLOT(pinTab())); menu.addSeparator(); menu.addAction(tr("Re&load All Tabs"), m_tabWidget, SLOT(reloadAllTabs())); @@ -158,7 +164,7 @@ void TabBar::contextMenuRequested(const QPoint &position) } else { menu.addAction(tr("Reloa&d All Tabs"), m_tabWidget, SLOT(reloadAllTabs())); - menu.addAction(tr("Bookmark &All Ta&bs"), p_QupZilla, SLOT(bookmarkAllTabs())); + menu.addAction(tr("Bookmark &All Tabs"), p_QupZilla, SLOT(bookmarkAllTabs())); menu.addSeparator(); QAction* action = menu.addAction(QIcon::fromTheme("user-trash"), tr("Restore &Closed Tab"), m_tabWidget, SLOT(restoreClosedTab())); action->setEnabled(m_tabWidget->canRestoreTab()); diff --git a/src/lib/webview/tabbar.h b/src/lib/webview/tabbar.h index f04daaaa6..f06d5a783 100644 --- a/src/lib/webview/tabbar.h +++ b/src/lib/webview/tabbar.h @@ -57,6 +57,7 @@ signals: void closeAllButCurrent(int index); void closeTab(int index); void duplicateTab(int index); + void detachTab(int index); void moveAddTabButton(int posX); @@ -74,6 +75,7 @@ private slots: void closeAllButCurrent() { emit closeAllButCurrent(m_clickedTab); } void closeTab() { emit closeTab(m_clickedTab); } void duplicateTab() { emit duplicateTab(m_clickedTab); } + void detachTab() { emit detachTab(m_clickedTab); } void bookmarkTab(); void pinTab(); diff --git a/src/lib/webview/tabwidget.cpp b/src/lib/webview/tabwidget.cpp index e7d5024ef..2af27c884 100644 --- a/src/lib/webview/tabwidget.cpp +++ b/src/lib/webview/tabwidget.cpp @@ -122,6 +122,7 @@ TabWidget::TabWidget(QupZilla* mainClass, QWidget* parent) connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); connect(m_tabBar, SIGNAL(closeAllButCurrent(int)), this, SLOT(closeAllButCurrent(int))); connect(m_tabBar, SIGNAL(duplicateTab(int)), this, SLOT(duplicateTab(int))); + connect(m_tabBar, SIGNAL(detachTab(int)), this, SLOT(detachTab(int))); connect(m_tabBar, SIGNAL(tabMoved(int,int)), this, SLOT(tabMoved(int,int))); connect(m_tabBar, SIGNAL(moveAddTabButton(int)), this, SLOT(moveAddTabButton(int))); @@ -371,6 +372,22 @@ int TabWidget::addView(QNetworkRequest req, const QString &title, const Qz::NewT return index; } +int TabWidget::addView(WebTab* tab) +{ + m_locationBars->addWidget(tab->locationBar()); + tab->locationBar()->setWebView(tab->view()); + + int index = addTab(tab, QString()); + setTabText(index, tab->title()); + setTabIcon(index, tab->icon()); + + connect(tab->view(), SIGNAL(wantsCloseTab(int)), this, SLOT(closeTab(int))); + connect(tab->view(), SIGNAL(changed()), mApp, SLOT(setStateChanged())); + connect(tab->view(), SIGNAL(ipChanged(QString)), p_QupZilla->ipLabel(), SLOT(setText(QString))); + + return index; +} + void TabWidget::closeTab(int index, bool force) { if (index == -1) { @@ -410,7 +427,7 @@ void TabWidget::closeTab(int index, bool force) disconnect(webView, SIGNAL(changed()), mApp, SLOT(setStateChanged())); disconnect(webView, SIGNAL(ipChanged(QString)), p_QupZilla->ipLabel(), SLOT(setText(QString))); - //Save last tab url and history + // Save last tab url and history m_closedTabsManager->saveView(webTab, index); if (m_isClosingToLastTabIndex && m_lastTabIndex < count() && index == currentIndex()) { @@ -650,6 +667,28 @@ void TabWidget::closeAllButCurrent(int index) } } +void TabWidget::detachTab(int index) +{ + WebTab* tab = weTab(index); + + if (tab->isPinned() || count() == 1) { + return; + } + + m_locationBars->removeWidget(tab->locationBar()); + disconnect(tab->view(), SIGNAL(wantsCloseTab(int)), this, SLOT(closeTab(int))); + disconnect(tab->view(), SIGNAL(changed()), mApp, SLOT(setStateChanged())); + disconnect(tab->view(), SIGNAL(ipChanged(QString)), p_QupZilla->ipLabel(), SLOT(setText(QString))); + + QupZilla* window = mApp->makeNewWindow(Qz::BW_NewWindow); + tab->moveToWindow(window); + window->openWithTab(tab); + + if (m_isClosingToLastTabIndex && m_lastTabIndex < count() && index == currentIndex()) { + setCurrentIndex(m_lastTabIndex); + } +} + int TabWidget::duplicateTab(int index) { if (!validIndex(index)) { diff --git a/src/lib/webview/tabwidget.h b/src/lib/webview/tabwidget.h index c4c24863c..1868b767f 100644 --- a/src/lib/webview/tabwidget.h +++ b/src/lib/webview/tabwidget.h @@ -106,6 +106,7 @@ public slots: int addView(const QUrl &url, const QString &title = tr("New tab"), const Qz::NewTabPositionFlags &openFlags = Qz::NT_SelectedTab, bool selectLine = false, int position = -1); int addView(QNetworkRequest req, const QString &title = tr("New tab"), const Qz::NewTabPositionFlags &openFlags = Qz::NT_SelectedTab, bool selectLine = false, int position = -1); + int addView(WebTab* tab); int duplicateTab(int index); @@ -114,6 +115,7 @@ public slots: void reloadAllTabs(); void stopTab(int index); void closeAllButCurrent(int index); + void detachTab(int index); void restoreClosedTab(QObject* obj = 0); void restoreAllClosedTabs(); void clearClosedTabsList(); diff --git a/src/lib/webview/webtab.cpp b/src/lib/webview/webtab.cpp index cf3d56e13..70a3de118 100644 --- a/src/lib/webview/webtab.cpp +++ b/src/lib/webview/webtab.cpp @@ -180,8 +180,10 @@ void WebTab::moveToWindow(QupZilla* window) { p_QupZilla = window; + hideNavigationBar(); + showNavigationBar(p_QupZilla->navigationContainer()); + m_view->moveToWindow(p_QupZilla); - //m_view->page()->moveToWindow(p_QupZilla); } void WebTab::setHistoryData(const QByteArray &data) @@ -390,10 +392,10 @@ void WebTab::disconnectObjects() disconnect(m_view); } -WebTab::~WebTab() + +void WebTab::hideNavigationBar() { - // #838 !mApp->isClosing() fixes crash on app close with Oxygen theme - if (m_navigationContainer && qzSettings->tabsOnTop && !p_QupZilla->isClosing()) { + if (m_navigationContainer && qzSettings->tabsOnTop) { m_layout->removeWidget(m_navigationContainer); // Needed to prevent flickering when closing tabs @@ -403,6 +405,14 @@ WebTab::~WebTab() // Needed to prevent deleting m_navigationContainer in ~QWidget m_navigationContainer->setParent(p_QupZilla); } +} + +WebTab::~WebTab() +{ + // #838 !p_QupZilla->isClosing() fixes crash on app close with Oxygen theme + if (!p_QupZilla->isClosing()) { + hideNavigationBar(); + } delete m_locationBar.data(); } diff --git a/src/lib/webview/webtab.h b/src/lib/webview/webtab.h index 2ae182bf2..1d5415159 100644 --- a/src/lib/webview/webtab.h +++ b/src/lib/webview/webtab.h @@ -103,6 +103,8 @@ private slots: void slotRestore(); private: + void hideNavigationBar(); + QupZilla* p_QupZilla; TabbedWebView* m_view; QVBoxLayout* m_layout;