mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support spliting edit windows
Signed-off-by: Le Tan <tamlokveer@gmail.com>
This commit is contained in:
parent
1bc95bcea0
commit
915c25e1a5
11
src/resources/icons/corner_menu.svg
Normal file
11
src/resources/icons/corner_menu.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<?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" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||
<g id="Icon_3_">
|
||||
<g>
|
||||
<path d="M64,384h384v-42.666H64V384z M64,277.334h384v-42.667H64V277.334z M64,128v42.665h384V128H64z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 626 B |
10
src/resources/icons/remove_split.svg
Normal file
10
src/resources/icons/remove_split.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<?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" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||
<path d="M458,210.409l-145.267-12.476L256,64l-56.743,133.934L54,210.409l110.192,95.524L131.161,448L256,372.686L380.83,448
|
||||
l-33.021-142.066L458,210.409z M272.531,345.286L256,335.312l-16.53,9.973l-59.988,36.191l15.879-68.296l4.369-18.79l-14.577-12.637
|
||||
l-52.994-45.939l69.836-5.998l19.206-1.65l7.521-17.75l27.276-64.381l27.27,64.379l7.52,17.751l19.208,1.65l69.846,5.998
|
||||
l-52.993,45.939l-14.576,12.636l4.367,18.788l15.875,68.299L272.531,345.286z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 935 B |
9
src/resources/icons/split_window.svg
Normal file
9
src/resources/icons/split_window.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" enable-background="new 0 0 512 512" xml:space="preserve">
|
||||
<path d="M458,210.409l-145.267-12.476L256,64l-56.743,133.934L54,210.409l110.192,95.524L131.161,448L256,372.686L380.83,448
|
||||
l-33.021-142.066L458,210.409z M272.531,345.287L256,335.313l-0.002-189.277l27.27,64.379l7.52,17.751l19.208,1.65l69.846,5.998
|
||||
l-52.993,45.939l-14.576,12.636l4.367,18.788l15.875,68.299L272.531,345.287z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 812 B |
10
src/src.pro
10
src/src.pro
@ -21,7 +21,6 @@ SOURCES += main.cpp\
|
||||
vconfigmanager.cpp \
|
||||
vfilelist.cpp \
|
||||
dialog/vnewfiledialog.cpp \
|
||||
vtabwidget.cpp \
|
||||
vedit.cpp \
|
||||
veditor.cpp \
|
||||
vnotefile.cpp \
|
||||
@ -40,7 +39,9 @@ SOURCES += main.cpp\
|
||||
veditoperations.cpp \
|
||||
vmdeditoperations.cpp \
|
||||
dialog/vinsertimagedialog.cpp \
|
||||
vdownloader.cpp
|
||||
vdownloader.cpp \
|
||||
veditarea.cpp \
|
||||
veditwindow.cpp
|
||||
|
||||
HEADERS += vmainwindow.h \
|
||||
vdirectorytree.h \
|
||||
@ -50,7 +51,6 @@ HEADERS += vmainwindow.h \
|
||||
vconfigmanager.h \
|
||||
vfilelist.h \
|
||||
dialog/vnewfiledialog.h \
|
||||
vtabwidget.h \
|
||||
vedit.h \
|
||||
veditor.h \
|
||||
vconstants.h \
|
||||
@ -71,7 +71,9 @@ HEADERS += vmainwindow.h \
|
||||
veditoperations.h \
|
||||
vmdeditoperations.h \
|
||||
dialog/vinsertimagedialog.h \
|
||||
vdownloader.h
|
||||
vdownloader.h \
|
||||
veditarea.h \
|
||||
veditwindow.h
|
||||
|
||||
RESOURCES += \
|
||||
vnote.qrc
|
||||
|
274
src/veditarea.cpp
Normal file
274
src/veditarea.cpp
Normal file
@ -0,0 +1,274 @@
|
||||
#include <QtWidgets>
|
||||
#include "veditarea.h"
|
||||
#include "veditwindow.h"
|
||||
#include "veditor.h"
|
||||
#include "vnote.h"
|
||||
#include "vconfigmanager.h"
|
||||
|
||||
VEditArea::VEditArea(VNote *vnote, QWidget *parent)
|
||||
: QWidget(parent), vnote(vnote), curWindowIndex(0)
|
||||
{
|
||||
setupUI();
|
||||
}
|
||||
|
||||
void VEditArea::setupUI()
|
||||
{
|
||||
splitter = new QSplitter(this);
|
||||
|
||||
// Add a window
|
||||
insertSplitWindow(0);
|
||||
setCurrentWindow(0, true);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout();
|
||||
mainLayout->addWidget(splitter);
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
void VEditArea::insertSplitWindow(int idx)
|
||||
{
|
||||
VEditWindow *win = new VEditWindow(vnote);
|
||||
splitter->insertWidget(idx, win);
|
||||
connect(win, &VEditWindow::tabStatusChanged,
|
||||
this, &VEditArea::curTabStatusChanged);
|
||||
connect(win, &VEditWindow::requestSplitWindow,
|
||||
this, &VEditArea::handleSplitWindowRequest);
|
||||
connect(win, &VEditWindow::requestRemoveSplit,
|
||||
this, &VEditArea::handleRemoveSplitRequest);
|
||||
connect(win, &VEditWindow::getFocused,
|
||||
this, &VEditArea::handleWindowFocused);
|
||||
|
||||
int nrWin = splitter->count();
|
||||
if (nrWin == 1) {
|
||||
// Disable removing split
|
||||
win->setRemoveSplitEnable(false);
|
||||
} else {
|
||||
// Enable removing split
|
||||
for (int i = 0; i < nrWin; ++i) {
|
||||
getWindow(i)->setRemoveSplitEnable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VEditArea::removeSplitWindow(VEditWindow *win)
|
||||
{
|
||||
if (!win) {
|
||||
return;
|
||||
}
|
||||
win->hide();
|
||||
// Should be deleted later
|
||||
win->deleteLater();
|
||||
|
||||
int nrWin = splitter->count();
|
||||
if (nrWin == 2) {
|
||||
// Disable removing split
|
||||
getWindow(0)->setRemoveSplitEnable(false);
|
||||
getWindow(1)->setRemoveSplitEnable(false);
|
||||
} else {
|
||||
// Enable removing split
|
||||
for (int i = 0; i < nrWin; ++i) {
|
||||
getWindow(i)->setRemoveSplitEnable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A given file can be opened in multiple split windows. A given file could be
|
||||
// opened at most in one tab inside a window.
|
||||
void VEditArea::openFile(QJsonObject fileJson)
|
||||
{
|
||||
if (fileJson.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString notebook = fileJson["notebook"].toString();
|
||||
QString relativePath = fileJson["relative_path"].toString();
|
||||
int mode = OpenFileMode::Read;
|
||||
if (fileJson.contains("mode")) {
|
||||
mode = fileJson["mode"].toInt();
|
||||
}
|
||||
|
||||
qDebug() << "open notebook" << notebook << "path" << relativePath << mode;
|
||||
|
||||
// Find if it has been opened already
|
||||
int winIdx, tabIdx;
|
||||
bool setFocus = false;
|
||||
auto tabs = findTabsByFile(notebook, relativePath);
|
||||
if (!tabs.empty()) {
|
||||
// Current window first
|
||||
winIdx = tabs[0].first;
|
||||
tabIdx = tabs[0].second;
|
||||
for (int i = 0; i < tabs.size(); ++i) {
|
||||
if (tabs[i].first == curWindowIndex) {
|
||||
winIdx = tabs[i].first;
|
||||
tabIdx = tabs[i].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setFocus = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Open it in current window
|
||||
winIdx = curWindowIndex;
|
||||
tabIdx = openFileInWindow(winIdx, notebook, relativePath, mode);
|
||||
|
||||
out:
|
||||
setCurrentTab(winIdx, tabIdx, setFocus);
|
||||
}
|
||||
|
||||
QVector<QPair<int, int> > VEditArea::findTabsByFile(const QString ¬ebook, const QString &relativePath)
|
||||
{
|
||||
QVector<QPair<int, int> > tabs;
|
||||
int nrWin = splitter->count();
|
||||
for (int winIdx = 0; winIdx < nrWin; ++winIdx) {
|
||||
VEditWindow *win = getWindow(winIdx);
|
||||
int tabIdx = win->findTabByFile(notebook, relativePath);
|
||||
if (tabIdx != -1) {
|
||||
QPair<int, int> match;
|
||||
match.first = winIdx;
|
||||
match.second = tabIdx;
|
||||
tabs.append(match);
|
||||
}
|
||||
}
|
||||
return tabs;
|
||||
}
|
||||
|
||||
int VEditArea::openFileInWindow(int windowIndex, const QString ¬ebook, const QString &relativePath,
|
||||
int mode)
|
||||
{
|
||||
Q_ASSERT(windowIndex < splitter->count());
|
||||
VEditWindow *win = getWindow(windowIndex);
|
||||
return win->openFile(notebook, relativePath, mode);
|
||||
}
|
||||
|
||||
void VEditArea::setCurrentTab(int windowIndex, int tabIndex, bool setFocus)
|
||||
{
|
||||
setCurrentWindow(windowIndex, setFocus);
|
||||
|
||||
VEditWindow *win = getWindow(windowIndex);
|
||||
win->setCurrentIndex(tabIndex);
|
||||
}
|
||||
|
||||
void VEditArea::setCurrentWindow(int windowIndex, bool setFocus)
|
||||
{
|
||||
if (curWindowIndex == windowIndex) {
|
||||
return;
|
||||
}
|
||||
qDebug() << "current window" << windowIndex;
|
||||
curWindowIndex = windowIndex;
|
||||
if (setFocus) {
|
||||
getWindow(windowIndex)->focusWindow();
|
||||
}
|
||||
|
||||
// Update tab status
|
||||
QString notebook, relativePath;
|
||||
bool editMode, modifiable;
|
||||
getWindow(curWindowIndex)->getTabStatus(notebook, relativePath, editMode, modifiable);
|
||||
emit curTabStatusChanged(notebook, relativePath, editMode, modifiable);
|
||||
}
|
||||
|
||||
void VEditArea::closeFile(QJsonObject fileJson)
|
||||
{
|
||||
if (fileJson.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QString notebook = fileJson["notebook"].toString();
|
||||
QString relativePath = fileJson["relative_path"].toString();
|
||||
|
||||
int nrWin = splitter->count();
|
||||
for (int i = 0; i < nrWin; ++i) {
|
||||
VEditWindow *win = getWindow(i);
|
||||
win->closeFile(notebook, relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
void VEditArea::editFile()
|
||||
{
|
||||
VEditWindow *win = getWindow(curWindowIndex);
|
||||
win->editFile();
|
||||
}
|
||||
|
||||
void VEditArea::saveFile()
|
||||
{
|
||||
VEditWindow *win = getWindow(curWindowIndex);
|
||||
win->saveFile();
|
||||
}
|
||||
|
||||
void VEditArea::readFile()
|
||||
{
|
||||
VEditWindow *win = getWindow(curWindowIndex);
|
||||
win->readFile();
|
||||
}
|
||||
|
||||
void VEditArea::saveAndReadFile()
|
||||
{
|
||||
VEditWindow *win = getWindow(curWindowIndex);
|
||||
win->saveAndReadFile();
|
||||
}
|
||||
|
||||
void VEditArea::handleNotebookRenamed(const QVector<VNotebook> ¬ebooks,
|
||||
const QString &oldName, const QString &newName)
|
||||
{
|
||||
int nrWin = splitter->count();
|
||||
for (int i = 0; i < nrWin; ++i) {
|
||||
VEditWindow *win = getWindow(i);
|
||||
win->handleNotebookRenamed(notebooks, oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
void VEditArea::handleSplitWindowRequest(VEditWindow *curWindow)
|
||||
{
|
||||
if (!curWindow) {
|
||||
return;
|
||||
}
|
||||
int idx = splitter->indexOf(curWindow);
|
||||
qDebug() << "window" << idx << "requests split itself";
|
||||
insertSplitWindow(++idx);
|
||||
setCurrentWindow(idx, true);
|
||||
}
|
||||
|
||||
void VEditArea::handleRemoveSplitRequest(VEditWindow *curWindow)
|
||||
{
|
||||
if (!curWindow) {
|
||||
return;
|
||||
}
|
||||
int idx = splitter->indexOf(curWindow);
|
||||
|
||||
removeSplitWindow(curWindow);
|
||||
|
||||
if (idx >= splitter->count()) {
|
||||
idx = splitter->count() - 1;
|
||||
}
|
||||
|
||||
// At least one split window left
|
||||
Q_ASSERT(idx >= 0);
|
||||
setCurrentWindow(idx, true);
|
||||
}
|
||||
|
||||
void VEditArea::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
return;
|
||||
qDebug() << "VEditArea press event" << event;
|
||||
QPoint pos = event->pos();
|
||||
int nrWin = splitter->count();
|
||||
for (int i = 0; i < nrWin; ++i) {
|
||||
VEditWindow *win = getWindow(i);
|
||||
if (win->geometry().contains(pos, true)) {
|
||||
setCurrentWindow(i, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void VEditArea::handleWindowFocused()
|
||||
{
|
||||
QObject *winObject = sender();
|
||||
int nrWin = splitter->count();
|
||||
for (int i = 0; i < nrWin; ++i) {
|
||||
if (splitter->widget(i) == winObject) {
|
||||
setCurrentWindow(i, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
70
src/veditarea.h
Normal file
70
src/veditarea.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef VEDITAREA_H
|
||||
#define VEDITAREA_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include <QVector>
|
||||
#include <QPair>
|
||||
#include <QtDebug>
|
||||
#include <QSplitter>
|
||||
#include "vnotebook.h"
|
||||
#include "veditwindow.h"
|
||||
|
||||
class VNote;
|
||||
|
||||
class VEditArea : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VEditArea(VNote *vnote, QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
void curTabStatusChanged(const QString ¬ebook, const QString &relativePath,
|
||||
bool editMode, bool modifiable);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
public slots:
|
||||
void openFile(QJsonObject fileJson);
|
||||
// Close the file forcely
|
||||
void closeFile(QJsonObject fileJson);
|
||||
void editFile();
|
||||
void saveFile();
|
||||
void readFile();
|
||||
void saveAndReadFile();
|
||||
void handleNotebookRenamed(const QVector<VNotebook> ¬ebooks, const QString &oldName,
|
||||
const QString &newName);
|
||||
|
||||
private slots:
|
||||
void handleSplitWindowRequest(VEditWindow *curWindow);
|
||||
void handleRemoveSplitRequest(VEditWindow *curWindow);
|
||||
void handleWindowFocused();
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
QVector<QPair<int, int> > findTabsByFile(const QString ¬ebook, const QString &relativePath);
|
||||
int openFileInWindow(int windowIndex, const QString ¬ebook, const QString &relativePath,
|
||||
int mode);
|
||||
void setCurrentTab(int windowIndex, int tabIndex, bool setFocus);
|
||||
void setCurrentWindow(int windowIndex, bool setFocus);
|
||||
inline VEditWindow *getWindow(int windowIndex) const;
|
||||
void insertSplitWindow(int idx);
|
||||
void removeSplitWindow(VEditWindow *win);
|
||||
|
||||
VNote *vnote;
|
||||
int curWindowIndex;
|
||||
|
||||
// Splitter holding multiple split windows
|
||||
QSplitter *splitter;
|
||||
};
|
||||
|
||||
inline VEditWindow* VEditArea::getWindow(int windowIndex) const
|
||||
{
|
||||
return dynamic_cast<VEditWindow *>(splitter->widget(windowIndex));
|
||||
}
|
||||
|
||||
#endif // VEDITAREA_H
|
@ -32,6 +32,9 @@ VEditor::VEditor(const QString &path, bool modifiable, QWidget *parent)
|
||||
setupUI();
|
||||
|
||||
showFileReadMode();
|
||||
|
||||
connect(qApp, &QApplication::focusChanged,
|
||||
this, &VEditor::handleFocusChanged);
|
||||
}
|
||||
|
||||
VEditor::~VEditor()
|
||||
@ -148,7 +151,7 @@ void VEditor::readFile()
|
||||
if (textEditor->isModified()) {
|
||||
// Need to save the changes
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setText("The note has been modified.");
|
||||
msgBox.setText(QString("The note \"%1\" has been modified.").arg(noteFile->fileName));
|
||||
msgBox.setInformativeText("Do you want to save your changes?");
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||
@ -220,3 +223,15 @@ void VEditor::setupMarkdownPreview()
|
||||
|
||||
addWidget(webPreviewer);
|
||||
}
|
||||
|
||||
void VEditor::focusTab()
|
||||
{
|
||||
currentWidget()->setFocus();
|
||||
}
|
||||
|
||||
void VEditor::handleFocusChanged(QWidget *old, QWidget *now)
|
||||
{
|
||||
if (isChild(now)) {
|
||||
emit getFocused();
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ class VNote;
|
||||
|
||||
class VEditor : public QStackedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VEditor(const QString &path, bool modifiable, QWidget *parent = 0);
|
||||
~VEditor();
|
||||
@ -29,6 +30,13 @@ public:
|
||||
|
||||
inline bool getIsEditMode() const;
|
||||
inline bool isModified() const;
|
||||
void focusTab();
|
||||
|
||||
signals:
|
||||
void getFocused();
|
||||
|
||||
private slots:
|
||||
void handleFocusChanged(QWidget *old, QWidget *now);
|
||||
|
||||
private:
|
||||
bool isMarkdown(const QString &name);
|
||||
@ -37,6 +45,7 @@ private:
|
||||
void showFileEditMode();
|
||||
void setupMarkdownPreview();
|
||||
void previewByConverter();
|
||||
inline bool isChild(QObject *obj);
|
||||
|
||||
VNoteFile *noteFile;
|
||||
bool isEditMode;
|
||||
@ -57,4 +66,15 @@ inline bool VEditor::isModified() const
|
||||
return textEditor->isModified();
|
||||
}
|
||||
|
||||
inline bool VEditor::isChild(QObject *obj)
|
||||
{
|
||||
while (obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
obj = obj->parent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // VEDITOR_H
|
||||
|
296
src/veditwindow.cpp
Normal file
296
src/veditwindow.cpp
Normal file
@ -0,0 +1,296 @@
|
||||
#include <QtWidgets>
|
||||
#include <QtDebug>
|
||||
#include "veditwindow.h"
|
||||
#include "veditor.h"
|
||||
#include "vnote.h"
|
||||
#include "vconfigmanager.h"
|
||||
|
||||
extern VConfigManager vconfig;
|
||||
|
||||
VEditWindow::VEditWindow(VNote *vnote, QWidget *parent)
|
||||
: QTabWidget(parent), vnote(vnote)
|
||||
{
|
||||
setupCornerWidget();
|
||||
|
||||
setTabsClosable(true);
|
||||
setMovable(true);
|
||||
|
||||
connect(this, &VEditWindow::tabCloseRequested,
|
||||
this, &VEditWindow::handleTabCloseRequest);
|
||||
connect(this, &VEditWindow::tabBarClicked,
|
||||
this, &VEditWindow::handleTabbarClicked);
|
||||
}
|
||||
|
||||
void VEditWindow::setupCornerWidget()
|
||||
{
|
||||
// Right corner button
|
||||
// Actions
|
||||
splitAct = new QAction(QIcon(":/resources/icons/split_window.svg"),
|
||||
tr("Split"), this);
|
||||
splitAct->setStatusTip(tr("Split current window vertically"));
|
||||
connect(splitAct, &QAction::triggered,
|
||||
this, &VEditWindow::splitWindow);
|
||||
|
||||
removeSplitAct = new QAction(QIcon(":/resources/icons/remove_split.svg"),
|
||||
tr("Remove split"), this);
|
||||
removeSplitAct->setStatusTip(tr("Remove current split window"));
|
||||
connect(removeSplitAct, &QAction::triggered,
|
||||
this, &VEditWindow::removeSplit);
|
||||
|
||||
rightBtn = new QPushButton(QIcon(":/resources/icons/corner_menu.svg"),
|
||||
"", this);
|
||||
QMenu *rightMenu = new QMenu(this);
|
||||
rightMenu->addAction(splitAct);
|
||||
rightMenu->addAction(removeSplitAct);
|
||||
rightBtn->setMenu(rightMenu);
|
||||
|
||||
setCornerWidget(rightBtn, Qt::TopRightCorner);
|
||||
}
|
||||
|
||||
void VEditWindow::splitWindow()
|
||||
{
|
||||
emit requestSplitWindow(this);
|
||||
}
|
||||
|
||||
void VEditWindow::removeSplit()
|
||||
{
|
||||
// Close all the files one by one
|
||||
// If user do not want to close a file, just stop removing
|
||||
if (closeAllFiles()) {
|
||||
Q_ASSERT(count() == 0);
|
||||
emit requestRemoveSplit(this);
|
||||
}
|
||||
}
|
||||
|
||||
void VEditWindow::setRemoveSplitEnable(bool enabled)
|
||||
{
|
||||
removeSplitAct->setVisible(enabled);
|
||||
}
|
||||
|
||||
void VEditWindow::openWelcomePage()
|
||||
{
|
||||
int idx = openFileInTab("", vconfig.getWelcomePagePath(), false);
|
||||
setTabText(idx, "Welcome to VNote");
|
||||
setTabToolTip(idx, "VNote");
|
||||
}
|
||||
|
||||
int VEditWindow::insertTabWithData(int index, QWidget *page,
|
||||
const QJsonObject &tabData)
|
||||
{
|
||||
QString label = getFileName(tabData["relative_path"].toString());
|
||||
int idx = insertTab(index, page, label);
|
||||
QTabBar *tabs = tabBar();
|
||||
tabs->setTabData(idx, tabData);
|
||||
noticeTabStatus(currentIndex());
|
||||
return idx;
|
||||
}
|
||||
|
||||
int VEditWindow::appendTabWithData(QWidget *page, const QJsonObject &tabData)
|
||||
{
|
||||
return insertTabWithData(count(), page, tabData);
|
||||
}
|
||||
|
||||
int VEditWindow::openFile(const QString ¬ebook, const QString &relativePath, int mode)
|
||||
{
|
||||
// Find if it has been opened already
|
||||
int idx = findTabByFile(notebook, relativePath);
|
||||
if (idx > -1) {
|
||||
goto out;
|
||||
}
|
||||
idx = openFileInTab(notebook, relativePath, true);
|
||||
out:
|
||||
setCurrentIndex(idx);
|
||||
if (mode == OpenFileMode::Edit) {
|
||||
editFile();
|
||||
}
|
||||
focusWindow();
|
||||
return idx;
|
||||
}
|
||||
|
||||
void VEditWindow::closeFile(const QString ¬ebook, const QString &relativePath)
|
||||
{
|
||||
// Find if it has been opened already
|
||||
int idx = findTabByFile(notebook, relativePath);
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not check if modified
|
||||
VEditor *editor = getTab(idx);
|
||||
Q_ASSERT(editor);
|
||||
removeTab(idx);
|
||||
delete editor;
|
||||
}
|
||||
|
||||
bool VEditWindow::closeAllFiles()
|
||||
{
|
||||
int nrTab = count();
|
||||
for (int i = 0; i < nrTab; ++i) {
|
||||
// Always close the first tab
|
||||
if (!handleTabCloseRequest(0)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int VEditWindow::openFileInTab(const QString ¬ebook, const QString &relativePath,
|
||||
bool modifiable)
|
||||
{
|
||||
QString rootPath;
|
||||
const QVector<VNotebook> ¬ebooks = vnote->getNotebooks();
|
||||
for (int i = 0; i < notebooks.size(); ++i) {
|
||||
if (notebooks[i].getName() == notebook) {
|
||||
rootPath = notebooks[i].getPath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VEditor *editor = new VEditor(QDir::cleanPath(QDir(rootPath).filePath(relativePath)),
|
||||
modifiable);
|
||||
connect(editor, &VEditor::getFocused,
|
||||
this, &VEditWindow::getFocused);
|
||||
|
||||
QJsonObject tabJson;
|
||||
tabJson["notebook"] = notebook;
|
||||
tabJson["relative_path"] = relativePath;
|
||||
tabJson["modifiable"] = modifiable;
|
||||
return appendTabWithData(editor, tabJson);
|
||||
}
|
||||
|
||||
int VEditWindow::findTabByFile(const QString ¬ebook, const QString &relativePath) const
|
||||
{
|
||||
QTabBar *tabs = tabBar();
|
||||
int nrTabs = tabs->count();
|
||||
|
||||
for (int i = 0; i < nrTabs; ++i) {
|
||||
QJsonObject tabJson = tabs->tabData(i).toJsonObject();
|
||||
if (tabJson["notebook"] == notebook && tabJson["relative_path"] == relativePath) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool VEditWindow::handleTabCloseRequest(int index)
|
||||
{
|
||||
qDebug() << "request closing tab" << index;
|
||||
VEditor *editor = getTab(index);
|
||||
Q_ASSERT(editor);
|
||||
bool ok = editor->requestClose();
|
||||
if (ok) {
|
||||
removeTab(index);
|
||||
delete editor;
|
||||
}
|
||||
noticeTabStatus(currentIndex());
|
||||
// User clicks the close button. We should make this window
|
||||
// to be current window.
|
||||
emit getFocused();
|
||||
return ok;
|
||||
}
|
||||
|
||||
void VEditWindow::readFile()
|
||||
{
|
||||
VEditor *editor = getTab(currentIndex());
|
||||
Q_ASSERT(editor);
|
||||
editor->readFile();
|
||||
noticeTabStatus(currentIndex());
|
||||
}
|
||||
|
||||
void VEditWindow::saveAndReadFile()
|
||||
{
|
||||
saveFile();
|
||||
readFile();
|
||||
noticeTabStatus(currentIndex());
|
||||
}
|
||||
|
||||
void VEditWindow::editFile()
|
||||
{
|
||||
VEditor *editor = getTab(currentIndex());
|
||||
Q_ASSERT(editor);
|
||||
editor->editFile();
|
||||
noticeTabStatus(currentIndex());
|
||||
}
|
||||
|
||||
void VEditWindow::saveFile()
|
||||
{
|
||||
VEditor *editor = getTab(currentIndex());
|
||||
Q_ASSERT(editor);
|
||||
editor->saveFile();
|
||||
}
|
||||
|
||||
void VEditWindow::handleNotebookRenamed(const QVector<VNotebook> ¬ebooks,
|
||||
const QString &oldName, const QString &newName)
|
||||
{
|
||||
QTabBar *tabs = tabBar();
|
||||
int nrTabs = tabs->count();
|
||||
for (int i = 0; i < nrTabs; ++i) {
|
||||
QJsonObject tabJson = tabs->tabData(i).toJsonObject();
|
||||
if (tabJson["notebook"] == oldName) {
|
||||
tabJson["notebook"] = newName;
|
||||
tabs->setTabData(i, tabJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VEditWindow::noticeTabStatus(int index)
|
||||
{
|
||||
if (index == -1) {
|
||||
emit tabStatusChanged("", "", false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject tabJson = tabBar()->tabData(index).toJsonObject();
|
||||
Q_ASSERT(!tabJson.isEmpty());
|
||||
|
||||
QString notebook = tabJson["notebook"].toString();
|
||||
QString relativePath = tabJson["relative_path"].toString();
|
||||
VEditor *editor = getTab(index);
|
||||
bool editMode = editor->getIsEditMode();
|
||||
bool modifiable = tabJson["modifiable"].toBool();
|
||||
|
||||
emit tabStatusChanged(notebook, relativePath,
|
||||
editMode, modifiable);
|
||||
}
|
||||
|
||||
void VEditWindow::getTabStatus(QString ¬ebook, QString &relativePath,
|
||||
bool &editMode, bool &modifiable) const
|
||||
{
|
||||
int idx = currentIndex();
|
||||
if (idx == -1) {
|
||||
notebook = relativePath = "";
|
||||
editMode = modifiable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject tabJson = tabBar()->tabData(idx).toJsonObject();
|
||||
Q_ASSERT(!tabJson.isEmpty());
|
||||
notebook = tabJson["notebook"].toString();
|
||||
relativePath = tabJson["relative_path"].toString();
|
||||
VEditor *editor = getTab(idx);
|
||||
editMode = editor->getIsEditMode();
|
||||
modifiable = tabJson["modifiable"].toBool();
|
||||
}
|
||||
|
||||
void VEditWindow::focusWindow()
|
||||
{
|
||||
int idx = currentIndex();
|
||||
if (idx == -1) {
|
||||
setFocus();
|
||||
return;
|
||||
}
|
||||
getTab(idx)->focusTab();
|
||||
}
|
||||
|
||||
void VEditWindow::handleTabbarClicked(int index)
|
||||
{
|
||||
// The child will emit getFocused here
|
||||
focusWindow();
|
||||
noticeTabStatus(index);
|
||||
}
|
||||
|
||||
void VEditWindow::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
emit getFocused();
|
||||
QTabWidget::mousePressEvent(event);
|
||||
}
|
84
src/veditwindow.h
Normal file
84
src/veditwindow.h
Normal file
@ -0,0 +1,84 @@
|
||||
#ifndef VEDITWINDOW_H
|
||||
#define VEDITWINDOW_H
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include "vnotebook.h"
|
||||
#include "veditor.h"
|
||||
|
||||
class VNote;
|
||||
class QPushButton;
|
||||
|
||||
class VEditWindow : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VEditWindow(VNote *vnote, QWidget *parent = 0);
|
||||
int findTabByFile(const QString ¬ebook, const QString &relativePath) const;
|
||||
int openFile(const QString ¬ebook, const QString &relativePath,
|
||||
int mode);
|
||||
// Close the file forcely
|
||||
void closeFile(const QString ¬ebook, const QString &relativePath);
|
||||
void editFile();
|
||||
void saveFile();
|
||||
void readFile();
|
||||
void saveAndReadFile();
|
||||
void handleNotebookRenamed(const QVector<VNotebook> ¬ebooks, const QString &oldName,
|
||||
const QString &newName);
|
||||
bool closeAllFiles();
|
||||
void setRemoveSplitEnable(bool enabled);
|
||||
void getTabStatus(QString ¬ebook, QString &relativePath,
|
||||
bool &editMode, bool &modifiable) const;
|
||||
// Focus to current tab's editor
|
||||
void focusWindow();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
signals:
|
||||
void tabStatusChanged(const QString ¬ebook, const QString &relativePath,
|
||||
bool editMode, bool modifiable);
|
||||
void requestSplitWindow(VEditWindow *curWindow);
|
||||
void requestRemoveSplit(VEditWindow *curWindow);
|
||||
// This widget or its children get the focus
|
||||
void getFocused();
|
||||
|
||||
private slots:
|
||||
bool handleTabCloseRequest(int index);
|
||||
void splitWindow();
|
||||
void removeSplit();
|
||||
void handleTabbarClicked(int index);
|
||||
|
||||
private:
|
||||
void setupCornerWidget();
|
||||
void openWelcomePage();
|
||||
int insertTabWithData(int index, QWidget *page, const QJsonObject &tabData);
|
||||
int appendTabWithData(QWidget *page, const QJsonObject &tabData);
|
||||
int openFileInTab(const QString ¬ebook, const QString &relativePath, bool modifiable);
|
||||
inline QString getFileName(const QString &relativePath) const;
|
||||
inline VEditor *getTab(int tabIndex) const;
|
||||
void noticeTabStatus(int index);
|
||||
|
||||
VNote *vnote;
|
||||
// Button in the right corner
|
||||
QPushButton *rightBtn;
|
||||
|
||||
// Actions
|
||||
QAction *splitAct;
|
||||
QAction *removeSplitAct;
|
||||
};
|
||||
|
||||
inline QString VEditWindow::getFileName(const QString &path) const
|
||||
{
|
||||
return QFileInfo(QDir::cleanPath(path)).fileName();
|
||||
}
|
||||
|
||||
inline VEditor* VEditWindow::getTab(int tabIndex) const
|
||||
{
|
||||
return dynamic_cast<VEditor *>(widget(tabIndex));
|
||||
}
|
||||
|
||||
#endif // VEDITWINDOW_H
|
@ -4,11 +4,11 @@
|
||||
#include "vdirectorytree.h"
|
||||
#include "vnote.h"
|
||||
#include "vfilelist.h"
|
||||
#include "vtabwidget.h"
|
||||
#include "vconfigmanager.h"
|
||||
#include "dialog/vnewnotebookdialog.h"
|
||||
#include "dialog/vnotebookinfodialog.h"
|
||||
#include "utils/vutils.h"
|
||||
#include "veditarea.h"
|
||||
|
||||
extern VConfigManager vconfig;
|
||||
|
||||
@ -79,15 +79,14 @@ void VMainWindow::setupUI()
|
||||
fileList = new VFileList(vnote);
|
||||
fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
||||
|
||||
// Editor tab widget
|
||||
tabs = new VTabWidget(vnote);
|
||||
tabs->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
editArea = new VEditArea(vnote);
|
||||
editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
// Main Splitter
|
||||
mainSplitter = new QSplitter();
|
||||
mainSplitter->addWidget(nbContainer);
|
||||
mainSplitter->addWidget(fileList);
|
||||
mainSplitter->addWidget(tabs);
|
||||
mainSplitter->addWidget(editArea);
|
||||
mainSplitter->setStretchFactor(0, 0);
|
||||
mainSplitter->setStretchFactor(1, 0);
|
||||
mainSplitter->setStretchFactor(2, 1);
|
||||
@ -106,14 +105,14 @@ void VMainWindow::setupUI()
|
||||
this, &VMainWindow::handleFileListDirectoryChanged);
|
||||
|
||||
connect(fileList, &VFileList::fileClicked,
|
||||
tabs, &VTabWidget::openFile);
|
||||
editArea, &VEditArea::openFile);
|
||||
connect(fileList, &VFileList::fileDeleted,
|
||||
tabs, &VTabWidget::closeFile);
|
||||
editArea, &VEditArea::closeFile);
|
||||
connect(fileList, &VFileList::fileCreated,
|
||||
tabs, &VTabWidget::openFile);
|
||||
editArea, &VEditArea::openFile);
|
||||
connect(vnote, &VNote::notebooksRenamed,
|
||||
tabs, &VTabWidget::handleNotebookRenamed);
|
||||
connect(tabs, &VTabWidget::tabModeChanged,
|
||||
editArea, &VEditArea::handleNotebookRenamed);
|
||||
connect(editArea, &VEditArea::curTabStatusChanged,
|
||||
this, &VMainWindow::updateToolbarFromTabChage);
|
||||
|
||||
connect(newNotebookBtn, &QPushButton::clicked,
|
||||
@ -160,26 +159,26 @@ void VMainWindow::initActions()
|
||||
tr("&Edit"), this);
|
||||
editNoteAct->setStatusTip(tr("Edit current note"));
|
||||
connect(editNoteAct, &QAction::triggered,
|
||||
tabs, &VTabWidget::editFile);
|
||||
editArea, &VEditArea::editFile);
|
||||
|
||||
discardExitAct = new QAction(QIcon(":/resources/icons/discard_exit.svg"),
|
||||
tr("Discard changes and exit"), this);
|
||||
discardExitAct->setStatusTip(tr("Discard changes and exit edit mode"));
|
||||
connect(discardExitAct, &QAction::triggered,
|
||||
tabs, &VTabWidget::readFile);
|
||||
editArea, &VEditArea::readFile);
|
||||
|
||||
saveExitAct = new QAction(QIcon(":/resources/icons/save_exit.svg"),
|
||||
tr("Save changes and exit"), this);
|
||||
saveExitAct->setStatusTip(tr("Save changes and exit edit mode"));
|
||||
connect(saveExitAct, &QAction::triggered,
|
||||
tabs, &VTabWidget::saveAndReadFile);
|
||||
editArea, &VEditArea::saveAndReadFile);
|
||||
|
||||
saveNoteAct = new QAction(QIcon(":/resources/icons/save_note.svg"),
|
||||
tr("&Save"), this);
|
||||
saveNoteAct->setStatusTip(tr("Save current note"));
|
||||
saveNoteAct->setShortcut(QKeySequence::Save);
|
||||
connect(saveNoteAct, &QAction::triggered,
|
||||
tabs, &VTabWidget::saveFile);
|
||||
editArea, &VEditArea::saveFile);
|
||||
|
||||
viewAct = new QActionGroup(this);
|
||||
twoPanelViewAct = new QAction(QIcon(":/resources/icons/two_panels.svg"),
|
||||
|
@ -11,12 +11,12 @@ class QListWidget;
|
||||
class QTabWidget;
|
||||
class QToolBar;
|
||||
class VNote;
|
||||
class VTabWidget;
|
||||
class QAction;
|
||||
class QPushButton;
|
||||
class VNotebook;
|
||||
class QActionGroup;
|
||||
class VFileList;
|
||||
class VEditArea;
|
||||
|
||||
class VMainWindow : public QMainWindow
|
||||
{
|
||||
@ -65,6 +65,7 @@ private:
|
||||
|
||||
// If true, comboBox changes will not trigger any signal out
|
||||
bool notebookComboMuted;
|
||||
VNote *vnote;
|
||||
|
||||
QLabel *notebookLabel;
|
||||
QLabel *directoryLabel;
|
||||
@ -77,9 +78,8 @@ private:
|
||||
QPushButton *dirInfoBtn;
|
||||
VFileList *fileList;
|
||||
VDirectoryTree *directoryTree;
|
||||
VTabWidget *tabs;
|
||||
QSplitter *mainSplitter;
|
||||
VNote *vnote;
|
||||
VEditArea *editArea;
|
||||
|
||||
// Actions
|
||||
QAction *newNoteAct;
|
||||
|
@ -53,5 +53,8 @@
|
||||
<file>resources/icons/expand.svg</file>
|
||||
<file>resources/icons/two_panels.svg</file>
|
||||
<file>resources/icons/one_panel.svg</file>
|
||||
<file>resources/icons/split_window.svg</file>
|
||||
<file>resources/icons/corner_menu.svg</file>
|
||||
<file>resources/icons/remove_split.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -1,210 +0,0 @@
|
||||
#include <QtWidgets>
|
||||
#include <QtDebug>
|
||||
#include "vtabwidget.h"
|
||||
#include "veditor.h"
|
||||
#include "vnote.h"
|
||||
#include "vconfigmanager.h"
|
||||
|
||||
extern VConfigManager vconfig;
|
||||
|
||||
VTabWidget::VTabWidget(VNote *vnote, QWidget *parent)
|
||||
: QTabWidget(parent), vnote(vnote)
|
||||
{
|
||||
setTabsClosable(true);
|
||||
setMovable(true);
|
||||
connect(this, &VTabWidget::tabCloseRequested,
|
||||
this, &VTabWidget::handleTabCloseRequest);
|
||||
connect(this, &VTabWidget::currentChanged,
|
||||
this, &VTabWidget::onCurrentChanged);
|
||||
}
|
||||
|
||||
void VTabWidget::openWelcomePage()
|
||||
{
|
||||
int idx = openFileInTab("", vconfig.getWelcomePagePath(), false);
|
||||
setTabText(idx, "Welcome to VNote");
|
||||
setTabToolTip(idx, "VNote");
|
||||
}
|
||||
|
||||
int VTabWidget::insertTabWithData(int index, QWidget *page,
|
||||
const QJsonObject &tabData)
|
||||
{
|
||||
QString label = getFileName(tabData["relative_path"].toString());
|
||||
int idx = insertTab(index, page, label);
|
||||
QTabBar *tabs = tabBar();
|
||||
tabs->setTabData(idx, tabData);
|
||||
|
||||
// Need to update again with tabData
|
||||
onCurrentChanged(idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
int VTabWidget::appendTabWithData(QWidget *page, const QJsonObject &tabData)
|
||||
{
|
||||
return insertTabWithData(count(), page, tabData);
|
||||
}
|
||||
|
||||
void VTabWidget::openFile(QJsonObject fileJson)
|
||||
{
|
||||
if (fileJson.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString notebook = fileJson["notebook"].toString();
|
||||
QString relativePath = fileJson["relative_path"].toString();
|
||||
int mode = OpenFileMode::Read;
|
||||
if (fileJson.contains("mode")) {
|
||||
mode = fileJson["mode"].toInt();
|
||||
}
|
||||
|
||||
qDebug() << "open notebook" << notebook << "path" << relativePath << mode;
|
||||
|
||||
// Find if it has been opened already
|
||||
int idx = findTabByFile(notebook, relativePath);
|
||||
if (idx > -1) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
idx = openFileInTab(notebook, relativePath, true);
|
||||
|
||||
out:
|
||||
setCurrentIndex(idx);
|
||||
if (mode == OpenFileMode::Edit) {
|
||||
editFile();
|
||||
}
|
||||
}
|
||||
|
||||
void VTabWidget::closeFile(QJsonObject fileJson)
|
||||
{
|
||||
if (fileJson.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
qDebug() << "close file:" << fileJson;
|
||||
|
||||
QString notebook = fileJson["notebook"].toString();
|
||||
QString relativePath = fileJson["relative_path"].toString();
|
||||
|
||||
// Find if it has been opened already
|
||||
int idx = findTabByFile(notebook, relativePath);
|
||||
if (idx == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
QWidget* page = widget(idx);
|
||||
Q_ASSERT(page);
|
||||
removeTab(idx);
|
||||
delete page;
|
||||
}
|
||||
|
||||
int VTabWidget::openFileInTab(const QString ¬ebook, const QString &relativePath,
|
||||
bool modifiable)
|
||||
{
|
||||
QString rootPath;
|
||||
const QVector<VNotebook> ¬ebooks = vnote->getNotebooks();
|
||||
for (int i = 0; i < notebooks.size(); ++i) {
|
||||
if (notebooks[i].getName() == notebook) {
|
||||
rootPath = notebooks[i].getPath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VEditor *editor = new VEditor(QDir::cleanPath(QDir(rootPath).filePath(relativePath)),
|
||||
modifiable);
|
||||
QJsonObject tabJson;
|
||||
tabJson["notebook"] = notebook;
|
||||
tabJson["relative_path"] = relativePath;
|
||||
tabJson["modifiable"] = modifiable;
|
||||
return appendTabWithData(editor, tabJson);
|
||||
}
|
||||
|
||||
int VTabWidget::findTabByFile(const QString ¬ebook, const QString &relativePath) const
|
||||
{
|
||||
QTabBar *tabs = tabBar();
|
||||
int nrTabs = tabs->count();
|
||||
|
||||
for (int i = 0; i < nrTabs; ++i) {
|
||||
QJsonObject tabJson = tabs->tabData(i).toJsonObject();
|
||||
if (tabJson["notebook"] == notebook && tabJson["relative_path"] == relativePath) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void VTabWidget::handleTabCloseRequest(int index)
|
||||
{
|
||||
qDebug() << "request closing tab" << index;
|
||||
VEditor *editor = dynamic_cast<VEditor *>(widget(index));
|
||||
Q_ASSERT(editor);
|
||||
bool ok = editor->requestClose();
|
||||
if (ok) {
|
||||
removeTab(index);
|
||||
delete editor;
|
||||
}
|
||||
}
|
||||
|
||||
void VTabWidget::readFile()
|
||||
{
|
||||
VEditor *editor = dynamic_cast<VEditor *>(currentWidget());
|
||||
Q_ASSERT(editor);
|
||||
editor->readFile();
|
||||
onCurrentChanged(currentIndex());
|
||||
}
|
||||
|
||||
void VTabWidget::saveAndReadFile()
|
||||
{
|
||||
saveFile();
|
||||
readFile();
|
||||
onCurrentChanged(currentIndex());
|
||||
}
|
||||
|
||||
void VTabWidget::editFile()
|
||||
{
|
||||
VEditor *editor = dynamic_cast<VEditor *>(currentWidget());
|
||||
Q_ASSERT(editor);
|
||||
editor->editFile();
|
||||
onCurrentChanged(currentIndex());
|
||||
}
|
||||
|
||||
void VTabWidget::saveFile()
|
||||
{
|
||||
VEditor *editor = dynamic_cast<VEditor *>(currentWidget());
|
||||
Q_ASSERT(editor);
|
||||
editor->saveFile();
|
||||
}
|
||||
|
||||
void VTabWidget::handleNotebookRenamed(const QVector<VNotebook> ¬ebooks,
|
||||
const QString &oldName, const QString &newName)
|
||||
{
|
||||
QTabBar *tabs = tabBar();
|
||||
int nrTabs = tabs->count();
|
||||
for (int i = 0; i < nrTabs; ++i) {
|
||||
QJsonObject tabJson = tabs->tabData(i).toJsonObject();
|
||||
if (tabJson["notebook"] == oldName) {
|
||||
tabJson["notebook"] = newName;
|
||||
tabs->setTabData(i, tabJson);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VTabWidget::onCurrentChanged(int index)
|
||||
{
|
||||
if (index == -1) {
|
||||
emit tabModeChanged("", "", false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject tabJson = tabBar()->tabData(index).toJsonObject();
|
||||
if (tabJson.isEmpty()) {
|
||||
// Maybe the tab data has not been set yet
|
||||
return;
|
||||
}
|
||||
|
||||
QString notebook = tabJson["notebook"].toString();
|
||||
QString relativePath = tabJson["relative_path"].toString();
|
||||
VEditor *editor = (VEditor *)widget(index);
|
||||
bool editMode = editor->getIsEditMode();
|
||||
bool modifiable = tabJson["modifiable"].toBool();
|
||||
|
||||
emit tabModeChanged(notebook, relativePath,
|
||||
editMode, modifiable);
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
#ifndef VTABWIDGET_H
|
||||
#define VTABWIDGET_H
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
#include "vnotebook.h"
|
||||
|
||||
class VNote;
|
||||
|
||||
class VTabWidget : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VTabWidget(VNote *vnote, QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
void tabModeChanged(const QString ¬ebook, const QString &relativePath,
|
||||
bool editMode, bool modifiable);
|
||||
|
||||
public slots:
|
||||
void openFile(QJsonObject fileJson);
|
||||
// Close the file forcely
|
||||
void closeFile(QJsonObject fileJson);
|
||||
void editFile();
|
||||
void saveFile();
|
||||
void readFile();
|
||||
void saveAndReadFile();
|
||||
void handleNotebookRenamed(const QVector<VNotebook> ¬ebooks, const QString &oldName,
|
||||
const QString &newName);
|
||||
|
||||
private slots:
|
||||
void handleTabCloseRequest(int index);
|
||||
void onCurrentChanged(int index);
|
||||
|
||||
private:
|
||||
void openWelcomePage();
|
||||
int insertTabWithData(int index, QWidget *page, const QJsonObject &tabData);
|
||||
int appendTabWithData(QWidget *page, const QJsonObject &tabData);
|
||||
int findTabByFile(const QString ¬ebook, const QString &relativePath) const;
|
||||
int openFileInTab(const QString ¬ebook, const QString &relativePath, bool modifiable);
|
||||
inline QString getFileName(const QString &relativePath) const;
|
||||
|
||||
VNote *vnote;
|
||||
};
|
||||
|
||||
inline QString VTabWidget::getFileName(const QString &path) const
|
||||
{
|
||||
return QFileInfo(QDir::cleanPath(path)).fileName();
|
||||
}
|
||||
|
||||
#endif // VTABWIDGET_H
|
Loading…
x
Reference in New Issue
Block a user