refine context menu of edit tab

1. "Move one split left/right" will create a new split if needed;
2. Add "Close Tab", "Close Other Tabs", and "Close Tabs To The Right" actions.
This commit is contained in:
Le Tan 2017-06-26 19:38:57 +08:00
parent 003ba7a1f2
commit bf8bf9cc4f
4 changed files with 132 additions and 21 deletions

View File

@ -70,7 +70,7 @@ void VEditArea::insertSplitWindow(int idx)
connect(win, &VEditWindow::tabStatusUpdated, connect(win, &VEditWindow::tabStatusUpdated,
this, &VEditArea::handleWindowTabStatusUpdated); this, &VEditArea::handleWindowTabStatusUpdated);
connect(win, &VEditWindow::requestSplitWindow, connect(win, &VEditWindow::requestSplitWindow,
this, &VEditArea::handleSplitWindowRequest); this, &VEditArea::splitWindow);
connect(win, &VEditWindow::requestRemoveSplit, connect(win, &VEditWindow::requestRemoveSplit,
this, &VEditArea::handleRemoveSplitRequest); this, &VEditArea::handleRemoveSplitRequest);
connect(win, &VEditWindow::getFocused, connect(win, &VEditWindow::getFocused,
@ -338,21 +338,31 @@ void VEditArea::saveAndReadFile()
win->saveAndReadFile(); win->saveAndReadFile();
} }
void VEditArea::handleSplitWindowRequest(VEditWindow *curWindow) void VEditArea::splitWindow(VEditWindow *p_window, bool p_right)
{ {
if (!curWindow) { if (!p_window) {
return; return;
} }
int idx = splitter->indexOf(curWindow);
qDebug() << "window" << idx << "requests split itself"; int idx = splitter->indexOf(p_window);
insertSplitWindow(++idx); Q_ASSERT(idx > -1);
if (p_right) {
++idx;
} else {
--idx;
if (idx < 0) {
idx = 0;
}
}
insertSplitWindow(idx);
setCurrentWindow(idx, true); setCurrentWindow(idx, true);
} }
void VEditArea::splitCurrentWindow() void VEditArea::splitCurrentWindow()
{ {
if (curWindowIndex > -1) { if (curWindowIndex > -1) {
handleSplitWindowRequest(getWindow(curWindowIndex)); splitWindow(getWindow(curWindowIndex));
} }
} }

View File

@ -87,7 +87,10 @@ public slots:
void handleNotebookUpdated(const VNotebook *p_notebook); void handleNotebookUpdated(const VNotebook *p_notebook);
private slots: private slots:
void handleSplitWindowRequest(VEditWindow *curWindow); // Split @curWindow via inserting a new window around it.
// @p_right: insert the new window on the right side.
void splitWindow(VEditWindow *p_window, bool p_right = true);
void handleRemoveSplitRequest(VEditWindow *curWindow); void handleRemoveSplitRequest(VEditWindow *curWindow);
void handleWindowFocused(); void handleWindowFocused();
void handleOutlineChanged(const VToc &toc); void handleOutlineChanged(const VToc &toc);

View File

@ -33,7 +33,7 @@ VEditWindow::VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent)
this, &VEditWindow::tabbarContextMenuRequested); this, &VEditWindow::tabbarContextMenuRequested);
connect(this, &VEditWindow::tabCloseRequested, connect(this, &VEditWindow::tabCloseRequested,
this, &VEditWindow::handleTabCloseRequest); this, &VEditWindow::closeTab);
connect(this, &VEditWindow::tabBarClicked, connect(this, &VEditWindow::tabBarClicked,
this, &VEditWindow::handleTabbarClicked); this, &VEditWindow::handleTabbarClicked);
connect(this, &VEditWindow::currentChanged, connect(this, &VEditWindow::currentChanged,
@ -61,6 +61,55 @@ void VEditWindow::initTabActions()
m_moveRightAct->setToolTip(tr("Move current tab to the split on the right")); m_moveRightAct->setToolTip(tr("Move current tab to the split on the right"));
connect(m_moveRightAct, &QAction::triggered, connect(m_moveRightAct, &QAction::triggered,
this, &VEditWindow::handleMoveRightAct); this, &VEditWindow::handleMoveRightAct);
m_closeTabAct = new QAction(tr("Close Tab"), this);
m_closeTabAct->setToolTip(tr("Close current note tab"));
connect(m_closeTabAct, &QAction::triggered,
this, [this](){
int tab = this->m_closeTabAct->data().toInt();
Q_ASSERT(tab != -1);
closeTab(tab);
});
m_closeOthersAct = new QAction(tr("Close Other Tabs"), this);
m_closeOthersAct->setToolTip(tr("Close all other note tabs"));
connect(m_closeOthersAct, &QAction::triggered,
this, [this](){
int tab = this->m_closeTabAct->data().toInt();
Q_ASSERT(tab != -1);
for (int i = tab - 1; i >= 0; --i) {
this->setCurrentIndex(i);
this->updateTabStatus(i);
if (this->closeTab(i)) {
--tab;
}
}
for (int i = tab + 1; i < this->count();) {
this->setCurrentIndex(i);
this->updateTabStatus(i);
if (!this->closeTab(i)) {
++i;
}
}
});
m_closeRightAct = new QAction(tr("Close Tabs To The Right"), this);
m_closeRightAct->setToolTip(tr("Close all the note tabs to the right of current tab"));
connect(m_closeRightAct, &QAction::triggered,
this, [this](){
int tab = this->m_closeTabAct->data().toInt();
Q_ASSERT(tab != -1);
for (int i = tab + 1; i < this->count();) {
this->setCurrentIndex(i);
this->updateTabStatus(i);
if (!this->closeTab(i)) {
++i;
}
}
});
} }
void VEditWindow::setupCornerWidget() void VEditWindow::setupCornerWidget()
@ -103,9 +152,9 @@ void VEditWindow::setupCornerWidget()
this, &VEditWindow::updateSplitMenu); this, &VEditWindow::updateSplitMenu);
} }
void VEditWindow::splitWindow() void VEditWindow::splitWindow(bool p_right)
{ {
emit requestSplitWindow(this); emit requestSplitWindow(this, p_right);
} }
void VEditWindow::removeSplit() void VEditWindow::removeSplit()
@ -288,13 +337,13 @@ int VEditWindow::findTabByFile(const VFile *p_file) const
return -1; return -1;
} }
bool VEditWindow::handleTabCloseRequest(int index) bool VEditWindow::closeTab(int p_index)
{ {
VEditTab *editor = getTab(index); VEditTab *editor = getTab(p_index);
Q_ASSERT(editor); Q_ASSERT(editor);
bool ok = editor->closeFile(false); bool ok = editor->closeFile(false);
if (ok) { if (ok) {
removeEditTab(index); removeEditTab(p_index);
} }
// User clicks the close button. We should make this window // User clicks the close button. We should make this window
@ -458,23 +507,42 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
if (tab == -1) { if (tab == -1) {
return; return;
} }
m_locateAct->setData(tab); m_locateAct->setData(tab);
VEditTab *editor = getTab(tab); VEditTab *editor = getTab(tab);
QPointer<VFile> file = editor->getFile(); QPointer<VFile> file = editor->getFile();
if (file->getType() == FileType::Normal) { if (file->getType() == FileType::Normal) {
// Locate to folder.
menu.addAction(m_locateAct); menu.addAction(m_locateAct);
} }
int totalWin = m_editArea->windowCount(); int totalWin = m_editArea->windowCount();
if (totalWin > 1) { // When there is only one tab and one split window, there is no need to
// display these two actions.
if (totalWin > 1 || count() > 1) {
menu.addSeparator(); menu.addSeparator();
m_moveLeftAct->setData(tab); m_moveLeftAct->setData(tab);
// Move one split left.
menu.addAction(m_moveLeftAct); menu.addAction(m_moveLeftAct);
m_moveRightAct->setData(tab); m_moveRightAct->setData(tab);
// Move one split right.
menu.addAction(m_moveRightAct); menu.addAction(m_moveRightAct);
} }
// Close tab, or other tabs, or tabs to the right.
menu.addSeparator();
m_closeTabAct->setData(tab);
menu.addAction(m_closeTabAct);
if (count() > 1) {
m_closeOthersAct->setData(tab);
menu.addAction(m_closeOthersAct);
if (tab < count() - 1) {
m_closeRightAct->setData(tab);
menu.addAction(m_closeRightAct);
}
}
if (!menu.actions().isEmpty()) { if (!menu.actions().isEmpty()) {
menu.exec(bar->mapToGlobal(p_pos)); menu.exec(bar->mapToGlobal(p_pos));
} }
@ -657,10 +725,19 @@ void VEditWindow::handleMoveRightAct()
void VEditWindow::moveTabOneSplit(int p_tabIdx, bool p_right) void VEditWindow::moveTabOneSplit(int p_tabIdx, bool p_right)
{ {
Q_ASSERT(p_tabIdx > -1 && p_tabIdx < count()); Q_ASSERT(p_tabIdx > -1 && p_tabIdx < count());
int totalWin = m_editArea->windowCount(); // Add split window if needed.
if (totalWin < 2) { if (m_editArea->windowCount() < 2) {
return; // Request VEditArea to split window.
splitWindow(p_right);
// Though the signal and slot will behave like a function call. We wait
// here until the window split finished.
while (m_editArea->windowCount() < 2) {
VUtils::sleepWait(100);
} }
}
int totalWin = m_editArea->windowCount();
int idx = m_editArea->windowIndex(this); int idx = m_editArea->windowIndex(this);
int newIdx = p_right ? idx + 1 : idx - 1; int newIdx = p_right ? idx + 1 : idx - 1;
if (newIdx >= totalWin) { if (newIdx >= totalWin) {

View File

@ -67,7 +67,9 @@ signals:
// Status of current VEditTab has update. // Status of current VEditTab has update.
void tabStatusUpdated(const VEditTabInfo &p_info); void tabStatusUpdated(const VEditTabInfo &p_info);
void requestSplitWindow(VEditWindow *curWindow); // Requst VEditArea to split this window.
void requestSplitWindow(VEditWindow *p_window, bool p_right = true);
void requestRemoveSplit(VEditWindow *curWindow); void requestRemoveSplit(VEditWindow *curWindow);
// This widget or its children get the focus // This widget or its children get the focus
void getFocused(); void getFocused();
@ -81,8 +83,12 @@ signals:
void vimStatusUpdated(const VVim *p_vim); void vimStatusUpdated(const VVim *p_vim);
private slots: private slots:
bool handleTabCloseRequest(int index); // Close tab @p_index.
void splitWindow(); bool closeTab(int p_index);
// Split this window on the right/left.
void splitWindow(bool p_right = true);
void removeSplit(); void removeSplit();
void handleTabbarClicked(int p_index); void handleTabbarClicked(int p_index);
void handleCurrentIndexChanged(int p_index); void handleCurrentIndexChanged(int p_index);
@ -116,7 +122,13 @@ private:
inline QString generateTabText(int p_index, const QString &p_name, inline QString generateTabText(int p_index, const QString &p_name,
bool p_modified, bool p_modifiable) const; bool p_modified, bool p_modifiable) const;
bool canRemoveSplit(); bool canRemoveSplit();
// Move tab at @p_tabIdx one split window.
// @p_right: move right or left.
// If there is only one split window, it will request to split current window
// and move the tab to the new split.
void moveTabOneSplit(int p_tabIdx, bool p_right); void moveTabOneSplit(int p_tabIdx, bool p_right);
void updateTabInfo(int p_idx); void updateTabInfo(int p_idx);
// Update the sequence number of all the tabs. // Update the sequence number of all the tabs.
void updateAllTabsSequence(); void updateAllTabsSequence();
@ -140,6 +152,15 @@ private:
QAction *m_locateAct; QAction *m_locateAct;
QAction *m_moveLeftAct; QAction *m_moveLeftAct;
QAction *m_moveRightAct; QAction *m_moveRightAct;
// Close current tab action in tab menu.
QAction *m_closeTabAct;
// Close other tabs action in tab menu.
QAction *m_closeOthersAct;
// Close tabs to the right in tab menu.
QAction *m_closeRightAct;
}; };
inline QString VEditWindow::generateTooltip(const VFile *p_file) const inline QString VEditWindow::generateTooltip(const VFile *p_file) const