diff --git a/autotests/mainshelltest.cpp b/autotests/mainshelltest.cpp --- a/autotests/mainshelltest.cpp +++ b/autotests/mainshelltest.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,7 @@ void testFileRemembersPagePosition(); void test2FilesError_data(); void test2FilesError(); + void testMiddleButtonCloseUndo(); void testSessionRestore_data(); void testSessionRestore(); @@ -597,5 +599,28 @@ QCOMPARE( shells.size(), useTabsRestore ? numWindows : paths.size() ); } +void MainShellTest::testMiddleButtonCloseUndo() +{ + const QStringList paths = { QStringLiteral(KDESRCDIR "data/file1.pdf"), QStringLiteral(KDESRCDIR "data/file2.pdf") }; + QString serializedOptions; + serializedOptions = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); + + Okular::Settings::self()->setShellOpenFileInTabs(true); + Okular::Status status = Okular::main(paths, serializedOptions); + QCOMPARE(status, Okular::Success); + Shell *s = findShell(); + QVERIFY(s); + + QCOMPARE(s->m_tabWidget->count(), paths.size()); + // Close a tab using middle key + QWidget *firstTab = s->m_tabWidget->tabBar()->tabButton(0, QTabBar::RightSide); + QVERIFY(firstTab); + QTest::mouseClick(firstTab, Qt::MiddleButton); + QCOMPARE(s->m_tabWidget->count(), paths.size() - 1); + // Undo tab close + s->undoCloseTab(); + QCOMPARE(s->m_tabWidget->count(), paths.size()); +} + QTEST_MAIN( MainShellTest ) #include "mainshelltest.moc" diff --git a/shell/shell.h b/shell/shell.h --- a/shell/shell.h +++ b/shell/shell.h @@ -21,6 +21,7 @@ #include #include #include +#include #include // krazy:exclude=includes @@ -126,6 +127,7 @@ void closeTab( int tab ); void activateNextTab(); void activatePrevTab(); + void undoCloseTab(); void moveTabData( int from, int to ); void slotFitWindowToPage( const QSize& pageViewSize, const QSize& pageSize ); @@ -170,8 +172,10 @@ bool closeEnabled; }; QList m_tabs; + QList m_closedTabUrls; QAction* m_nextTabAction; QAction* m_prevTabAction; + QAction* m_undoCloseTab; #ifndef Q_OS_WIN KActivities::ResourceInstance* m_activityResource; diff --git a/shell/shell.cpp b/shell/shell.cpp --- a/shell/shell.cpp +++ b/shell/shell.cpp @@ -171,6 +171,18 @@ dEvent->setAccepted(true); return true; } + + // Handle middle button click events on the tab bar + if (obj == m_tabWidget && event->type() == QEvent::MouseButtonRelease) { + QMouseEvent* mEvent = static_cast(event); + if (mEvent->button() == Qt::MiddleButton) { + int tabIndex = m_tabWidget->tabBar()->tabAt(mEvent->pos()); + if (tabIndex != -1) { + closeTab(tabIndex); + return true; + } + } + } return false; } @@ -362,6 +374,13 @@ actionCollection()->setDefaultShortcuts(m_prevTabAction, KStandardShortcut::tabPrev()); m_prevTabAction->setEnabled( false ); connect( m_prevTabAction, &QAction::triggered, this, &Shell::activatePrevTab ); + + m_undoCloseTab = actionCollection()->addAction(QStringLiteral("undo-close-tab")); + m_undoCloseTab->setText( i18n("Undo close tab") ); + actionCollection()->setDefaultShortcut(m_undoCloseTab, QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_T)); + m_undoCloseTab->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo"))); + m_undoCloseTab->setEnabled( false ); + connect( m_undoCloseTab, &QAction::triggered, this, &Shell::undoCloseTab ); } void Shell::saveProperties(KConfigGroup &group) @@ -628,6 +647,7 @@ void Shell::closeTab( int tab ) { KParts::ReadWritePart* const part = m_tabs[tab].part; + QUrl url = part->url(); if( part->closeUrl() && m_tabs.count() > 1 ) { if( part->factory() ) @@ -636,6 +656,8 @@ part->deleteLater(); m_tabs.removeAt( tab ); m_tabWidget->removeTab( tab ); + m_undoCloseTab->setEnabled( true ); + m_closedTabUrls.append( url ); if( m_tabWidget->count() == 1 ) { @@ -751,6 +773,23 @@ setActiveTab( prevTab ); } +void Shell::undoCloseTab() +{ + if ( m_closedTabUrls.isEmpty() ) + { + return; + } + + const QUrl lastTabUrl = m_closedTabUrls.takeLast(); + + if ( m_closedTabUrls.isEmpty() ) + { + m_undoCloseTab->setEnabled(false); + } + + openUrl(lastTabUrl); +} + void Shell::setTabIcon( const QMimeType& mimeType ) { int i = findTabIndex( sender() ); diff --git a/shell/shell.rc b/shell/shell.rc --- a/shell/shell.rc +++ b/shell/shell.rc @@ -1,10 +1,11 @@ - + +