support editing read-only files

This commit is contained in:
Le Tan 2017-10-22 21:26:39 +08:00
parent ae19191917
commit 73ee02d3b2
9 changed files with 103 additions and 53 deletions

View File

@ -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();
}

View File

@ -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;

View File

@ -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))
return QString("%1.%2%3%4").arg(QString::number(p_index + c_tabSequenceBase, 10))
.arg(p_file->getName())
.arg(p_file->isModifiable()
? (p_file->isModified() ? "*" : "") : "#");
.arg(p_file->isModifiable() ? "" : "#")
.arg(p_file->isModified() ? "*" : "");
}
#endif // VEDITWINDOW_H

View File

@ -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();

View File

@ -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."),

View File

@ -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->isModifiable()) {
title.append('#');
}
if (m_curFile->isModified()) {
title.append('*');
}
} else {
title.append('#');
}
}
updateWindowTitle(title);

View File

@ -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();

View File

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

View File

@ -169,12 +169,11 @@ inline VEdit *VMdTab::getEditor()
{
if (m_editor) {
return m_editor;
} else if (m_file->isModifiable()) {
} else {
setupMarkdownEditor();
}
return m_editor;
}
}
inline VEdit *VMdTab::getEditor() const
{