From 98907c205591551decd6b68b1868bf873dc70090 Mon Sep 17 00:00:00 2001 From: nowrep Date: Tue, 1 Apr 2014 18:47:19 +0200 Subject: [PATCH] [WebTab] Reworked tab attaching/detaching. This also fixes crash on detach --- src/lib/app/browserwindow.cpp | 2 +- src/lib/history/history.cpp | 3 +- src/lib/navigation/navigationbar.cpp | 2 +- src/lib/tabwidget/combotabbar.cpp | 11 ++-- src/lib/tabwidget/combotabbar.h | 2 + src/lib/tabwidget/tabbar.cpp | 12 ++-- src/lib/tabwidget/tabbar.h | 1 + src/lib/tabwidget/tabstackedwidget.cpp | 43 +++++++------- src/lib/tabwidget/tabstackedwidget.h | 3 +- src/lib/tabwidget/tabwidget.cpp | 26 +++------ src/lib/webkit/webview.cpp | 7 ++- src/lib/webkit/webview.h | 4 +- src/lib/webtab/tabbedwebview.cpp | 32 +++-------- src/lib/webtab/tabbedwebview.h | 8 +-- src/lib/webtab/webtab.cpp | 79 ++++++++++++++++++-------- src/lib/webtab/webtab.h | 11 ++-- 16 files changed, 129 insertions(+), 117 deletions(-) diff --git a/src/lib/app/browserwindow.cpp b/src/lib/app/browserwindow.cpp index 017ff32ee..3fc092355 100644 --- a/src/lib/app/browserwindow.cpp +++ b/src/lib/app/browserwindow.cpp @@ -836,7 +836,7 @@ void BrowserWindow::currentTabChanged() return; } - setWindowTitle(tr("%1 - QupZilla").arg(view->title())); + setWindowTitle(tr("%1 - QupZilla").arg(view->webTab()->title())); m_ipLabel->setText(view->getIp()); view->setFocus(); diff --git a/src/lib/history/history.cpp b/src/lib/history/history.cpp index 4e833b226..6c687de70 100644 --- a/src/lib/history/history.cpp +++ b/src/lib/history/history.cpp @@ -74,8 +74,9 @@ void History::addHistoryEntry(const QUrl &url, QString title) url.isEmpty()) { return; } + if (title.isEmpty()) { - title = tr("No Named Page"); + title = tr("Empty Page"); } QSqlQuery query; diff --git a/src/lib/navigation/navigationbar.cpp b/src/lib/navigation/navigationbar.cpp index 034ff1f8e..dcf77a9fa 100644 --- a/src/lib/navigation/navigationbar.cpp +++ b/src/lib/navigation/navigationbar.cpp @@ -391,7 +391,7 @@ QString NavigationBar::titleForUrl(QString title, const QUrl &url) } if (title.isEmpty()) { - return tr("No Named Page"); + return tr("Empty Page"); } return QzTools::truncatedText(title, 40); diff --git a/src/lib/tabwidget/combotabbar.cpp b/src/lib/tabwidget/combotabbar.cpp index 62e1e5fad..9c7b342ac 100644 --- a/src/lib/tabwidget/combotabbar.cpp +++ b/src/lib/tabwidget/combotabbar.cpp @@ -43,6 +43,7 @@ ComboTabBar::ComboTabBar(QWidget* parent) , m_mainBarOverFlowed(false) , m_lastAppliedOverflow(false) , m_usesScrollButtons(false) + , m_blockCurrentChangedSignal(false) { m_mainTabBar = new TabBarHelper(this); m_pinnedTabBar = new TabBarHelper(this); @@ -259,6 +260,10 @@ void ComboTabBar::setCurrentIndex(int index) void ComboTabBar::slotCurrentChanged(int index) { + if (m_blockCurrentChangedSignal) { + return; + } + if (sender() == m_pinnedTabBar) { if (index == -1 && m_mainTabBar->count() > 0) { m_mainTabBar->setActiveTabBar(true); @@ -949,14 +954,12 @@ void TabBarHelper::removeTab(int index) // Removing tab in inactive tabbar will change current index and thus // changing active tabbar, which is really not wanted. if (!m_activeTabBar) { - blockSignals(true); + m_comboTabBar->m_blockCurrentChangedSignal = true; } QTabBar::removeTab(index); - if (!m_activeTabBar) { - blockSignals(false); - } + m_comboTabBar->m_blockCurrentChangedSignal = false; } void TabBarHelper::setScrollArea(QScrollArea* scrollArea) diff --git a/src/lib/tabwidget/combotabbar.h b/src/lib/tabwidget/combotabbar.h index 9e6a14a3c..457db0a18 100644 --- a/src/lib/tabwidget/combotabbar.h +++ b/src/lib/tabwidget/combotabbar.h @@ -195,8 +195,10 @@ private: bool m_lastAppliedOverflow; bool m_usesScrollButtons; bool m_bluredBackground; + bool m_blockCurrentChangedSignal; friend class TabBarHelper; + friend class TabStackedWidget; }; class QUPZILLA_EXPORT TabBarHelper : public QTabBar diff --git a/src/lib/tabwidget/tabbar.cpp b/src/lib/tabwidget/tabbar.cpp index 5cd48031c..52f80fbf6 100644 --- a/src/lib/tabwidget/tabbar.cpp +++ b/src/lib/tabwidget/tabbar.cpp @@ -110,6 +110,11 @@ void TabBar::loadSettings() setUpLayout(); } +TabWidget* TabBar::tabWidget() const +{ + return m_tabWidget; +} + void TabBar::setVisible(bool visible) { if (visible && m_window->isFullScreen()) { @@ -466,11 +471,10 @@ void TabBar::bookmarkTab() void TabBar::pinTab() { WebTab* webTab = qobject_cast(m_tabWidget->widget(m_clickedTab)); - if (!webTab) { - return; - } - webTab->pinTab(m_clickedTab); + if (webTab) { + webTab->togglePinned(); + } } void TabBar::overrideTabTextColor(int index, QColor color) diff --git a/src/lib/tabwidget/tabbar.h b/src/lib/tabwidget/tabbar.h index 543bc498c..5180bdabb 100644 --- a/src/lib/tabwidget/tabbar.h +++ b/src/lib/tabwidget/tabbar.h @@ -37,6 +37,7 @@ public: void loadSettings(); + TabWidget* tabWidget() const; void setVisible(bool visible); void overrideTabTextColor(int index, QColor color); diff --git a/src/lib/tabwidget/tabstackedwidget.cpp b/src/lib/tabwidget/tabstackedwidget.cpp index 95c374d22..ab675f320 100644 --- a/src/lib/tabwidget/tabstackedwidget.cpp +++ b/src/lib/tabwidget/tabstackedwidget.cpp @@ -81,11 +81,6 @@ void TabStackedWidget::setTabBar(ComboTabBar* tb) setUpLayout(); } -void TabStackedWidget::tabWasRemoved(int index) -{ - m_tabBar->removeTab(index); -} - void TabStackedWidget::tabWasMoved(int from, int to) { m_stack->blockSignals(true); @@ -96,6 +91,11 @@ void TabStackedWidget::tabWasMoved(int from, int to) m_stack->blockSignals(false); } +void TabStackedWidget::tabWasRemoved(int index) +{ + m_tabBar->removeTab(index); +} + void TabStackedWidget::setUpLayout() { if (!m_tabBar->isVisible()) { @@ -234,33 +234,28 @@ void TabStackedWidget::setTabToolTip(int index, const QString &tip) int TabStackedWidget::pinUnPinTab(int index, const QString &title) { int newIndex = -1; - if (QWidget* w = m_stack->widget(index)) { + QWidget* widget = m_stack->widget(index); + QWidget* currentWidget = m_stack->currentWidget(); + + m_tabBar->m_blockCurrentChangedSignal = true; + + if (widget) { + bool makePinned = index >= m_tabBar->pinnedTabsCount(); QWidget* button = m_tabBar->tabButton(index, m_tabBar->iconButtonPosition()); - m_tabBar->setUpdatesEnabled(false); m_tabBar->setTabButton(index, m_tabBar->iconButtonPosition(), 0); - if (index < m_tabBar->pinnedTabsCount()) { - // Unpin - // fix selecting and loading a tab after removing the tab that contains 'w' - // by blocking ComboTabBar::currentChanged() - m_tabBar->blockSignals(true); - m_stack->removeWidget(w); - m_tabBar->blockSignals(false); - newIndex = insertTab(m_tabBar->pinnedTabsCount(), w, title, false); - } - else { - // Pin // same as above - m_tabBar->blockSignals(true); - m_stack->removeWidget(w); - m_tabBar->blockSignals(false); - newIndex = insertTab(0, w, QString(), true); - } + m_stack->removeWidget(widget); + newIndex = insertTab(makePinned ? 0 : m_tabBar->pinnedTabsCount(), widget, title, makePinned); m_tabBar->setTabButton(newIndex, m_tabBar->iconButtonPosition(), button); - m_tabBar->setUpdatesEnabled(true); } + m_tabBar->m_blockCurrentChangedSignal = false; + + // Restore current index + setCurrentWidget(currentWidget); + return newIndex; } diff --git a/src/lib/tabwidget/tabstackedwidget.h b/src/lib/tabwidget/tabstackedwidget.h index b79c92df4..9081a011b 100644 --- a/src/lib/tabwidget/tabstackedwidget.h +++ b/src/lib/tabwidget/tabstackedwidget.h @@ -54,7 +54,6 @@ public: void removeTab(int index); - int currentIndex() const; QWidget* currentWidget() const; QWidget* widget(int index) const; @@ -71,9 +70,9 @@ public slots: void setUpLayout(); private slots: - void tabWasRemoved(int index); void showTab(int index); void tabWasMoved(int from, int to); + void tabWasRemoved(int index); protected: bool eventFilter(QObject* obj, QEvent* event); diff --git a/src/lib/tabwidget/tabwidget.cpp b/src/lib/tabwidget/tabwidget.cpp index 0b17ba77c..b66619db2 100644 --- a/src/lib/tabwidget/tabwidget.cpp +++ b/src/lib/tabwidget/tabwidget.cpp @@ -272,20 +272,9 @@ void TabWidget::aboutToShowTabsMenu() QAction* action = new QAction(this); action->setIcon(i == currentIndex() ? QIcon(QSL(":/icons/menu/dot.png")) : tab->icon()); - if (tab->title().isEmpty()) { - if (tab->isLoading()) { - action->setText(tr("Loading...")); - action->setIcon(QIcon(":/icons/other/progress.gif")); - } - else { - action->setText(tr("No Named Page")); - } - } - else { - QString title = tab->title(); - title.replace(QLatin1Char('&'), QLatin1String("&&")); - action->setText(QzTools::truncatedText(title, 40)); - } + QString title = tab->title(); + title.replace(QLatin1Char('&'), QLatin1String("&&")); + action->setText(QzTools::truncatedText(title, 40)); action->setData(QVariant::fromValue(qobject_cast(tab))); connect(action, SIGNAL(triggered()), this, SLOT(actionChangeIndex())); @@ -373,10 +362,10 @@ int TabWidget::addView(const LoadRequest &req, const QString &title, const Qz::N m_locationBars->addWidget(webTab->locationBar()); int index = insertTab(position == -1 ? count() : position, webTab, QString(), pinned); - webTab->setTabbed(index); + webTab->attach(m_window, m_tabBar); if (!title.isEmpty()) { - webTab->setTabTitle(title); + m_tabBar->setTabText(index, title); } if (openFlags & Qz::NT_SelectedTab) { @@ -437,7 +426,7 @@ int TabWidget::addView(WebTab* tab) { m_locationBars->addWidget(tab->locationBar()); int index = addTab(tab, QString()); - tab->setTabbed(index); + tab->attach(m_window, m_tabBar); connect(tab->webView(), SIGNAL(wantsCloseTab(int)), this, SLOT(closeTab(int))); connect(tab->webView(), SIGNAL(changed()), this, SIGNAL(changed())); @@ -658,8 +647,9 @@ void TabWidget::detachTab(int index) disconnect(tab->webView(), SIGNAL(changed()), this, SIGNAL(changed())); disconnect(tab->webView(), SIGNAL(ipChanged(QString)), m_window->ipLabel(), SLOT(setText(QString))); + tab->detach(); + BrowserWindow* window = mApp->createWindow(Qz::BW_NewWindow); - tab->moveToWindow(window); window->setStartTab(tab); if (m_isClosingToLastTabIndex && m_lastTabIndex < count() && index == currentIndex()) { diff --git a/src/lib/webkit/webview.cpp b/src/lib/webkit/webview.cpp index 44360e3c9..9b9f5412c 100644 --- a/src/lib/webkit/webview.cpp +++ b/src/lib/webkit/webview.cpp @@ -122,12 +122,17 @@ QString WebView::title() const } if (title.isEmpty() || title == QLatin1String("about:blank")) { - return tr("No Named Page"); + return tr("Empty Page"); } return title; } +bool WebView::isTitleEmpty() const +{ + return QWebView::title().isEmpty(); +} + QUrl WebView::url() const { QUrl returnUrl = page()->url(); diff --git a/src/lib/webkit/webview.h b/src/lib/webkit/webview.h index 0ea017702..c366d231e 100644 --- a/src/lib/webkit/webview.h +++ b/src/lib/webkit/webview.h @@ -35,9 +35,11 @@ public: ~WebView(); QIcon icon() const; - QString title() const; QUrl url() const; + QString title() const; + bool isTitleEmpty() const; + WebPage* page() const; void setPage(QWebPage* page); diff --git a/src/lib/webtab/tabbedwebview.cpp b/src/lib/webtab/tabbedwebview.cpp index 68078bef7..029be1277 100644 --- a/src/lib/webtab/tabbedwebview.cpp +++ b/src/lib/webtab/tabbedwebview.cpp @@ -47,12 +47,9 @@ TabbedWebView::TabbedWebView(BrowserWindow* window, WebTab* webTab) m_menu->setCloseOnMiddleClick(true); connect(this, SIGNAL(loadStarted()), this, SLOT(slotLoadStarted())); - connect(this, SIGNAL(loadProgress(int)), this, SLOT(loadProgress(int))); + connect(this, SIGNAL(loadProgress(int)), this, SLOT(slotLoadProgress(int))); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinished())); - connect(this, SIGNAL(urlChanged(QUrl)), this, SLOT(urlChanged(QUrl))); - connect(this, SIGNAL(titleChanged(QString)), this, SLOT(titleChanged())); - connect(this, SIGNAL(statusBarMessage(QString)), m_window->statusBar(), SLOT(showMessage(QString))); } @@ -101,7 +98,7 @@ void TabbedWebView::urlChanged(const QUrl &url) } } -void TabbedWebView::loadProgress(int prog) +void TabbedWebView::slotLoadProgress(int prog) { Q_UNUSED(prog) @@ -123,10 +120,6 @@ void TabbedWebView::userLoadAction(const LoadRequest &req) void TabbedWebView::slotLoadStarted() { - if (title().isNull()) { - m_webTab->setTabTitle(tr("Loading...")); - } - m_currentIp.clear(); } @@ -152,15 +145,6 @@ void TabbedWebView::setIp(const QHostInfo &info) } } -void TabbedWebView::titleChanged() -{ - if (m_webTab->isCurrentTab()) { - m_window->setWindowTitle(tr("%1 - QupZilla").arg(title())); - } - - m_webTab->setTabTitle(title()); -} - void TabbedWebView::linkHovered(const QString &link, const QString &title, const QString &content) { Q_UNUSED(title) @@ -182,7 +166,7 @@ void TabbedWebView::linkHovered(const QString &link, const QString &title, const int TabbedWebView::tabIndex() const { - return tabWidget()->indexOf(m_webTab); + return m_webTab->tabIndex(); } BrowserWindow* TabbedWebView::mainWindow() const @@ -192,11 +176,11 @@ BrowserWindow* TabbedWebView::mainWindow() const void TabbedWebView::moveToWindow(BrowserWindow* window) { - disconnect(this, SIGNAL(statusBarMessage(QString)), m_window->statusBar(), SLOT(showMessage(QString))); - - m_window = window; - - connect(this, SIGNAL(statusBarMessage(QString)), m_window->statusBar(), SLOT(showMessage(QString))); + if (m_window != window) { + disconnect(this, SIGNAL(statusBarMessage(QString)), m_window->statusBar(), SLOT(showMessage(QString))); + m_window = window; + connect(this, SIGNAL(statusBarMessage(QString)), m_window->statusBar(), SLOT(showMessage(QString))); + } } QWidget* TabbedWebView::overlayWidget() diff --git a/src/lib/webtab/tabbedwebview.h b/src/lib/webtab/tabbedwebview.h index 39f94bed7..605842d22 100644 --- a/src/lib/webtab/tabbedwebview.h +++ b/src/lib/webtab/tabbedwebview.h @@ -56,21 +56,17 @@ signals: void changed(); public slots: - void titleChanged(); void setAsCurrentTab(); - - void slotLoadStarted(); - void loadProgress(int prog); - void userLoadAction(const LoadRequest &req); void closeView(); void openNewTab(); void loadInNewTab(const LoadRequest &req, Qz::NewTabPositionFlags position); - private slots: + void slotLoadStarted(); void slotLoadFinished(); + void slotLoadProgress(int prog); void urlChanged(const QUrl &url); void linkHovered(const QString &link, const QString &title, const QString &content); void setIp(const QHostInfo &info); diff --git a/src/lib/webtab/webtab.cpp b/src/lib/webtab/webtab.cpp index b142f1b55..0ac078f09 100644 --- a/src/lib/webtab/webtab.cpp +++ b/src/lib/webtab/webtab.cpp @@ -89,7 +89,7 @@ WebTab::WebTab(BrowserWindow* window) : QWidget() , m_window(window) , m_inspector(0) - , m_tabBar(window->tabWidget()->getTabBar()) + , m_tabBar(0) , m_isPinned(false) { setObjectName(QSL("webtab")); @@ -118,6 +118,8 @@ WebTab::WebTab(BrowserWindow* window) setLayout(m_layout); connect(m_webView, SIGNAL(showNotification(QWidget*)), this, SLOT(showNotification(QWidget*))); + connect(m_webView, SIGNAL(loadStarted()), this, SLOT(loadStarted())); + connect(m_webView, SIGNAL(titleChanged(QString)), this, SLOT(titleChanged(QString))); } TabbedWebView* WebTab::webView() const @@ -171,24 +173,26 @@ QWebHistory* WebTab::history() const return m_webView->history(); } -void WebTab::moveToWindow(BrowserWindow* window) +void WebTab::detach() +{ + // Remove icon from tab + m_tabBar->setTabButton(tabIndex(), m_tabBar->iconButtonPosition(), 0); + + m_window = 0; + m_tabBar = 0; + + setParent(0); + m_locationBar->setParent(this); +} + +void WebTab::attach(BrowserWindow* window, TabBar* tabBar) { m_window = window; + m_tabBar = tabBar; + m_webView->moveToWindow(m_window); - - m_tabBar->setTabButton(tabIndex(), m_tabBar->iconButtonPosition(), 0); - m_tabIcon->setParent(0); -} - -void WebTab::setTabbed(int index) -{ - m_tabBar->setTabButton(index, m_tabBar->iconButtonPosition(), m_tabIcon); - m_tabBar->setTabText(index, title()); -} - -void WebTab::setTabTitle(const QString &title) -{ - m_tabBar->setTabText(tabIndex(), title); + m_tabBar->setTabButton(tabIndex(), m_tabBar->iconButtonPosition(), m_tabIcon); + m_tabBar->setTabText(tabIndex(), title()); } void WebTab::setHistoryData(const QByteArray &data) @@ -253,6 +257,8 @@ bool WebTab::isRestored() const void WebTab::restoreTab(const WebTab::SavedTab &tab) { + Q_ASSERT(m_tabBar); + if (qzSettings->loadTabsOnActivation) { m_savedTab = tab; int index = tabIndex(); @@ -294,13 +300,13 @@ void WebTab::p_restoreTab(const WebTab::SavedTab &tab) QPixmap WebTab::renderTabPreview() { - TabbedWebView* currentWebView = m_window->weView(); WebPage* page = m_webView->page(); const QSize oldSize = page->viewportSize(); const QPoint originalScrollPosition = page->mainFrame()->scrollPosition(); // Hack to ensure rendering the same preview before and after the page was shown for the first time // This can occur eg. with opening background tabs + TabbedWebView* currentWebView = m_window ? m_window->weView() : 0; if (currentWebView) { page->setViewportSize(currentWebView->size()); } @@ -342,8 +348,30 @@ void WebTab::showNotification(QWidget* notif) notif->show(); } +void WebTab::loadStarted() +{ + if (m_tabBar && m_webView->isTitleEmpty()) { + m_tabBar->setTabText(tabIndex(), tr("Loading...")); + } +} + +void WebTab::titleChanged(const QString &title) +{ + if (!m_tabBar || !m_window || title.isEmpty()) { + return; + } + + if (isCurrentTab()) { + m_window->setWindowTitle(tr("%1 - QupZilla").arg(title)); + } + + m_tabBar->setTabText(tabIndex(), title); +} + void WebTab::slotRestore() { + Q_ASSERT(m_tabBar); + p_restoreTab(m_savedTab); m_savedTab.clear(); @@ -363,24 +391,25 @@ void WebTab::showEvent(QShowEvent* event) QTimer::singleShot(0, this, SLOT(slotRestore())); } } - } bool WebTab::isCurrentTab() const { - return tabIndex() == m_tabBar->currentIndex(); + return m_tabBar && tabIndex() == m_tabBar->currentIndex(); } int WebTab::tabIndex() const { - return m_webView->tabIndex(); + Q_ASSERT(m_tabBar); + + return m_tabBar->tabWidget()->indexOf(const_cast(this)); } -void WebTab::pinTab(int index) +void WebTab::togglePinned() { - m_isPinned = !m_isPinned; + Q_ASSERT(m_tabBar); + Q_ASSERT(m_window); - index = m_window->tabWidget()->pinUnPinTab(index, m_webView->title()); - m_tabBar->setTabText(index, m_webView->title()); - m_tabBar->setCurrentIndex(index); + m_isPinned = !m_isPinned; + m_window->tabWidget()->pinUnPinTab(tabIndex(), title()); } diff --git a/src/lib/webtab/webtab.h b/src/lib/webtab/webtab.h index ca20f5e46..c88ce3e53 100644 --- a/src/lib/webtab/webtab.h +++ b/src/lib/webtab/webtab.h @@ -66,9 +66,8 @@ public: QIcon icon() const; QWebHistory* history() const; - void moveToWindow(BrowserWindow* window); - void setTabbed(int index); - void setTabTitle(const QString &title); + void detach(); + void attach(BrowserWindow* window, TabBar* tabBar); void setHistoryData(const QByteArray &data); QByteArray historyData() const; @@ -79,12 +78,11 @@ public: bool isPinned() const; void setPinned(bool state); + void togglePinned(); int tabIndex() const; - void pinTab(int index); bool isCurrentTab() const; - void showWebInspector(); bool isRestored() const; @@ -96,6 +94,9 @@ public: private slots: void showNotification(QWidget* notif); + void loadStarted(); + void titleChanged(const QString &title); + void slotRestore(); private: