From 73ee02d3b27918c193ce20a3c5207fd573c93d5b Mon Sep 17 00:00:00 2001 From: Le Tan Date: Sun, 22 Oct 2017 21:26:39 +0800 Subject: [PATCH] support editing read-only files --- src/vedit.cpp | 20 ++++++++++++-------- src/vedit.h | 4 +++- src/veditwindow.h | 8 ++++---- src/vfile.cpp | 1 + src/vhtmltab.cpp | 45 ++++++++++++++++++++++++++++++++------------- src/vmainwindow.cpp | 14 +++++++------- src/vmdedit.cpp | 20 +++++++++++++------- src/vmdtab.cpp | 39 +++++++++++++++++++++++++++++---------- src/vmdtab.h | 5 ++--- 9 files changed, 103 insertions(+), 53 deletions(-) diff --git a/src/vedit.cpp b/src/vedit.cpp index 4d1669f0..9866bc56 100644 --- a/src/vedit.cpp +++ b/src/vedit.cpp @@ -141,20 +141,24 @@ void VEdit::beginEdit() updateConfig(); - setReadOnly(false); + setReadOnlyAndHighlight(false); + setModified(false); } void VEdit::endEdit() { - setReadOnly(true); + setReadOnlyAndHighlight(true); } void VEdit::saveFile() { + Q_ASSERT(m_file->isModifiable()); + if (!document()->isModified()) { return; } + m_file->setContent(toHtml()); setModified(false); } @@ -600,12 +604,6 @@ void VEdit::highlightCurrentLine() highlightExtraSelections(true); } -void VEdit::setReadOnly(bool p_ro) -{ - QTextEdit::setReadOnly(p_ro); - highlightCurrentLine(); -} - void VEdit::highlightSelectedWord() { QList &selects = m_extraSelections[(int)SelectionId::SelectedWord]; @@ -1469,3 +1467,9 @@ void VEdit::evaluateMagicWords() setTextCursor(cursor); } } + +void VEdit::setReadOnlyAndHighlight(bool p_readonly) +{ + setReadOnly(p_readonly); + highlightCurrentLine(); +} diff --git a/src/vedit.h b/src/vedit.h index f2d7e4b8..ff58524f 100644 --- a/src/vedit.h +++ b/src/vedit.h @@ -108,7 +108,6 @@ public: const QString &p_replaceText, bool p_findNext); void replaceTextAll(const QString &p_text, uint p_options, const QString &p_replaceText); - void setReadOnly(bool p_ro); // Clear SearchedKeyword highlight. void clearSearchedWordHighlight(); @@ -229,6 +228,9 @@ protected: // Called in contextMenuEvent() to modify the context menu. virtual void alterContextMenu(QMenu *p_menu, const QList &p_actions); + // Set read-only property and highlight current line. + void setReadOnlyAndHighlight(bool p_readonly); + private: QLabel *m_wrapLabel; QTimer *m_labelTimer; diff --git a/src/veditwindow.h b/src/veditwindow.h index 8e58ebb0..39c95eda 100644 --- a/src/veditwindow.h +++ b/src/veditwindow.h @@ -221,10 +221,10 @@ inline QString VEditWindow::generateTabText(int p_index, const VFile *p_file) co return ""; } - return QString("%1.%2%3").arg(QString::number(p_index + c_tabSequenceBase, 10)) - .arg(p_file->getName()) - .arg(p_file->isModifiable() - ? (p_file->isModified() ? "*" : "") : "#"); + return QString("%1.%2%3%4").arg(QString::number(p_index + c_tabSequenceBase, 10)) + .arg(p_file->getName()) + .arg(p_file->isModifiable() ? "" : "#") + .arg(p_file->isModified() ? "*" : ""); } #endif // VEDITWINDOW_H diff --git a/src/vfile.cpp b/src/vfile.cpp index 81e68629..198470c5 100644 --- a/src/vfile.cpp +++ b/src/vfile.cpp @@ -59,6 +59,7 @@ void VFile::close() bool VFile::save() { Q_ASSERT(m_opened); + Q_ASSERT(m_modifiable); bool ret = VUtils::writeFileToDisk(fetchPath(), m_content); if (ret) { m_modifiedTimeUtc = QDateTime::currentDateTimeUtc(); diff --git a/src/vhtmltab.cpp b/src/vhtmltab.cpp index 6c8fb40c..c751b2ef 100644 --- a/src/vhtmltab.cpp +++ b/src/vhtmltab.cpp @@ -63,10 +63,6 @@ void VHtmlTab::showFileReadMode() void VHtmlTab::showFileEditMode() { - if (!m_file->isModifiable()) { - return; - } - m_isEditMode = true; m_editor->beginEdit(); @@ -92,7 +88,7 @@ bool VHtmlTab::closeFile(bool p_forced) void VHtmlTab::editFile() { - if (m_isEditMode || !m_file->isModifiable()) { + if (m_isEditMode) { return; } @@ -107,15 +103,26 @@ void VHtmlTab::readFile() if (m_editor && m_editor->isModified()) { // Prompt to save the changes. - int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), + bool modifiable = m_file->isModifiable(); + int ret = VUtils::showMessage(QMessageBox::Information, + tr("Information"), tr("Note %2 has been modified.") .arg(g_config->c_dataTextStyle).arg(m_file->getName()), tr("Do you want to save your changes?"), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, - QMessageBox::Save, this); + modifiable ? (QMessageBox::Save + | QMessageBox::Discard + | QMessageBox::Cancel) + : (QMessageBox::Discard + | QMessageBox::Cancel), + modifiable ? QMessageBox::Save + : QMessageBox::Cancel, + this); switch (ret) { case QMessageBox::Save: - saveFile(); + if (!saveFile()) { + return; + } + // Fall through case QMessageBox::Discard: @@ -127,7 +134,7 @@ void VHtmlTab::readFile() return; default: - qWarning() << "wrong return value from QMessageBox:" << ret; + Q_ASSERT(false); return; } } @@ -145,10 +152,22 @@ bool VHtmlTab::saveFile() return true; } - bool ret; + QString filePath = m_file->fetchPath(); + + if (!m_file->isModifiable()) { + VUtils::showMessage(QMessageBox::Warning, + tr("Warning"), + tr("Could not modify a read-only note %2.") + .arg(g_config->c_dataTextStyle).arg(filePath), + tr("Please save your changes to other notes manually."), + QMessageBox::Ok, + QMessageBox::Ok, + this); + return false; + } + // Make sure the file already exists. Temporary deal with cases when user delete or move // a file. - QString filePath = m_file->fetchPath(); if (!QFileInfo::exists(filePath)) { qWarning() << filePath << "being written has been removed"; VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), @@ -159,7 +178,7 @@ bool VHtmlTab::saveFile() } m_editor->saveFile(); - ret = m_file->save(); + bool ret = m_file->save(); if (!ret) { VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), tr("Fail to write to disk when saving a note. Please try it again."), diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 068c2440..225598dd 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -1793,9 +1793,9 @@ void VMainWindow::updateActionsStateFromTab(const VEditTab *p_tab) discardExitAct->setVisible(file && editMode); saveExitAct->setVisible(file && editMode); - editNoteAct->setEnabled(file && file->isModifiable() && !editMode); + editNoteAct->setEnabled(file && !editMode); editNoteAct->setVisible(!saveExitAct->isVisible()); - saveNoteAct->setEnabled(file && editMode); + saveNoteAct->setEnabled(file && editMode && file->isModifiable()); deleteNoteAct->setEnabled(file && file->getType() == FileType::Note); noteInfoAct->setEnabled(file && !systemFile); @@ -1846,13 +1846,13 @@ void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info) title = QString("%1").arg(m_curFile->fetchPath()); } - if (m_curFile->isModifiable()) { - if (m_curFile->isModified()) { - title.append('*'); - } - } else { + if (!m_curFile->isModifiable()) { title.append('#'); } + + if (m_curFile->isModified()) { + title.append('*'); + } } updateWindowTitle(title); diff --git a/src/vmdedit.cpp b/src/vmdedit.cpp index 2ca757a0..3ac6067e 100644 --- a/src/vmdedit.cpp +++ b/src/vmdedit.cpp @@ -104,11 +104,11 @@ void VMdEdit::beginEdit() if (m_freshEdit) { // Will set to false when all async jobs completed. - setReadOnly(true); + setReadOnlyAndHighlight(true); // Disable and clear undo stacks temporary. setUndoRedoEnabled(false); } else { - setReadOnly(false); + setReadOnlyAndHighlight(false); } updateHeaders(m_mdHighlighter->getHeaderRegions()); @@ -116,12 +116,14 @@ void VMdEdit::beginEdit() void VMdEdit::endEdit() { - setReadOnly(true); + setReadOnlyAndHighlight(true); clearUnusedImages(); } void VMdEdit::saveFile() { + Q_ASSERT(m_file->isModifiable()); + if (!document()->isModified()) { return; } @@ -464,7 +466,9 @@ void VMdEdit::updateHeaders(const QVector &p_headerRegions) m_headers.clear(); - bool autoSequence = m_config.m_enableHeadingSequence && !isReadOnly(); + bool autoSequence = m_config.m_enableHeadingSequence + && !isReadOnly() + && m_file->isModifiable(); int headingSequenceBaseLevel = g_config->getHeadingSequenceBaseLevel(); if (headingSequenceBaseLevel < 1 || headingSequenceBaseLevel > 6) { headingSequenceBaseLevel = 1; @@ -523,9 +527,9 @@ QString VMdEdit::toPlainTextWithoutImg() { QString text; bool readOnly = isReadOnly(); - setReadOnly(true); + setReadOnlyAndHighlight(true); text = getPlainTextWithoutPreviewImage(); - setReadOnly(readOnly); + setReadOnlyAndHighlight(readOnly); return text; } @@ -806,7 +810,9 @@ void VMdEdit::finishOneAsyncJob(int p_idx) if (-1 == m_finishedAsyncJobs.indexOf(false)) { // All jobs finished. setUndoRedoEnabled(true); - setReadOnly(false); + + setReadOnlyAndHighlight(false); + setModified(false); m_freshEdit = false; emit statusChanged(); diff --git a/src/vmdtab.cpp b/src/vmdtab.cpp index 658d5d07..eb696908 100644 --- a/src/vmdtab.cpp +++ b/src/vmdtab.cpp @@ -181,10 +181,6 @@ void VMdTab::viewWebByConverter() void VMdTab::showFileEditMode() { - if (!m_file->isModifiable()) { - return; - } - VHeaderPointer header(m_currentHeader); m_isEditMode = true; @@ -227,7 +223,7 @@ bool VMdTab::closeFile(bool p_forced) void VMdTab::editFile() { - if (m_isEditMode || !m_file->isModifiable()) { + if (m_isEditMode) { return; } @@ -242,15 +238,25 @@ void VMdTab::readFile() if (m_editor && m_editor->isModified()) { // Prompt to save the changes. + bool modifiable = m_file->isModifiable(); int ret = VUtils::showMessage(QMessageBox::Information, tr("Information"), tr("Note %2 has been modified.") .arg(g_config->c_dataTextStyle).arg(m_file->getName()), tr("Do you want to save your changes?"), - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, - QMessageBox::Save, this); + modifiable ? (QMessageBox::Save + | QMessageBox::Discard + | QMessageBox::Cancel) + : (QMessageBox::Discard + | QMessageBox::Cancel), + modifiable ? QMessageBox::Save + : QMessageBox::Cancel, + this); switch (ret) { case QMessageBox::Save: - saveFile(); + if (!saveFile()) { + return; + } + // Fall through case QMessageBox::Discard: @@ -286,10 +292,23 @@ bool VMdTab::saveFile() return true; } + QString filePath = m_file->fetchPath(); + + if (!m_file->isModifiable()) { + VUtils::showMessage(QMessageBox::Warning, + tr("Warning"), + tr("Could not modify a read-only note %2.") + .arg(g_config->c_dataTextStyle).arg(filePath), + tr("Please save your changes to other notes manually."), + QMessageBox::Ok, + QMessageBox::Ok, + this); + return false; + } + bool ret = true; // Make sure the file already exists. Temporary deal with cases when user delete or move // a file. - QString filePath = m_file->fetchPath(); if (!QFileInfo::exists(filePath)) { qWarning() << filePath << "being written has been removed"; VUtils::showMessage(QMessageBox::Warning, tr("Warning"), tr("Fail to save note."), @@ -356,7 +375,7 @@ void VMdTab::setupMarkdownViewer() void VMdTab::setupMarkdownEditor() { - Q_ASSERT(m_file->isModifiable() && !m_editor); + Q_ASSERT(!m_editor); qDebug() << "create Markdown editor"; m_editor = new VMdEdit(m_file, m_document, m_mdConType, this); diff --git a/src/vmdtab.h b/src/vmdtab.h index 267df642..03dca941 100644 --- a/src/vmdtab.h +++ b/src/vmdtab.h @@ -169,11 +169,10 @@ inline VEdit *VMdTab::getEditor() { if (m_editor) { return m_editor; - } else if (m_file->isModifiable()) { + } else { setupMarkdownEditor(); + return m_editor; } - - return m_editor; } inline VEdit *VMdTab::getEditor() const