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