diff --git a/src/resources/icons/corner_tablist.svg b/src/resources/icons/corner_tablist.svg new file mode 100644 index 00000000..d001b26e --- /dev/null +++ b/src/resources/icons/corner_tablist.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp index d9e1e83c..52aab5d1 100644 --- a/src/veditwindow.cpp +++ b/src/veditwindow.cpp @@ -46,8 +46,17 @@ void VEditWindow::setupCornerWidget() rightMenu->addAction(splitAct); rightMenu->addAction(removeSplitAct); rightBtn->setMenu(rightMenu); - setCornerWidget(rightBtn, Qt::TopRightCorner); + + // Left corner button + tabListAct = new QActionGroup(this); + connect(tabListAct, &QActionGroup::triggered, + this, &VEditWindow::tabListJump); + leftBtn = new QPushButton(QIcon(":/resources/icons/corner_tablist.svg"), + "", this); + QMenu *leftMenu = new QMenu(this); + leftBtn->setMenu(leftMenu); + setCornerWidget(leftBtn, Qt::TopLeftCorner); } void VEditWindow::splitWindow() @@ -124,6 +133,8 @@ void VEditWindow::closeFile(const QString ¬ebook, const QString &relativePath Q_ASSERT(editor); removeTab(idx); delete editor; + + updateTabListMenu(); } bool VEditWindow::closeAllFiles() @@ -159,7 +170,9 @@ int VEditWindow::openFileInTab(const QString ¬ebook, const QString &relativeP tabJson["notebook"] = notebook; tabJson["relative_path"] = relativePath; tabJson["modifiable"] = modifiable; - return appendTabWithData(editor, tabJson); + int idx = appendTabWithData(editor, tabJson); + updateTabListMenu(); + return idx; } int VEditWindow::findTabByFile(const QString ¬ebook, const QString &relativePath) const @@ -186,6 +199,7 @@ bool VEditWindow::handleTabCloseRequest(int index) removeTab(index); delete editor; } + updateTabListMenu(); noticeTabStatus(currentIndex()); // User clicks the close button. We should make this window // to be current window. @@ -306,3 +320,39 @@ void VEditWindow::contextMenuRequested(QPoint pos) menu.addAction(removeSplitAct); menu.exec(this->mapToGlobal(pos)); } + +void VEditWindow::tabListJump(QAction *action) +{ + if (!action) { + return; + } + + QJsonObject tabJson = action->data().toJsonObject(); + int idx = findTabByFile(tabJson["notebook"].toString(), + tabJson["relative_path"].toString()); + Q_ASSERT(idx >= 0); + setCurrentIndex(idx); + noticeTabStatus(idx); +} + +void VEditWindow::updateTabListMenu() +{ + // Re-generate the tab list menu + QMenu *menu = leftBtn->menu(); + QList actions = menu->actions(); + int nrActions = actions.size(); + for (int i = 0; i < nrActions; ++i) { + QAction *tmpAct = actions.at(i); + menu->removeAction(tmpAct); + tabListAct->removeAction(tmpAct); + delete tmpAct; + } + + QTabBar *tabbar = tabBar(); + int nrTab = tabbar->count(); + for (int i = 0; i < nrTab; ++i) { + QAction *action = new QAction(tabbar->tabText(i), tabListAct); + action->setData(tabbar->tabData(i)); + menu->addAction(action); + } +} diff --git a/src/veditwindow.h b/src/veditwindow.h index 2d3ecdf8..78ac9371 100644 --- a/src/veditwindow.h +++ b/src/veditwindow.h @@ -11,6 +11,7 @@ class VNote; class QPushButton; +class QActionGroup; class VEditWindow : public QTabWidget { @@ -52,6 +53,7 @@ private slots: void removeSplit(); void handleTabbarClicked(int index); void contextMenuRequested(QPoint pos); + void tabListJump(QAction *action); private: void setupCornerWidget(); @@ -62,14 +64,18 @@ private: inline QString getFileName(const QString &relativePath) const; inline VEditTab *getTab(int tabIndex) const; void noticeTabStatus(int index); + void updateTabListMenu(); VNote *vnote; // Button in the right corner QPushButton *rightBtn; + // Button in the left corner + QPushButton *leftBtn; // Actions QAction *splitAct; QAction *removeSplitAct; + QActionGroup *tabListAct; }; inline QString VEditWindow::getFileName(const QString &path) const diff --git a/src/vnote.qrc b/src/vnote.qrc index 4a40ded6..f57e401b 100644 --- a/src/vnote.qrc +++ b/src/vnote.qrc @@ -56,5 +56,6 @@ resources/icons/split_window.svg resources/icons/corner_menu.svg resources/icons/remove_split.svg + resources/icons/corner_tablist.svg