complete rename logics

1. Handle directory rename correctly;
2. Handle file rename correctly;

Signed-off-by: Le Tan <tamlokveer@gmail.com>
This commit is contained in:
Le Tan 2016-11-13 18:24:37 +08:00
parent 5e97ca8060
commit 62c75427e7
11 changed files with 195 additions and 47 deletions

View File

@ -91,3 +91,20 @@ void VUtils::processStyle(QString &style)
style.replace("@" + map.first, map.second);
}
}
bool VUtils::isMarkdown(const QString &name)
{
const QVector<QString> 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;
}

View File

@ -19,6 +19,7 @@ public:
static QString generateImageFileName(const QString &path, const QString &title,
const QString &format = "png");
static void processStyle(QString &style);
static bool isMarkdown(const QString &fileName);
private:
static inline void addQssVarToMap(QVector<QPair<QString, QString> > &map,
const QString &key, const QString &value);

View File

@ -178,19 +178,22 @@ void VEditArea::updateWindowStatus()
win->requestUpdateCurHeader();
}
void VEditArea::closeFile(QJsonObject fileJson)
bool VEditArea::closeFile(QJsonObject fileJson)
{
if (fileJson.isEmpty()) {
return;
return true;
}
QString notebook = fileJson["notebook"].toString();
QString relativePath = fileJson["relative_path"].toString();
bool isForced = fileJson["is_forced"].toBool();
int nrWin = splitter->count();
bool ret = false;
for (int i = 0; i < nrWin; ++i) {
VEditWindow *win = getWindow(i);
win->closeFile(notebook, relativePath);
ret = ret || win->closeFile(notebook, relativePath, isForced);
}
return ret;
}
void VEditArea::editFile()
@ -225,6 +228,29 @@ void VEditArea::handleNotebookRenamed(const QVector<VNotebook> &notebooks,
VEditWindow *win = getWindow(i);
win->handleNotebookRenamed(notebooks, oldName, newName);
}
updateWindowStatus();
}
void VEditArea::handleDirectoryRenamed(const QString &notebook, const QString &oldRelativePath,
const QString &newRelativePath)
{
int nrWin = splitter->count();
for (int i = 0; i < nrWin; ++i) {
VEditWindow *win = getWindow(i);
win->handleDirectoryRenamed(notebook, oldRelativePath, newRelativePath);
}
updateWindowStatus();
}
void VEditArea::handleFileRenamed(const QString &notebook,
const QString &oldRelativePath, const QString &newRelativePath)
{
int nrWin = splitter->count();
for (int i = 0; i < nrWin; ++i) {
VEditWindow *win = getWindow(i);
win->handleFileRenamed(notebook, oldRelativePath, newRelativePath);
}
updateWindowStatus();
}
void VEditArea::handleSplitWindowRequest(VEditWindow *curWindow)
@ -305,3 +331,8 @@ void VEditArea::handleOutlineItemActivated(const VAnchor &anchor)
// Notice current window
getWindow(curWindowIndex)->scrollCurTab(anchor);
}
bool VEditArea::isFileOpened(const QString &notebook, const QString &relativePath)
{
return !findTabsByFile(notebook, relativePath).isEmpty();
}

View File

@ -21,6 +21,7 @@ class VEditArea : public QWidget
Q_OBJECT
public:
explicit VEditArea(VNote *vnote, QWidget *parent = 0);
bool isFileOpened(const QString &notebook, const QString &relativePath);
signals:
void curTabStatusChanged(const QString &notebook, const QString &relativePath,
@ -33,8 +34,7 @@ protected:
public slots:
void openFile(QJsonObject fileJson);
// Close the file forcely
void closeFile(QJsonObject fileJson);
bool closeFile(QJsonObject fileJson);
void editFile();
void saveFile();
void readFile();
@ -42,6 +42,10 @@ public slots:
void handleNotebookRenamed(const QVector<VNotebook> &notebooks, const QString &oldName,
const QString &newName);
void handleOutlineItemActivated(const VAnchor &anchor);
void handleDirectoryRenamed(const QString &notebook,
const QString &oldRelativePath, const QString &newRelativePath);
void handleFileRenamed(const QString &notebook,
const QString &oldRelativePath, const QString &newRelativePath);
private slots:
void handleSplitWindowRequest(VEditWindow *curWindow);

View File

@ -21,7 +21,7 @@ extern VConfigManager vconfig;
VEditTab::VEditTab(const QString &path, bool modifiable, QWidget *parent)
: QStackedWidget(parent), mdConverterType(vconfig.getMdConverterType())
{
DocType docType = isMarkdown(path) ? DocType::Markdown : DocType::Html;
DocType docType = VUtils::isMarkdown(path) ? DocType::Markdown : DocType::Html;
QString basePath = QFileInfo(path).path();
QString fileName = QFileInfo(path).fileName();
qDebug() << "VEditTab basePath" << basePath << "file" << fileName;
@ -75,23 +75,6 @@ void VEditTab::setupUI()
}
}
bool VEditTab::isMarkdown(const QString &name)
{
const QVector<QString> 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;
}
void VEditTab::showFileReadMode()
{
isEditMode = false;
@ -402,3 +385,10 @@ void VEditTab::updateCurHeader(int lineNumber)
emit curHeaderChanged(curHeader);
}
}
void VEditTab::updatePath(const QString &newPath)
{
QFileInfo info(newPath);
noteFile->basePath = info.path();
noteFile->fileName = info.fileName();
}

View File

@ -36,6 +36,7 @@ public:
void requestUpdateOutline();
void requestUpdateCurHeader();
void scrollToAnchor(const VAnchor& anchor);
void updatePath(const QString &newPath);
signals:
void getFocused();
@ -51,7 +52,6 @@ private slots:
void updateTocFromHeaders(const QVector<VHeader> &headers);
private:
bool isMarkdown(const QString &name);
void setupUI();
void showFileReadMode();
void showFileEditMode();

View File

@ -123,21 +123,26 @@ out:
return idx;
}
void VEditWindow::closeFile(const QString &notebook, const QString &relativePath)
bool VEditWindow::closeFile(const QString &notebook, const QString &relativePath, bool isForced)
{
// Find if it has been opened already
int idx = findTabByFile(notebook, relativePath);
if (idx == -1) {
return;
return true;
}
// Do not check if modified
VEditTab *editor = getTab(idx);
Q_ASSERT(editor);
bool ok = true;
if (!isForced) {
ok = editor->requestClose();
}
if (ok) {
removeTab(idx);
delete editor;
}
updateTabListMenu();
return ok;
}
bool VEditWindow::closeAllFiles()
@ -155,17 +160,8 @@ bool VEditWindow::closeAllFiles()
int VEditWindow::openFileInTab(const QString &notebook, const QString &relativePath,
bool modifiable)
{
QString rootPath;
const QVector<VNotebook> &notebooks = vnote->getNotebooks();
for (int i = 0; i < notebooks.size(); ++i) {
if (notebooks[i].getName() == notebook) {
rootPath = notebooks[i].getPath();
break;
}
}
VEditTab *editor = new VEditTab(QDir::cleanPath(QDir(rootPath).filePath(relativePath)),
modifiable);
QString path = QDir::cleanPath(QDir(vnote->getNotebookPath(notebook)).filePath(relativePath));
VEditTab *editor = new VEditTab(path, modifiable);
connect(editor, &VEditTab::getFocused,
this, &VEditWindow::getFocused);
connect(editor, &VEditTab::outlineChanged,
@ -200,7 +196,6 @@ int VEditWindow::findTabByFile(const QString &notebook, const QString &relativeP
bool VEditWindow::handleTabCloseRequest(int index)
{
qDebug() << "request closing tab" << index;
VEditTab *editor = getTab(index);
Q_ASSERT(editor);
bool ok = editor->requestClose();
@ -262,6 +257,51 @@ void VEditWindow::handleNotebookRenamed(const QVector<VNotebook> &notebooks,
updateTabListMenu();
}
void VEditWindow::handleDirectoryRenamed(const QString &notebook, const QString &oldRelativePath,
const QString &newRelativePath)
{
QTabBar *tabs = tabBar();
int nrTabs = tabs->count();
for (int i = 0; i < nrTabs; ++i) {
QJsonObject tabJson = tabs->tabData(i).toJsonObject();
if (tabJson["notebook"].toString() == notebook) {
QString relativePath = tabJson["relative_path"].toString();
if (relativePath.startsWith(oldRelativePath)) {
relativePath.replace(0, oldRelativePath.size(), newRelativePath);
tabJson["relative_path"] = relativePath;
tabs->setTabData(i, tabJson);
tabs->setTabToolTip(i, generateTooltip(tabJson));
QString path = QDir::cleanPath(QDir(vnote->getNotebookPath(notebook)).filePath(relativePath));
getTab(i)->updatePath(path);
}
}
}
updateTabListMenu();
}
void VEditWindow::handleFileRenamed(const QString &notebook, const QString &oldRelativePath,
const QString &newRelativePath)
{
QTabBar *tabs = tabBar();
int nrTabs = tabs->count();
for (int i = 0; i < nrTabs; ++i) {
QJsonObject tabJson = tabs->tabData(i).toJsonObject();
if (tabJson["notebook"].toString() == notebook) {
QString relativePath = tabJson["relative_path"].toString();
if (relativePath == oldRelativePath) {
relativePath = newRelativePath;
tabJson["relative_path"] = relativePath;
tabs->setTabData(i, tabJson);
tabs->setTabToolTip(i, generateTooltip(tabJson));
tabs->setTabText(i, getFileName(relativePath));
QString path = QDir::cleanPath(QDir(vnote->getNotebookPath(notebook)).filePath(relativePath));
getTab(i)->updatePath(path);
}
}
}
updateTabListMenu();
}
void VEditWindow::noticeTabStatus(int index)
{
if (index == -1) {

View File

@ -22,8 +22,7 @@ public:
int findTabByFile(const QString &notebook, const QString &relativePath) const;
int openFile(const QString &notebook, const QString &relativePath,
int mode);
// Close the file forcely
void closeFile(const QString &notebook, const QString &relativePath);
bool closeFile(const QString &notebook, const QString &relativePath, bool isForced);
void editFile();
void saveFile();
void readFile();
@ -38,6 +37,10 @@ public:
// Focus to current tab's editor
void focusWindow();
void scrollCurTab(const VAnchor &anchor);
void handleDirectoryRenamed(const QString &notebook,
const QString &oldRelativePath, const QString &newRelativePath);
void handleFileRenamed(const QString &notebook,
const QString &oldRelativePath, const QString &newRelativePath);
protected:
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;

View File

@ -5,6 +5,8 @@
#include "dialog/vnewfiledialog.h"
#include "dialog/vfileinfodialog.h"
#include "vnote.h"
#include "veditarea.h"
#include "utils/vutils.h"
VFileList::VFileList(VNote *vnote, QWidget *parent)
: QWidget(parent), vnote(vnote)
@ -219,6 +221,7 @@ void VFileList::deleteFile()
// First close this file forcely
curItemJson["notebook"] = notebook;
curItemJson["relative_path"] = QDir::cleanPath(QDir(relativePath).filePath(curItemName));
curItemJson["is_forced"] = true;
emit fileDeleted(curItemJson);
deleteFileAndUpdateList(curItem);
@ -399,13 +402,12 @@ void VFileList::handleNotebookRenamed(const QVector<VNotebook> &notebooks,
}
}
// FIXME: when @oldRelativePath is part of relativePath, we also need to update relativePath partialy
void VFileList::handleDirectoryRenamed(const QString &notebook,
const QString &oldRelativePath, const QString &newRelativePath)
{
if (notebook == this->notebook
&& oldRelativePath == relativePath) {
relativePath = newRelativePath;
&& relativePath.startsWith(oldRelativePath)) {
relativePath.replace(0, oldRelativePath.size(), newRelativePath);
}
}
@ -417,6 +419,32 @@ void VFileList::renameFile(QListWidgetItem *item, const QString &newName)
QJsonObject itemJson = item->data(Qt::UserRole).toJsonObject();
Q_ASSERT(!itemJson.isEmpty());
QString name = itemJson["name"].toString();
// If change the file type, we need to convert it
DocType docType = VUtils::isMarkdown(name) ? DocType::Markdown : DocType::Html;
DocType newDocType = VUtils::isMarkdown(newName) ? DocType::Markdown : DocType::Html;
if (docType != newDocType) {
QString fileRelativePath = QDir::cleanPath(QDir(relativePath).filePath(name));
if (editArea->isFileOpened(notebook, fileRelativePath)) {
QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), QString("Rename will change the note type"),
QMessageBox::Ok | QMessageBox::Cancel, this);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.setInformativeText(QString("You should close the note %1 before continue").arg(name));
if (QMessageBox::Ok == msgBox.exec()) {
QJsonObject curItemJson;
curItemJson["notebook"] = notebook;
curItemJson["relative_path"] = fileRelativePath;
curItemJson["is_forced"] = false;
if (!editArea->closeFile(curItemJson)) {
return;
}
} else {
return;
}
}
convertFileType(notebook, fileRelativePath, docType, newDocType);
}
QString path = QDir(rootPath).filePath(relativePath);
QFile file(QDir(path).filePath(name));
QString newFilePath(QDir(path).filePath(newName));
@ -462,3 +490,20 @@ void VFileList::renameFile(QListWidgetItem *item, const QString &newName)
qDebug() << "file renamed" << oldPath << "to" << newPath;
emit fileRenamed(notebook, oldPath, newPath);
}
void VFileList::convertFileType(const QString &notebook, const QString &fileRelativePath,
DocType oldType, DocType newType)
{
Q_ASSERT(oldType != newType);
QString filePath = QDir(vnote->getNotebookPath(notebook)).filePath(fileRelativePath);
QString fileText = VUtils::readFileFromDisk(filePath);
QTextEdit editor;
if (oldType == DocType::Markdown) {
editor.setPlainText(fileText);
fileText = editor.toHtml();
} else {
editor.setHtml(fileText);
fileText = editor.toPlainText();
}
VUtils::writeFileToDisk(filePath, fileText);
}

View File

@ -6,12 +6,14 @@
#include <QFileInfo>
#include <QDir>
#include "vnotebook.h"
#include "vconstants.h"
class QAction;
class VNote;
class QListWidget;
class QListWidgetItem;
class QPushButton;
class VEditArea;
class VFileList : public QWidget
{
@ -19,6 +21,7 @@ class VFileList : public QWidget
public:
explicit VFileList(VNote *vnote, QWidget *parent = 0);
bool importFile(const QString &name);
inline void setEditArea(VEditArea *editArea);
signals:
void fileClicked(QJsonObject fileJson);
@ -54,6 +57,8 @@ private:
void clearDirectoryInfo();
inline QString getDirectoryName();
void renameFile(QListWidgetItem *item, const QString &newName);
void convertFileType(const QString &notebook, const QString &fileRelativePath,
DocType oldType, DocType newType);
VNote *vnote;
QString notebook;
@ -62,6 +67,8 @@ private:
// Used for cache
QString rootPath;
VEditArea *editArea;
QListWidget *fileList;
// Actions
@ -78,4 +85,9 @@ inline QString VFileList::getDirectoryName()
return QFileInfo(QDir::cleanPath(relativePath)).fileName();
}
inline void VFileList::setEditArea(VEditArea *editArea)
{
this->editArea = editArea;
}
#endif // VFILELIST_H

View File

@ -76,6 +76,7 @@ void VMainWindow::setupUI()
editArea = new VEditArea(vnote);
editArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
fileList->setEditArea(editArea);
// Main Splitter
mainSplitter = new QSplitter();
@ -109,6 +110,10 @@ void VMainWindow::setupUI()
editArea, &VEditArea::handleNotebookRenamed);
connect(editArea, &VEditArea::curTabStatusChanged,
this, &VMainWindow::handleCurTabStatusChanged);
connect(directoryTree, &VDirectoryTree::directoryRenamed,
editArea, &VEditArea::handleDirectoryRenamed);
connect(fileList, &VFileList::fileRenamed,
editArea, &VEditArea::handleFileRenamed);
connect(newNotebookBtn, &QPushButton::clicked,
this, &VMainWindow::onNewNotebookBtnClicked);