From 3f8c87a32517856561d7a1021e10245d6786549e Mon Sep 17 00:00:00 2001 From: Le Tan Date: Fri, 7 Oct 2016 10:56:28 +0800 Subject: [PATCH] add basic logics for handling html file Add edit/read/save logics for html file. Signed-off-by: Le Tan --- vedit.cpp | 127 ++++++++++++++++++++++++++++++++++++++++++++---- vedit.h | 20 ++++++-- vmainwindow.cpp | 30 +++++++++++- vmainwindow.h | 10 ++++ vtabwidget.cpp | 30 ++++++++++-- vtabwidget.h | 5 +- 6 files changed, 203 insertions(+), 19 deletions(-) diff --git a/vedit.cpp b/vedit.cpp index b87fe5eb..2e3692fd 100644 --- a/vedit.cpp +++ b/vedit.cpp @@ -1,20 +1,52 @@ #include #include "vedit.h" -VEdit::VEdit(const QString &path, const QString &name, - QWidget *parent) : QTextEdit(parent), path(path), name(name) +VEdit::VEdit(const QString &path, const QString &name, bool modifiable, + QWidget *parent) + : QTextEdit(parent), path(path), name(name), modifiable(modifiable) { - fileText = readFile(QDir(path).filePath(name)); - showTextReadMode(); + docType = isMarkdown() ? DocType::Markdown : DocType::Html; + fileText = readFileFromDisk(QDir(path).filePath(name)); + showFileReadMode(); + fileLoaded = true; + qDebug() << "VEdit:" << name << (docType == DocType::Markdown ? "Markdown" : "Html"); } -void VEdit::showTextReadMode() +void VEdit::showFileReadMode() { - setText(fileText); setReadOnly(true); + switch (docType) { + case DocType::Html: + if (!fileLoaded) { + setHtml(fileText); + } + break; + case DocType::Markdown: + setText(fileText); + break; + default: + qWarning() << "error: unknown doc type" << int(docType); + } } -QString VEdit::readFile(const QString &filePath) +void VEdit::showFileEditMode() +{ + setReadOnly(false); + switch (docType) { + case DocType::Html: + if (!fileLoaded) { + setHtml(fileText); + } + break; + case DocType::Markdown: + setText(fileText); + break; + default: + qWarning() << "error: unknown doc type" << int(docType); + } +} + +QString VEdit::readFileFromDisk(const QString &filePath) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { @@ -23,10 +55,11 @@ QString VEdit::readFile(const QString &filePath) } QString fileText(file.readAll()); file.close(); + qDebug() << "read file content:" << filePath; return fileText; } -bool VEdit::writeFile(const QString &filePath, const QString &text) +bool VEdit::writeFileToDisk(const QString &filePath, const QString &text) { QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { @@ -36,10 +69,86 @@ bool VEdit::writeFile(const QString &filePath, const QString &text) QTextStream stream(&file); stream << text; file.close(); + qDebug() << "write file content:" << filePath; return true; } bool VEdit::requestClose() { - return true; + readFile(); + return isReadOnly(); +} + +void VEdit::editFile() +{ + if (!modifiable || !isReadOnly()) { + return; + } + showFileEditMode(); +} + +void VEdit::readFile() +{ + if (isReadOnly()) { + return; + } + if (document()->isModified()) { + QMessageBox msgBox(QMessageBox::Information, tr("Exit edit mode"), + QString("Note has been changed. Do you want to save it before exit?")); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::No | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Save); + int ret = msgBox.exec(); + switch (ret) { + case QMessageBox::Save: + saveFile(); + // Fall through + case QMessageBox::No: + showFileReadMode(); + break; + case QMessageBox::Cancel: + break; + default: + qWarning() << "error: wrong return value from QMessageBox:" << ret; + } + } else { + showFileReadMode(); + } +} + +void VEdit::saveFile() +{ + if (!modifiable || !document()->isModified()) { + return; + } + + switch (docType) { + case DocType::Html: + fileText = toHtml(); + writeFileToDisk(QDir(path).filePath(name), fileText); + break; + case DocType::Markdown: + + break; + default: + qWarning() << "error: unknown doc type" << int(docType); + } + + document()->setModified(false); +} + +bool VEdit::isMarkdown() +{ + const QVector mdPostfix({"md", "markdown", "mkd"}); + + QStringList list = name.split('.', QString::SkipEmptyParts); + if (list.isEmpty()) { + return false; + } + const QString &postfix = list.last(); + for (int i = 0; i < mdPostfix.size(); ++i) { + if (postfix == mdPostfix[i]) { + return true; + } + } + return false; } diff --git a/vedit.h b/vedit.h index cf2049d2..380aee4d 100644 --- a/vedit.h +++ b/vedit.h @@ -8,9 +8,15 @@ class VEdit : public QTextEdit { Q_OBJECT public: - explicit VEdit(const QString &path, const QString &name, + explicit VEdit(const QString &path, const QString &name, bool modifiable = false, QWidget *parent = 0); bool requestClose(); + // Enter edit mode + void editFile(); + // Enter read mode + void readFile(); + // Save file + void saveFile(); signals: @@ -18,13 +24,19 @@ public slots: private: - QString readFile(const QString &filePath); - bool writeFile(const QString &filePath, const QString &text); - void showTextReadMode(); + enum class DocType { Html, Markdown }; + QString readFileFromDisk(const QString &filePath); + bool writeFileToDisk(const QString &filePath, const QString &text); + void showFileReadMode(); + void showFileEditMode(); + bool isMarkdown(); QString path; QString name; QString fileText; + DocType docType; + bool modifiable; + bool fileLoaded; }; #endif // VEDIT_H diff --git a/vmainwindow.cpp b/vmainwindow.cpp index 61fc794a..1609b980 100644 --- a/vmainwindow.cpp +++ b/vmainwindow.cpp @@ -9,7 +9,8 @@ VMainWindow::VMainWindow(QWidget *parent) : QMainWindow(parent) { setupUI(); - + initActions(); + initToolBar(); vnote = new VNote(); vnote->readGlobalConfig(); updateNotebookComboBox(); @@ -74,6 +75,33 @@ void VMainWindow::setupUI() statusBar(); } +void VMainWindow::initActions() +{ + editNoteAct = new QAction(tr("&Edit"), this); + editNoteAct->setStatusTip(tr("Edit current note")); + connect(editNoteAct, &QAction::triggered, + tabs, &VTabWidget::editFile); + + readNoteAct = new QAction(tr("&Read"), this); + readNoteAct->setStatusTip(tr("Open current note in read mode")); + connect(readNoteAct, &QAction::triggered, + tabs, &VTabWidget::readFile); + + saveNoteAct = new QAction(tr("&Save"), this); + saveNoteAct->setStatusTip(tr("Save current note")); + connect(saveNoteAct, &QAction::triggered, + tabs, &VTabWidget::saveFile); +} + +void VMainWindow::initToolBar() +{ + fileToolBar = addToolBar(tr("Note")); + fileToolBar->setMovable(false); + fileToolBar->addAction(editNoteAct); + fileToolBar->addAction(readNoteAct); + fileToolBar->addAction(saveNoteAct); +} + void VMainWindow::updateNotebookComboBox() { const QVector ¬ebooks = vnote->getNotebooks(); diff --git a/vmainwindow.h b/vmainwindow.h index 350d2fea..5fa561f5 100644 --- a/vmainwindow.h +++ b/vmainwindow.h @@ -9,9 +9,11 @@ class VDirectoryTree; class QSplitter; class QListWidget; class QTabWidget; +class QToolBar; class VNote; class VFileList; class VTabWidget; +class QAction; class VMainWindow : public QMainWindow { @@ -32,6 +34,8 @@ private: void setupUI(); // Update notebookComboBox according to vnote void updateNotebookComboBox(); + void initActions(); + void initToolBar(); QLabel *notebookLabel; QComboBox *notebookComboBox; @@ -40,6 +44,12 @@ private: VTabWidget *tabs; QSplitter *mainSplitter; VNote *vnote; + QToolBar *fileToolBar; + + // Actions + QAction *editNoteAct; + QAction *saveNoteAct; + QAction *readNoteAct; }; #endif // VMAINWINDOW_H diff --git a/vtabwidget.cpp b/vtabwidget.cpp index 99196510..44f02739 100644 --- a/vtabwidget.cpp +++ b/vtabwidget.cpp @@ -15,7 +15,7 @@ VTabWidget::VTabWidget(const QString &welcomePageUrl, QWidget *parent) void VTabWidget::openWelcomePage() { - int idx = openFileInTab(welcomePageUrl, ""); + int idx = openFileInTab(welcomePageUrl, "", false); setTabText(idx, "Welcome to VNote"); setTabToolTip(idx, "VNote"); } @@ -52,14 +52,14 @@ void VTabWidget::openFile(QJsonObject fileJson) return; } - idx = openFileInTab(path, name); + idx = openFileInTab(path, name, true); setCurrentIndex(idx); } -int VTabWidget::openFileInTab(const QString &path, const QString &name) +int VTabWidget::openFileInTab(const QString &path, const QString &name, bool modifiable) { - VEdit *edit = new VEdit(path, name); + VEdit *edit = new VEdit(path, name, modifiable); QJsonObject tabJson; tabJson["path"] = path; tabJson["name"] = name; @@ -86,9 +86,31 @@ void VTabWidget::handleTabCloseRequest(int index) { qDebug() << "request closing tab" << index; VEdit *edit = dynamic_cast(widget(index)); + Q_ASSERT(edit); bool ok = edit->requestClose(); if (ok) { removeTab(index); delete edit; } } + +void VTabWidget::readFile() +{ + VEdit *edit = dynamic_cast(currentWidget()); + Q_ASSERT(edit); + edit->readFile(); +} + +void VTabWidget::editFile() +{ + VEdit *edit = dynamic_cast(currentWidget()); + Q_ASSERT(edit); + edit->editFile(); +} + +void VTabWidget::saveFile() +{ + VEdit *edit = dynamic_cast(currentWidget()); + Q_ASSERT(edit); + edit->saveFile(); +} diff --git a/vtabwidget.h b/vtabwidget.h index 66b1be61..b9aea16f 100644 --- a/vtabwidget.h +++ b/vtabwidget.h @@ -15,6 +15,9 @@ signals: public slots: void openFile(QJsonObject fileJson); + void editFile(); + void saveFile(); + void readFile(); private slots: void handleTabCloseRequest(int index); @@ -24,7 +27,7 @@ private: 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); + int openFileInTab(const QString &path, const QString &name, bool modifiable); QString welcomePageUrl; };