mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
refactor VFile and VOrphanFile
1. Make VFile a real abstract class; 2. Use VNoteFile for internal note file; 3. Use VOrphanFile for external orphan file;
This commit is contained in:
parent
eb24360aa9
commit
a64d01ea86
@ -1,30 +1,31 @@
|
||||
#include <QtWidgets>
|
||||
#include "vfileinfodialog.h"
|
||||
#include "vdirectory.h"
|
||||
#include "vfile.h"
|
||||
#include "vnotefile.h"
|
||||
#include "vconfigmanager.h"
|
||||
#include "utils/vutils.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
VFileInfoDialog::VFileInfoDialog(const QString &title, const QString &info,
|
||||
VDirectory *directory, const VFile *file,
|
||||
VFileInfoDialog::VFileInfoDialog(const QString &title,
|
||||
const QString &info,
|
||||
VDirectory *directory,
|
||||
const VNoteFile *file,
|
||||
QWidget *parent)
|
||||
: QDialog(parent), title(title), info(info),
|
||||
m_directory(directory), m_file(file)
|
||||
: QDialog(parent), m_directory(directory), m_file(file)
|
||||
{
|
||||
setupUI();
|
||||
setupUI(title, info);
|
||||
|
||||
connect(nameEdit, &QLineEdit::textChanged, this, &VFileInfoDialog::handleInputChanged);
|
||||
|
||||
handleInputChanged();
|
||||
}
|
||||
|
||||
void VFileInfoDialog::setupUI()
|
||||
void VFileInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
||||
{
|
||||
QLabel *infoLabel = NULL;
|
||||
if (!info.isEmpty()) {
|
||||
infoLabel = new QLabel(info);
|
||||
if (!p_info.isEmpty()) {
|
||||
infoLabel = new QLabel(p_info);
|
||||
}
|
||||
|
||||
// File name.
|
||||
@ -78,7 +79,7 @@ void VFileInfoDialog::setupUI()
|
||||
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(title);
|
||||
setWindowTitle(p_title);
|
||||
}
|
||||
|
||||
void VFileInfoDialog::handleInputChanged()
|
||||
@ -89,7 +90,7 @@ void VFileInfoDialog::handleInputChanged()
|
||||
if (nameOk && name != m_file->getName()) {
|
||||
// Check if the name conflicts with existing note name.
|
||||
// Case-insensitive when creating note.
|
||||
const VFile *file = m_directory->findFile(name, false);
|
||||
const VNoteFile *file = m_directory->findFile(name, false);
|
||||
if (file && file != m_file) {
|
||||
nameOk = false;
|
||||
showWarnLabel = true;
|
||||
|
@ -8,32 +8,33 @@ class QLineEdit;
|
||||
class QDialogButtonBox;
|
||||
class QString;
|
||||
class VDirectory;
|
||||
class VFile;
|
||||
class VNoteFile;
|
||||
|
||||
// File information dialog for internal note file.
|
||||
class VFileInfoDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VFileInfoDialog(const QString &title, const QString &info,
|
||||
VDirectory *directory, const VFile *file,
|
||||
VFileInfoDialog(const QString &title,
|
||||
const QString &info,
|
||||
VDirectory *directory,
|
||||
const VNoteFile *file,
|
||||
QWidget *parent = 0);
|
||||
|
||||
QString getNameInput() const;
|
||||
|
||||
private slots:
|
||||
void handleInputChanged();
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
void setupUI(const QString &p_title, const QString &p_info);
|
||||
|
||||
QLineEdit *nameEdit;
|
||||
QLabel *m_warnLabel;
|
||||
QDialogButtonBox *m_btnBox;
|
||||
|
||||
QString title;
|
||||
QString info;
|
||||
|
||||
VDirectory *m_directory;
|
||||
const VFile *m_file;
|
||||
const VNoteFile *m_file;
|
||||
};
|
||||
|
||||
#endif // VFILEINFODIALOG_H
|
||||
|
@ -74,7 +74,8 @@ SOURCES += main.cpp\
|
||||
dialog/vorphanfileinfodialog.cpp \
|
||||
vtextblockdata.cpp \
|
||||
utils/vpreviewutils.cpp \
|
||||
dialog/vconfirmdeletiondialog.cpp
|
||||
dialog/vconfirmdeletiondialog.cpp \
|
||||
vnotefile.cpp
|
||||
|
||||
HEADERS += vmainwindow.h \
|
||||
vdirectorytree.h \
|
||||
@ -136,7 +137,8 @@ HEADERS += vmainwindow.h \
|
||||
dialog/vorphanfileinfodialog.h \
|
||||
vtextblockdata.h \
|
||||
utils/vpreviewutils.h \
|
||||
dialog/vconfirmdeletiondialog.h
|
||||
dialog/vconfirmdeletiondialog.h \
|
||||
vnotefile.h
|
||||
|
||||
RESOURCES += \
|
||||
vnote.qrc \
|
||||
|
@ -820,6 +820,19 @@ bool VUtils::deleteFile(const VNotebook *p_notebook,
|
||||
}
|
||||
}
|
||||
|
||||
bool VUtils::deleteFile(const QString &p_path,
|
||||
bool p_skipRecycleBin)
|
||||
{
|
||||
if (p_skipRecycleBin) {
|
||||
QFile file(p_path);
|
||||
return file.remove();
|
||||
} else {
|
||||
// TODO: Move it to the recycle bin folder.
|
||||
QFile file(p_path);
|
||||
return file.remove();
|
||||
}
|
||||
}
|
||||
|
||||
QVector<VElementRegion> VUtils::fetchImageRegionsUsingParser(const QString &p_content)
|
||||
{
|
||||
Q_ASSERT(!p_content.isEmpty());
|
||||
|
@ -146,6 +146,12 @@ public:
|
||||
const QString &p_path,
|
||||
bool p_skipRecycleBin = false);
|
||||
|
||||
// Delete file specified by @p_path.
|
||||
// Will just move the file to the recycle bin of VNote if
|
||||
// @p_skipRecycleBin is false.
|
||||
static bool deleteFile(const QString &p_path,
|
||||
bool p_skipRecycleBin = false);
|
||||
|
||||
// Regular expression for image link.
|
||||
// 
|
||||
// Captured texts (need to be trimmed):
|
||||
|
@ -7,9 +7,9 @@
|
||||
// Container: a composite file containing multiple files;
|
||||
enum class DocType { Html = 0, Markdown, List, Container, Invalid };
|
||||
|
||||
// Normal: note file managed by VNote;
|
||||
// Note: note file managed by VNote;
|
||||
// Orphan: external file;
|
||||
enum class FileType { Normal, Orphan };
|
||||
enum class FileType { Note, Orphan };
|
||||
|
||||
enum class ClipboardOpType { Invalid, CopyFile, CopyDir };
|
||||
enum class OpenFileMode {Read = 0, Edit};
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <QJsonArray>
|
||||
#include <QDebug>
|
||||
#include "vconfigmanager.h"
|
||||
#include "vfile.h"
|
||||
#include "vnotefile.h"
|
||||
#include "utils/vutils.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
@ -53,10 +53,10 @@ bool VDirectory::open()
|
||||
QJsonArray fileJson = configJson[DirConfig::c_files].toArray();
|
||||
for (int i = 0; i < fileJson.size(); ++i) {
|
||||
QJsonObject fileItem = fileJson[i].toObject();
|
||||
VFile *file = VFile::fromJson(fileItem,
|
||||
this,
|
||||
FileType::Normal,
|
||||
true);
|
||||
VNoteFile *file = VNoteFile::fromJson(this,
|
||||
fileItem,
|
||||
FileType::Note,
|
||||
true);
|
||||
m_files.append(file);
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ void VDirectory::close()
|
||||
m_subDirs.clear();
|
||||
|
||||
for (int i = 0; i < m_files.size(); ++i) {
|
||||
VFile *file = m_files[i];
|
||||
VNoteFile *file = m_files[i];
|
||||
file->close();
|
||||
delete file;
|
||||
}
|
||||
@ -237,7 +237,7 @@ VDirectory *VDirectory::findSubDirectory(const QString &p_name, bool p_caseSensi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VFile *VDirectory::findFile(const QString &p_name, bool p_caseSensitive)
|
||||
VNoteFile *VDirectory::findFile(const QString &p_name, bool p_caseSensitive)
|
||||
{
|
||||
if (!open()) {
|
||||
return NULL;
|
||||
@ -271,7 +271,7 @@ bool VDirectory::containsFile(const VFile *p_file) const
|
||||
return false;
|
||||
}
|
||||
|
||||
VFile *VDirectory::createFile(const QString &p_name)
|
||||
VNoteFile *VDirectory::createFile(const QString &p_name)
|
||||
{
|
||||
Q_ASSERT(!p_name.isEmpty());
|
||||
if (!open()) {
|
||||
@ -288,12 +288,12 @@ VFile *VDirectory::createFile(const QString &p_name)
|
||||
file.close();
|
||||
|
||||
QDateTime dateTime = QDateTime::currentDateTimeUtc();
|
||||
VFile *ret = new VFile(this,
|
||||
p_name,
|
||||
FileType::Normal,
|
||||
true,
|
||||
dateTime,
|
||||
dateTime);
|
||||
VNoteFile *ret = new VNoteFile(this,
|
||||
p_name,
|
||||
FileType::Note,
|
||||
true,
|
||||
dateTime,
|
||||
dateTime);
|
||||
m_files.append(ret);
|
||||
if (!writeToConfig()) {
|
||||
file.remove();
|
||||
@ -307,7 +307,7 @@ VFile *VDirectory::createFile(const QString &p_name)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VDirectory::addFile(VFile *p_file, int p_index)
|
||||
bool VDirectory::addFile(VNoteFile *p_file, int p_index)
|
||||
{
|
||||
if (!open()) {
|
||||
return false;
|
||||
@ -336,19 +336,19 @@ bool VDirectory::addFile(VFile *p_file, int p_index)
|
||||
return true;
|
||||
}
|
||||
|
||||
VFile *VDirectory::addFile(const QString &p_name, int p_index)
|
||||
VNoteFile *VDirectory::addFile(const QString &p_name, int p_index)
|
||||
{
|
||||
if (!open() || p_name.isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QDateTime dateTime = QDateTime::currentDateTimeUtc();
|
||||
VFile *file = new VFile(this,
|
||||
p_name,
|
||||
FileType::Normal,
|
||||
true,
|
||||
dateTime,
|
||||
dateTime);
|
||||
VNoteFile *file = new VNoteFile(this,
|
||||
p_name,
|
||||
FileType::Note,
|
||||
true,
|
||||
dateTime,
|
||||
dateTime);
|
||||
if (!file) {
|
||||
return NULL;
|
||||
}
|
||||
@ -450,7 +450,7 @@ bool VDirectory::removeSubDirectory(VDirectory *p_dir)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VDirectory::removeFile(VFile *p_file)
|
||||
bool VDirectory::removeFile(VNoteFile *p_file)
|
||||
{
|
||||
V_ASSERT(m_opened);
|
||||
V_ASSERT(p_file);
|
||||
@ -468,7 +468,7 @@ bool VDirectory::removeFile(VFile *p_file)
|
||||
return true;
|
||||
}
|
||||
|
||||
void VDirectory::deleteFile(VFile *p_file)
|
||||
void VDirectory::deleteFile(VNoteFile *p_file)
|
||||
{
|
||||
removeFile(p_file);
|
||||
|
||||
@ -476,7 +476,7 @@ void VDirectory::deleteFile(VFile *p_file)
|
||||
V_ASSERT(!p_file->isOpened());
|
||||
V_ASSERT(p_file->parent());
|
||||
|
||||
p_file->deleteDiskFile();
|
||||
p_file->deleteFile();
|
||||
|
||||
delete p_file;
|
||||
}
|
||||
@ -512,8 +512,8 @@ bool VDirectory::rename(const QString &p_name)
|
||||
return true;
|
||||
}
|
||||
|
||||
VFile *VDirectory::copyFile(VDirectory *p_destDir, const QString &p_destName,
|
||||
VFile *p_srcFile, bool p_cut)
|
||||
VNoteFile *VDirectory::copyFile(VDirectory *p_destDir, const QString &p_destName,
|
||||
VNoteFile *p_srcFile, bool p_cut)
|
||||
{
|
||||
QString srcPath = QDir::cleanPath(p_srcFile->fetchPath());
|
||||
QString destPath = QDir::cleanPath(QDir(p_destDir->fetchPath()).filePath(p_destName));
|
||||
@ -536,9 +536,9 @@ VFile *VDirectory::copyFile(VDirectory *p_destDir, const QString &p_destName,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Handle VDirectory and VFile
|
||||
// Handle VDirectory and VNoteFile
|
||||
int index = -1;
|
||||
VFile *destFile = NULL;
|
||||
VNoteFile *destFile = NULL;
|
||||
if (p_cut) {
|
||||
// Remove the file from config
|
||||
srcDir->removeFile(p_srcFile);
|
||||
@ -710,7 +710,7 @@ void VDirectory::reorderFiles(int p_first, int p_last, int p_destStart)
|
||||
}
|
||||
}
|
||||
|
||||
VFile *VDirectory::tryLoadFile(QStringList &p_filePath)
|
||||
VNoteFile *VDirectory::tryLoadFile(QStringList &p_filePath)
|
||||
{
|
||||
qDebug() << "directory" << m_name << "tryLoadFile()" << p_filePath.join("/");
|
||||
if (p_filePath.isEmpty()) {
|
||||
@ -722,7 +722,7 @@ VFile *VDirectory::tryLoadFile(QStringList &p_filePath)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VFile *file = NULL;
|
||||
VNoteFile *file = NULL;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
bool caseSensitive = false;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "vnotebook.h"
|
||||
|
||||
class VFile;
|
||||
class VNoteFile;
|
||||
|
||||
class VDirectory : public QObject
|
||||
{
|
||||
@ -27,20 +28,20 @@ public:
|
||||
// Returns the VDirectory with the name @p_name directly in this directory.
|
||||
VDirectory *findSubDirectory(const QString &p_name, bool p_caseSensitive);
|
||||
|
||||
// Returns the VFile with the name @p_name directly in this directory.
|
||||
VFile *findFile(const QString &p_name, bool p_caseSensitive);
|
||||
// Returns the VNoteFile with the name @p_name directly in this directory.
|
||||
VNoteFile *findFile(const QString &p_name, bool p_caseSensitive);
|
||||
|
||||
// If current dir or its sub-dir contains @p_file.
|
||||
bool containsFile(const VFile *p_file) const;
|
||||
|
||||
VFile *createFile(const QString &p_name);
|
||||
VNoteFile *createFile(const QString &p_name);
|
||||
|
||||
// Remove and delete subdirectory @p_subDir.
|
||||
void deleteSubDirectory(VDirectory *p_subDir, bool p_skipRecycleBin = false);
|
||||
|
||||
// Remove the file in the config and m_files without deleting it in the disk.
|
||||
// It won't change the parent of @p_file to enable it find its path.
|
||||
bool removeFile(VFile *p_file);
|
||||
bool removeFile(VNoteFile *p_file);
|
||||
|
||||
// Remove the directory in the config and m_subDirs without deleting it in the disk.
|
||||
// It won't change the parent of @p_dir to enable it find its path.
|
||||
@ -48,20 +49,20 @@ public:
|
||||
|
||||
// Add the file in the config and m_files. If @p_index is -1, add it at the end.
|
||||
// @p_name: the file name of the file to add.
|
||||
// Return the VFile if succeed.
|
||||
VFile *addFile(const QString &p_name, int p_index);
|
||||
// Return the VNoteFile if succeed.
|
||||
VNoteFile *addFile(const QString &p_name, int p_index);
|
||||
|
||||
// Delete @p_file both from disk and config, as well as its local images.
|
||||
void deleteFile(VFile *p_file);
|
||||
void deleteFile(VNoteFile *p_file);
|
||||
|
||||
// Rename current directory to @p_name.
|
||||
bool rename(const QString &p_name);
|
||||
|
||||
// Copy @p_srcFile to @p_destDir, setting new name to @p_destName.
|
||||
// @p_cut: copy or cut.
|
||||
// Returns the dest VFile.
|
||||
static VFile *copyFile(VDirectory *p_destDir, const QString &p_destName,
|
||||
VFile *p_srcFile, bool p_cut);
|
||||
// Returns the dest VNoteFile.
|
||||
static VNoteFile *copyFile(VDirectory *p_destDir, const QString &p_destName,
|
||||
VNoteFile *p_srcFile, bool p_cut);
|
||||
|
||||
static VDirectory *copyDirectory(VDirectory *p_destDir, const QString &p_destName,
|
||||
VDirectory *p_srcDir, bool p_cut);
|
||||
@ -74,7 +75,7 @@ public:
|
||||
const VDirectory *getParentDirectory() const;
|
||||
VNotebook *getNotebook();
|
||||
const VNotebook *getNotebook() const;
|
||||
const QVector<VFile *> &getFiles() const;
|
||||
const QVector<VNoteFile *> &getFiles() const;
|
||||
QString fetchPath() const;
|
||||
QString fetchBasePath() const;
|
||||
QString fetchRelativePath() const;
|
||||
@ -97,7 +98,7 @@ public:
|
||||
bool writeToConfig() const;
|
||||
|
||||
// Try to load file given relative path @p_filePath.
|
||||
VFile *tryLoadFile(QStringList &p_filePath);
|
||||
VNoteFile *tryLoadFile(QStringList &p_filePath);
|
||||
|
||||
QDateTime getCreatedTimeUtc() const;
|
||||
|
||||
@ -115,7 +116,7 @@ private:
|
||||
void addNotebookConfig(QJsonObject &p_json) const;
|
||||
|
||||
// Add the file in the config and m_files. If @p_index is -1, add it at the end.
|
||||
bool addFile(VFile *p_file, int p_index);
|
||||
bool addFile(VNoteFile *p_file, int p_index);
|
||||
|
||||
// Add the directory in the config and m_subDirs. If @p_index is -1, add it at the end.
|
||||
// Return the VDirectory if succeed.
|
||||
@ -134,7 +135,7 @@ private:
|
||||
QVector<VDirectory *> m_subDirs;
|
||||
|
||||
// Owner of the files
|
||||
QVector<VFile *> m_files;
|
||||
QVector<VNoteFile *> m_files;
|
||||
|
||||
// Whether the directory has been opened.
|
||||
bool m_opened;
|
||||
@ -177,7 +178,7 @@ inline const VDirectory *VDirectory::getParentDirectory() const
|
||||
return (const VDirectory *)this->parent();
|
||||
}
|
||||
|
||||
inline const QVector<VFile *> &VDirectory::getFiles() const
|
||||
inline const QVector<VNoteFile *> &VDirectory::getFiles() const
|
||||
{
|
||||
return m_files;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <QFontMetrics>
|
||||
#include "vconstants.h"
|
||||
#include "vtoc.h"
|
||||
#include "vfile.h"
|
||||
#include "vnotefile.h"
|
||||
|
||||
class VEditOperations;
|
||||
class QLabel;
|
||||
|
@ -125,8 +125,9 @@ void VEditWindow::initTabActions()
|
||||
VEditTab *editor = getTab(tab);
|
||||
QPointer<VFile> file = editor->getFile();
|
||||
Q_ASSERT(file);
|
||||
if (file->getType() == FileType::Normal) {
|
||||
g_vnote->getMainWindow()->getFileList()->fileInfo(file);
|
||||
if (file->getType() == FileType::Note) {
|
||||
VNoteFile *tmpFile = dynamic_cast<VNoteFile *>((VFile *)file);
|
||||
g_vnote->getMainWindow()->getFileList()->fileInfo(tmpFile);
|
||||
} else if (file->getType() == FileType::Orphan) {
|
||||
g_vnote->getMainWindow()->editOrphanFileInfo(file);
|
||||
}
|
||||
@ -554,7 +555,7 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
||||
|
||||
VEditTab *editor = getTab(tab);
|
||||
VFile *file = editor->getFile();
|
||||
if (file->getType() == FileType::Normal) {
|
||||
if (file->getType() == FileType::Note) {
|
||||
// Locate to folder.
|
||||
m_locateAct->setData(tab);
|
||||
menu.addAction(m_locateAct);
|
||||
@ -565,7 +566,7 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
||||
m_noteInfoAct->setData(tab);
|
||||
menu.addAction(m_noteInfoAct);
|
||||
} else if (file->getType() == FileType::Orphan
|
||||
&& !dynamic_cast<VOrphanFile *>(file)->isSystemFile()) {
|
||||
&& !(dynamic_cast<VOrphanFile *>(file)->isSystemFile())) {
|
||||
m_openLocationAct->setData(tab);
|
||||
menu.addAction(m_openLocationAct);
|
||||
|
||||
@ -761,7 +762,7 @@ void VEditWindow::handleLocateAct()
|
||||
int tab = m_locateAct->data().toInt();
|
||||
VEditTab *editor = getTab(tab);
|
||||
QPointer<VFile> file = editor->getFile();
|
||||
if (file->getType() == FileType::Normal) {
|
||||
if (file->getType() == FileType::Note) {
|
||||
vnote->getMainWindow()->locateFile(file);
|
||||
}
|
||||
}
|
||||
|
@ -10,11 +10,11 @@
|
||||
#include "vedittab.h"
|
||||
#include "vtoc.h"
|
||||
#include "vconstants.h"
|
||||
#include "vnotefile.h"
|
||||
|
||||
class VNote;
|
||||
class QPushButton;
|
||||
class QActionGroup;
|
||||
class VFile;
|
||||
class VEditArea;
|
||||
|
||||
class VEditWindow : public QTabWidget
|
||||
@ -184,8 +184,14 @@ inline QString VEditWindow::generateTooltip(const VFile *p_file) const
|
||||
if (!p_file) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// [Notebook]path
|
||||
return QString("[%1] %2").arg(p_file->getNotebookName()).arg(p_file->fetchPath());
|
||||
if (p_file->getType() == FileType::Note) {
|
||||
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>(p_file);
|
||||
return QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath());
|
||||
} else {
|
||||
return QString("%1").arg(p_file->fetchPath());
|
||||
}
|
||||
}
|
||||
|
||||
inline QString VEditWindow::generateTabText(int p_index, const QString &p_name,
|
||||
|
225
src/vfile.cpp
225
src/vfile.cpp
@ -30,17 +30,18 @@ VFile::~VFile()
|
||||
|
||||
bool VFile::open()
|
||||
{
|
||||
Q_ASSERT(!m_name.isEmpty());
|
||||
if (m_opened) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Q_ASSERT(!m_name.isEmpty());
|
||||
Q_ASSERT(m_content.isEmpty());
|
||||
QString path = fetchPath();
|
||||
qDebug() << "path" << path;
|
||||
m_content = VUtils::readFileFromDisk(path);
|
||||
|
||||
QString filePath = fetchPath();
|
||||
Q_ASSERT(QFileInfo::exists(filePath));
|
||||
m_content = VUtils::readFileFromDisk(filePath);
|
||||
m_modified = false;
|
||||
m_opened = true;
|
||||
qDebug() << "file" << m_name << "opened";
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -49,164 +50,24 @@ void VFile::close()
|
||||
if (!m_opened) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_content.clear();
|
||||
m_modified = false;
|
||||
m_opened = false;
|
||||
}
|
||||
|
||||
void VFile::deleteDiskFile()
|
||||
{
|
||||
V_ASSERT(parent());
|
||||
|
||||
// Delete local images if it is Markdown.
|
||||
if (m_docType == DocType::Markdown) {
|
||||
deleteLocalImages();
|
||||
}
|
||||
|
||||
// Delete the file
|
||||
QString filePath = fetchPath();
|
||||
if (VUtils::deleteFile(getNotebook(), filePath, false)) {
|
||||
qDebug() << "deleted" << filePath;
|
||||
} else {
|
||||
qWarning() << "fail to delete" << filePath;
|
||||
}
|
||||
}
|
||||
|
||||
bool VFile::save()
|
||||
{
|
||||
Q_ASSERT(m_opened);
|
||||
bool ret = VUtils::writeFileToDisk(fetchPath(), m_content);
|
||||
if (ret) {
|
||||
m_modifiedTimeUtc = QDateTime::currentDateTimeUtc();
|
||||
m_modified = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VFile::setModified(bool p_modified)
|
||||
{
|
||||
m_modified = p_modified;
|
||||
}
|
||||
|
||||
void VFile::deleteLocalImages()
|
||||
{
|
||||
V_ASSERT(m_docType == DocType::Markdown);
|
||||
|
||||
QVector<ImageLink> images = VUtils::fetchImagesFromMarkdownFile(this,
|
||||
ImageLink::LocalRelativeInternal);
|
||||
int deleted = 0;
|
||||
for (int i = 0; i < images.size(); ++i) {
|
||||
if (VUtils::deleteFile(getNotebook(), images[i].m_path, false)) {
|
||||
++deleted;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "delete" << deleted << "images for" << fetchPath();
|
||||
}
|
||||
|
||||
void VFile::setName(const QString &p_name)
|
||||
{
|
||||
m_name = p_name;
|
||||
DocType newType = VUtils::docTypeFromName(p_name);
|
||||
if (newType != m_docType) {
|
||||
qWarning() << "setName() change the DocType. A convertion should be followed";
|
||||
}
|
||||
}
|
||||
|
||||
const QString &VFile::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
VDirectory *VFile::getDirectory()
|
||||
{
|
||||
Q_ASSERT(parent());
|
||||
return (VDirectory *)parent();
|
||||
}
|
||||
|
||||
const VDirectory *VFile::getDirectory() const
|
||||
{
|
||||
Q_ASSERT(parent());
|
||||
return (const VDirectory *)parent();
|
||||
}
|
||||
|
||||
DocType VFile::getDocType() const
|
||||
{
|
||||
return m_docType;
|
||||
}
|
||||
|
||||
const QString &VFile::getContent() const
|
||||
{
|
||||
return m_content;
|
||||
}
|
||||
|
||||
QString VFile::getNotebookName() const
|
||||
{
|
||||
return getDirectory()->getNotebookName();
|
||||
}
|
||||
|
||||
const VNotebook *VFile::getNotebook() const
|
||||
{
|
||||
return getDirectory()->getNotebook();
|
||||
}
|
||||
|
||||
VNotebook *VFile::getNotebook()
|
||||
{
|
||||
return getDirectory()->getNotebook();
|
||||
}
|
||||
|
||||
QString VFile::fetchPath() const
|
||||
{
|
||||
QString dirPath = getDirectory()->fetchPath();
|
||||
return QDir(dirPath).filePath(m_name);
|
||||
}
|
||||
|
||||
QString VFile::fetchRelativePath() const
|
||||
{
|
||||
QString dirRelativePath = getDirectory()->fetchRelativePath();
|
||||
return QDir(dirRelativePath).filePath(m_name);
|
||||
}
|
||||
|
||||
QString VFile::fetchBasePath() const
|
||||
{
|
||||
return getDirectory()->fetchPath();
|
||||
}
|
||||
|
||||
QString VFile::fetchImagePath() const
|
||||
{
|
||||
return QDir(fetchBasePath()).filePath(getNotebook()->getImageFolder());
|
||||
}
|
||||
|
||||
void VFile::setContent(const QString &p_content)
|
||||
{
|
||||
m_content = p_content;
|
||||
}
|
||||
|
||||
bool VFile::isModified() const
|
||||
{
|
||||
return m_modified;
|
||||
}
|
||||
|
||||
bool VFile::isModifiable() const
|
||||
{
|
||||
return m_modifiable;
|
||||
}
|
||||
|
||||
bool VFile::isOpened() const
|
||||
{
|
||||
return m_opened;
|
||||
}
|
||||
|
||||
FileType VFile::getType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
bool VFile::isInternalImageFolder(const QString &p_path) const
|
||||
{
|
||||
return VUtils::equalPath(VUtils::basePathFromPath(p_path),
|
||||
getDirectory()->fetchPath());
|
||||
}
|
||||
|
||||
QUrl VFile::getBaseUrl() const
|
||||
{
|
||||
// Need to judge the path: Url, local file, resource file.
|
||||
@ -229,71 +90,15 @@ QUrl VFile::getBaseUrl() const
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
bool VFile::rename(const QString &p_name)
|
||||
bool VFile::isInternalImageFolder(const QString &p_path) const
|
||||
{
|
||||
if (m_name == p_name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString oldName = m_name;
|
||||
|
||||
VDirectory *dir = getDirectory();
|
||||
V_ASSERT(dir);
|
||||
// Rename it in disk.
|
||||
QDir diskDir(dir->fetchPath());
|
||||
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;
|
||||
}
|
||||
|
||||
// Can't not change doc type.
|
||||
Q_ASSERT(m_docType == VUtils::docTypeFromName(m_name));
|
||||
|
||||
qDebug() << "note renamed from" << oldName << "to" << m_name;
|
||||
|
||||
return true;
|
||||
return VUtils::equalPath(VUtils::basePathFromPath(p_path),
|
||||
fetchBasePath())
|
||||
|| VUtils::equalPath(p_path, fetchImageFolderPath());
|
||||
}
|
||||
|
||||
bool VFile::isRelativeImageFolder() const
|
||||
void VFile::setModified(bool p_modified)
|
||||
{
|
||||
return true;
|
||||
m_modified = p_modified;
|
||||
}
|
||||
|
||||
QString VFile::getImageFolderInLink() const
|
||||
{
|
||||
return getNotebook()->getImageFolder();
|
||||
}
|
||||
|
||||
VFile *VFile::fromJson(const QJsonObject &p_json,
|
||||
QObject *p_parent,
|
||||
FileType p_type,
|
||||
bool p_modifiable)
|
||||
{
|
||||
return new VFile(p_parent,
|
||||
p_json[DirConfig::c_name].toString(),
|
||||
p_type,
|
||||
p_modifiable,
|
||||
QDateTime::fromString(p_json[DirConfig::c_createdTime].toString(),
|
||||
Qt::ISODate),
|
||||
QDateTime::fromString(p_json[DirConfig::c_modifiedTime].toString(),
|
||||
Qt::ISODate));
|
||||
}
|
||||
|
||||
QJsonObject VFile::toConfigJson() const
|
||||
{
|
||||
QJsonObject item;
|
||||
item[DirConfig::c_name] = m_name;
|
||||
item[DirConfig::c_createdTime] = m_createdTimeUtc.toString(Qt::ISODate);
|
||||
item[DirConfig::c_modifiedTime] = m_modifiedTimeUtc.toString(Qt::ISODate);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
120
src/vfile.h
120
src/vfile.h
@ -5,11 +5,9 @@
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
#include <QDateTime>
|
||||
#include "vdirectory.h"
|
||||
#include "vconstants.h"
|
||||
|
||||
class VNotebook;
|
||||
|
||||
// VFile is an abstract class representing a file in VNote.
|
||||
class VFile : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -22,57 +20,56 @@ public:
|
||||
QDateTime p_modifiedTimeUtc);
|
||||
|
||||
virtual ~VFile();
|
||||
|
||||
// Open the file to load content into m_content.
|
||||
// Init m_opened, m_modified, and m_content.
|
||||
virtual bool open();
|
||||
|
||||
// Close the file.
|
||||
// Clear m_modified, m_content, m_opened.
|
||||
virtual void close();
|
||||
|
||||
// Save m_content to the file.
|
||||
virtual bool save();
|
||||
|
||||
const QString &getName() const;
|
||||
virtual void setName(const QString &p_name);
|
||||
virtual VDirectory *getDirectory();
|
||||
virtual const VDirectory *getDirectory() const;
|
||||
DocType getDocType() const;
|
||||
const QString &getContent() const;
|
||||
virtual void setContent(const QString &p_content);
|
||||
virtual const VNotebook *getNotebook() const;
|
||||
virtual VNotebook *getNotebook();
|
||||
virtual QString getNotebookName() const;
|
||||
virtual QString fetchPath() const;
|
||||
virtual QString fetchRelativePath() const;
|
||||
virtual QString fetchBasePath() const;
|
||||
|
||||
// The path of the image folder.
|
||||
virtual QString fetchImagePath() const;
|
||||
DocType getDocType() const;
|
||||
|
||||
bool isModified() const;
|
||||
|
||||
bool isModifiable() const;
|
||||
|
||||
bool isOpened() const;
|
||||
|
||||
FileType getType() const;
|
||||
|
||||
const QString &getContent() const;
|
||||
|
||||
void setContent(const QString &p_content);
|
||||
|
||||
// Get the absolute full path of the file.
|
||||
virtual QString fetchPath() const = 0;
|
||||
|
||||
// Get the absolute full path of the directory containing the file.
|
||||
virtual QString fetchBasePath() const = 0;
|
||||
|
||||
// The path of the image folder to store images of this file.
|
||||
virtual QString fetchImageFolderPath() const = 0;
|
||||
|
||||
// Return the base URL for this file when loaded in VWebView.
|
||||
QUrl getBaseUrl() const;
|
||||
|
||||
// Whether the directory @p_path is an internal image folder of this file.
|
||||
// It is true only when the folder is in the same directory as the parent
|
||||
// directory of this file.
|
||||
virtual bool isInternalImageFolder(const QString &p_path) const;
|
||||
// directory of this file or equals to fetchImageFolderPath().
|
||||
bool isInternalImageFolder(const QString &p_path) const;
|
||||
|
||||
// Rename the file.
|
||||
virtual bool rename(const QString &p_name);
|
||||
|
||||
// Whether the image folder is a relative path.
|
||||
virtual bool isRelativeImageFolder() const;
|
||||
// Whether use a relative image folder.
|
||||
virtual bool useRelativeImageFolder() const = 0;
|
||||
|
||||
// Return the image folder part in an image link.
|
||||
virtual QString getImageFolderInLink() const;
|
||||
|
||||
// Create a VFile from @p_json Json object.
|
||||
static VFile *fromJson(const QJsonObject &p_json,
|
||||
QObject *p_parent,
|
||||
FileType p_type,
|
||||
bool p_modifiable);
|
||||
|
||||
// Create a Json object from current instance.
|
||||
QJsonObject toConfigJson() const;
|
||||
virtual QString getImageFolderInLink() const = 0;
|
||||
|
||||
QDateTime getCreatedTimeUtc() const;
|
||||
|
||||
@ -82,19 +79,13 @@ public slots:
|
||||
void setModified(bool p_modified);
|
||||
|
||||
protected:
|
||||
// Delete the file and corresponding images
|
||||
void deleteDiskFile();
|
||||
|
||||
// Delete local images of DocType::Markdown.
|
||||
void deleteLocalImages();
|
||||
|
||||
// Name of this file.
|
||||
QString m_name;
|
||||
|
||||
// Whether this file has been opened.
|
||||
// Whether this file has been opened (content loaded).
|
||||
bool m_opened;
|
||||
|
||||
// File has been modified in editor
|
||||
// m_content is different from that in the disk.
|
||||
bool m_modified;
|
||||
|
||||
// DocType of this file: Html, Markdown.
|
||||
@ -103,6 +94,7 @@ protected:
|
||||
// Content of this file.
|
||||
QString m_content;
|
||||
|
||||
// FileType of this file: Note, Orphan.
|
||||
FileType m_type;
|
||||
|
||||
// Whether this file is modifiable.
|
||||
@ -113,10 +105,50 @@ protected:
|
||||
|
||||
// UTC time of last modification to this file in VNote.
|
||||
QDateTime m_modifiedTimeUtc;
|
||||
|
||||
friend class VDirectory;
|
||||
};
|
||||
|
||||
inline const QString &VFile::getName() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
inline DocType VFile::getDocType() const
|
||||
{
|
||||
return m_docType;
|
||||
}
|
||||
|
||||
inline bool VFile::isModified() const
|
||||
{
|
||||
return m_modified;
|
||||
}
|
||||
|
||||
inline bool VFile::isModifiable() const
|
||||
{
|
||||
return m_modifiable;
|
||||
}
|
||||
|
||||
inline bool VFile::isOpened() const
|
||||
{
|
||||
return m_opened;
|
||||
}
|
||||
|
||||
inline FileType VFile::getType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
inline const QString &VFile::getContent() const
|
||||
{
|
||||
Q_ASSERT(m_opened);
|
||||
return m_content;
|
||||
}
|
||||
|
||||
inline void VFile::setContent(const QString &p_content)
|
||||
{
|
||||
m_content = p_content;
|
||||
m_modified = true;
|
||||
}
|
||||
|
||||
inline QDateTime VFile::getCreatedTimeUtc() const
|
||||
{
|
||||
return m_createdTimeUtc;
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "vnote.h"
|
||||
#include "veditarea.h"
|
||||
#include "utils/vutils.h"
|
||||
#include "vfile.h"
|
||||
#include "vnotefile.h"
|
||||
#include "vconfigmanager.h"
|
||||
#include "vmdedit.h"
|
||||
#include "vmdtab.h"
|
||||
@ -182,9 +182,10 @@ void VFileList::updateFileList()
|
||||
if (!m_directory->open()) {
|
||||
return;
|
||||
}
|
||||
const QVector<VFile *> &files = m_directory->getFiles();
|
||||
|
||||
const QVector<VNoteFile *> &files = m_directory->getFiles();
|
||||
for (int i = 0; i < files.size(); ++i) {
|
||||
VFile *file = files[i];
|
||||
VNoteFile *file = files[i];
|
||||
insertFileListItem(file);
|
||||
}
|
||||
}
|
||||
@ -205,7 +206,7 @@ void VFileList::openFileLocation() const
|
||||
QDesktopServices::openUrl(url);
|
||||
}
|
||||
|
||||
void VFileList::fileInfo(VFile *p_file)
|
||||
void VFileList::fileInfo(VNoteFile *p_file)
|
||||
{
|
||||
if (!p_file) {
|
||||
return;
|
||||
@ -239,7 +240,7 @@ void VFileList::fileInfo(VFile *p_file)
|
||||
}
|
||||
}
|
||||
|
||||
void VFileList::fillItem(QListWidgetItem *p_item, const VFile *p_file)
|
||||
void VFileList::fillItem(QListWidgetItem *p_item, const VNoteFile *p_file)
|
||||
{
|
||||
unsigned long long ptr = (long long)p_file;
|
||||
p_item->setData(Qt::UserRole, ptr);
|
||||
@ -249,7 +250,7 @@ void VFileList::fillItem(QListWidgetItem *p_item, const VFile *p_file)
|
||||
V_ASSERT(sizeof(p_file) <= sizeof(ptr));
|
||||
}
|
||||
|
||||
QListWidgetItem* VFileList::insertFileListItem(VFile *file, bool atFront)
|
||||
QListWidgetItem* VFileList::insertFileListItem(VNoteFile *file, bool atFront)
|
||||
{
|
||||
V_ASSERT(file);
|
||||
QListWidgetItem *item = new QListWidgetItem();
|
||||
@ -300,7 +301,7 @@ void VFileList::newFile()
|
||||
defaultName = VUtils::getFileNameWithSequence(m_directory->fetchPath(), defaultName);
|
||||
VNewFileDialog dialog(tr("Create Note"), info, defaultName, m_directory, this);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
VFile *file = m_directory->createFile(dialog.getNameInput());
|
||||
VNoteFile *file = m_directory->createFile(dialog.getNameInput());
|
||||
if (!file) {
|
||||
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
|
||||
tr("Fail to create note <span style=\"%1\">%2</span>.")
|
||||
@ -355,14 +356,14 @@ void VFileList::newFile()
|
||||
QVector<QListWidgetItem *> VFileList::updateFileListAdded()
|
||||
{
|
||||
QVector<QListWidgetItem *> ret;
|
||||
const QVector<VFile *> &files = m_directory->getFiles();
|
||||
const QVector<VNoteFile *> &files = m_directory->getFiles();
|
||||
for (int i = 0; i < files.size(); ++i) {
|
||||
VFile *file = files[i];
|
||||
VNoteFile *file = files[i];
|
||||
if (i >= fileList->count()) {
|
||||
QListWidgetItem *item = insertFileListItem(file, false);
|
||||
ret.append(item);
|
||||
} else {
|
||||
VFile *itemFile = getVFile(fileList->item(i));
|
||||
VNoteFile *itemFile = getVFile(fileList->item(i));
|
||||
if (itemFile != file) {
|
||||
QListWidgetItem *item = insertFileListItem(file, false);
|
||||
ret.append(item);
|
||||
@ -384,11 +385,12 @@ void VFileList::deleteFile()
|
||||
}
|
||||
|
||||
// @p_file may or may not be listed in VFileList
|
||||
void VFileList::deleteFile(VFile *p_file)
|
||||
void VFileList::deleteFile(VNoteFile *p_file)
|
||||
{
|
||||
if (!p_file) {
|
||||
return;
|
||||
}
|
||||
|
||||
VDirectory *dir = p_file->getDirectory();
|
||||
QString fileName = p_file->getName();
|
||||
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
|
||||
@ -427,7 +429,7 @@ void VFileList::contextMenuRequested(QPoint pos)
|
||||
}
|
||||
|
||||
if (item && fileList->selectedItems().size() == 1) {
|
||||
VFile *file = getVFile(item);
|
||||
VNoteFile *file = getVFile(item);
|
||||
if (file && file->getDocType() == DocType::Markdown) {
|
||||
menu.addAction(m_openInReadAct);
|
||||
menu.addAction(m_openInEditAct);
|
||||
@ -464,7 +466,7 @@ void VFileList::contextMenuRequested(QPoint pos)
|
||||
menu.exec(fileList->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
QListWidgetItem* VFileList::findItem(const VFile *p_file)
|
||||
QListWidgetItem* VFileList::findItem(const VNoteFile *p_file)
|
||||
{
|
||||
if (!p_file || p_file->getDirectory() != m_directory) {
|
||||
return NULL;
|
||||
@ -477,6 +479,7 @@ QListWidgetItem* VFileList::findItem(const VFile *p_file)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -515,7 +518,7 @@ bool VFileList::importFile(const QString &p_srcFilePath)
|
||||
return false;
|
||||
}
|
||||
|
||||
VFile *destFile = m_directory->addFile(srcName, -1);
|
||||
VNoteFile *destFile = m_directory->addFile(srcName, -1);
|
||||
if (destFile) {
|
||||
return insertFileListItem(destFile, false);
|
||||
}
|
||||
@ -531,7 +534,7 @@ void VFileList::copySelectedFiles(bool p_isCut)
|
||||
QJsonArray files;
|
||||
m_copiedFiles.clear();
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
VFile *file = getVFile(items[i]);
|
||||
VNoteFile *file = getVFile(items[i]);
|
||||
QJsonObject fileJson;
|
||||
fileJson["notebook"] = file->getNotebookName();
|
||||
fileJson["path"] = file->fetchPath();
|
||||
@ -579,10 +582,11 @@ void VFileList::pasteFiles(VDirectory *p_destDir)
|
||||
|
||||
int nrPasted = 0;
|
||||
for (int i = 0; i < m_copiedFiles.size(); ++i) {
|
||||
QPointer<VFile> srcFile = m_copiedFiles[i];
|
||||
QPointer<VNoteFile> srcFile = m_copiedFiles[i];
|
||||
if (!srcFile) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString fileName = srcFile->getName();
|
||||
VDirectory *srcDir = srcFile->getDirectory();
|
||||
if (srcDir == p_destDir && !isCut) {
|
||||
@ -606,7 +610,7 @@ void VFileList::pasteFiles(VDirectory *p_destDir)
|
||||
m_copiedFiles.clear();
|
||||
}
|
||||
|
||||
bool VFileList::copyFile(VDirectory *p_destDir, const QString &p_destName, VFile *p_file, bool p_cut)
|
||||
bool VFileList::copyFile(VDirectory *p_destDir, const QString &p_destName, VNoteFile *p_file, bool p_cut)
|
||||
{
|
||||
QString srcPath = QDir::cleanPath(p_file->fetchPath());
|
||||
QString destPath = QDir::cleanPath(QDir(p_destDir->fetchPath()).filePath(p_destName));
|
||||
@ -617,7 +621,7 @@ bool VFileList::copyFile(VDirectory *p_destDir, const QString &p_destName, VFile
|
||||
// DocType is not allowed to change.
|
||||
Q_ASSERT(p_file->getDocType() == VUtils::docTypeFromName(destPath));
|
||||
|
||||
VFile *destFile = VDirectory::copyFile(p_destDir, p_destName, p_file, p_cut);
|
||||
VNoteFile *destFile = VDirectory::copyFile(p_destDir, p_destName, p_file, p_cut);
|
||||
updateFileList();
|
||||
if (destFile) {
|
||||
emit fileUpdated(destFile);
|
||||
@ -676,7 +680,7 @@ void VFileList::focusInEvent(QFocusEvent * /* p_event */)
|
||||
fileList->setFocus();
|
||||
}
|
||||
|
||||
bool VFileList::locateFile(const VFile *p_file)
|
||||
bool VFileList::locateFile(const VNoteFile *p_file)
|
||||
{
|
||||
if (p_file) {
|
||||
if (p_file->getDirectory() != m_directory) {
|
||||
@ -704,7 +708,7 @@ void VFileList::handleRowsMoved(const QModelIndex &p_parent, int p_start, int p_
|
||||
|
||||
bool VFileList::identicalListWithDirectory() const
|
||||
{
|
||||
const QVector<VFile *> files = m_directory->getFiles();
|
||||
const QVector<VNoteFile *> files = m_directory->getFiles();
|
||||
int nrItems = fileList->count();
|
||||
if (nrItems != files.size()) {
|
||||
return false;
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "vnotebook.h"
|
||||
#include "vconstants.h"
|
||||
#include "vdirectory.h"
|
||||
#include "vfile.h"
|
||||
#include "vnotefile.h"
|
||||
#include "vnavigationmode.h"
|
||||
|
||||
class QAction;
|
||||
@ -29,9 +29,9 @@ public:
|
||||
explicit VFileList(QWidget *parent = 0);
|
||||
bool importFile(const QString &p_srcFilePath);
|
||||
inline void setEditArea(VEditArea *editArea);
|
||||
void fileInfo(VFile *p_file);
|
||||
void deleteFile(VFile *p_file);
|
||||
bool locateFile(const VFile *p_file);
|
||||
void fileInfo(VNoteFile *p_file);
|
||||
void deleteFile(VNoteFile *p_file);
|
||||
bool locateFile(const VNoteFile *p_file);
|
||||
inline const VDirectory *currentDirectory() const;
|
||||
|
||||
// Implementations for VNavigationMode.
|
||||
@ -41,16 +41,16 @@ public:
|
||||
bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE;
|
||||
|
||||
signals:
|
||||
void fileClicked(VFile *p_file, OpenFileMode mode = OpenFileMode::Read);
|
||||
void fileCreated(VFile *p_file, OpenFileMode mode = OpenFileMode::Read);
|
||||
void fileUpdated(const VFile *p_file);
|
||||
void fileClicked(VNoteFile *p_file, OpenFileMode mode = OpenFileMode::Read);
|
||||
void fileCreated(VNoteFile *p_file, OpenFileMode mode = OpenFileMode::Read);
|
||||
void fileUpdated(const VNoteFile *p_file);
|
||||
|
||||
private slots:
|
||||
void contextMenuRequested(QPoint pos);
|
||||
void handleItemClicked(QListWidgetItem *currentItem);
|
||||
void fileInfo();
|
||||
void openFileLocation() const;
|
||||
// m_copiedFiles will keep the files's VFile.
|
||||
// m_copiedFiles will keep the files's VNoteFile.
|
||||
void copySelectedFiles(bool p_isCut = false);
|
||||
void cutSelectedFiles();
|
||||
void pasteFilesInCurDir();
|
||||
@ -72,32 +72,36 @@ private:
|
||||
void initShortcuts();
|
||||
|
||||
void updateFileList();
|
||||
QListWidgetItem *insertFileListItem(VFile *file, bool atFront = false);
|
||||
|
||||
QListWidgetItem *insertFileListItem(VNoteFile *file, bool atFront = false);
|
||||
|
||||
void removeFileListItem(QListWidgetItem *item);
|
||||
|
||||
// Init actions.
|
||||
void initActions();
|
||||
|
||||
// Return the corresponding QListWidgetItem of @p_file.
|
||||
QListWidgetItem *findItem(const VFile *p_file);
|
||||
QListWidgetItem *findItem(const VNoteFile *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);
|
||||
bool copyFile(VDirectory *p_destDir, const QString &p_destName, VNoteFile *p_file, bool p_cut);
|
||||
// New items have been added to direcotry. Update file list accordingly.
|
||||
QVector<QListWidgetItem *> updateFileListAdded();
|
||||
inline QPointer<VFile> getVFile(QListWidgetItem *p_item) const;
|
||||
|
||||
inline QPointer<VNoteFile> getVFile(QListWidgetItem *p_item) const;
|
||||
|
||||
// Check if the list items match exactly the contents of the directory.
|
||||
bool identicalListWithDirectory() const;
|
||||
QList<QListWidgetItem *> getVisibleItems() const;
|
||||
|
||||
// Fill the info of @p_item according to @p_file.
|
||||
void fillItem(QListWidgetItem *p_item, const VFile *p_file);
|
||||
void fillItem(QListWidgetItem *p_item, const VNoteFile *p_file);
|
||||
|
||||
VEditArea *editArea;
|
||||
QListWidget *fileList;
|
||||
QPointer<VDirectory> m_directory;
|
||||
QVector<QPointer<VFile> > m_copiedFiles;
|
||||
QVector<QPointer<VNoteFile> > m_copiedFiles;
|
||||
|
||||
// Actions
|
||||
QAction *m_openInReadAct;
|
||||
@ -126,10 +130,10 @@ inline void VFileList::setEditArea(VEditArea *editArea)
|
||||
this->editArea = editArea;
|
||||
}
|
||||
|
||||
inline QPointer<VFile> VFileList::getVFile(QListWidgetItem *p_item) const
|
||||
inline QPointer<VNoteFile> VFileList::getVFile(QListWidgetItem *p_item) const
|
||||
{
|
||||
Q_ASSERT(p_item);
|
||||
return (VFile *)p_item->data(Qt::UserRole).toULongLong();
|
||||
return (VNoteFile *)p_item->data(Qt::UserRole).toULongLong();
|
||||
}
|
||||
|
||||
inline const VDirectory *VFileList::currentDirectory() const
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "vorphanfile.h"
|
||||
#include "dialog/vorphanfileinfodialog.h"
|
||||
#include "vsingleinstanceguard.h"
|
||||
#include "vnotefile.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
@ -464,7 +465,6 @@ void VMainWindow::initHelpMenu()
|
||||
}
|
||||
|
||||
VFile *file = vnote->getOrphanFile(docName, false, true);
|
||||
(dynamic_cast<VOrphanFile *>(file))->setNotebookName(tr("[Help]"));
|
||||
editArea->openFile(file, OpenFileMode::Read);
|
||||
});
|
||||
|
||||
@ -1508,7 +1508,7 @@ void VMainWindow::updateActionStateFromTabStatusChange(const VFile *p_file,
|
||||
editNoteAct->setEnabled(p_file && p_file->isModifiable() && !p_editMode);
|
||||
editNoteAct->setVisible(!saveExitAct->isVisible());
|
||||
saveNoteAct->setEnabled(p_file && p_editMode);
|
||||
deleteNoteAct->setEnabled(p_file && p_file->getType() == FileType::Normal);
|
||||
deleteNoteAct->setEnabled(p_file && p_file->getType() == FileType::Note);
|
||||
noteInfoAct->setEnabled(p_file && !systemFile);
|
||||
|
||||
m_insertImageAct->setEnabled(p_file && p_editMode);
|
||||
@ -1545,7 +1545,13 @@ void VMainWindow::handleAreaTabStatusUpdated(const VEditTabInfo &p_info)
|
||||
if (m_curFile) {
|
||||
m_findReplaceDialog->updateState(m_curFile->getDocType(), editMode);
|
||||
|
||||
title = QString("[%1] %2").arg(m_curFile->getNotebookName()).arg(m_curFile->fetchPath());
|
||||
if (m_curFile->getType() == FileType::Note) {
|
||||
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>((VFile *)m_curFile);
|
||||
title = QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath());
|
||||
} else {
|
||||
title = QString("%1").arg(m_curFile->fetchPath());
|
||||
}
|
||||
|
||||
if (m_curFile->isModifiable()) {
|
||||
if (m_curFile->isModified()) {
|
||||
title.append('*');
|
||||
@ -1636,8 +1642,10 @@ void VMainWindow::curEditFileInfo()
|
||||
{
|
||||
Q_ASSERT(m_curFile);
|
||||
|
||||
if (m_curFile->getType() == FileType::Normal) {
|
||||
fileList->fileInfo(m_curFile);
|
||||
if (m_curFile->getType() == FileType::Note) {
|
||||
VNoteFile *file = dynamic_cast<VNoteFile *>((VFile *)m_curFile);
|
||||
Q_ASSERT(file);
|
||||
fileList->fileInfo(file);
|
||||
} else if (m_curFile->getType() == FileType::Orphan) {
|
||||
VOrphanFile *file = dynamic_cast<VOrphanFile *>((VFile *)m_curFile);
|
||||
Q_ASSERT(file);
|
||||
@ -1649,11 +1657,12 @@ void VMainWindow::curEditFileInfo()
|
||||
|
||||
void VMainWindow::deleteCurNote()
|
||||
{
|
||||
if (!m_curFile || m_curFile->getType() != FileType::Normal) {
|
||||
if (!m_curFile || m_curFile->getType() != FileType::Note) {
|
||||
return;
|
||||
}
|
||||
|
||||
fileList->deleteFile(m_curFile);
|
||||
VNoteFile *file = dynamic_cast<VNoteFile *>((VFile *)m_curFile);
|
||||
fileList->deleteFile(file);
|
||||
}
|
||||
|
||||
void VMainWindow::closeEvent(QCloseEvent *event)
|
||||
@ -1793,23 +1802,24 @@ void VMainWindow::insertImage()
|
||||
bool VMainWindow::locateFile(VFile *p_file)
|
||||
{
|
||||
bool ret = false;
|
||||
if (!p_file || p_file->getType() != FileType::Normal) {
|
||||
if (!p_file || p_file->getType() != FileType::Note) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
VNotebook *notebook = p_file->getNotebook();
|
||||
VNoteFile *file = dynamic_cast<VNoteFile *>(p_file);
|
||||
VNotebook *notebook = file->getNotebook();
|
||||
if (notebookSelector->locateNotebook(notebook)) {
|
||||
while (directoryTree->currentNotebook() != notebook) {
|
||||
QCoreApplication::sendPostedEvents();
|
||||
}
|
||||
|
||||
VDirectory *dir = p_file->getDirectory();
|
||||
VDirectory *dir = file->getDirectory();
|
||||
if (directoryTree->locateDirectory(dir)) {
|
||||
while (fileList->currentDirectory() != dir) {
|
||||
QCoreApplication::sendPostedEvents();
|
||||
}
|
||||
|
||||
if (fileList->locateFile(p_file)) {
|
||||
if (fileList->locateFile(file)) {
|
||||
ret = true;
|
||||
fileList->setFocus();
|
||||
}
|
||||
@ -1933,7 +1943,6 @@ void VMainWindow::shortcutHelp()
|
||||
}
|
||||
|
||||
VFile *file = vnote->getOrphanFile(docName, false, true);
|
||||
(dynamic_cast<VOrphanFile *>(file))->setNotebookName(tr("[Help]"));
|
||||
editArea->openFile(file, OpenFileMode::Read);
|
||||
}
|
||||
|
||||
|
@ -219,7 +219,7 @@ void VMdEdit::imageInserted(const QString &p_path)
|
||||
{
|
||||
ImageLink link;
|
||||
link.m_path = p_path;
|
||||
if (m_file->isRelativeImageFolder()) {
|
||||
if (m_file->useRelativeImageFolder()) {
|
||||
link.m_type = ImageLink::LocalRelativeInternal;
|
||||
} else {
|
||||
link.m_type = ImageLink::LocalAbsolute;
|
||||
@ -300,7 +300,15 @@ void VMdEdit::clearUnusedImages()
|
||||
}
|
||||
|
||||
for (int i = 0; i < unusedImages.size(); ++i) {
|
||||
if (!VUtils::deleteFile(m_file->getNotebook(), unusedImages[i], false)) {
|
||||
bool ret = false;
|
||||
if (m_file->getType() == FileType::Note) {
|
||||
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>((VFile *)m_file);
|
||||
ret = VUtils::deleteFile(tmpFile->getNotebook(), unusedImages[i], false);
|
||||
} else {
|
||||
ret = VUtils::deleteFile(unusedImages[i], false);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
qWarning() << "fail to delete unused original image" << unusedImages[i];
|
||||
} else {
|
||||
qDebug() << "delete unused image" << unusedImages[i];
|
||||
|
@ -45,7 +45,7 @@ bool VMdEditOperations::insertImageFromMimeData(const QMimeData *source)
|
||||
dialog.setImage(image);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
insertImageFromQImage(dialog.getImageTitleInput(),
|
||||
m_file->fetchImagePath(),
|
||||
m_file->fetchImageFolderPath(),
|
||||
m_file->getImageFolderInLink(),
|
||||
image);
|
||||
}
|
||||
@ -170,12 +170,12 @@ bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl)
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
if (isLocal) {
|
||||
insertImageFromPath(dialog.getImageTitleInput(),
|
||||
m_file->fetchImagePath(),
|
||||
m_file->fetchImageFolderPath(),
|
||||
m_file->getImageFolderInLink(),
|
||||
imagePath);
|
||||
} else {
|
||||
insertImageFromQImage(dialog.getImageTitleInput(),
|
||||
m_file->fetchImagePath(),
|
||||
m_file->fetchImageFolderPath(),
|
||||
m_file->getImageFolderInLink(),
|
||||
dialog.getImage());
|
||||
}
|
||||
@ -192,7 +192,7 @@ bool VMdEditOperations::insertImage()
|
||||
QString imagePath = dialog.getPathInput();
|
||||
qDebug() << "insert image from" << imagePath << "as" << title;
|
||||
insertImageFromPath(title,
|
||||
m_file->fetchImagePath(),
|
||||
m_file->fetchImageFolderPath(),
|
||||
m_file->getImageFolderInLink(),
|
||||
imagePath);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "vconfigmanager.h"
|
||||
#include "vmainwindow.h"
|
||||
#include "vorphanfile.h"
|
||||
#include "vnotefile.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
@ -281,7 +282,7 @@ const QString &VNote::getMonospacedFont() const
|
||||
return font;
|
||||
}
|
||||
|
||||
VFile *VNote::getOrphanFile(const QString &p_path, bool p_modifiable, bool p_systemFile)
|
||||
VOrphanFile *VNote::getOrphanFile(const QString &p_path, bool p_modifiable, bool p_systemFile)
|
||||
{
|
||||
if (p_path.isEmpty()) {
|
||||
return NULL;
|
||||
@ -290,17 +291,15 @@ VFile *VNote::getOrphanFile(const QString &p_path, bool p_modifiable, bool p_sys
|
||||
QString path = QDir::cleanPath(p_path);
|
||||
// See if the file has already been opened before.
|
||||
for (auto const &file : m_externalFiles) {
|
||||
Q_ASSERT(file->getType() == FileType::Orphan);
|
||||
VOrphanFile *oFile = dynamic_cast<VOrphanFile *>(file);
|
||||
if (VUtils::equalPath(QDir::cleanPath(oFile->fetchPath()), path)) {
|
||||
Q_ASSERT(oFile->isModifiable() == p_modifiable);
|
||||
Q_ASSERT(oFile->isSystemFile() == p_systemFile);
|
||||
if (VUtils::equalPath(QDir::cleanPath(file->fetchPath()), path)) {
|
||||
Q_ASSERT(file->isModifiable() == p_modifiable);
|
||||
Q_ASSERT(file->isSystemFile() == p_systemFile);
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_externalFiles.size(); ++i) {
|
||||
VFile *file = m_externalFiles[i];
|
||||
VOrphanFile *file = m_externalFiles[i];
|
||||
if (!file->isOpened()) {
|
||||
qDebug() << "release orphan file" << file;
|
||||
m_externalFiles.removeAt(i);
|
||||
@ -310,14 +309,14 @@ VFile *VNote::getOrphanFile(const QString &p_path, bool p_modifiable, bool p_sys
|
||||
}
|
||||
|
||||
// Create a VOrphanFile for path.
|
||||
VOrphanFile *file = new VOrphanFile(path, this, p_modifiable, p_systemFile);
|
||||
VOrphanFile *file = new VOrphanFile(this, path, p_modifiable, p_systemFile);
|
||||
m_externalFiles.append(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
VFile *VNote::getInternalFile(const QString &p_path)
|
||||
VNoteFile *VNote::getInternalFile(const QString &p_path)
|
||||
{
|
||||
VFile *file = NULL;
|
||||
VNoteFile *file = NULL;
|
||||
for (auto & nb : m_notebooks) {
|
||||
file = nb->tryLoadFile(p_path);
|
||||
if (file) {
|
||||
|
16
src/vnote.h
16
src/vnote.h
@ -14,7 +14,8 @@
|
||||
#include "vconstants.h"
|
||||
|
||||
class VMainWindow;
|
||||
class VFile;
|
||||
class VOrphanFile;
|
||||
class VNoteFile;
|
||||
|
||||
class VNote : public QObject
|
||||
{
|
||||
@ -80,14 +81,15 @@ public:
|
||||
|
||||
QString getNavigationLabelStyle(const QString &p_str) const;
|
||||
|
||||
// Given the path of an external file, create a VFile struct.
|
||||
VFile *getOrphanFile(const QString &p_path, bool p_modifiable,
|
||||
bool p_systemFile = false);
|
||||
// Given the path of an external file, create a VOrphanFile struct.
|
||||
VOrphanFile *getOrphanFile(const QString &p_path,
|
||||
bool p_modifiable,
|
||||
bool p_systemFile = false);
|
||||
|
||||
// Given the path of a file, try to find it in all notebooks.
|
||||
// Returns a VFile struct if it is a note in one notebook.
|
||||
// Returns a VNoteFile struct if it is a note in one notebook.
|
||||
// Otherwise, returns NULL.
|
||||
VFile *getInternalFile(const QString &p_path);
|
||||
VNoteFile *getInternalFile(const QString &p_path);
|
||||
|
||||
public slots:
|
||||
void updateTemplate();
|
||||
@ -102,7 +104,7 @@ private:
|
||||
|
||||
// Hold all external file: Orphan File.
|
||||
// Need to clean up periodly.
|
||||
QList<VFile *> m_externalFiles;
|
||||
QList<VOrphanFile *> m_externalFiles;
|
||||
};
|
||||
|
||||
inline const QVector<QPair<QString, QString> >& VNote::getPalette() const
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "vdirectory.h"
|
||||
#include "utils/vutils.h"
|
||||
#include "vconfigmanager.h"
|
||||
#include "vfile.h"
|
||||
#include "vnotefile.h"
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
@ -221,7 +221,7 @@ bool VNotebook::containsFile(const VFile *p_file) const
|
||||
return m_rootDir->containsFile(p_file);
|
||||
}
|
||||
|
||||
VFile *VNotebook::tryLoadFile(const QString &p_path)
|
||||
VNoteFile *VNotebook::tryLoadFile(const QString &p_path)
|
||||
{
|
||||
QFileInfo fi(p_path);
|
||||
Q_ASSERT(fi.isAbsolute());
|
||||
@ -240,7 +240,7 @@ VFile *VNotebook::tryLoadFile(const QString &p_path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VFile *file = m_rootDir->tryLoadFile(filePath);
|
||||
VNoteFile *file = m_rootDir->tryLoadFile(filePath);
|
||||
|
||||
if (!file && !opened) {
|
||||
close();
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
class VDirectory;
|
||||
class VFile;
|
||||
class VNoteFile;
|
||||
|
||||
class VNotebook : public QObject
|
||||
{
|
||||
@ -29,11 +30,11 @@ public:
|
||||
bool containsFile(const VFile *p_file) const;
|
||||
|
||||
// Try to load the file @p_path.
|
||||
// Returns the corresponding VFile struct if @p_path is a note inside this notebook.
|
||||
// Returns the corresponding VNoteFile struct if @p_path is a note inside this notebook.
|
||||
// Otherwise, returns NULL.
|
||||
// If notebook is not opened currently, it will open itself and close itself
|
||||
// if @p_path is not inside this notebook.
|
||||
VFile *tryLoadFile(const QString &p_path);
|
||||
VNoteFile *tryLoadFile(const QString &p_path);
|
||||
|
||||
const QString &getName() const;
|
||||
const QString &getPath() const;
|
||||
|
187
src/vnotefile.cpp
Normal file
187
src/vnotefile.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include "vnotefile.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QTextEdit>
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
|
||||
#include "utils/vutils.h"
|
||||
#include "vdirectory.h"
|
||||
|
||||
VNoteFile::VNoteFile(VDirectory *p_directory,
|
||||
const QString &p_name,
|
||||
FileType p_type,
|
||||
bool p_modifiable,
|
||||
QDateTime p_createdTimeUtc,
|
||||
QDateTime p_modifiedTimeUtc)
|
||||
: VFile(p_directory, p_name, p_type, p_modifiable, p_createdTimeUtc, p_modifiedTimeUtc)
|
||||
{
|
||||
}
|
||||
|
||||
QString VNoteFile::fetchPath() const
|
||||
{
|
||||
return QDir(getDirectory()->fetchPath()).filePath(m_name);
|
||||
}
|
||||
|
||||
QString VNoteFile::fetchBasePath() const
|
||||
{
|
||||
return getDirectory()->fetchPath();
|
||||
}
|
||||
|
||||
QString VNoteFile::fetchImageFolderPath() const
|
||||
{
|
||||
return QDir(fetchBasePath()).filePath(getNotebook()->getImageFolder());
|
||||
}
|
||||
|
||||
bool VNoteFile::useRelativeImageFolder() const
|
||||
{
|
||||
// Always use relative image folder.
|
||||
return true;
|
||||
}
|
||||
|
||||
QString VNoteFile::getImageFolderInLink() const
|
||||
{
|
||||
return getNotebook()->getImageFolder();
|
||||
}
|
||||
|
||||
void VNoteFile::setName(const QString &p_name)
|
||||
{
|
||||
Q_ASSERT(m_name.isEmpty()
|
||||
|| (m_docType == VUtils::docTypeFromName(p_name)));
|
||||
|
||||
m_name = p_name;
|
||||
}
|
||||
|
||||
bool VNoteFile::rename(const QString &p_name)
|
||||
{
|
||||
if (m_name == p_name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString oldName = m_name;
|
||||
|
||||
VDirectory *dir = getDirectory();
|
||||
Q_ASSERT(dir);
|
||||
|
||||
// Rename it in disk.
|
||||
QDir diskDir(dir->fetchPath());
|
||||
if (!diskDir.rename(m_name, p_name)) {
|
||||
qWarning() << "fail to rename file" << 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;
|
||||
}
|
||||
|
||||
// Can't not change doc type.
|
||||
Q_ASSERT(m_docType == VUtils::docTypeFromName(m_name));
|
||||
|
||||
qDebug() << "file renamed from" << oldName << "to" << m_name;
|
||||
return true;
|
||||
}
|
||||
|
||||
VDirectory *VNoteFile::getDirectory()
|
||||
{
|
||||
Q_ASSERT(parent());
|
||||
return (VDirectory *)parent();
|
||||
}
|
||||
|
||||
const VDirectory *VNoteFile::getDirectory() const
|
||||
{
|
||||
Q_ASSERT(parent());
|
||||
return (const VDirectory *)parent();
|
||||
}
|
||||
|
||||
VNotebook *VNoteFile::getNotebook()
|
||||
{
|
||||
return getDirectory()->getNotebook();
|
||||
}
|
||||
|
||||
const VNotebook *VNoteFile::getNotebook() const
|
||||
{
|
||||
return getDirectory()->getNotebook();
|
||||
}
|
||||
|
||||
QString VNoteFile::getNotebookName() const
|
||||
{
|
||||
return getDirectory()->getNotebookName();
|
||||
}
|
||||
|
||||
QString VNoteFile::fetchRelativePath() const
|
||||
{
|
||||
return QDir(getDirectory()->fetchRelativePath()).filePath(m_name);
|
||||
}
|
||||
|
||||
VNoteFile *VNoteFile::fromJson(VDirectory *p_directory,
|
||||
const QJsonObject &p_json,
|
||||
FileType p_type,
|
||||
bool p_modifiable)
|
||||
{
|
||||
return new VNoteFile(p_directory,
|
||||
p_json[DirConfig::c_name].toString(),
|
||||
p_type,
|
||||
p_modifiable,
|
||||
QDateTime::fromString(p_json[DirConfig::c_createdTime].toString(),
|
||||
Qt::ISODate),
|
||||
QDateTime::fromString(p_json[DirConfig::c_modifiedTime].toString(),
|
||||
Qt::ISODate));
|
||||
}
|
||||
|
||||
QJsonObject VNoteFile::toConfigJson() const
|
||||
{
|
||||
QJsonObject item;
|
||||
item[DirConfig::c_name] = m_name;
|
||||
item[DirConfig::c_createdTime] = m_createdTimeUtc.toString(Qt::ISODate);
|
||||
item[DirConfig::c_modifiedTime] = m_modifiedTimeUtc.toString(Qt::ISODate);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
bool VNoteFile::deleteFile()
|
||||
{
|
||||
Q_ASSERT(parent());
|
||||
|
||||
bool ret = false;
|
||||
|
||||
// Delete local images if it is Markdown.
|
||||
if (m_docType == DocType::Markdown) {
|
||||
deleteInternalImages();
|
||||
}
|
||||
|
||||
// TODO: Delete attachments.
|
||||
|
||||
// Delete the file.
|
||||
QString filePath = fetchPath();
|
||||
if (VUtils::deleteFile(getNotebook(), filePath, false)) {
|
||||
ret = true;
|
||||
qDebug() << "deleted" << m_name << filePath;
|
||||
} else {
|
||||
qWarning() << "fail to delete" << m_name << filePath;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VNoteFile::deleteInternalImages()
|
||||
{
|
||||
Q_ASSERT(parent() && m_docType == DocType::Markdown);
|
||||
|
||||
QVector<ImageLink> images = VUtils::fetchImagesFromMarkdownFile(this,
|
||||
ImageLink::LocalRelativeInternal);
|
||||
int deleted = 0;
|
||||
for (int i = 0; i < images.size(); ++i) {
|
||||
if (VUtils::deleteFile(getNotebook(), images[i].m_path, false)) {
|
||||
++deleted;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "delete" << deleted << "images for" << m_name << fetchPath();
|
||||
}
|
||||
|
66
src/vnotefile.h
Normal file
66
src/vnotefile.h
Normal file
@ -0,0 +1,66 @@
|
||||
#ifndef VNOTEFILE_H
|
||||
#define VNOTEFILE_H
|
||||
|
||||
#include "vfile.h"
|
||||
|
||||
class VDirectory;
|
||||
class VNotebook;
|
||||
|
||||
class VNoteFile : public VFile
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VNoteFile(VDirectory *p_directory,
|
||||
const QString &p_name,
|
||||
FileType p_type,
|
||||
bool p_modifiable,
|
||||
QDateTime p_createdTimeUtc,
|
||||
QDateTime p_modifiedTimeUtc);
|
||||
|
||||
QString fetchPath() const Q_DECL_OVERRIDE;
|
||||
|
||||
QString fetchBasePath() const Q_DECL_OVERRIDE;
|
||||
|
||||
QString fetchImageFolderPath() const Q_DECL_OVERRIDE;
|
||||
|
||||
bool useRelativeImageFolder() const Q_DECL_OVERRIDE;
|
||||
|
||||
QString getImageFolderInLink() const Q_DECL_OVERRIDE;
|
||||
|
||||
// Set the name of this file.
|
||||
void setName(const QString &p_name);
|
||||
|
||||
// Rename the name of this file in disk and config.
|
||||
bool rename(const QString &p_name);
|
||||
|
||||
VDirectory *getDirectory();
|
||||
|
||||
const VDirectory *getDirectory() const;
|
||||
|
||||
VNotebook *getNotebook();
|
||||
|
||||
const VNotebook *getNotebook() const;
|
||||
|
||||
QString getNotebookName() const;
|
||||
|
||||
// Get the relative path related to the notebook.
|
||||
QString fetchRelativePath() const;
|
||||
|
||||
// Create a VNoteFile from @p_json Json object.
|
||||
static VNoteFile *fromJson(VDirectory *p_directory,
|
||||
const QJsonObject &p_json,
|
||||
FileType p_type,
|
||||
bool p_modifiable);
|
||||
|
||||
// Create a Json object from current instance.
|
||||
QJsonObject toConfigJson() const;
|
||||
|
||||
// Delete this file in disk as well as all its images/attachments.
|
||||
bool deleteFile();
|
||||
|
||||
private:
|
||||
// Delete internal images of this file.
|
||||
void deleteInternalImages();
|
||||
};
|
||||
|
||||
#endif // VNOTEFILE_H
|
@ -8,7 +8,7 @@
|
||||
#include <QStyleFactory>
|
||||
|
||||
#include "veditwindow.h"
|
||||
#include "vfile.h"
|
||||
#include "vnotefile.h"
|
||||
#include "vedittab.h"
|
||||
#include "vdirectory.h"
|
||||
#include "utils/vutils.h"
|
||||
@ -18,8 +18,19 @@ static const int c_cmdTime = 1 * 1000;
|
||||
static bool fileComp(const VOpenedListMenu::ItemInfo &a,
|
||||
const VOpenedListMenu::ItemInfo &b)
|
||||
{
|
||||
QString notebooka = a.file->getNotebookName().toLower();
|
||||
QString notebookb = b.file->getNotebookName().toLower();
|
||||
QString notebooka, notebookb;
|
||||
if (a.file->getType() == FileType::Note) {
|
||||
notebooka = dynamic_cast<const VNoteFile *>(a.file)->getNotebookName().toLower();
|
||||
} else {
|
||||
notebooka = "EXTERNAL_FILES";
|
||||
}
|
||||
|
||||
if (b.file->getType() == FileType::Note) {
|
||||
notebookb = dynamic_cast<const VNoteFile *>(b.file)->getNotebookName().toLower();
|
||||
} else {
|
||||
notebookb = "EXTERNAL_FILES";
|
||||
}
|
||||
|
||||
if (notebooka < notebookb) {
|
||||
return true;
|
||||
} else if (notebooka > notebookb) {
|
||||
@ -87,11 +98,20 @@ void VOpenedListMenu::updateOpenedList()
|
||||
int index = files[i].index;
|
||||
|
||||
// Whether add separator.
|
||||
QString curNotebook = file->getNotebookName();
|
||||
QString curNotebook;
|
||||
const VDirectory *curDirectory = NULL;
|
||||
if (file->getType() == FileType::Note) {
|
||||
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>((VFile *)file);
|
||||
curNotebook = tmpFile->getNotebookName();
|
||||
curDirectory = tmpFile->getDirectory();
|
||||
} else {
|
||||
curNotebook = "EXTERNAL_FILES";
|
||||
}
|
||||
|
||||
if (curNotebook != notebook
|
||||
|| file->getDirectory() != directory) {
|
||||
|| curDirectory != directory) {
|
||||
notebook = curNotebook;
|
||||
directory = file->getDirectory();
|
||||
directory = curDirectory;
|
||||
QString dirName;
|
||||
if (directory) {
|
||||
dirName = directory->getName();
|
||||
@ -127,8 +147,14 @@ QString VOpenedListMenu::generateDescription(const VFile *p_file) const
|
||||
if (!p_file) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// [Notebook]path
|
||||
return QString("[%1] %2").arg(p_file->getNotebookName()).arg(p_file->fetchPath());
|
||||
if (p_file->getType() == FileType::Note) {
|
||||
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>(p_file);
|
||||
return QString("[%1] %2").arg(tmpFile->getNotebookName()).arg(tmpFile->fetchPath());
|
||||
} else {
|
||||
return QString("%1").arg(p_file->fetchPath());
|
||||
}
|
||||
}
|
||||
|
||||
void VOpenedListMenu::handleItemTriggered(QAction *p_action)
|
||||
|
@ -8,33 +8,19 @@
|
||||
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
VOrphanFile::VOrphanFile(const QString &p_path, QObject *p_parent,
|
||||
bool p_modifiable, bool p_systemFile)
|
||||
VOrphanFile::VOrphanFile(QObject *p_parent,
|
||||
const QString &p_path,
|
||||
bool p_modifiable,
|
||||
bool p_systemFile)
|
||||
: VFile(p_parent,
|
||||
VUtils::fileNameFromPath(p_path),
|
||||
FileType::Orphan,
|
||||
p_modifiable,
|
||||
QDateTime(),
|
||||
QDateTime()),
|
||||
m_path(p_path), m_notebookName(tr("[EXTERNAL]")), m_systemFile(p_systemFile)
|
||||
m_path(p_path),
|
||||
m_systemFile(p_systemFile)
|
||||
{
|
||||
qDebug() << "VOrphanFile" << p_path << m_name << p_modifiable;
|
||||
}
|
||||
|
||||
bool VOrphanFile::open()
|
||||
{
|
||||
Q_ASSERT(!m_name.isEmpty());
|
||||
if (m_opened) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Q_ASSERT(m_content.isEmpty());
|
||||
Q_ASSERT(QFileInfo::exists(m_path));
|
||||
|
||||
m_content = VUtils::readFileFromDisk(m_path);
|
||||
m_modified = false;
|
||||
m_opened = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString VOrphanFile::fetchPath() const
|
||||
@ -42,17 +28,12 @@ QString VOrphanFile::fetchPath() const
|
||||
return m_path;
|
||||
}
|
||||
|
||||
QString VOrphanFile::fetchRelativePath() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
QString VOrphanFile::fetchBasePath() const
|
||||
{
|
||||
return VUtils::basePathFromPath(m_path);
|
||||
}
|
||||
|
||||
QString VOrphanFile::fetchImagePath() const
|
||||
QString VOrphanFile::fetchImageFolderPath() const
|
||||
{
|
||||
QString folder = m_imageFolder;
|
||||
if (m_imageFolder.isEmpty()) {
|
||||
@ -67,76 +48,7 @@ QString VOrphanFile::fetchImagePath() const
|
||||
}
|
||||
}
|
||||
|
||||
bool VOrphanFile::save()
|
||||
{
|
||||
Q_ASSERT(m_opened);
|
||||
Q_ASSERT(m_modifiable);
|
||||
return VUtils::writeFileToDisk(fetchPath(), m_content);
|
||||
}
|
||||
|
||||
void VOrphanFile::setName(const QString & /* p_name */)
|
||||
{
|
||||
V_ASSERT(false);
|
||||
}
|
||||
|
||||
VDirectory *VOrphanFile::getDirectory()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const VDirectory *VOrphanFile::getDirectory() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QString VOrphanFile::getNotebookName() const
|
||||
{
|
||||
return m_notebookName;
|
||||
}
|
||||
|
||||
void VOrphanFile::setNotebookName(const QString &p_notebook)
|
||||
{
|
||||
m_notebookName = p_notebook;
|
||||
}
|
||||
|
||||
VNotebook *VOrphanFile::getNotebook()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void VOrphanFile::setContent(const QString & p_content)
|
||||
{
|
||||
m_content = p_content;
|
||||
}
|
||||
|
||||
bool VOrphanFile::isInternalImageFolder(const QString &p_path) const
|
||||
{
|
||||
return VUtils::equalPath(VUtils::basePathFromPath(p_path),
|
||||
fetchBasePath())
|
||||
|| VUtils::equalPath(p_path, fetchImagePath());
|
||||
}
|
||||
|
||||
bool VOrphanFile::rename(const QString &p_name)
|
||||
{
|
||||
QDir dir(fetchBasePath());
|
||||
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;
|
||||
}
|
||||
|
||||
void VOrphanFile::setImageFolder(const QString &p_path)
|
||||
{
|
||||
qDebug() << "orphan file" << fetchPath() << "image folder"
|
||||
<< m_imageFolder << "->" << p_path;
|
||||
m_imageFolder = p_path;
|
||||
}
|
||||
|
||||
bool VOrphanFile::isRelativeImageFolder() const
|
||||
bool VOrphanFile::useRelativeImageFolder() const
|
||||
{
|
||||
QString folder = m_imageFolder;
|
||||
if (m_imageFolder.isEmpty()) {
|
||||
|
@ -3,78 +3,65 @@
|
||||
|
||||
#include "vfile.h"
|
||||
|
||||
// VOrphanFile is file not belong to any notebooks or directories.
|
||||
// VOrphanFile is a file not belonging to any notebooks or directories.
|
||||
// Such as external files, system files.
|
||||
// It uses the file path to locate and identify a file.
|
||||
class VOrphanFile : public VFile
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VOrphanFile(const QString &p_path, QObject *p_parent,
|
||||
bool p_modifiable, bool p_systemFile = false);
|
||||
VOrphanFile(QObject *p_parent,
|
||||
const QString &p_path,
|
||||
bool p_modifiable,
|
||||
bool p_systemFile = false);
|
||||
|
||||
bool open() Q_DECL_OVERRIDE;
|
||||
QString fetchPath() const Q_DECL_OVERRIDE;
|
||||
QString fetchRelativePath() const Q_DECL_OVERRIDE;
|
||||
|
||||
QString fetchBasePath() const Q_DECL_OVERRIDE;
|
||||
VDirectory *getDirectory() Q_DECL_OVERRIDE;
|
||||
const VDirectory *getDirectory() const Q_DECL_OVERRIDE;
|
||||
QString getNotebookName() const Q_DECL_OVERRIDE;
|
||||
|
||||
void setNotebookName(const QString &p_notebook);
|
||||
QString fetchImageFolderPath() const Q_DECL_OVERRIDE;
|
||||
|
||||
VNotebook *getNotebook() Q_DECL_OVERRIDE;
|
||||
|
||||
// Rename file.
|
||||
bool rename(const QString &p_name) Q_DECL_OVERRIDE;
|
||||
|
||||
void setImageFolder(const QString &p_path);
|
||||
|
||||
const QString getImageFolder() const;
|
||||
|
||||
// Whether the image folder is a relative path.
|
||||
bool isRelativeImageFolder() const Q_DECL_OVERRIDE;
|
||||
// Whether use a relative image folder.
|
||||
bool useRelativeImageFolder() const Q_DECL_OVERRIDE;
|
||||
|
||||
// Return the image folder part in an image link.
|
||||
QString getImageFolderInLink() const Q_DECL_OVERRIDE;
|
||||
|
||||
// Return image folder config.
|
||||
const QString getImageFolder() const;
|
||||
|
||||
// Set the image folder config.
|
||||
void setImageFolder(const QString &p_path);
|
||||
|
||||
bool isSystemFile() const;
|
||||
|
||||
private:
|
||||
bool save() Q_DECL_OVERRIDE;
|
||||
void setName(const QString &p_name) Q_DECL_OVERRIDE;
|
||||
QString fetchImagePath() const Q_DECL_OVERRIDE;
|
||||
void setContent(const QString &p_content) Q_DECL_OVERRIDE;
|
||||
bool isInternalImageFolder(const QString &p_path) const Q_DECL_OVERRIDE;
|
||||
|
||||
static VFile *fromJson(const QJsonObject &p_json,
|
||||
QObject *p_parent,
|
||||
FileType p_type,
|
||||
bool p_modifiable);
|
||||
|
||||
QJsonObject toConfigJson() const;
|
||||
|
||||
// Full path of this file.
|
||||
QString m_path;
|
||||
|
||||
QString m_notebookName;
|
||||
|
||||
// Image folder path of this file.
|
||||
// It could be an absolute or relative path.
|
||||
// Empty to use the global default config.
|
||||
// Valid only within a session.
|
||||
QString m_imageFolder;
|
||||
|
||||
// Whether it is a system internal file.
|
||||
bool m_systemFile;
|
||||
|
||||
friend class VDirectory;
|
||||
};
|
||||
|
||||
inline bool VOrphanFile::isSystemFile() const
|
||||
{
|
||||
return m_systemFile;
|
||||
}
|
||||
|
||||
inline const QString VOrphanFile::getImageFolder() const
|
||||
{
|
||||
return m_imageFolder;
|
||||
}
|
||||
|
||||
inline void VOrphanFile::setImageFolder(const QString &p_path)
|
||||
{
|
||||
m_imageFolder = p_path;
|
||||
}
|
||||
|
||||
inline bool VOrphanFile::isSystemFile() const
|
||||
{
|
||||
return m_systemFile;
|
||||
}
|
||||
|
||||
#endif // VORPHANFILE_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user