mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support moving tabs between windows
Add two menu item on the tab's context menu to move one split left/right. Signed-off-by: Le Tan <tamlokveer@gmail.com>
This commit is contained in:
parent
1aa264adc8
commit
16858d7474
9
src/resources/icons/move_tab_left.svg
Normal file
9
src/resources/icons/move_tab_left.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path d="M189.3,128.4L89,233.4c-6,5.8-9,13.7-9,22.4c0,8.7,3,16.5,9,22.4l100.3,105.4c11.9,12.5,31.3,12.5,43.2,0
|
||||
c11.9-12.5,11.9-32.7,0-45.2L184.4,288h217c16.9,0,30.6-14.3,30.6-32c0-17.7-13.7-32-30.6-32h-217l48.2-50.4
|
||||
c11.9-12.5,11.9-32.7,0-45.2C220.6,115.9,201.3,115.9,189.3,128.4z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 779 B |
9
src/resources/icons/move_tab_right.svg
Normal file
9
src/resources/icons/move_tab_right.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="512px" height="512px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<path d="M322.7,128.4L423,233.4c6,5.8,9,13.7,9,22.4c0,8.7-3,16.5-9,22.4L322.7,383.6c-11.9,12.5-31.3,12.5-43.2,0
|
||||
c-11.9-12.5-11.9-32.7,0-45.2l48.2-50.4h-217C93.7,288,80,273.7,80,256c0-17.7,13.7-32,30.6-32h217l-48.2-50.4
|
||||
c-11.9-12.5-11.9-32.7,0-45.2C291.4,115.9,310.7,115.9,322.7,128.4z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 783 B |
@ -29,7 +29,7 @@ void VEditArea::setupUI()
|
||||
|
||||
void VEditArea::insertSplitWindow(int idx)
|
||||
{
|
||||
VEditWindow *win = new VEditWindow(vnote);
|
||||
VEditWindow *win = new VEditWindow(vnote, this);
|
||||
splitter->insertWidget(idx, win);
|
||||
connect(win, &VEditWindow::tabStatusChanged,
|
||||
this, &VEditArea::curTabStatusChanged);
|
||||
@ -385,3 +385,27 @@ VEditTab *VEditArea::currentEditTab()
|
||||
VEditWindow *win = getWindow(curWindowIndex);
|
||||
return win->currentEditTab();
|
||||
}
|
||||
|
||||
int VEditArea::windowIndex(const VEditWindow *p_window) const
|
||||
{
|
||||
int nrWin = splitter->count();
|
||||
for (int i = 0; i < nrWin; ++i) {
|
||||
if (p_window == getWindow(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void VEditArea::moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx)
|
||||
{
|
||||
int nrWin = splitter->count();
|
||||
if (!p_widget || p_fromIdx < 0 || p_fromIdx >= nrWin
|
||||
|| p_toIdx < 0 || p_toIdx >= nrWin) {
|
||||
return;
|
||||
}
|
||||
qDebug() << "move widget" << p_widget << "from" << p_fromIdx << "to" << p_toIdx;
|
||||
if (!getWindow(p_toIdx)->addEditTab(p_widget)) {
|
||||
delete p_widget;
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,14 @@ public:
|
||||
bool closeFile(const VNotebook *p_notebook, bool p_forced);
|
||||
// Returns current edit tab.
|
||||
VEditTab *currentEditTab();
|
||||
// Returns the count of VEditWindow.
|
||||
inline int windowCount() const;
|
||||
// Returns the index of @p_window.
|
||||
int windowIndex(const VEditWindow *p_window) const;
|
||||
// Move tab widget @p_widget from window @p_fromIdx to @p_toIdx.
|
||||
// @p_widget has been removed from the original window.
|
||||
// If fail, just delete the p_widget.
|
||||
void moveTab(QWidget *p_widget, int p_fromIdx, int p_toIdx);
|
||||
|
||||
signals:
|
||||
void curTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode);
|
||||
@ -81,4 +89,9 @@ inline VEditWindow* VEditArea::getWindow(int windowIndex) const
|
||||
return dynamic_cast<VEditWindow *>(splitter->widget(windowIndex));
|
||||
}
|
||||
|
||||
inline int VEditArea::windowCount() const
|
||||
{
|
||||
return splitter->count();
|
||||
}
|
||||
|
||||
#endif // VEDITAREA_H
|
||||
|
@ -7,11 +7,12 @@
|
||||
#include "utils/vutils.h"
|
||||
#include "vfile.h"
|
||||
#include "vmainwindow.h"
|
||||
#include "veditarea.h"
|
||||
|
||||
extern VConfigManager vconfig;
|
||||
|
||||
VEditWindow::VEditWindow(VNote *vnote, QWidget *parent)
|
||||
: QTabWidget(parent), vnote(vnote)
|
||||
VEditWindow::VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent)
|
||||
: QTabWidget(parent), vnote(vnote), m_editArea(editArea)
|
||||
{
|
||||
initTabActions();
|
||||
setupCornerWidget();
|
||||
@ -37,11 +38,23 @@ VEditWindow::VEditWindow(VNote *vnote, QWidget *parent)
|
||||
|
||||
void VEditWindow::initTabActions()
|
||||
{
|
||||
locateAct = new QAction(QIcon(":/resources/icons/locate_note.svg"),
|
||||
tr("Locate"), this);
|
||||
locateAct->setStatusTip(tr("Locate the directory of current note"));
|
||||
connect(locateAct, &QAction::triggered,
|
||||
m_locateAct = new QAction(QIcon(":/resources/icons/locate_note.svg"),
|
||||
tr("Locate"), this);
|
||||
m_locateAct->setStatusTip(tr("Locate the directory of current note"));
|
||||
connect(m_locateAct, &QAction::triggered,
|
||||
this, &VEditWindow::handleLocateAct);
|
||||
|
||||
m_moveLeftAct = new QAction(QIcon(":/resources/icons/move_tab_left.svg"),
|
||||
tr("Move One Split Left"), this);
|
||||
m_moveLeftAct->setStatusTip(tr("Move current tab to the split on the left"));
|
||||
connect(m_moveLeftAct, &QAction::triggered,
|
||||
this, &VEditWindow::handleMoveLeftAct);
|
||||
|
||||
m_moveRightAct = new QAction(QIcon(":/resources/icons/move_tab_right.svg"),
|
||||
tr("Move One Split Right"), this);
|
||||
m_moveRightAct->setStatusTip(tr("Move current tab to the split on the right"));
|
||||
connect(m_moveRightAct, &QAction::triggered,
|
||||
this, &VEditWindow::handleMoveRightAct);
|
||||
}
|
||||
|
||||
void VEditWindow::setupCornerWidget()
|
||||
@ -111,7 +124,6 @@ int VEditWindow::insertEditTab(int p_index, VFile *p_file, QWidget *p_page)
|
||||
{
|
||||
int idx = insertTab(p_index, p_page, p_file->getName());
|
||||
setTabToolTip(idx, generateTooltip(p_file));
|
||||
setTabIcon(idx, QIcon(":/resources/icons/reading.svg"));
|
||||
return idx;
|
||||
}
|
||||
|
||||
@ -386,8 +398,23 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
||||
if (tab == -1) {
|
||||
return;
|
||||
}
|
||||
locateAct->setData(tab);
|
||||
menu.addAction(locateAct);
|
||||
m_locateAct->setData(tab);
|
||||
menu.addAction(m_locateAct);
|
||||
|
||||
int totalWin = m_editArea->windowCount();
|
||||
int idx = m_editArea->windowIndex(this);
|
||||
if (totalWin > 1) {
|
||||
menu.addSeparator();
|
||||
if (idx > 0) {
|
||||
m_moveLeftAct->setData(tab);
|
||||
menu.addAction(m_moveLeftAct);
|
||||
}
|
||||
if (idx < totalWin - 1) {
|
||||
m_moveRightAct->setData(tab);
|
||||
menu.addAction(m_moveRightAct);
|
||||
}
|
||||
}
|
||||
|
||||
menu.exec(mapToGlobal(p_pos));
|
||||
}
|
||||
|
||||
@ -596,9 +623,74 @@ VEditTab *VEditWindow::currentEditTab()
|
||||
|
||||
void VEditWindow::handleLocateAct()
|
||||
{
|
||||
int tab = locateAct->data().toInt();
|
||||
qDebug() << "context menu of tab" << tab;
|
||||
int tab = m_locateAct->data().toInt();
|
||||
VEditTab *editor = getTab(tab);
|
||||
QPointer<VFile> file = editor->getFile();
|
||||
vnote->getMainWindow()->locateFile(file);
|
||||
}
|
||||
|
||||
void VEditWindow::handleMoveLeftAct()
|
||||
{
|
||||
int tab = m_locateAct->data().toInt();
|
||||
Q_ASSERT(tab != -1);
|
||||
VEditTab *editor = getTab(tab);
|
||||
// Remove it from current window. This won't close the split even if it is
|
||||
// the only tab.
|
||||
removeTab(tab);
|
||||
|
||||
// Disconnect all the signals.
|
||||
disconnect(editor, 0, this, 0);
|
||||
|
||||
int idx = m_editArea->windowIndex(this);
|
||||
m_editArea->moveTab(editor, idx, idx - 1);
|
||||
|
||||
// If there is no tab, remove current split.
|
||||
if (count() == 0) {
|
||||
emit requestRemoveSplit(this);
|
||||
}
|
||||
}
|
||||
|
||||
void VEditWindow::handleMoveRightAct()
|
||||
{
|
||||
int tab = m_locateAct->data().toInt();
|
||||
Q_ASSERT(tab != -1);
|
||||
VEditTab *editor = getTab(tab);
|
||||
// Remove it from current window. This won't close the split even if it is
|
||||
// the only tab.
|
||||
removeTab(tab);
|
||||
|
||||
// Disconnect all the signals.
|
||||
disconnect(editor, 0, this, 0);
|
||||
|
||||
int idx = m_editArea->windowIndex(this);
|
||||
m_editArea->moveTab(editor, idx, idx + 1);
|
||||
|
||||
// If there is no tab, remove current split.
|
||||
if (count() == 0) {
|
||||
emit requestRemoveSplit(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool VEditWindow::addEditTab(QWidget *p_widget)
|
||||
{
|
||||
if (!p_widget) {
|
||||
return false;
|
||||
}
|
||||
VEditTab *editor = dynamic_cast<VEditTab *>(p_widget);
|
||||
if (!editor) {
|
||||
return false;
|
||||
}
|
||||
// Connect the signals.
|
||||
connect(editor, &VEditTab::getFocused,
|
||||
this, &VEditWindow::getFocused);
|
||||
connect(editor, &VEditTab::outlineChanged,
|
||||
this, &VEditWindow::handleOutlineChanged);
|
||||
connect(editor, &VEditTab::curHeaderChanged,
|
||||
this, &VEditWindow::handleCurHeaderChanged);
|
||||
connect(editor, &VEditTab::statusChanged,
|
||||
this, &VEditWindow::handleTabStatusChanged);
|
||||
int idx = appendEditTab(editor->getFile(), editor);
|
||||
setCurrentIndex(idx);
|
||||
noticeTabStatus(idx);
|
||||
return true;
|
||||
}
|
||||
|
@ -14,12 +14,13 @@ class VNote;
|
||||
class QPushButton;
|
||||
class QActionGroup;
|
||||
class VFile;
|
||||
class VEditArea;
|
||||
|
||||
class VEditWindow : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VEditWindow(VNote *vnote, QWidget *parent = 0);
|
||||
explicit VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent = 0);
|
||||
int findTabByFile(const VFile *p_file) const;
|
||||
int openFile(VFile *p_file, OpenFileMode p_mode);
|
||||
bool closeFile(const VFile *p_file, bool p_forced);
|
||||
@ -40,6 +41,8 @@ public:
|
||||
void updateDirectoryInfo(const VDirectory *p_dir);
|
||||
void updateNotebookInfo(const VNotebook *p_notebook);
|
||||
VEditTab *currentEditTab();
|
||||
// Insert a tab with @p_widget. @p_widget is a fully initialized VEditTab.
|
||||
bool addEditTab(QWidget *p_widget);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
@ -68,6 +71,8 @@ private slots:
|
||||
void updateSplitMenu();
|
||||
void tabbarContextMenuRequested(QPoint p_pos);
|
||||
void handleLocateAct();
|
||||
void handleMoveLeftAct();
|
||||
void handleMoveRightAct();
|
||||
|
||||
private:
|
||||
void initTabActions();
|
||||
@ -87,6 +92,7 @@ private:
|
||||
void setLeftCornerWidgetVisible(bool p_visible);
|
||||
|
||||
VNote *vnote;
|
||||
VEditArea *m_editArea;
|
||||
// Button in the right corner
|
||||
QPushButton *rightBtn;
|
||||
// Button in the left corner
|
||||
@ -97,7 +103,9 @@ private:
|
||||
QAction *removeSplitAct;
|
||||
QActionGroup *tabListAct;
|
||||
// Locate current note in the directory and file list
|
||||
QAction *locateAct;
|
||||
QAction *m_locateAct;
|
||||
QAction *m_moveLeftAct;
|
||||
QAction *m_moveRightAct;
|
||||
};
|
||||
|
||||
inline VEditTab* VEditWindow::getTab(int tabIndex) const
|
||||
|
@ -77,5 +77,7 @@
|
||||
<file>resources/icons/editing.svg</file>
|
||||
<file>resources/icons/reading.svg</file>
|
||||
<file>resources/icons/locate_note.svg</file>
|
||||
<file>resources/icons/move_tab_left.svg</file>
|
||||
<file>resources/icons/move_tab_right.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user