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.cpp | 439 ++++++++++++---------------------------------- 1 file changed, 111 insertions(+), 328 deletions(-) (limited to 'src/dolphinmainwindow.cpp') diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index c60951d2c..d9fe6458d 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -27,6 +27,7 @@ #include "dolphinnewfilemenu.h" #include "dolphinrecenttabsmenu.h" #include "dolphinviewcontainer.h" +#include "dolphintabpage.h" #include "panels/folders/folderspanel.h" #include "panels/places/placespanel.h" #include "panels/information/informationpanel.h" @@ -86,7 +87,6 @@ #include #include #include -#include namespace { // Used for GeneralSettings::version() to determine whether @@ -100,7 +100,7 @@ DolphinMainWindow::DolphinMainWindow() : m_tabBar(0), m_activeViewContainer(0), m_centralWidgetLayout(0), - m_tabIndex(0), + m_tabIndex(-1), m_viewTab(), m_actionHandler(0), m_remoteEncoding(0), @@ -111,10 +111,6 @@ DolphinMainWindow::DolphinMainWindow() : { setObjectName("Dolphin#"); - m_viewTab.append(ViewTab()); - ViewTab& viewTab = m_viewTab[m_tabIndex]; - viewTab.wasActive = true; // The first opened tab is automatically active - connect(&DolphinNewFileMenuObserver::instance(), SIGNAL(errorMessage(QString)), this, SLOT(showErrorMessage(QString))); @@ -138,25 +134,12 @@ DolphinMainWindow::DolphinMainWindow() : setAcceptDrops(true); - viewTab.splitter = new QSplitter(this); - viewTab.splitter->setChildrenCollapsible(false); - setupActions(); - const KUrl homeUrl(generalSettings->homeUrl()); - setUrlAsCaption(homeUrl); m_actionHandler = new DolphinViewActionHandler(actionCollection(), this); connect(m_actionHandler, SIGNAL(actionBeingHandled()), SLOT(clearStatusBar())); connect(m_actionHandler, SIGNAL(createDirectory()), SLOT(createDirectory())); - viewTab.primaryView = createViewContainer(homeUrl, viewTab.splitter); - - m_activeViewContainer = viewTab.primaryView; - connectViewSignals(m_activeViewContainer); - DolphinView* view = m_activeViewContainer->view(); - m_activeViewContainer->show(); - m_actionHandler->setCurrentView(view); - m_remoteEncoding = new DolphinRemoteEncoding(this, m_actionHandler); connect(this, SIGNAL(urlChanged(KUrl)), m_remoteEncoding, SLOT(slotAboutToOpenUrl())); @@ -182,17 +165,16 @@ DolphinMainWindow::DolphinMainWindow() : this, SLOT(tabDropEvent(int,QDropEvent*))); m_tabBar->blockSignals(true); // signals get unblocked after at least 2 tabs are open + m_tabBar->hide(); QWidget* centralWidget = new QWidget(this); m_centralWidgetLayout = new QVBoxLayout(centralWidget); m_centralWidgetLayout->setSpacing(0); m_centralWidgetLayout->setMargin(0); m_centralWidgetLayout->addWidget(m_tabBar); - m_centralWidgetLayout->addWidget(viewTab.splitter, 1); setCentralWidget(centralWidget); setupDockWidgets(); - emit urlChanged(homeUrl); setupGUI(Keys | Save | Create | ToolBar); stateChanged("new_file"); @@ -201,14 +183,6 @@ DolphinMainWindow::DolphinMainWindow() : connect(clipboard, SIGNAL(dataChanged()), this, SLOT(updatePasteAction())); - if (generalSettings->splitView()) { - toggleSplitView(); - } - updateEditActions(); - updatePasteAction(); - updateViewActions(); - updateGoActions(); - QAction* showFilterBarAction = actionCollection()->action("show_filter_bar"); showFilterBarAction->setChecked(generalSettings->filterBar()); @@ -224,6 +198,9 @@ DolphinMainWindow::DolphinMainWindow() : if (!showMenu) { createControlButton(); } + + const KUrl homeUrl(generalSettings->homeUrl()); + openNewActivatedTab(homeUrl); } DolphinMainWindow::~DolphinMainWindow() @@ -249,13 +226,12 @@ void DolphinMainWindow::openDirectories(const QList& dirs) // always show two directories within one tab. QList::const_iterator it = dirs.constBegin(); while (it != dirs.constEnd()) { - openNewTab(*it); - ++it; - + const KUrl& primaryUrl = *(it++); if (hasSplitView && (it != dirs.constEnd())) { - const int tabIndex = m_viewTab.count() - 1; - m_viewTab[tabIndex].secondaryView->setUrl(*it); - ++it; + const KUrl& secondaryUrl = *(it++); + openNewTab(primaryUrl, secondaryUrl); + } else { + openNewTab(primaryUrl); } } @@ -287,14 +263,9 @@ void DolphinMainWindow::openFiles(const QList& files) // Select the files. Although the files can be split between several // tabs, there is no need to split 'files' accordingly, as // the DolphinView will just ignore invalid selections. - const int tabCount = m_viewTab.count(); - for (int i = 0; i < tabCount; ++i) { - m_viewTab[i].primaryView->view()->markUrlsAsSelected(files); - m_viewTab[i].primaryView->view()->markUrlAsCurrent(files.at(0)); - if (m_viewTab[i].secondaryView) { - m_viewTab[i].secondaryView->view()->markUrlsAsSelected(files); - m_viewTab[i].secondaryView->view()->markUrlAsCurrent(files.at(0)); - } + foreach (DolphinTabPage* tabPage, m_viewTab) { + tabPage->markUrlsAsSelected(files); + tabPage->markUrlAsCurrent(files.first()); } } @@ -349,11 +320,11 @@ void DolphinMainWindow::changeUrl(const KUrl& url) updateViewActions(); updateGoActions(); setUrlAsCaption(url); - if (m_viewTab.count() > 1) { - m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(m_activeViewContainer->url()))); - } + const QString iconName = KMimeType::iconNameForUrl(url); m_tabBar->setTabIcon(m_tabIndex, KIcon(iconName)); + m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(view->url()))); + emit urlChanged(url); } } @@ -376,11 +347,7 @@ void DolphinMainWindow::slotSelectionChanged(const KFileItemList& selection) { updateEditActions(); - Q_ASSERT(m_viewTab[m_tabIndex].primaryView); - int selectedUrlsCount = m_viewTab[m_tabIndex].primaryView->view()->selectedItemsCount(); - if (m_viewTab[m_tabIndex].secondaryView) { - selectedUrlsCount += m_viewTab[m_tabIndex].secondaryView->view()->selectedItemsCount(); - } + const int selectedUrlsCount = m_viewTab.at(m_tabIndex)->selectedItemsCount(); QAction* compareFilesAction = actionCollection()->action("compare_files"); if (selectedUrlsCount == 2) { @@ -445,41 +412,41 @@ void DolphinMainWindow::openNewTab() } } -void DolphinMainWindow::openNewTab(const KUrl& url) +void DolphinMainWindow::openNewTab(const KUrl& primaryUrl, const KUrl& secondaryUrl) { QWidget* focusWidget = QApplication::focusWidget(); - if (m_viewTab.count() == 1) { - // Only one view is open currently and hence no tab is shown at - // all. Before creating a tab for 'url', provide a tab for the current URL. - const KUrl currentUrl = m_activeViewContainer->url(); - m_tabBar->addTab(KIcon(KMimeType::iconNameForUrl(currentUrl)), - squeezedText(tabName(currentUrl))); - m_tabBar->blockSignals(false); - } + DolphinTabPage* tabPage = new DolphinTabPage(primaryUrl, secondaryUrl, this); + m_viewTab.append(tabPage); - m_tabBar->addTab(KIcon(KMimeType::iconNameForUrl(url)), - squeezedText(tabName(url))); + connect(tabPage, SIGNAL(activeViewChanged()), + this, SLOT(activeViewChanged())); - ViewTab viewTab; - viewTab.splitter = new QSplitter(this); - viewTab.splitter->setChildrenCollapsible(false); - viewTab.primaryView = createViewContainer(url, viewTab.splitter); - viewTab.primaryView->setActive(false); - connectViewSignals(viewTab.primaryView); + // The places-selector from the URL navigator should only be shown + // if the places dock is invisible + QDockWidget* placesDock = findChild("placesDock"); + const bool placesSelectorVisible = !placesDock || !placesDock->isVisible(); + tabPage->setPlacesSelectorVisible(placesSelectorVisible); + + DolphinViewContainer* primaryContainer = tabPage->primaryViewContainer(); + connectViewSignals(primaryContainer); + + if (tabPage->splitViewEnabled()) { + DolphinViewContainer* secondaryContainer = tabPage->secondaryViewContainer(); + connectViewSignals(secondaryContainer); + } - m_viewTab.append(viewTab); + tabPage->hide(); - actionCollection()->action("close_tab")->setEnabled(true); - actionCollection()->action("activate_prev_tab")->setEnabled(true); - actionCollection()->action("activate_next_tab")->setEnabled(true); + m_tabBar->addTab(KIcon(KMimeType::iconNameForUrl(primaryUrl)), + squeezedText(tabName(primaryUrl))); - // Provide a split view, if the startup settings are set this way - if (GeneralSettings::splitView()) { - const int newTabIndex = m_viewTab.count() - 1; - createSecondaryView(newTabIndex); - m_viewTab[newTabIndex].secondaryView->setActive(true); - m_viewTab[newTabIndex].isPrimaryViewActive = false; + if (m_viewTab.count() > 1) { + actionCollection()->action("close_tab")->setEnabled(true); + actionCollection()->action("activate_prev_tab")->setEnabled(true); + actionCollection()->action("activate_next_tab")->setEnabled(true); + m_tabBar->show(); + m_tabBar->blockSignals(false); } if (focusWidget) { @@ -489,17 +456,17 @@ void DolphinMainWindow::openNewTab(const KUrl& url) } } -void DolphinMainWindow::openNewActivatedTab(const KUrl& url) +void DolphinMainWindow::openNewActivatedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl) { - openNewTab(url); - m_tabBar->setCurrentIndex(m_viewTab.count() - 1); + openNewTab(primaryUrl, secondaryUrl); + setActiveTab(m_viewTab.count() - 1); } void DolphinMainWindow::activateNextTab() { if (m_viewTab.count() >= 2) { const int tabIndex = (m_tabBar->currentIndex() + 1) % m_tabBar->count(); - m_tabBar->setCurrentIndex(tabIndex); + setActiveTab(tabIndex); } } @@ -510,7 +477,7 @@ void DolphinMainWindow::activatePrevTab() if (tabIndex == -1) { tabIndex = m_tabBar->count() - 1; } - m_tabBar->setCurrentIndex(tabIndex); + setActiveTab(tabIndex); } } @@ -546,21 +513,6 @@ void DolphinMainWindow::openInNewWindow() } } -void DolphinMainWindow::toggleActiveView() -{ - if (!m_viewTab[m_tabIndex].secondaryView) { - // only one view is available - return; - } - - Q_ASSERT(m_activeViewContainer); - Q_ASSERT(m_viewTab[m_tabIndex].primaryView); - - DolphinViewContainer* left = m_viewTab[m_tabIndex].primaryView; - DolphinViewContainer* right = m_viewTab[m_tabIndex].secondaryView; - setActiveViewContainer(m_activeViewContainer == right ? left : right); -} - void DolphinMainWindow::showEvent(QShowEvent* event) { KXmlGuiWindow::showEvent(event); @@ -634,17 +586,8 @@ void DolphinMainWindow::saveProperties(KConfigGroup& group) group.writeEntry("Active Tab Index", m_tabBar->currentIndex()); for (int i = 0; i < tabCount; ++i) { - const DolphinViewContainer* cont = m_viewTab[i].primaryView; - group.writeEntry(tabProperty("Primary URL", i), cont->url().url()); - group.writeEntry(tabProperty("Primary Editable", i), - cont->urlNavigator()->isUrlEditable()); - - cont = m_viewTab[i].secondaryView; - if (cont) { - group.writeEntry(tabProperty("Secondary URL", i), cont->url().url()); - group.writeEntry(tabProperty("Secondary Editable", i), - cont->urlNavigator()->isUrlEditable()); - } + const DolphinTabPage* tabPage = m_viewTab.at(i); + group.writeEntry("Tab " % QString::number(i), tabPage->saveState()); } } @@ -652,38 +595,9 @@ void DolphinMainWindow::readProperties(const KConfigGroup& group) { const int tabCount = group.readEntry("Tab Count", 1); for (int i = 0; i < tabCount; ++i) { - DolphinViewContainer* cont = m_viewTab[i].primaryView; - - cont->setUrl(group.readEntry(tabProperty("Primary URL", i))); - const bool editable = group.readEntry(tabProperty("Primary Editable", i), false); - cont->urlNavigator()->setUrlEditable(editable); - - cont = m_viewTab[i].secondaryView; - const QString secondaryUrl = group.readEntry(tabProperty("Secondary URL", i)); - if (!secondaryUrl.isEmpty()) { - if (!cont) { - // a secondary view should be shown, but no one is available - // currently -> create a new view - toggleSplitView(); - cont = m_viewTab[i].secondaryView; - Q_ASSERT(cont); - } - - // The right view must be activated before the URL is set. Changing - // the URL in the right view will emit the right URL navigator's - // urlChanged(KUrl) signal, which is connected to the changeUrl(KUrl) - // slot. That slot will change the URL in the left view if it is still - // active. See https://bugs.kde.org/show_bug.cgi?id=330047. - setActiveViewContainer(cont); - - cont->setUrl(secondaryUrl); - const bool editable = group.readEntry(tabProperty("Secondary Editable", i), false); - cont->urlNavigator()->setUrlEditable(editable); - } else if (cont) { - // no secondary view should be shown, but the default setting shows - // one already -> close the view - toggleSplitView(); - } + const QByteArray state = group.readEntry("Tab " % QString::number(i), QByteArray()); + DolphinTabPage* tabPage = m_viewTab.at(i); + tabPage->restoreState(state); // openNewTab() needs to be called only tabCount - 1 times if (i != tabCount - 1) { @@ -796,28 +710,11 @@ void DolphinMainWindow::invertSelection() void DolphinMainWindow::toggleSplitView() { - if (!m_viewTab[m_tabIndex].secondaryView) { - createSecondaryView(m_tabIndex); - setActiveViewContainer(m_viewTab[m_tabIndex].secondaryView); - } else if (m_activeViewContainer == m_viewTab[m_tabIndex].secondaryView) { - // remove secondary view - m_viewTab[m_tabIndex].secondaryView->close(); - m_viewTab[m_tabIndex].secondaryView->deleteLater(); - m_viewTab[m_tabIndex].secondaryView = 0; - - setActiveViewContainer(m_viewTab[m_tabIndex].primaryView); - } else { - // The primary view is active and should be closed. Hence from a users point of view - // the content of the secondary view should be moved to the primary view. - // From an implementation point of view it is more efficient to close - // the primary view and exchange the internal pointers afterwards. + DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex); + tabPage->setSplitViewEnabled(!tabPage->splitViewEnabled()); - m_viewTab[m_tabIndex].primaryView->close(); - m_viewTab[m_tabIndex].primaryView->deleteLater(); - m_viewTab[m_tabIndex].primaryView = m_viewTab[m_tabIndex].secondaryView; - m_viewTab[m_tabIndex].secondaryView = 0; - - setActiveViewContainer(m_viewTab[m_tabIndex].primaryView); + if (tabPage->splitViewEnabled()) { + connectViewSignals(tabPage->secondaryViewContainer()); } updateViewActions(); @@ -884,14 +781,8 @@ void DolphinMainWindow::togglePanelLockState() void DolphinMainWindow::slotPlacesPanelVisibilityChanged(bool visible) { - const int tabCount = m_viewTab.count(); - for (int i = 0; i < tabCount; ++i) { - ViewTab& tab = m_viewTab[i]; - Q_ASSERT(tab.primaryView); - tab.primaryView->urlNavigator()->setPlacesSelectorVisible(!visible); - if (tab.secondaryView) { - tab.secondaryView->urlNavigator()->setPlacesSelectorVisible(!visible); - } + foreach (DolphinTabPage* tabPage, m_viewTab) { + tabPage->setPlacesSelectorVisible(visible); } } @@ -960,15 +851,7 @@ void DolphinMainWindow::goHome(Qt::MouseButtons buttons) void DolphinMainWindow::compareFiles() { - const DolphinViewContainer* primaryViewContainer = m_viewTab[m_tabIndex].primaryView; - Q_ASSERT(primaryViewContainer); - KFileItemList items = primaryViewContainer->view()->selectedItems(); - - const DolphinViewContainer* secondaryViewContainer = m_viewTab[m_tabIndex].secondaryView; - if (secondaryViewContainer) { - items.append(secondaryViewContainer->view()->selectedItems()); - } - + const KFileItemList items = m_viewTab.at(m_tabIndex)->selectedItems(); if (items.count() != 2) { // The action is disabled in this case, but it could have been triggered // via D-Bus, see https://bugs.kde.org/show_bug.cgi?id=325517 @@ -1038,42 +921,23 @@ void DolphinMainWindow::setActiveTab(int index) return; } + m_tabBar->setCurrentIndex(index); + // hide current tab content - ViewTab& hiddenTab = m_viewTab[m_tabIndex]; - hiddenTab.isPrimaryViewActive = hiddenTab.primaryView->isActive(); - hiddenTab.primaryView->setActive(false); - if (hiddenTab.secondaryView) { - hiddenTab.secondaryView->setActive(false); + if (m_tabIndex >= 0) { + DolphinTabPage* hiddenTabPage = m_viewTab.at(m_tabIndex); + hiddenTabPage->hide(); + m_centralWidgetLayout->removeWidget(hiddenTabPage); } - QSplitter* splitter = m_viewTab[m_tabIndex].splitter; - splitter->hide(); - m_centralWidgetLayout->removeWidget(splitter); // show active tab content m_tabIndex = index; - ViewTab& viewTab = m_viewTab[index]; - m_centralWidgetLayout->addWidget(viewTab.splitter, 1); - viewTab.primaryView->show(); - if (viewTab.secondaryView) { - viewTab.secondaryView->show(); - } - viewTab.splitter->show(); - - if (!viewTab.wasActive) { - viewTab.wasActive = true; - - // If the tab has not been activated yet the size of the KItemListView is - // undefined and results in an unwanted animation. To prevent this a - // reloading of the directory gets triggered. - viewTab.primaryView->view()->reload(); - if (viewTab.secondaryView) { - viewTab.secondaryView->view()->reload(); - } - } + DolphinTabPage* tabPage = m_viewTab.at(index); + m_centralWidgetLayout->addWidget(tabPage, 1); + tabPage->show(); - setActiveViewContainer(viewTab.isPrimaryViewActive ? viewTab.primaryView : - viewTab.secondaryView); + setActiveViewContainer(tabPage->activeViewContainer()); } void DolphinMainWindow::closeTab() @@ -1096,17 +960,18 @@ void DolphinMainWindow::closeTab(int index) m_tabBar->setCurrentIndex((index > 0) ? index - 1 : 1); } - const KUrl primaryUrl(m_viewTab[index].primaryView->url()); - const KUrl secondaryUrl(m_viewTab[index].secondaryView ? m_viewTab[index].secondaryView->url() : KUrl()); - emit rememberClosedTab(primaryUrl, secondaryUrl); + DolphinTabPage* tabPage = m_viewTab.at(index); - // delete tab - m_viewTab[index].primaryView->deleteLater(); - if (m_viewTab[index].secondaryView) { - m_viewTab[index].secondaryView->deleteLater(); + if (tabPage->splitViewEnabled()) { + emit rememberClosedTab(tabPage->primaryViewContainer()->url(), + tabPage->secondaryViewContainer()->url()); + } else { + emit rememberClosedTab(tabPage->primaryViewContainer()->url(), KUrl()); } - m_viewTab[index].splitter->deleteLater(); - m_viewTab.erase(m_viewTab.begin() + index); + + // delete tab + m_viewTab.removeAt(index); + tabPage->deleteLater(); m_tabBar->blockSignals(true); m_tabBar->removeTab(index); @@ -1118,11 +983,11 @@ void DolphinMainWindow::closeTab(int index) // if only one tab is left, also remove the tab entry so that // closing the last tab is not possible - if (m_viewTab.count() == 1) { - m_tabBar->removeTab(0); + if (m_viewTab.count() < 2) { actionCollection()->action("close_tab")->setEnabled(false); actionCollection()->action("activate_prev_tab")->setEnabled(false); actionCollection()->action("activate_next_tab")->setEnabled(false); + m_tabBar->hide(); } else { m_tabBar->blockSignals(false); } @@ -1143,22 +1008,18 @@ void DolphinMainWindow::openTabContextMenu(int index, const QPoint& pos) closeTabAction->setShortcut(actionCollection()->action("close_tab")->shortcut()); QAction* selectedAction = menu.exec(pos); if (selectedAction == newTabAction) { - const ViewTab& tab = m_viewTab[index]; - Q_ASSERT(tab.primaryView); - const KUrl url = tab.secondaryView && tab.secondaryView->isActive() ? - tab.secondaryView->url() : tab.primaryView->url(); + 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"); - const ViewTab& tab = m_viewTab[index]; - Q_ASSERT(tab.primaryView); + const DolphinTabPage* tabPage = m_viewTab.at(index); - command += separator + tab.primaryView->url().url(); - if (tab.secondaryView) { - command += separator + tab.secondaryView->url().url(); + command += separator + tabPage->primaryViewContainer()->url().url(); + if (tabPage->splitViewEnabled()) { + command += separator + tabPage->secondaryViewContainer()->url().url(); command += separator + QLatin1String("-split"); } @@ -1226,9 +1087,8 @@ void DolphinMainWindow::tabDropEvent(int tab, QDropEvent* event) { const KUrl::List urls = KUrl::List::fromMimeData(event->mimeData()); if (!urls.isEmpty() && tab != -1) { - const ViewTab& viewTab = m_viewTab[tab]; - const DolphinView* view = viewTab.isPrimaryViewActive ? viewTab.primaryView->view() - : viewTab.secondaryView->view(); + const DolphinView* view = m_viewTab.at(tab)->activeViewContainer()->view(); + QString error; DragAndDropHelper::dropUrls(view->rootItem(), view->url(), event, error); if (!error.isEmpty()) { @@ -1396,37 +1256,22 @@ void DolphinMainWindow::slotPlaceActivated(const KUrl& url) } } -void DolphinMainWindow::restoreClosedTab(const KUrl& primaryUrl, const KUrl& secondaryUrl) +void DolphinMainWindow::activeViewChanged() { - openNewActivatedTab(primaryUrl); - - if (!secondaryUrl.isEmpty() && secondaryUrl.isValid()) { - const int index = m_tabBar->currentIndex(); - createSecondaryView(index); - setActiveViewContainer(m_viewTab[index].secondaryView); - m_viewTab[index].secondaryView->setUrl(secondaryUrl); - } + const DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex); + setActiveViewContainer(tabPage->activeViewContainer()); } void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContainer) { Q_ASSERT(viewContainer); - Q_ASSERT((viewContainer == m_viewTab[m_tabIndex].primaryView) || - (viewContainer == m_viewTab[m_tabIndex].secondaryView)); + Q_ASSERT((viewContainer == m_viewTab.at(m_tabIndex)->primaryViewContainer()) || + (viewContainer == m_viewTab.at(m_tabIndex)->secondaryViewContainer())); if (m_activeViewContainer == viewContainer) { return; } - m_activeViewContainer->setActive(false); m_activeViewContainer = viewContainer; - - // Activating the view container might trigger a recursive setActiveViewContainer() call - // inside DolphinMainWindow::toggleActiveView() when having a split view. Temporary - // disconnect the activated() signal in this case: - disconnect(m_activeViewContainer->view(), SIGNAL(activated()), this, SLOT(toggleActiveView())); - m_activeViewContainer->setActive(true); - connect(m_activeViewContainer->view(), SIGNAL(activated()), this, SLOT(toggleActiveView())); - m_actionHandler->setCurrentView(viewContainer->view()); updateHistory(); @@ -1437,26 +1282,12 @@ void DolphinMainWindow::setActiveViewContainer(DolphinViewContainer* viewContain const KUrl url = m_activeViewContainer->url(); setUrlAsCaption(url); - if (m_viewTab.count() > 1) { - m_tabBar->setTabText(m_tabIndex, tabName(url)); - m_tabBar->setTabIcon(m_tabIndex, KIcon(KMimeType::iconNameForUrl(url))); - } + m_tabBar->setTabText(m_tabIndex, squeezedText(tabName(url))); + m_tabBar->setTabIcon(m_tabIndex, KIcon(KMimeType::iconNameForUrl(url))); emit urlChanged(url); } -DolphinViewContainer* DolphinMainWindow::createViewContainer(const KUrl& url, QWidget* parent) -{ - DolphinViewContainer* container = new DolphinViewContainer(url, parent); - - // The places-selector from the URL navigator should only be shown - // if the places dock is invisible - QDockWidget* placesDock = findChild("placesDock"); - container->urlNavigator()->setPlacesSelectorVisible(!placesDock || !placesDock->isVisible()); - - return container; -} - void DolphinMainWindow::setupActions() { // setup 'File' menu @@ -1524,7 +1355,6 @@ void DolphinMainWindow::setupActions() KAction* split = actionCollection()->addAction("split_view"); split->setShortcut(Qt::Key_F3); - updateSplitAction(); connect(split, SIGNAL(triggered()), this, SLOT(toggleSplitView())); KAction* reload = actionCollection()->addAction("reload"); @@ -1561,7 +1391,7 @@ void DolphinMainWindow::setupActions() connect(this, SIGNAL(rememberClosedTab(KUrl,KUrl)), recentTabsMenu, SLOT(rememberClosedTab(KUrl,KUrl))); connect(recentTabsMenu, SIGNAL(restoreClosedTab(KUrl,KUrl)), - this, SLOT(restoreClosedTab(KUrl,KUrl))); + this, SLOT(openNewActivatedTab(KUrl,KUrl))); KAction* forwardAction = KStandardAction::forward(this, SLOT(goForward()), actionCollection()); connect(forwardAction, SIGNAL(triggered(Qt::MouseButtons,Qt::KeyboardModifiers)), this, SLOT(goForward(Qt::MouseButtons))); @@ -1872,33 +1702,16 @@ bool DolphinMainWindow::addActionToMenu(QAction* action, KMenu* menu) void DolphinMainWindow::refreshViews() { - Q_ASSERT(m_viewTab[m_tabIndex].primaryView); - - // remember the current active view, as because of - // the refreshing the active view might change to - // the secondary view - DolphinViewContainer* activeViewContainer = m_activeViewContainer; - - const int tabCount = m_viewTab.count(); - for (int i = 0; i < tabCount; ++i) { - m_viewTab[i].primaryView->readSettings(); - if (m_viewTab[i].secondaryView) { - m_viewTab[i].secondaryView->readSettings(); - } + foreach (DolphinTabPage* tabPage, m_viewTab) { + tabPage->refreshViews(); } - setActiveViewContainer(activeViewContainer); - if (GeneralSettings::modifiedStartupSettings()) { // The startup settings have been changed by the user (see bug #254947). // Synchronize the split-view setting with the active view: const bool splitView = GeneralSettings::splitView(); - const ViewTab& activeTab = m_viewTab[m_tabIndex]; - const bool toggle = ( splitView && !activeTab.secondaryView) - || (!splitView && activeTab.secondaryView); - if (toggle) { - toggleSplitView(); - } + m_viewTab.at(m_tabIndex)->setSplitViewEnabled(splitView); + updateSplitAction(); } emit settingsChanged(); @@ -1916,13 +1729,11 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) connect(container, SIGNAL(writeStateChanged(bool)), this, SLOT(slotWriteStateChanged(bool))); - DolphinView* view = container->view(); + const DolphinView* view = container->view(); connect(view, SIGNAL(selectionChanged(KFileItemList)), this, SLOT(slotSelectionChanged(KFileItemList))); connect(view, SIGNAL(requestItemInfo(KFileItem)), this, SLOT(slotRequestItemInfo(KFileItem))); - connect(view, SIGNAL(activated()), - this, SLOT(toggleActiveView())); connect(view, SIGNAL(tabRequested(KUrl)), this, SLOT(openNewTab(KUrl))); connect(view, SIGNAL(requestContextMenu(QPoint,KFileItem,KUrl,QList)), @@ -1950,15 +1761,16 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container) void DolphinMainWindow::updateSplitAction() { QAction* splitAction = actionCollection()->action("split_view"); - if (m_viewTab[m_tabIndex].secondaryView) { - if (m_activeViewContainer == m_viewTab[m_tabIndex].secondaryView) { - splitAction->setText(i18nc("@action:intoolbar Close right view", "Close")); - splitAction->setToolTip(i18nc("@info", "Close right view")); - splitAction->setIcon(KIcon("view-right-close")); - } else { + const DolphinTabPage* tabPage = m_viewTab.at(m_tabIndex); + if (tabPage->splitViewEnabled()) { + if (tabPage->primaryViewActive()) { splitAction->setText(i18nc("@action:intoolbar Close left view", "Close")); splitAction->setToolTip(i18nc("@info", "Close left view")); splitAction->setIcon(KIcon("view-left-close")); + } else { + splitAction->setText(i18nc("@action:intoolbar Close right view", "Close")); + splitAction->setToolTip(i18nc("@info", "Close right view")); + splitAction->setIcon(KIcon("view-right-close")); } } else { splitAction->setText(i18nc("@action:intoolbar Split view", "Split")); @@ -1998,35 +1810,6 @@ bool DolphinMainWindow::isKompareInstalled() const return installed; } -void DolphinMainWindow::createSecondaryView(int tabIndex) -{ - ViewTab& viewTab = m_viewTab[tabIndex]; - - QSplitter* splitter = viewTab.splitter; - const int newWidth = (viewTab.primaryView->width() - splitter->handleWidth()) / 2; - - const DolphinView* view = viewTab.primaryView->view(); - // The final parent of the new view container will be set by adding it - // to the splitter. However, we must make sure that the DolphinMainWindow - // is a parent of the view container already when it is constructed - // because this enables the container's KFileItemModel to assign its - // dir lister to the right main window. The dir lister can then cache - // authentication data. - viewTab.secondaryView = createViewContainer(view->url(), this); - splitter->addWidget(viewTab.secondaryView); - splitter->setSizes(QList() << newWidth << newWidth); - - connectViewSignals(viewTab.secondaryView); - viewTab.secondaryView->setActive(false); - viewTab.secondaryView->resize(newWidth, viewTab.primaryView->height()); - viewTab.secondaryView->show(); -} - -QString DolphinMainWindow::tabProperty(const QString& property, int tabIndex) const -{ - return "Tab " + QString::number(tabIndex) + ' ' + property; -} - void DolphinMainWindow::setUrlAsCaption(const KUrl& url) { QString caption; -- cgit v1.3 From 00754dda30dc3982d3e8edc5996cdb11b62fd99d Mon Sep 17 00:00:00 2001 From: Emmanuel Pescosta Date: Tue, 8 Jul 2014 19:16:17 +0200 Subject: Avoid opening unused tabs which are closed again after startup has finished (when directory/file urls are given) Instead of always opening a new tab with the home url and closing it again when directory/file urls are passed on, we now use the given directories/files directly to open new tabs on startup. Makes the code easier and we can reuse openDirectories/openFiles in future (if needed). REVIEW: 118966 --- src/dolphinapplication.cpp | 6 +++++- src/dolphinmainwindow.cpp | 26 +++++++------------------- 2 files changed, 12 insertions(+), 20 deletions(-) (limited to 'src/dolphinmainwindow.cpp') diff --git a/src/dolphinapplication.cpp b/src/dolphinapplication.cpp index 8e83a8592..a4b105b90 100644 --- a/src/dolphinapplication.cpp +++ b/src/dolphinapplication.cpp @@ -34,7 +34,6 @@ DolphinApplication::DolphinApplication() : m_mainWindow = new DolphinMainWindow(); m_mainWindow->setAttribute(Qt::WA_DeleteOnClose); - m_mainWindow->show(); KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); @@ -71,6 +70,9 @@ DolphinApplication::DolphinApplication() : } else { m_mainWindow->openDirectories(urls); } + } else { + const KUrl homeUrl(GeneralSettings::homeUrl()); + m_mainWindow->openNewActivatedTab(homeUrl); } if (resetSplitSettings) { @@ -78,6 +80,8 @@ DolphinApplication::DolphinApplication() : } args->clear(); + + m_mainWindow->show(); } DolphinApplication::~DolphinApplication() diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index d9fe6458d..0c48928bf 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -198,9 +198,6 @@ DolphinMainWindow::DolphinMainWindow() : if (!showMenu) { createControlButton(); } - - const KUrl homeUrl(generalSettings->homeUrl()); - openNewActivatedTab(homeUrl); } DolphinMainWindow::~DolphinMainWindow() @@ -209,17 +206,6 @@ DolphinMainWindow::~DolphinMainWindow() void DolphinMainWindow::openDirectories(const QList& dirs) { - if (dirs.isEmpty()) { - return; - } - - if (dirs.count() == 1) { - m_activeViewContainer->setUrl(dirs.first()); - return; - } - - const int oldOpenTabsCount = m_viewTab.count(); - const bool hasSplitView = GeneralSettings::splitView(); // Open each directory inside a new tab. If the "split view" option has been enabled, @@ -234,11 +220,6 @@ void DolphinMainWindow::openDirectories(const QList& dirs) openNewTab(primaryUrl); } } - - // Remove the previously opened tabs - for (int i = 0; i < oldOpenTabsCount; ++i) { - closeTab(0); - } } void DolphinMainWindow::openFiles(const QList& files) @@ -516,6 +497,13 @@ void DolphinMainWindow::openInNewWindow() void DolphinMainWindow::showEvent(QShowEvent* event) { KXmlGuiWindow::showEvent(event); + + if (!m_activeViewContainer && m_viewTab.count() > 0) { + // If we have no active view container yet, we set the primary view container + // of the first tab as active view container. + setActiveTab(0); + } + if (!event->spontaneous()) { m_activeViewContainer->view()->setFocus(); } -- 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.cpp') 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