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

View File

@ -87,7 +87,10 @@ public slots:
void handleNotebookUpdated(const VNotebook *p_notebook);
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 handleWindowFocused();
void handleOutlineChanged(const VToc &toc);

View File

@ -33,7 +33,7 @@ VEditWindow::VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent)
this, &VEditWindow::tabbarContextMenuRequested);
connect(this, &VEditWindow::tabCloseRequested,
this, &VEditWindow::handleTabCloseRequest);
this, &VEditWindow::closeTab);
connect(this, &VEditWindow::tabBarClicked,
this, &VEditWindow::handleTabbarClicked);
connect(this, &VEditWindow::currentChanged,
@ -61,6 +61,55 @@ void VEditWindow::initTabActions()
m_moveRightAct->setToolTip(tr("Move current tab to the split on the right"));
connect(m_moveRightAct, &QAction::triggered,
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()
@ -103,9 +152,9 @@ void VEditWindow::setupCornerWidget()
this, &VEditWindow::updateSplitMenu);
}
void VEditWindow::splitWindow()
void VEditWindow::splitWindow(bool p_right)
{
emit requestSplitWindow(this);
emit requestSplitWindow(this, p_right);
}
void VEditWindow::removeSplit()
@ -288,13 +337,13 @@ int VEditWindow::findTabByFile(const VFile *p_file) const
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);
bool ok = editor->closeFile(false);
if (ok) {
removeEditTab(index);
removeEditTab(p_index);
}
// User clicks the close button. We should make this window
@ -458,23 +507,42 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
if (tab == -1) {
return;
}
m_locateAct->setData(tab);
VEditTab *editor = getTab(tab);
QPointer<VFile> file = editor->getFile();
if (file->getType() == FileType::Normal) {
// Locate to folder.
menu.addAction(m_locateAct);
}
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();
m_moveLeftAct->setData(tab);
// Move one split left.
menu.addAction(m_moveLeftAct);
m_moveRightAct->setData(tab);
// Move one split right.
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()) {
menu.exec(bar->mapToGlobal(p_pos));
}
@ -657,10 +725,19 @@ void VEditWindow::handleMoveRightAct()
void VEditWindow::moveTabOneSplit(int p_tabIdx, bool p_right)
{
Q_ASSERT(p_tabIdx > -1 && p_tabIdx < count());
int totalWin = m_editArea->windowCount();
if (totalWin < 2) {
return;
// Add split window if needed.
if (m_editArea->windowCount() < 2) {
// 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 newIdx = p_right ? idx + 1 : idx - 1;
if (newIdx >= totalWin) {

View File

@ -67,7 +67,9 @@ signals:
// Status of current VEditTab has update.
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);
// This widget or its children get the focus
void getFocused();
@ -81,8 +83,12 @@ signals:
void vimStatusUpdated(const VVim *p_vim);
private slots:
bool handleTabCloseRequest(int index);
void splitWindow();
// Close tab @p_index.
bool closeTab(int p_index);
// Split this window on the right/left.
void splitWindow(bool p_right = true);
void removeSplit();
void handleTabbarClicked(int p_index);
void handleCurrentIndexChanged(int p_index);
@ -116,7 +122,13 @@ private:
inline QString generateTabText(int p_index, const QString &p_name,
bool p_modified, bool p_modifiable) const;
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 updateTabInfo(int p_idx);
// Update the sequence number of all the tabs.
void updateAllTabsSequence();
@ -140,6 +152,15 @@ private:
QAction *m_locateAct;
QAction *m_moveLeftAct;
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