From b0fb590ebdad6f90f204c1482806a9da38b08598 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Wed, 2 Jul 2014 15:30:37 +0200 Subject: Implemented DolphinTabPage class to encapsulate the split view handling from DolphinMainWindow. The signal activeViewUrlChanged in DolphinTabPage is currently unused, but we need it later when we implement the tab widget and tab bar. DolphinTabPage has saveState/restoreState which are using a QByteArray instead of the KConfigGroup to be more generic. REVIEW: 118964 --- src/dolphinmainwindow.h | 60 +++++++++---------------------------------------- 1 file changed, 10 insertions(+), 50 deletions(-) (limited to 'src/dolphinmainwindow.h') diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index acf60a4f6..7c3bff47f 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -40,6 +40,7 @@ class DolphinApplication; class DolphinSettingsDialog; class DolphinViewContainer; class DolphinRemoteEncoding; +class DolphinTabPage; class KAction; class KFileItem; class KFileItemList; @@ -88,13 +89,6 @@ public: */ void openFiles(const QList& files); - /** - * Returns true, if the main window contains two instances - * of a view container. The active view constainer can be - * accessed by DolphinMainWindow::activeViewContainer(). - */ - bool isSplit() const; - /** * Returns the 'Create New...' sub menu which also can be shared * with other menus (e. g. a context menu). @@ -353,15 +347,16 @@ private slots: void openNewTab(); /** - * Opens a new tab in the background showing the URL \a url. + * Opens a new tab in the background showing the URL \a primaryUrl and the + * optional URL \a secondaryUrl. */ - void openNewTab(const KUrl& url); + void openNewTab(const KUrl& primaryUrl, const KUrl& secondaryUrl = KUrl()); /** - * Opens a new tab showing the URL \a url and activates - * the tab. + * Opens a new tab showing the URL \a primaryUrl and the optional URL + * \a secondaryUrl and activates the tab. */ - void openNewActivatedTab(const KUrl& url); + void openNewActivatedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl = KUrl()); void activateNextTab(); @@ -377,9 +372,6 @@ private slots: */ void openInNewWindow(); - /** Toggles the active view if two views are shown within the main window. */ - void toggleActiveView(); - /** * Indicates in the statusbar that the execution of the command \a command * has been finished. @@ -474,11 +466,7 @@ private slots: */ void slotPlaceActivated(const KUrl& url); - /** - * Is called when the user wants to reopen a previously closed \a tab from - * the recent tabs menu. - */ - void restoreClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl); + void activeViewChanged(); private: /** @@ -489,11 +477,6 @@ private: */ void setActiveViewContainer(DolphinViewContainer* view); - /** - * Creates a view container and does a default initialization. - */ - DolphinViewContainer* createViewContainer(const KUrl& url, QWidget* parent); - void setupActions(); void setupDockWidgets(); void updateEditActions(); @@ -529,16 +512,8 @@ private: /** Returns the name of the tab for the URL \a url. */ QString tabName(const KUrl& url) const; - bool isKompareInstalled() const; - void createSecondaryView(int tabIndex); - - /** - * Helper method for saveProperties() and readProperties(): Returns - * the property string for a tab with the index \a tabIndex and - * the property \a property. - */ - QString tabProperty(const QString& property, int tabIndex) const; + bool isKompareInstalled() const; /** * Sets the window caption to url.fileName() if this is non-empty, @@ -579,18 +554,8 @@ private: QVBoxLayout* m_centralWidgetLayout; int m_id; - // Members for the tab-handling: - struct ViewTab - { - ViewTab() : isPrimaryViewActive(true), wasActive(false), primaryView(0), secondaryView(0), splitter(0) {} - bool isPrimaryViewActive; - bool wasActive; - DolphinViewContainer* primaryView; - DolphinViewContainer* secondaryView; - QSplitter* splitter; - }; int m_tabIndex; - QList m_viewTab; + QList m_viewTab; DolphinViewActionHandler* m_actionHandler; DolphinRemoteEncoding* m_remoteEncoding; @@ -608,11 +573,6 @@ inline DolphinViewContainer* DolphinMainWindow::activeViewContainer() const return m_activeViewContainer; } -inline bool DolphinMainWindow::isSplit() const -{ - return m_viewTab[m_tabIndex].secondaryView != 0; -} - inline KNewFileMenu* DolphinMainWindow::newFileMenu() const { return m_newFileMenu; -- cgit v1.3 From 1dfafcb176797e5075d0043e70ad07bde8bcc372 Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Tue, 8 Jul 2014 19:38:18 +0200 Subject: Implemented (QTabBar based) DolphinTabBar class to encapsulate the tab bar handling from DolphinMainWindow. REVIEW: 118969 --- src/CMakeLists.txt | 1 + src/dolphinmainwindow.cpp | 83 +++++++--------------- src/dolphinmainwindow.h | 22 +++--- src/dolphintabbar.cpp | 174 ++++++++++++++++++++++++++++++++++++++++++++++ src/dolphintabbar.h | 65 +++++++++++++++++ 5 files changed, 277 insertions(+), 68 deletions(-) create mode 100644 src/dolphintabbar.cpp create mode 100644 src/dolphintabbar.h (limited to 'src/dolphinmainwindow.h') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 518c8b7d2..7b0210aef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -171,6 +171,7 @@ set(dolphin_SRCS dolphinmainwindow.cpp dolphinviewcontainer.cpp dolphincontextmenu.cpp + dolphintabbar.cpp dolphinrecenttabsmenu.cpp dolphintabpage.cpp filterbar/filterbar.cpp diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 0c48928bf..41bd626ee 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -26,6 +26,7 @@ #include "dolphincontextmenu.h" #include "dolphinnewfilemenu.h" #include "dolphinrecenttabsmenu.h" +#include "dolphintabbar.h" #include "dolphinviewcontainer.h" #include "dolphintabpage.h" #include "panels/folders/folderspanel.h" @@ -75,7 +76,6 @@ #include #include #include -#include #include #include #include @@ -144,25 +144,19 @@ DolphinMainWindow::DolphinMainWindow() : connect(this, SIGNAL(urlChanged(KUrl)), m_remoteEncoding, SLOT(slotAboutToOpenUrl())); - m_tabBar = new KTabBar(this); - m_tabBar->setMovable(true); - m_tabBar->setTabsClosable(true); + m_tabBar = new DolphinTabBar(this); connect(m_tabBar, SIGNAL(currentChanged(int)), this, SLOT(setActiveTab(int))); connect(m_tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); - connect(m_tabBar, SIGNAL(contextMenu(int,QPoint)), - this, SLOT(openTabContextMenu(int,QPoint))); - connect(m_tabBar, SIGNAL(newTabRequest()), - this, SLOT(openNewTab())); - connect(m_tabBar, SIGNAL(testCanDecode(const QDragMoveEvent*,bool&)), - this, SLOT(slotTestCanDecode(const QDragMoveEvent*,bool&))); - connect(m_tabBar, SIGNAL(mouseMiddleClick(int)), - this, SLOT(closeTab(int))); + connect(m_tabBar, SIGNAL(openNewActivatedTab(int)), + this, SLOT(openNewActivatedTab(int))); connect(m_tabBar, SIGNAL(tabMoved(int,int)), this, SLOT(slotTabMoved(int,int))); - connect(m_tabBar, SIGNAL(receivedDropEvent(int,QDropEvent*)), + connect(m_tabBar, SIGNAL(tabDropEvent(int,QDropEvent*)), this, SLOT(tabDropEvent(int,QDropEvent*))); + connect(m_tabBar, SIGNAL(tabDetachRequested(int)), + this, SLOT(detachTab(int))); m_tabBar->blockSignals(true); // signals get unblocked after at least 2 tabs are open m_tabBar->hide(); @@ -443,6 +437,13 @@ void DolphinMainWindow::openNewActivatedTab(const KUrl& primaryUrl, const KUrl& setActiveTab(m_viewTab.count() - 1); } +void DolphinMainWindow::openNewActivatedTab(int index) +{ + Q_ASSERT(index >= 0); + const DolphinTabPage* tabPage = m_viewTab.at(index); + openNewActivatedTab(tabPage->activeViewContainer()->url()); +} + void DolphinMainWindow::activateNextTab() { if (m_viewTab.count() >= 2) { @@ -981,50 +982,23 @@ void DolphinMainWindow::closeTab(int index) } } -void DolphinMainWindow::openTabContextMenu(int index, const QPoint& pos) +void DolphinMainWindow::detachTab(int index) { - KMenu menu(this); - - QAction* newTabAction = menu.addAction(KIcon("tab-new"), i18nc("@action:inmenu", "New Tab")); - newTabAction->setShortcut(actionCollection()->action("new_tab")->shortcut()); - - QAction* detachTabAction = menu.addAction(KIcon("tab-detach"), i18nc("@action:inmenu", "Detach Tab")); - - QAction* closeOtherTabsAction = menu.addAction(KIcon("tab-close-other"), i18nc("@action:inmenu", "Close Other Tabs")); - - QAction* closeTabAction = menu.addAction(KIcon("tab-close"), i18nc("@action:inmenu", "Close Tab")); - closeTabAction->setShortcut(actionCollection()->action("close_tab")->shortcut()); - QAction* selectedAction = menu.exec(pos); - if (selectedAction == newTabAction) { - const KUrl url = m_viewTab.at(index)->activeViewContainer()->url(); - openNewTab(url); - m_tabBar->setCurrentIndex(m_viewTab.count() - 1); - } else if (selectedAction == detachTabAction) { - const QString separator(QLatin1Char(' ')); - QString command = QLatin1String("dolphin"); + Q_ASSERT(index >= 0); - const DolphinTabPage* tabPage = m_viewTab.at(index); + const QString separator(QLatin1Char(' ')); + QString command = QLatin1String("dolphin"); - command += separator + tabPage->primaryViewContainer()->url().url(); - if (tabPage->splitViewEnabled()) { - command += separator + tabPage->secondaryViewContainer()->url().url(); - command += separator + QLatin1String("-split"); - } + const DolphinTabPage* tabPage = m_viewTab.at(index); + command += separator + tabPage->primaryViewContainer()->url().url(); + if (tabPage->splitViewEnabled()) { + command += separator + tabPage->secondaryViewContainer()->url().url(); + command += separator + QLatin1String("-split"); + } - KRun::runCommand(command, this); + KRun::runCommand(command, this); - closeTab(index); - } else if (selectedAction == closeOtherTabsAction) { - const int count = m_tabBar->count(); - for (int i = 0; i < index; ++i) { - closeTab(0); - } - for (int i = index + 1; i < count; ++i) { - closeTab(1); - } - } else if (selectedAction == closeTabAction) { - closeTab(index); - } + closeTab(index); } void DolphinMainWindow::slotTabMoved(int from, int to) @@ -1033,11 +1007,6 @@ void DolphinMainWindow::slotTabMoved(int from, int to) m_tabIndex = m_tabBar->currentIndex(); } -void DolphinMainWindow::slotTestCanDecode(const QDragMoveEvent* event, bool& canDecode) -{ - canDecode = KUrl::List::canDecode(event->mimeData()); -} - void DolphinMainWindow::handleUrl(const KUrl& url) { delete m_lastHandleUrlStatJob; diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 7c3bff47f..9c7f185bc 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -38,6 +38,7 @@ typedef KIO::FileUndoManager::CommandType CommandType; class DolphinViewActionHandler; class DolphinApplication; class DolphinSettingsDialog; +class DolphinTabBar; class DolphinViewContainer; class DolphinRemoteEncoding; class DolphinTabPage; @@ -46,7 +47,6 @@ class KFileItem; class KFileItemList; class KJob; class KNewFileMenu; -class KTabBar; class KUrl; class QSplitter; class QToolButton; @@ -358,6 +358,12 @@ private slots: */ void openNewActivatedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl = KUrl()); + /** + * Opens a new tab showing the url from tab at the given \a index and + * activates the tab. + */ + void openNewActivatedTab(int index); + void activateNextTab(); void activatePrevTab(); @@ -393,10 +399,10 @@ private slots: void closeTab(int index); /** - * Opens a context menu for the tab with the index \a index - * on the position \a pos. + * Opens the tab with the index \a index in a new Dolphin instance and closes + * this tab. */ - void openTabContextMenu(int index, const QPoint& pos); + void detachTab(int index); /** * Is connected to the QTabBar signal tabMoved(int from, int to). @@ -405,12 +411,6 @@ private slots: */ void slotTabMoved(int from, int to); - /** - * Is connected to the KTabBar signal testCanDecode() and adjusts - * the output parameter \a accept. - */ - void slotTestCanDecode(const QDragMoveEvent* event, bool& accept); - /** * If the URL can be listed, open it in the current view, otherwise * run it through KRun. @@ -549,7 +549,7 @@ private: }; KNewFileMenu* m_newFileMenu; - KTabBar* m_tabBar; + DolphinTabBar* m_tabBar; DolphinViewContainer* m_activeViewContainer; QVBoxLayout* m_centralWidgetLayout; int m_id; diff --git a/src/dolphintabbar.cpp b/src/dolphintabbar.cpp new file mode 100644 index 000000000..78bd5edcb --- /dev/null +++ b/src/dolphintabbar.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + * Copyright (C) 2014 by Emmanuel Pescosta * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include "dolphintabbar.h" + +#include +#include +#include +#include +#include +#include + +DolphinTabBar::DolphinTabBar(QWidget* parent) : + QTabBar(parent), + m_autoActivationIndex(-1) +{ + setAcceptDrops(true); + setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); + setMovable(true); + setTabsClosable(true); + + m_autoActivationTimer = new QTimer(this); + m_autoActivationTimer->setSingleShot(true); + m_autoActivationTimer->setInterval(800); + connect(m_autoActivationTimer, SIGNAL(timeout()), + this, SLOT(slotAutoActivationTimeout())); +} + +void DolphinTabBar::dragEnterEvent(QDragEnterEvent* event) +{ + const QMimeData* mimeData = event->mimeData(); + const int index = tabAt(event->pos()); + + if (KUrl::List::canDecode(mimeData)) { + event->acceptProposedAction(); + updateAutoActivationTimer(index); + } + + QTabBar::dragEnterEvent(event); +} + +void DolphinTabBar::dragLeaveEvent(QDragLeaveEvent* event) +{ + updateAutoActivationTimer(-1); + + QTabBar::dragLeaveEvent(event); +} + +void DolphinTabBar::dragMoveEvent(QDragMoveEvent* event) +{ + const QMimeData* mimeData = event->mimeData(); + const int index = tabAt(event->pos()); + + if (KUrl::List::canDecode(mimeData)) { + updateAutoActivationTimer(index); + } + + QTabBar::dragMoveEvent(event); +} + +void DolphinTabBar::dropEvent(QDropEvent* event) +{ + // Disable the auto activation timer + updateAutoActivationTimer(-1); + + const QMimeData* mimeData = event->mimeData(); + const int index = tabAt(event->pos()); + + if (index >= 0 && KUrl::List::canDecode(mimeData)) { + emit tabDropEvent(index, event); + } + + QTabBar::dropEvent(event); +} + +void DolphinTabBar::mousePressEvent(QMouseEvent* event) +{ + const int index = tabAt(event->pos()); + + if (index >= 0 && event->button() == Qt::MiddleButton) { + // Mouse middle click on a tab closes this tab. + emit tabCloseRequested(index); + return; + } + + QTabBar::mousePressEvent(event); +} + +void DolphinTabBar::mouseDoubleClickEvent(QMouseEvent* event) +{ + const int index = tabAt(event->pos()); + + if (index < 0) { + // Double click on the empty tabbar area opens a new activated tab + // with the url from the current tab. + emit openNewActivatedTab(currentIndex()); + return; + } + + QTabBar::mouseDoubleClickEvent(event); +} + +void DolphinTabBar::contextMenuEvent(QContextMenuEvent* event) +{ + const int index = tabAt(event->pos()); + + if (index >= 0) { + // Tab context menu + KMenu menu(this); + + QAction* newTabAction = menu.addAction(KIcon("tab-new"), i18nc("@action:inmenu", "New Tab")); + QAction* detachTabAction = menu.addAction(KIcon("tab-detach"), i18nc("@action:inmenu", "Detach Tab")); + QAction* closeOtherTabsAction = menu.addAction(KIcon("tab-close-other"), i18nc("@action:inmenu", "Close Other Tabs")); + QAction* closeTabAction = menu.addAction(KIcon("tab-close"), i18nc("@action:inmenu", "Close Tab")); + + QAction* selectedAction = menu.exec(event->globalPos()); + if (selectedAction == newTabAction) { + emit openNewActivatedTab(index); + } else if (selectedAction == detachTabAction) { + emit tabDetachRequested(index); + } else if (selectedAction == closeOtherTabsAction) { + const int tabCount = count(); + for (int i = 0; i < index; i++) { + emit tabCloseRequested(0); + } + for (int i = index + 1; i < tabCount; i++) { + emit tabCloseRequested(1); + } + } else if (selectedAction == closeTabAction) { + emit tabCloseRequested(index); + } + + return; + } + + QTabBar::contextMenuEvent(event); +} + +void DolphinTabBar::slotAutoActivationTimeout() +{ + if (m_autoActivationIndex >= 0) { + setCurrentIndex(m_autoActivationIndex); + updateAutoActivationTimer(-1); + } +} + +void DolphinTabBar::updateAutoActivationTimer(const int index) +{ + if (m_autoActivationIndex != index) { + m_autoActivationIndex = index; + + if (m_autoActivationIndex < 0) { + m_autoActivationTimer->stop(); + } else { + m_autoActivationTimer->start(); + } + } +} diff --git a/src/dolphintabbar.h b/src/dolphintabbar.h new file mode 100644 index 000000000..d2b2e9e57 --- /dev/null +++ b/src/dolphintabbar.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2014 by Emmanuel Pescosta * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) 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. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef DOLPHIN_TAB_BAR_H +#define DOLPHIN_TAB_BAR_H + +#include + +class DolphinTabBar : public QTabBar +{ + Q_OBJECT + +public: + explicit DolphinTabBar(QWidget* parent); + +signals: + void openNewActivatedTab(int index); + void tabDropEvent(int index, QDropEvent* event); + void tabDetachRequested(int index); + +protected: + virtual void dragEnterEvent(QDragEnterEvent* event); + virtual void dragLeaveEvent(QDragLeaveEvent* event); + virtual void dragMoveEvent(QDragMoveEvent* event); + virtual void dropEvent(QDropEvent* event); + virtual void mousePressEvent(QMouseEvent* event); + virtual void mouseDoubleClickEvent(QMouseEvent* event); + + /** + * Opens a context menu for the tab on the \a event position. + */ + virtual void contextMenuEvent(QContextMenuEvent* event); + +private slots: + void slotAutoActivationTimeout(); + +private: + /** + * If \a index is a valid index (>= 0), store the index and start the timer + * (if the interval >= 0 ms). If the index is not valid (< 0), stop the timer. + */ + void updateAutoActivationTimer(const int index); + +private: + QTimer* m_autoActivationTimer; + int m_autoActivationIndex; +}; + +#endif // DOLPHIN_TAB_BAR_H -- cgit v1.3