diff --git a/src/resources/icons/move_tab_left.svg b/src/resources/icons/move_tab_left.svg
new file mode 100644
index 00000000..37f3511b
--- /dev/null
+++ b/src/resources/icons/move_tab_left.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/src/resources/icons/move_tab_right.svg b/src/resources/icons/move_tab_right.svg
new file mode 100644
index 00000000..332708ba
--- /dev/null
+++ b/src/resources/icons/move_tab_right.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/src/veditarea.cpp b/src/veditarea.cpp
index 1f0c5d9a..518818ee 100644
--- a/src/veditarea.cpp
+++ b/src/veditarea.cpp
@@ -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;
+ }
+}
diff --git a/src/veditarea.h b/src/veditarea.h
index 49268ec6..0e1b8ae6 100644
--- a/src/veditarea.h
+++ b/src/veditarea.h
@@ -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(splitter->widget(windowIndex));
}
+inline int VEditArea::windowCount() const
+{
+ return splitter->count();
+}
+
#endif // VEDITAREA_H
diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp
index 20c86809..7250b869 100644
--- a/src/veditwindow.cpp
+++ b/src/veditwindow.cpp
@@ -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 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(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;
+}
diff --git a/src/veditwindow.h b/src/veditwindow.h
index 2ce7d2b5..a1e2970c 100644
--- a/src/veditwindow.h
+++ b/src/veditwindow.h
@@ -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
diff --git a/src/vnote.qrc b/src/vnote.qrc
index 95b294e1..49f86cd0 100644
--- a/src/vnote.qrc
+++ b/src/vnote.qrc
@@ -77,5 +77,7 @@
resources/icons/editing.svg
resources/icons/reading.svg
resources/icons/locate_note.svg
+ resources/icons/move_tab_left.svg
+ resources/icons/move_tab_right.svg