diff --git a/src/vedittab.cpp b/src/vedittab.cpp
index 72d756cc..b34396d6 100644
--- a/src/vedittab.cpp
+++ b/src/vedittab.cpp
@@ -6,8 +6,8 @@ VEditTab::VEditTab(VFile *p_file, VEditArea *p_editArea, QWidget *p_parent)
: QWidget(p_parent), m_file(p_file), m_isEditMode(false),
m_modified(false), m_editArea(p_editArea)
{
- m_toc.filePath = m_file->retrivePath();
- m_curHeader.filePath = m_file->retrivePath();
+ m_toc.m_file = m_file;
+ m_curHeader.m_file = m_file;
connect(qApp, &QApplication::focusChanged,
this, &VEditTab::handleFocusChanged);
diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp
index 7b47b6e3..d12f4881 100644
--- a/src/veditwindow.cpp
+++ b/src/veditwindow.cpp
@@ -516,7 +516,7 @@ void VEditWindow::handleOutlineChanged(const VToc &p_toc)
return;
}
const VFile *file = getTab(idx)->getFile();
- if (p_toc.filePath == file->retrivePath()) {
+ if (p_toc.m_file == file) {
emit outlineChanged(p_toc);
}
}
@@ -530,7 +530,7 @@ void VEditWindow::handleCurHeaderChanged(const VAnchor &p_anchor)
return;
}
const VFile *file = getTab(idx)->getFile();
- if (p_anchor.filePath == file->retrivePath()) {
+ if (p_anchor.m_file == file) {
emit curHeaderChanged(p_anchor);
}
}
@@ -543,7 +543,7 @@ void VEditWindow::scrollCurTab(const VAnchor &p_anchor)
return;
}
const VFile *file = getTab(idx)->getFile();
- if (file->retrivePath() == p_anchor.filePath) {
+ if (file == p_anchor.m_file) {
getTab(idx)->scrollToAnchor(p_anchor);
}
}
diff --git a/src/vfile.cpp b/src/vfile.cpp
index 197ab5b9..b51e49e6 100644
--- a/src/vfile.cpp
+++ b/src/vfile.cpp
@@ -236,3 +236,41 @@ QUrl VFile::getBaseUrl() const
return baseUrl;
}
+
+bool VFile::rename(const QString &p_name)
+{
+ if (m_name == p_name) {
+ return true;
+ }
+
+ QString oldName = m_name;
+
+ VDirectory *dir = getDirectory();
+ V_ASSERT(dir);
+ // Rename it in disk.
+ QDir diskDir(dir->retrivePath());
+ if (!diskDir.rename(m_name, p_name)) {
+ qWarning() << "fail to rename note" << m_name << "to" << p_name << "in disk";
+ return false;
+ }
+
+ m_name = p_name;
+
+ // Update parent directory's config file.
+ if (!dir->writeToConfig()) {
+ m_name = oldName;
+ diskDir.rename(p_name, m_name);
+ return false;
+ }
+
+ // Handle DocType change.
+ DocType newType = VUtils::docTypeFromName(m_name);
+ if (m_docType != newType) {
+ convert(m_docType, newType);
+ m_docType = newType;
+ }
+
+ qDebug() << "note renamed from" << oldName << "to" << m_name;
+
+ return true;
+}
diff --git a/src/vfile.h b/src/vfile.h
index fc24a3b1..dc63f8b5 100644
--- a/src/vfile.h
+++ b/src/vfile.h
@@ -49,6 +49,9 @@ public:
// directory of this file.
virtual bool isInternalImageFolder(const QString &p_path) const;
+ // Rename the file.
+ virtual bool rename(const QString &p_name);
+
public slots:
void setModified(bool p_modified);
diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp
index 334aee8f..44f0969c 100644
--- a/src/vfilelist.cpp
+++ b/src/vfilelist.cpp
@@ -151,29 +151,55 @@ void VFileList::fileInfo(VFile *p_file)
defaultName = name;
continue;
}
- copyFile(dir, name, p_file, true);
+
+ if (!promptForDocTypeChange(p_file, QDir(p_file->retriveBasePath()).filePath(name))) {
+ return;
+ }
+
+ if (!p_file->rename(name)) {
+ VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
+ tr("Fail to rename note %2.")
+ .arg(vconfig.c_dataTextStyle).arg(curName), "",
+ QMessageBox::Ok, QMessageBox::Ok, this);
+ return;
+ }
+
+ QListWidgetItem *item = findItem(p_file);
+ if (item) {
+ fillItem(item, p_file);
+ }
+
+ emit fileUpdated(p_file);
}
break;
} while (true);
}
+void VFileList::fillItem(QListWidgetItem *p_item, const VFile *p_file)
+{
+ unsigned long long ptr = (long long)p_file;
+ p_item->setData(Qt::UserRole, ptr);
+ p_item->setToolTip(p_file->getName());
+ p_item->setText(p_file->getName());
+
+ V_ASSERT(sizeof(p_file) <= sizeof(ptr));
+}
+
QListWidgetItem* VFileList::insertFileListItem(VFile *file, bool atFront)
{
- Q_ASSERT(file);
- QString fileName = file->getName();
- QListWidgetItem *item = new QListWidgetItem(fileName);
- unsigned long long ptr = (long long)file;
- item->setData(Qt::UserRole, ptr);
- item->setToolTip(fileName);
- Q_ASSERT(sizeof(file) <= sizeof(ptr));
+ V_ASSERT(file);
+ QListWidgetItem *item = new QListWidgetItem();
+ fillItem(item, file);
+
if (atFront) {
fileList->insertItem(0, item);
} else {
fileList->addItem(item);
}
+
// Qt seems not to update the QListWidget correctly. Manually force it to repaint.
fileList->update();
- qDebug() << "VFileList adds" << fileName;
+ qDebug() << "VFileList adds" << file->getName();
return item;
}
@@ -464,8 +490,23 @@ bool VFileList::copyFile(VDirectory *p_destDir, const QString &p_destName, VFile
}
// If change the file type, we need to close it first
+ if (!promptForDocTypeChange(p_file, destPath)) {
+ return false;
+ }
+
+ VFile *destFile = VDirectory::copyFile(p_destDir, p_destName, p_file, p_cut);
+ updateFileList();
+ if (destFile) {
+ emit fileUpdated(destFile);
+ }
+ return destFile != NULL;
+}
+
+bool VFileList::promptForDocTypeChange(const VFile *p_file, const QString &p_newFilePath)
+{
DocType docType = p_file->getDocType();
- DocType newDocType = VUtils::docTypeFromName(destPath);
+ DocType newDocType = VUtils::docTypeFromName(p_newFilePath);
+
if (docType != newDocType) {
if (editArea->isFileOpened(p_file)) {
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
@@ -483,12 +524,7 @@ bool VFileList::copyFile(VDirectory *p_destDir, const QString &p_destName, VFile
}
}
- VFile *destFile = VDirectory::copyFile(p_destDir, p_destName, p_file, p_cut);
- updateFileList();
- if (destFile) {
- emit fileUpdated(destFile);
- }
- return destFile != NULL;
+ return true;
}
void VFileList::keyPressEvent(QKeyEvent *event)
diff --git a/src/vfilelist.h b/src/vfilelist.h
index 778d9f9c..93ebfd7f 100644
--- a/src/vfilelist.h
+++ b/src/vfilelist.h
@@ -71,7 +71,10 @@ private:
QListWidgetItem *insertFileListItem(VFile *file, bool atFront = false);
void removeFileListItem(QListWidgetItem *item);
void initActions();
+
+ // Return the corresponding QListWidgetItem of @p_file.
QListWidgetItem *findItem(const VFile *p_file);
+
void copyFileInfoToClipboard(const QJsonArray &p_files, bool p_isCut);
void pasteFiles(VDirectory *p_destDir);
bool copyFile(VDirectory *p_destDir, const QString &p_destName, VFile *p_file, bool p_cut);
@@ -82,6 +85,16 @@ private:
bool identicalListWithDirectory() const;
QList getVisibleItems() const;
+ // @p_file: the file to be renamed or copied.
+ // @p_newFilePath: the new file path of @p_file.
+ // Check if the rename/copy will change the DocType. If yes, then ask
+ // user for confirmation.
+ // Return true if we can continue.
+ bool promptForDocTypeChange(const VFile *p_file, const QString &p_newFilePath);
+
+ // Fill the info of @p_item according to @p_file.
+ void fillItem(QListWidgetItem *p_item, const VFile *p_file);
+
VEditArea *editArea;
QListWidget *fileList;
QPointer m_directory;
diff --git a/src/vmdtab.cpp b/src/vmdtab.cpp
index cbbef982..0385e639 100644
--- a/src/vmdtab.cpp
+++ b/src/vmdtab.cpp
@@ -451,7 +451,7 @@ void VMdTab::updateTocFromHtml(const QString &p_tocHtml)
return;
}
- m_toc.filePath = m_file->retrivePath();
+ m_toc.m_file = m_file;
m_toc.valid = true;
emit outlineChanged(m_toc);
@@ -465,7 +465,7 @@ void VMdTab::updateTocFromHeaders(const QVector &p_headers)
m_toc.type = VHeaderType::LineNumber;
m_toc.headers = p_headers;
- m_toc.filePath = m_file->retrivePath();
+ m_toc.m_file = m_file;
m_toc.valid = true;
emit outlineChanged(m_toc);
@@ -495,7 +495,7 @@ void VMdTab::updateCurHeader(const QString &p_anchor)
return;
}
- m_curHeader = VAnchor(m_file->retrivePath(), "#" + p_anchor, -1);
+ m_curHeader = VAnchor(m_file, "#" + p_anchor, -1);
if (!p_anchor.isEmpty()) {
const QVector &headers = m_toc.headers;
for (int i = 0; i < headers.size(); ++i) {
@@ -515,7 +515,7 @@ void VMdTab::updateCurHeader(int p_lineNumber, int p_outlineIndex)
return;
}
- m_curHeader = VAnchor(m_file->retrivePath(), "", p_lineNumber);
+ m_curHeader = VAnchor(m_file, "", p_lineNumber);
m_curHeader.m_outlineIndex = p_outlineIndex;
if (p_lineNumber > -1) {
emit curHeaderChanged(m_curHeader);
diff --git a/src/vorphanfile.cpp b/src/vorphanfile.cpp
index 7a13aa46..444c34b6 100644
--- a/src/vorphanfile.cpp
+++ b/src/vorphanfile.cpp
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
#include "utils/vutils.h"
VOrphanFile::VOrphanFile(const QString &p_path, QObject *p_parent)
@@ -91,3 +92,16 @@ bool VOrphanFile::isInternalImageFolder(const QString &p_path) const
{
return VUtils::basePathFromPath(p_path) == VUtils::basePathFromPath(m_path);
}
+
+bool VOrphanFile::rename(const QString &p_name)
+{
+ QDir dir(retriveBasePath());
+ if (!dir.rename(m_name, p_name)) {
+ qWarning() << "fail to rename note" << m_name << "to" << p_name << "in disk";
+ return false;
+ }
+
+ m_name = p_name;
+ m_path = dir.filePath(m_name);
+ return true;
+}
diff --git a/src/vorphanfile.h b/src/vorphanfile.h
index 7848880d..900cd271 100644
--- a/src/vorphanfile.h
+++ b/src/vorphanfile.h
@@ -19,6 +19,9 @@ public:
QString getNotebookName() const Q_DECL_OVERRIDE;
VNotebook *getNotebook() Q_DECL_OVERRIDE;
+ // Rename file.
+ bool rename(const QString &p_name) Q_DECL_OVERRIDE;
+
private:
bool save() Q_DECL_OVERRIDE;
void convert(DocType p_curType, DocType p_targetType) Q_DECL_OVERRIDE;
diff --git a/src/voutline.cpp b/src/voutline.cpp
index 85ac0970..7158424e 100644
--- a/src/voutline.cpp
+++ b/src/voutline.cpp
@@ -92,7 +92,7 @@ void VOutline::handleCurItemChanged(QTreeWidgetItem *p_curItem, QTreeWidgetItem
int lineNumber = itemJson["line_number"].toInt();
int outlineIndex = itemJson["outline_index"].toInt();
VAnchor tmp;
- tmp.filePath = outline.filePath;
+ tmp.m_file = outline.m_file;
tmp.anchor = anchor;
tmp.lineNumber = lineNumber;
tmp.m_outlineIndex = outlineIndex;
diff --git a/src/vtoc.h b/src/vtoc.h
index 27b28e46..8b0227c3 100644
--- a/src/vtoc.h
+++ b/src/vtoc.h
@@ -4,6 +4,8 @@
#include
#include
+class VFile;
+
enum VHeaderType
{
Anchor = 0,
@@ -24,16 +26,16 @@ struct VHeader
struct VAnchor
{
VAnchor() : lineNumber(-1), m_outlineIndex(0) {}
- VAnchor(const QString filePath, const QString &anchor, int lineNumber)
- : filePath(filePath), anchor(anchor), lineNumber(lineNumber), m_outlineIndex(0) {}
- QString filePath;
+ VAnchor(const VFile *file, const QString &anchor, int lineNumber)
+ : m_file(file), anchor(anchor), lineNumber(lineNumber), m_outlineIndex(0) {}
+ const VFile *m_file;
QString anchor;
int lineNumber;
// Index of this anchor in VToc outline.
int m_outlineIndex;
bool operator==(const VAnchor &p_anchor) const {
- return (p_anchor.filePath == filePath
+ return (p_anchor.m_file == m_file
&& p_anchor.anchor == anchor
&& p_anchor.lineNumber == lineNumber);
}
@@ -46,7 +48,7 @@ public:
QVector headers;
int type;
- QString filePath;
+ const VFile *m_file;
bool valid;
};