diff --git a/VNote.pro b/VNote.pro index ced264f0..f335ae93 100644 --- a/VNote.pro +++ b/VNote.pro @@ -20,7 +20,9 @@ SOURCES += main.cpp\ vnewdirdialog.cpp \ vconfigmanager.cpp \ vfilelist.cpp \ - vnewfiledialog.cpp + vnewfiledialog.cpp \ + vtabwidget.cpp \ + vedit.cpp HEADERS += vmainwindow.h \ vdirectorytree.h \ @@ -29,7 +31,9 @@ HEADERS += vmainwindow.h \ vnewdirdialog.h \ vconfigmanager.h \ vfilelist.h \ - vnewfiledialog.h + vnewfiledialog.h \ + vtabwidget.h \ + vedit.h RESOURCES += \ vnote.qrc diff --git a/vedit.cpp b/vedit.cpp new file mode 100644 index 00000000..b87fe5eb --- /dev/null +++ b/vedit.cpp @@ -0,0 +1,45 @@ +#include +#include "vedit.h" + +VEdit::VEdit(const QString &path, const QString &name, + QWidget *parent) : QTextEdit(parent), path(path), name(name) +{ + fileText = readFile(QDir(path).filePath(name)); + showTextReadMode(); +} + +void VEdit::showTextReadMode() +{ + setText(fileText); + setReadOnly(true); +} + +QString VEdit::readFile(const QString &filePath) +{ + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning() << "error: fail to read file" << filePath; + return QString(); + } + QString fileText(file.readAll()); + file.close(); + return fileText; +} + +bool VEdit::writeFile(const QString &filePath, const QString &text) +{ + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + qWarning() << "error: fail to open file" << filePath << "to write to"; + return false; + } + QTextStream stream(&file); + stream << text; + file.close(); + return true; +} + +bool VEdit::requestClose() +{ + return true; +} diff --git a/vedit.h b/vedit.h new file mode 100644 index 00000000..cf2049d2 --- /dev/null +++ b/vedit.h @@ -0,0 +1,30 @@ +#ifndef VEDIT_H +#define VEDIT_H + +#include +#include + +class VEdit : public QTextEdit +{ + Q_OBJECT +public: + explicit VEdit(const QString &path, const QString &name, + QWidget *parent = 0); + bool requestClose(); + +signals: + +public slots: + + +private: + QString readFile(const QString &filePath); + bool writeFile(const QString &filePath, const QString &text); + void showTextReadMode(); + + QString path; + QString name; + QString fileText; +}; + +#endif // VEDIT_H diff --git a/vmainwindow.cpp b/vmainwindow.cpp index 908c41e6..61fc794a 100644 --- a/vmainwindow.cpp +++ b/vmainwindow.cpp @@ -3,6 +3,7 @@ #include "vdirectorytree.h" #include "vnote.h" #include "vfilelist.h" +#include "vtabwidget.h" VMainWindow::VMainWindow(QWidget *parent) : QMainWindow(parent) @@ -45,24 +46,15 @@ void VMainWindow::setupUI() fileList->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); // Editor tab widget - editorTabWidget = new QTabWidget(); - editorTabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - editorTabWidget->setTabBarAutoHide(true); - QFile welcomeFile(":/resources/welcome.html"); - QString welcomeText("Welcome to VNote!"); - if (welcomeFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - welcomeText = QString(welcomeFile.readAll()); - welcomeFile.close(); - } - QTextBrowser *welcomePage = new QTextBrowser(); - welcomePage->setHtml(welcomeText); - editorTabWidget->addTab(welcomePage, tr("Welcome to VNote")); + tabs = new VTabWidget(VNote::welcomePageUrl); + tabs->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + tabs->setTabBarAutoHide(true); // Main Splitter mainSplitter = new QSplitter(); mainSplitter->addWidget(nbContainer); mainSplitter->addWidget(fileList); - mainSplitter->addWidget(editorTabWidget); + mainSplitter->addWidget(tabs); mainSplitter->setStretchFactor(0, 1); mainSplitter->setStretchFactor(1, 1); mainSplitter->setStretchFactor(2, 10); @@ -74,6 +66,8 @@ void VMainWindow::setupUI() SLOT(setTreePath(const QString&))); connect(directoryTree, &VDirectoryTree::currentDirectoryChanged, fileList, &VFileList::setDirectory); + connect(fileList, &VFileList::currentFileChanged, + tabs, &VTabWidget::openFile); setCentralWidget(mainSplitter); // Create and show the status bar diff --git a/vmainwindow.h b/vmainwindow.h index 68cfc8a7..350d2fea 100644 --- a/vmainwindow.h +++ b/vmainwindow.h @@ -11,6 +11,7 @@ class QListWidget; class QTabWidget; class VNote; class VFileList; +class VTabWidget; class VMainWindow : public QMainWindow { @@ -36,7 +37,7 @@ private: QComboBox *notebookComboBox; VDirectoryTree *directoryTree; VFileList *fileList; - QTabWidget *editorTabWidget; + VTabWidget *tabs; QSplitter *mainSplitter; VNote *vnote; }; diff --git a/vnote.cpp b/vnote.cpp index 2b486524..f66f85c8 100644 --- a/vnote.cpp +++ b/vnote.cpp @@ -4,6 +4,7 @@ const QString VNote::orgName = QString("tamlok"); const QString VNote::appName = QString("VNote"); +const QString VNote::welcomePageUrl = QString(":/resources/welcome.html"); VNote::VNote() : curNotebookIndex(0) diff --git a/vnote.h b/vnote.h index a57cf92b..b06a023c 100644 --- a/vnote.h +++ b/vnote.h @@ -19,6 +19,7 @@ public: static const QString orgName; static const QString appName; + static const QString welcomePageUrl; private: // Write notebooks section of global config diff --git a/vtabwidget.cpp b/vtabwidget.cpp new file mode 100644 index 00000000..99196510 --- /dev/null +++ b/vtabwidget.cpp @@ -0,0 +1,94 @@ +#include +#include +#include "vtabwidget.h" +#include "vedit.h" + +VTabWidget::VTabWidget(const QString &welcomePageUrl, QWidget *parent) + : QTabWidget(parent), welcomePageUrl(welcomePageUrl) +{ + setTabsClosable(true); + connect(tabBar(), &QTabBar::tabCloseRequested, + this, &VTabWidget::handleTabCloseRequest); + + openWelcomePage(); +} + +void VTabWidget::openWelcomePage() +{ + int idx = openFileInTab(welcomePageUrl, ""); + setTabText(idx, "Welcome to VNote"); + setTabToolTip(idx, "VNote"); +} + +int VTabWidget::insertTabWithData(int index, QWidget *page, const QString &label, + const QJsonObject &tabData) +{ + int idx = insertTab(index, page, label); + QTabBar *tabs = tabBar(); + tabs->setTabData(idx, tabData); + Q_ASSERT(tabs->tabText(idx) == label); + return idx; +} + +int VTabWidget::appendTabWithData(QWidget *page, const QString &label, const QJsonObject &tabData) +{ + return insertTabWithData(count(), page, label, tabData); +} + +void VTabWidget::openFile(QJsonObject fileJson) +{ + if (fileJson.isEmpty()) { + return; + } + qDebug() << "open file:" << fileJson; + + QString path = fileJson["path"].toString(); + QString name = fileJson["name"].toString(); + + // Find if it has been opened already + int idx = findTabByFile(path, name); + if (idx > -1) { + setCurrentIndex(idx); + return; + } + + idx = openFileInTab(path, name); + + setCurrentIndex(idx); +} + +int VTabWidget::openFileInTab(const QString &path, const QString &name) +{ + VEdit *edit = new VEdit(path, name); + QJsonObject tabJson; + tabJson["path"] = path; + tabJson["name"] = name; + int idx = appendTabWithData(edit, name, tabJson); + setTabToolTip(idx, path); + return idx; +} + +int VTabWidget::findTabByFile(const QString &path, const QString &name) +{ + QTabBar *tabs = tabBar(); + int nrTabs = tabs->count(); + + for (int i = 0; i < nrTabs; ++i) { + QJsonObject tabJson = tabs->tabData(i).toJsonObject(); + if (tabJson["name"] == name && tabJson["path"] == path) { + return i; + } + } + return -1; +} + +void VTabWidget::handleTabCloseRequest(int index) +{ + qDebug() << "request closing tab" << index; + VEdit *edit = dynamic_cast(widget(index)); + bool ok = edit->requestClose(); + if (ok) { + removeTab(index); + delete edit; + } +} diff --git a/vtabwidget.h b/vtabwidget.h new file mode 100644 index 00000000..66b1be61 --- /dev/null +++ b/vtabwidget.h @@ -0,0 +1,31 @@ +#ifndef VTABWIDGET_H +#define VTABWIDGET_H + +#include +#include +#include + +class VTabWidget : public QTabWidget +{ + Q_OBJECT +public: + explicit VTabWidget(const QString &welcomePageUrl, QWidget *parent = 0); + +signals: + +public slots: + void openFile(QJsonObject fileJson); + +private slots: + void handleTabCloseRequest(int index); + +private: + void openWelcomePage(); + int insertTabWithData(int index, QWidget *page, const QString &label, const QJsonObject &tabData); + int appendTabWithData(QWidget *page, const QString &label, const QJsonObject &tabData); + int findTabByFile(const QString &path, const QString &name); + int openFileInTab(const QString &path, const QString &name); + QString welcomePageUrl; +}; + +#endif // VTABWIDGET_H