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)
|
void VEditArea::insertSplitWindow(int idx)
|
||||||
{
|
{
|
||||||
VEditWindow *win = new VEditWindow(vnote);
|
VEditWindow *win = new VEditWindow(vnote, this);
|
||||||
splitter->insertWidget(idx, win);
|
splitter->insertWidget(idx, win);
|
||||||
connect(win, &VEditWindow::tabStatusChanged,
|
connect(win, &VEditWindow::tabStatusChanged,
|
||||||
this, &VEditArea::curTabStatusChanged);
|
this, &VEditArea::curTabStatusChanged);
|
||||||
@ -385,3 +385,27 @@ VEditTab *VEditArea::currentEditTab()
|
|||||||
VEditWindow *win = getWindow(curWindowIndex);
|
VEditWindow *win = getWindow(curWindowIndex);
|
||||||
return win->currentEditTab();
|
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);
|
bool closeFile(const VNotebook *p_notebook, bool p_forced);
|
||||||
// Returns current edit tab.
|
// Returns current edit tab.
|
||||||
VEditTab *currentEditTab();
|
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:
|
signals:
|
||||||
void curTabStatusChanged(const VFile *p_file, const VEditTab *p_editTab, bool p_editMode);
|
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));
|
return dynamic_cast<VEditWindow *>(splitter->widget(windowIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int VEditArea::windowCount() const
|
||||||
|
{
|
||||||
|
return splitter->count();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VEDITAREA_H
|
#endif // VEDITAREA_H
|
||||||
|
@ -7,11 +7,12 @@
|
|||||||
#include "utils/vutils.h"
|
#include "utils/vutils.h"
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
#include "vmainwindow.h"
|
#include "vmainwindow.h"
|
||||||
|
#include "veditarea.h"
|
||||||
|
|
||||||
extern VConfigManager vconfig;
|
extern VConfigManager vconfig;
|
||||||
|
|
||||||
VEditWindow::VEditWindow(VNote *vnote, QWidget *parent)
|
VEditWindow::VEditWindow(VNote *vnote, VEditArea *editArea, QWidget *parent)
|
||||||
: QTabWidget(parent), vnote(vnote)
|
: QTabWidget(parent), vnote(vnote), m_editArea(editArea)
|
||||||
{
|
{
|
||||||
initTabActions();
|
initTabActions();
|
||||||
setupCornerWidget();
|
setupCornerWidget();
|
||||||
@ -37,11 +38,23 @@ VEditWindow::VEditWindow(VNote *vnote, QWidget *parent)
|
|||||||
|
|
||||||
void VEditWindow::initTabActions()
|
void VEditWindow::initTabActions()
|
||||||
{
|
{
|
||||||
locateAct = new QAction(QIcon(":/resources/icons/locate_note.svg"),
|
m_locateAct = new QAction(QIcon(":/resources/icons/locate_note.svg"),
|
||||||
tr("Locate"), this);
|
tr("Locate"), this);
|
||||||
locateAct->setStatusTip(tr("Locate the directory of current note"));
|
m_locateAct->setStatusTip(tr("Locate the directory of current note"));
|
||||||
connect(locateAct, &QAction::triggered,
|
connect(m_locateAct, &QAction::triggered,
|
||||||
this, &VEditWindow::handleLocateAct);
|
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()
|
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());
|
int idx = insertTab(p_index, p_page, p_file->getName());
|
||||||
setTabToolTip(idx, generateTooltip(p_file));
|
setTabToolTip(idx, generateTooltip(p_file));
|
||||||
setTabIcon(idx, QIcon(":/resources/icons/reading.svg"));
|
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,8 +398,23 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
|||||||
if (tab == -1) {
|
if (tab == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
locateAct->setData(tab);
|
m_locateAct->setData(tab);
|
||||||
menu.addAction(locateAct);
|
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));
|
menu.exec(mapToGlobal(p_pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,9 +623,74 @@ VEditTab *VEditWindow::currentEditTab()
|
|||||||
|
|
||||||
void VEditWindow::handleLocateAct()
|
void VEditWindow::handleLocateAct()
|
||||||
{
|
{
|
||||||
int tab = locateAct->data().toInt();
|
int tab = m_locateAct->data().toInt();
|
||||||
qDebug() << "context menu of tab" << tab;
|
|
||||||
VEditTab *editor = getTab(tab);
|
VEditTab *editor = getTab(tab);
|
||||||
QPointer<VFile> file = editor->getFile();
|
QPointer<VFile> file = editor->getFile();
|
||||||
vnote->getMainWindow()->locateFile(file);
|
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 QPushButton;
|
||||||
class QActionGroup;
|
class QActionGroup;
|
||||||
class VFile;
|
class VFile;
|
||||||
|
class VEditArea;
|
||||||
|
|
||||||
class VEditWindow : public QTabWidget
|
class VEditWindow : public QTabWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
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 findTabByFile(const VFile *p_file) const;
|
||||||
int openFile(VFile *p_file, OpenFileMode p_mode);
|
int openFile(VFile *p_file, OpenFileMode p_mode);
|
||||||
bool closeFile(const VFile *p_file, bool p_forced);
|
bool closeFile(const VFile *p_file, bool p_forced);
|
||||||
@ -40,6 +41,8 @@ public:
|
|||||||
void updateDirectoryInfo(const VDirectory *p_dir);
|
void updateDirectoryInfo(const VDirectory *p_dir);
|
||||||
void updateNotebookInfo(const VNotebook *p_notebook);
|
void updateNotebookInfo(const VNotebook *p_notebook);
|
||||||
VEditTab *currentEditTab();
|
VEditTab *currentEditTab();
|
||||||
|
// Insert a tab with @p_widget. @p_widget is a fully initialized VEditTab.
|
||||||
|
bool addEditTab(QWidget *p_widget);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
@ -68,6 +71,8 @@ private slots:
|
|||||||
void updateSplitMenu();
|
void updateSplitMenu();
|
||||||
void tabbarContextMenuRequested(QPoint p_pos);
|
void tabbarContextMenuRequested(QPoint p_pos);
|
||||||
void handleLocateAct();
|
void handleLocateAct();
|
||||||
|
void handleMoveLeftAct();
|
||||||
|
void handleMoveRightAct();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initTabActions();
|
void initTabActions();
|
||||||
@ -87,6 +92,7 @@ private:
|
|||||||
void setLeftCornerWidgetVisible(bool p_visible);
|
void setLeftCornerWidgetVisible(bool p_visible);
|
||||||
|
|
||||||
VNote *vnote;
|
VNote *vnote;
|
||||||
|
VEditArea *m_editArea;
|
||||||
// Button in the right corner
|
// Button in the right corner
|
||||||
QPushButton *rightBtn;
|
QPushButton *rightBtn;
|
||||||
// Button in the left corner
|
// Button in the left corner
|
||||||
@ -97,7 +103,9 @@ private:
|
|||||||
QAction *removeSplitAct;
|
QAction *removeSplitAct;
|
||||||
QActionGroup *tabListAct;
|
QActionGroup *tabListAct;
|
||||||
// Locate current note in the directory and file list
|
// 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
|
inline VEditTab* VEditWindow::getTab(int tabIndex) const
|
||||||
|
@ -77,5 +77,7 @@
|
|||||||
<file>resources/icons/editing.svg</file>
|
<file>resources/icons/editing.svg</file>
|
||||||
<file>resources/icons/reading.svg</file>
|
<file>resources/icons/reading.svg</file>
|
||||||
<file>resources/icons/locate_note.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>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user