Browse Source

support editing read-only files

Le Tan 8 years ago
parent
commit
73ee02d3b2
9 changed files with 103 additions and 53 deletions
  1. 12 8
      src/vedit.cpp
  2. 3 1
      src/vedit.h
  3. 4 4
      src/veditwindow.h
  4. 1 0
      src/vfile.cpp
  5. 32 13
      src/vhtmltab.cpp
  6. 7 7
      src/vmainwindow.cpp
  7. 13 7
      src/vmdedit.cpp
  8. 29 10
      src/vmdtab.cpp
  9. 2 3
      src/vmdtab.h

+ 12 - 8
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<QTextEdit::ExtraSelection> &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();
+}

+ 3 - 1
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<QAction *> &p_actions);
 
+    // Set read-only property and highlight current line.
+    void setReadOnlyAndHighlight(bool p_readonly);
+
 private:
     QLabel *m_wrapLabel;
     QTimer *m_labelTimer;

+ 4 - 4
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

+ 1 - 0
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();

+ 32 - 13
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 <span style=\"%1\">%2</span> 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 <span style=\"%1\">%2</span>.")
+                              .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."),

+ 7 - 7
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);

+ 13 - 7
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<VElementRegion> &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();

+ 29 - 10
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 <span style=\"%1\">%2</span> 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 <span style=\"%1\">%2</span>.")
+                              .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);

+ 2 - 3
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