mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
refactor VDirectoryTree
- Refine folder deletion logics; - Refine folder copy/paste logics; - Add folder sort logics;
This commit is contained in:
parent
f9080db71c
commit
3724eb35dd
@ -132,6 +132,11 @@ void VSortDialog::treeUpdated()
|
||||
m_treeWidget->resizeColumnToContents(i);
|
||||
}
|
||||
|
||||
QHeaderView *header = m_treeWidget->header();
|
||||
if (header) {
|
||||
header->setStretchLastSection(true);
|
||||
}
|
||||
|
||||
// We just need single level.
|
||||
int cnt = m_treeWidget->topLevelItemCount();
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
|
@ -374,7 +374,6 @@ void VAttachmentList::sortItems()
|
||||
QTreeWidget *tree = dialog.getTreeWidget();
|
||||
tree->clear();
|
||||
tree->setColumnCount(1);
|
||||
tree->header()->setStretchLastSection(true);
|
||||
QStringList headers;
|
||||
headers << tr("Name");
|
||||
tree->setHeaderLabels(headers);
|
||||
|
@ -19,6 +19,7 @@ namespace ClipboardConfig
|
||||
static const QString c_magic = "magic";
|
||||
static const QString c_isCut = "is_cut";
|
||||
static const QString c_files = "files";
|
||||
static const QString c_dirs = "dirs";
|
||||
}
|
||||
|
||||
enum class OpenFileMode {Read = 0, Edit};
|
||||
|
@ -10,8 +10,8 @@
|
||||
extern VConfigManager *g_config;
|
||||
|
||||
VDirectory::VDirectory(VNotebook *p_notebook,
|
||||
VDirectory *p_parent,
|
||||
const QString &p_name,
|
||||
QObject *p_parent,
|
||||
QDateTime p_createdTimeUtc)
|
||||
: QObject(p_parent),
|
||||
m_notebook(p_notebook),
|
||||
@ -45,7 +45,7 @@ bool VDirectory::open()
|
||||
QJsonArray dirJson = configJson[DirConfig::c_subDirectories].toArray();
|
||||
for (int i = 0; i < dirJson.size(); ++i) {
|
||||
QJsonObject dirItem = dirJson[i].toObject();
|
||||
VDirectory *dir = new VDirectory(m_notebook, dirItem[DirConfig::c_name].toString(), this);
|
||||
VDirectory *dir = new VDirectory(m_notebook, this, dirItem[DirConfig::c_name].toString());
|
||||
m_subDirs.append(dir);
|
||||
}
|
||||
|
||||
@ -188,28 +188,37 @@ void VDirectory::addNotebookConfig(QJsonObject &p_json) const
|
||||
}
|
||||
}
|
||||
|
||||
VDirectory *VDirectory::createSubDirectory(const QString &p_name)
|
||||
VDirectory *VDirectory::createSubDirectory(const QString &p_name,
|
||||
QString *p_errMsg)
|
||||
{
|
||||
Q_ASSERT(!p_name.isEmpty());
|
||||
// First open current directory
|
||||
|
||||
if (!open()) {
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to open folder %1.").arg(m_name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qDebug() << "create subfolder" << p_name << "in" << m_name;
|
||||
QDir dir(fetchPath());
|
||||
if (dir.exists(p_name)) {
|
||||
VUtils::addErrMsg(p_errMsg, tr("%1 already exists in directory %2.")
|
||||
.arg(p_name)
|
||||
.arg(fetchPath()));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QString path = fetchPath();
|
||||
QDir dir(path);
|
||||
if (!dir.mkdir(p_name)) {
|
||||
qWarning() << "fail to create directory" << p_name << "under" << path;
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to create folder in %1.")
|
||||
.arg(m_name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VDirectory *ret = new VDirectory(m_notebook,
|
||||
p_name,
|
||||
this,
|
||||
p_name,
|
||||
QDateTime::currentDateTimeUtc());
|
||||
if (!ret->writeToConfig()) {
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to write configuration of folder %1.")
|
||||
.arg(p_name));
|
||||
dir.rmdir(p_name);
|
||||
delete ret;
|
||||
return NULL;
|
||||
@ -217,11 +226,13 @@ VDirectory *VDirectory::createSubDirectory(const QString &p_name)
|
||||
|
||||
m_subDirs.append(ret);
|
||||
if (!writeToConfig()) {
|
||||
VConfigManager::deleteDirectoryConfig(QDir(path).filePath(p_name));
|
||||
dir.rmdir(p_name);
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to write configuration of folder %1.")
|
||||
.arg(p_name));
|
||||
|
||||
QDir subdir(dir.filePath(p_name));
|
||||
subdir.removeRecursively();
|
||||
delete ret;
|
||||
m_subDirs.removeLast();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -399,13 +410,13 @@ bool VDirectory::addSubDirectory(VDirectory *p_dir, int p_index)
|
||||
|
||||
VDirectory *VDirectory::addSubDirectory(const QString &p_name, int p_index)
|
||||
{
|
||||
if (!open()) {
|
||||
if (!open() || p_name.isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VDirectory *dir = new VDirectory(m_notebook,
|
||||
p_name,
|
||||
this,
|
||||
p_name,
|
||||
QDateTime::currentDateTimeUtc());
|
||||
if (!dir) {
|
||||
return NULL;
|
||||
@ -419,24 +430,45 @@ VDirectory *VDirectory::addSubDirectory(const QString &p_name, int p_index)
|
||||
return dir;
|
||||
}
|
||||
|
||||
void VDirectory::deleteSubDirectory(VDirectory *p_subDir, bool p_skipRecycleBin)
|
||||
bool VDirectory::deleteDirectory(bool p_skipRecycleBin, QString *p_errMsg)
|
||||
{
|
||||
Q_ASSERT(p_subDir->getNotebook() == m_notebook);
|
||||
|
||||
QString dirPath = p_subDir->fetchPath();
|
||||
|
||||
p_subDir->close();
|
||||
|
||||
removeSubDirectory(p_subDir);
|
||||
Q_ASSERT(!m_opened);
|
||||
Q_ASSERT(parent());
|
||||
|
||||
// Delete the entire directory.
|
||||
bool ret = true;
|
||||
QString dirPath = fetchPath();
|
||||
if (!VUtils::deleteDirectory(m_notebook, dirPath, p_skipRecycleBin)) {
|
||||
qWarning() << "fail to remove directory" << dirPath << "recursively";
|
||||
} else {
|
||||
qDebug() << "deleted" << dirPath << (p_skipRecycleBin ? "from disk" : "to recycle bin");
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to delete the directory %1.").arg(dirPath));
|
||||
ret = false;
|
||||
}
|
||||
|
||||
delete p_subDir;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VDirectory::deleteDirectory(VDirectory *p_dir, bool p_skipRecycleBin, QString *p_errMsg)
|
||||
{
|
||||
p_dir->close();
|
||||
|
||||
bool ret = true;
|
||||
|
||||
QString name = p_dir->getName();
|
||||
QString path = p_dir->fetchPath();
|
||||
|
||||
if (!p_dir->deleteDirectory(p_skipRecycleBin, p_errMsg)) {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
VDirectory *paDir = p_dir->getParentDirectory();
|
||||
Q_ASSERT(paDir);
|
||||
if (!paDir->removeSubDirectory(p_dir)) {
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to remove the folder from the folder configuration."));
|
||||
ret = false;
|
||||
}
|
||||
|
||||
delete p_dir;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VDirectory::removeSubDirectory(VDirectory *p_dir)
|
||||
@ -452,8 +484,6 @@ bool VDirectory::removeSubDirectory(VDirectory *p_dir)
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "folder" << p_dir->getName() << "removed from folder" << m_name;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -504,35 +534,48 @@ bool VDirectory::rename(const QString &p_name)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copy @p_srcDir to be a sub-directory of @p_destDir with name @p_destName.
|
||||
VDirectory *VDirectory::copyDirectory(VDirectory *p_destDir, const QString &p_destName,
|
||||
VDirectory *p_srcDir, bool p_cut)
|
||||
bool VDirectory::copyDirectory(VDirectory *p_destDir,
|
||||
const QString &p_destName,
|
||||
VDirectory *p_dir,
|
||||
bool p_isCut,
|
||||
VDirectory **p_targetDir,
|
||||
QString *p_errMsg)
|
||||
{
|
||||
QString srcPath = QDir::cleanPath(p_srcDir->fetchPath());
|
||||
bool ret = true;
|
||||
*p_targetDir = NULL;
|
||||
|
||||
QString srcPath = QDir::cleanPath(p_dir->fetchPath());
|
||||
QString destPath = QDir::cleanPath(QDir(p_destDir->fetchPath()).filePath(p_destName));
|
||||
if (VUtils::equalPath(srcPath, destPath)) {
|
||||
return p_srcDir;
|
||||
*p_targetDir = p_dir;
|
||||
return false;
|
||||
}
|
||||
|
||||
VDirectory *srcParentDir = p_srcDir->getParentDirectory();
|
||||
|
||||
// Copy the directory
|
||||
if (!VUtils::copyDirectory(srcPath, destPath, p_cut)) {
|
||||
return NULL;
|
||||
if (!p_destDir->isOpened()) {
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to open target folder."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle VDirectory
|
||||
int index = -1;
|
||||
QString opStr = p_isCut ? tr("cut") : tr("copy");
|
||||
VDirectory *paDir = p_dir->getParentDirectory();
|
||||
|
||||
Q_ASSERT(paDir->isOpened());
|
||||
|
||||
// Copy the directory.
|
||||
if (!VUtils::copyDirectory(srcPath, destPath, p_isCut)) {
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to %1 the folder.").arg(opStr));
|
||||
qWarning() << "fail to" << opStr << "the folder directory" << srcPath << "to" << destPath;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add directory to VDirectory.
|
||||
VDirectory *destDir = NULL;
|
||||
if (p_cut) {
|
||||
// Remove the directory from config
|
||||
srcParentDir->removeSubDirectory(p_srcDir);
|
||||
|
||||
p_srcDir->setName(p_destName);
|
||||
|
||||
if (p_isCut) {
|
||||
paDir->removeSubDirectory(p_dir);
|
||||
p_dir->setName(p_destName);
|
||||
// Add the directory to new dir's config
|
||||
if (p_destDir->addSubDirectory(p_srcDir, index)) {
|
||||
destDir = p_srcDir;
|
||||
if (p_destDir->addSubDirectory(p_dir, -1)) {
|
||||
destDir = p_dir;
|
||||
} else {
|
||||
destDir = NULL;
|
||||
}
|
||||
@ -540,7 +583,15 @@ VDirectory *VDirectory::copyDirectory(VDirectory *p_destDir, const QString &p_de
|
||||
destDir = p_destDir->addSubDirectory(p_destName, -1);
|
||||
}
|
||||
|
||||
return destDir;
|
||||
if (!destDir) {
|
||||
VUtils::addErrMsg(p_errMsg, tr("Fail to add the folder to target folder's configuration."));
|
||||
return false;
|
||||
}
|
||||
|
||||
qDebug() << "copyDirectory:" << p_dir << "to" << destDir;
|
||||
|
||||
*p_targetDir = destDir;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VDirectory::setExpanded(bool p_expanded)
|
||||
@ -591,6 +642,39 @@ VNoteFile *VDirectory::tryLoadFile(QStringList &p_filePath)
|
||||
return file;
|
||||
}
|
||||
|
||||
VDirectory *VDirectory::tryLoadDirectory(QStringList &p_filePath)
|
||||
{
|
||||
qDebug() << "directory" << m_name << "tryLoadDirectory()" << p_filePath.join("/");
|
||||
if (p_filePath.isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool opened = isOpened();
|
||||
if (!open()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
bool caseSensitive = false;
|
||||
#else
|
||||
bool caseSensitive = true;
|
||||
#endif
|
||||
|
||||
VDirectory *dir = findSubDirectory(p_filePath.at(0), caseSensitive);
|
||||
if (dir) {
|
||||
if (p_filePath.size() > 1) {
|
||||
p_filePath.removeFirst();
|
||||
dir = dir->tryLoadDirectory(p_filePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dir && !opened) {
|
||||
close();
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
bool VDirectory::sortFiles(const QVector<int> &p_sortedIdx)
|
||||
{
|
||||
V_ASSERT(m_opened);
|
||||
@ -611,3 +695,24 @@ bool VDirectory::sortFiles(const QVector<int> &p_sortedIdx)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VDirectory::sortSubDirectories(const QVector<int> &p_sortedIdx)
|
||||
{
|
||||
V_ASSERT(m_opened);
|
||||
V_ASSERT(p_sortedIdx.size() == m_subDirs.size());
|
||||
|
||||
auto ori = m_subDirs;
|
||||
|
||||
for (int i = 0; i < p_sortedIdx.size(); ++i) {
|
||||
m_subDirs[i] = ori[p_sortedIdx[i]];
|
||||
}
|
||||
|
||||
bool ret = true;
|
||||
if (!writeToConfig()) {
|
||||
qWarning() << "fail to reorder sub-directories in config" << p_sortedIdx;
|
||||
m_subDirs = ori;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -17,13 +17,16 @@ class VDirectory : public QObject
|
||||
Q_OBJECT
|
||||
public:
|
||||
VDirectory(VNotebook *p_notebook,
|
||||
VDirectory *p_parent,
|
||||
const QString &p_name,
|
||||
QObject *p_parent = 0,
|
||||
QDateTime p_createdTimeUtc = QDateTime());
|
||||
|
||||
bool open();
|
||||
void close();
|
||||
VDirectory *createSubDirectory(const QString &p_name);
|
||||
|
||||
// Create a sub-directory with name @p_name.
|
||||
VDirectory *createSubDirectory(const QString &p_name,
|
||||
QString *p_errMsg = NULL);
|
||||
|
||||
// Returns the VDirectory with the name @p_name directly in this directory.
|
||||
VDirectory *findSubDirectory(const QString &p_name, bool p_caseSensitive);
|
||||
@ -36,9 +39,6 @@ public:
|
||||
|
||||
VNoteFile *createFile(const QString &p_name);
|
||||
|
||||
// Remove and delete subdirectory @p_subDir.
|
||||
void deleteSubDirectory(VDirectory *p_subDir, bool p_skipRecycleBin = false);
|
||||
|
||||
// Remove the file in the config and m_files without deleting it in the disk.
|
||||
// It won't change the parent of @p_file to enable it find its path.
|
||||
bool removeFile(VNoteFile *p_file);
|
||||
@ -58,10 +58,17 @@ public:
|
||||
// Rename current directory to @p_name.
|
||||
bool rename(const QString &p_name);
|
||||
|
||||
static VDirectory *copyDirectory(VDirectory *p_destDir, const QString &p_destName,
|
||||
VDirectory *p_srcDir, bool p_cut);
|
||||
// Copy @p_dir as a sub-directory of @p_destDir with the new name @p_destName.
|
||||
// Return a directory representing the destination directory after copy/cut.
|
||||
static bool copyDirectory(VDirectory *p_destDir,
|
||||
const QString &p_destName,
|
||||
VDirectory *p_dir,
|
||||
bool p_isCut,
|
||||
VDirectory **p_targetDir,
|
||||
QString *p_errMsg = NULL);
|
||||
|
||||
const QVector<VDirectory *> &getSubDirs() const;
|
||||
|
||||
const QString &getName() const;
|
||||
void setName(const QString &p_name);
|
||||
bool isOpened() const;
|
||||
@ -96,11 +103,22 @@ public:
|
||||
// Try to load file given relative path @p_filePath.
|
||||
VNoteFile *tryLoadFile(QStringList &p_filePath);
|
||||
|
||||
// Try to load directory given relative path @p_filePath.
|
||||
VDirectory *tryLoadDirectory(QStringList &p_filePath);
|
||||
|
||||
QDateTime getCreatedTimeUtc() const;
|
||||
|
||||
// Reorder files in m_files by index.
|
||||
bool sortFiles(const QVector<int> &p_sortedIdx);
|
||||
|
||||
// Reorder sub-directories in m_subDirs by index.
|
||||
bool sortSubDirectories(const QVector<int> &p_sortedIdx);
|
||||
|
||||
// Delete directory @p_dir.
|
||||
static bool deleteDirectory(VDirectory *p_dir,
|
||||
bool p_skipRecycleBin = false,
|
||||
QString *p_errMsg = NULL);
|
||||
|
||||
private:
|
||||
// Get the path of @p_dir recursively
|
||||
QString fetchPath(const VDirectory *p_dir) const;
|
||||
@ -121,6 +139,9 @@ private:
|
||||
// Add the directory in the config and m_subDirs. If @p_index is -1, add it at the end.
|
||||
bool addSubDirectory(VDirectory *p_dir, int p_index);
|
||||
|
||||
// Delete this directory in disk.
|
||||
bool deleteDirectory(bool p_skipRecycleBin = false, QString *p_errMsg = NULL);
|
||||
|
||||
// Notebook containing this folder.
|
||||
QPointer<VNotebook> m_notebook;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,6 @@
|
||||
#include "vnotebook.h"
|
||||
#include "vnavigationmode.h"
|
||||
|
||||
class VNote;
|
||||
class VEditArea;
|
||||
class QLabel;
|
||||
|
||||
@ -20,10 +19,14 @@ class VDirectoryTree : public QTreeWidget, public VNavigationMode
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VDirectoryTree(VNote *vnote, QWidget *parent = 0);
|
||||
inline void setEditArea(VEditArea *p_editArea);
|
||||
explicit VDirectoryTree(QWidget *parent = 0);
|
||||
|
||||
void setEditArea(VEditArea *p_editArea);
|
||||
|
||||
// Locate to the item representing @p_directory.
|
||||
bool locateDirectory(const VDirectory *p_directory);
|
||||
inline const VNotebook *currentNotebook() const;
|
||||
|
||||
const VNotebook *currentNotebook() const;
|
||||
|
||||
// Implementations for VNavigationMode.
|
||||
void registerNavigation(QChar p_majorKey) Q_DECL_OVERRIDE;
|
||||
@ -33,12 +36,17 @@ public:
|
||||
|
||||
signals:
|
||||
void currentDirectoryChanged(VDirectory *p_directory);
|
||||
|
||||
void directoryUpdated(const VDirectory *p_directory);
|
||||
|
||||
public slots:
|
||||
// Set directory tree to display a given notebook @p_notebook.
|
||||
void setNotebook(VNotebook *p_notebook);
|
||||
|
||||
// Create a root folder.
|
||||
void newRootDirectory();
|
||||
void deleteDirectory();
|
||||
|
||||
// View and edit info about directory.
|
||||
void editDirectoryInfo();
|
||||
|
||||
// Clear and re-build the whole directory tree.
|
||||
@ -46,75 +54,117 @@ public slots:
|
||||
void updateDirectoryTree();
|
||||
|
||||
private slots:
|
||||
// Set the state of expansion of the directory.
|
||||
void handleItemExpanded(QTreeWidgetItem *p_item);
|
||||
|
||||
// Set the state of expansion of the directory.
|
||||
void handleItemCollapsed(QTreeWidgetItem *p_item);
|
||||
|
||||
void contextMenuRequested(QPoint pos);
|
||||
|
||||
// Directory selected folder.
|
||||
// Currently only support single selected item.
|
||||
void deleteSelectedDirectory();
|
||||
|
||||
// Create sub-directory of current item's directory.
|
||||
void newSubDirectory();
|
||||
|
||||
// Current tree item changed.
|
||||
void currentDirectoryItemChanged(QTreeWidgetItem *currentItem);
|
||||
void copySelectedDirectories(bool p_cut = false);
|
||||
|
||||
// Copy selected directories.
|
||||
// Will put a Json string into the clipboard which contains the information
|
||||
// about copied directories.
|
||||
void copySelectedDirectories(bool p_isCut = false);
|
||||
|
||||
void cutSelectedDirectories();
|
||||
void pasteDirectoriesInCurDir();
|
||||
|
||||
// Paste directories from clipboard as sub-directories of current item.
|
||||
void pasteDirectoriesFromClipboard();
|
||||
|
||||
// Open the folder's parent directory in system's file browser.
|
||||
void openDirectoryLocation() const;
|
||||
|
||||
// Reload the content of current directory.
|
||||
void reloadFromDisk();
|
||||
|
||||
// Sort sub-folders of current item's folder.
|
||||
void sortItems();
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
// Build the subtree of @p_parent recursively to the depth @p_depth.
|
||||
// Item @p_parent must not be built before.
|
||||
// Will expand the item if the corresponding directory was expanded before.
|
||||
// @p_depth: valid only when greater than 0.
|
||||
void updateDirectoryTreeOne(QTreeWidgetItem *p_parent, int p_depth);
|
||||
|
||||
// Build the subtree of @p_parent recursively to the depth @p_depth.
|
||||
// @p_depth: negative - infinite levels.
|
||||
// Will expand the item if the corresponding directory was expanded before.
|
||||
// Will treat items with children as items having been built before.
|
||||
void buildSubTree(QTreeWidgetItem *p_parent, int p_depth);
|
||||
|
||||
// Fill the content of a tree item.
|
||||
void fillTreeItem(QTreeWidgetItem &p_item, const QString &p_name,
|
||||
VDirectory *p_directory, const QIcon &p_icon);
|
||||
// Fill the content of a tree item according to @p_directory.
|
||||
void fillTreeItem(QTreeWidgetItem *p_item, VDirectory *p_directory);
|
||||
|
||||
void initShortcuts();
|
||||
|
||||
void initActions();
|
||||
|
||||
// Update @p_item's direct children only: deleted, added, renamed.
|
||||
void updateItemChildren(QTreeWidgetItem *p_item);
|
||||
void updateItemDirectChildren(QTreeWidgetItem *p_item);
|
||||
|
||||
// Find the corresponding item of @p_dir;
|
||||
// Return's NULL if no item is found and it is the root directory if @p_widget is true.
|
||||
QTreeWidgetItem *findVDirectory(const VDirectory *p_dir, bool &p_widget);
|
||||
inline QPointer<VDirectory> getVDirectory(QTreeWidgetItem *p_item) const;
|
||||
void copyDirectoryInfoToClipboard(const QJsonArray &p_dirs, bool p_cut);
|
||||
void pasteDirectories(VDirectory *p_destDir);
|
||||
bool copyDirectory(VDirectory *p_destDir, const QString &p_destName,
|
||||
VDirectory *p_srcDir, bool p_cut);
|
||||
QTreeWidgetItem *findVDirectory(const VDirectory *p_dir, bool *p_widget = NULL);
|
||||
|
||||
QPointer<VDirectory> getVDirectory(QTreeWidgetItem *p_item) const;
|
||||
|
||||
// Paste @p_dirs as sub-directory of @p_destDir.
|
||||
void pasteDirectories(VDirectory *p_destDir,
|
||||
const QVector<QString> &p_dirs,
|
||||
bool p_isCut);
|
||||
|
||||
// Build the subtree of @p_item's children if it has not been built yet.
|
||||
void updateChildren(QTreeWidgetItem *p_item);
|
||||
// We need to fill the children before showing a item to get a correct render.
|
||||
void buildChildren(QTreeWidgetItem *p_item);
|
||||
|
||||
// Expand/create the directory tree nodes to @p_directory.
|
||||
QTreeWidgetItem *expandToVDirectory(const VDirectory *p_directory);
|
||||
|
||||
// Expand the currently-built subtree of @p_item according to VDirectory.isExpanded().
|
||||
void expandItemTree(QTreeWidgetItem *p_item);
|
||||
void expandSubTree(QTreeWidgetItem *p_item);
|
||||
|
||||
QList<QTreeWidgetItem *> getVisibleItems() const;
|
||||
|
||||
QList<QTreeWidgetItem *> getVisibleChildItems(const QTreeWidgetItem *p_item) const;
|
||||
|
||||
// We use a map to save and restore current directory of each notebook.
|
||||
// Try to restore current directory after changing notebook.
|
||||
// Return false if no cache item found for current notebook.
|
||||
bool restoreCurrentItem();
|
||||
|
||||
VNote *vnote;
|
||||
// Generate new magic to m_magicForClipboard.
|
||||
int getNewMagic();
|
||||
|
||||
// Check if @p_magic equals to m_magicForClipboard.
|
||||
bool checkMagic(int p_magic) const;
|
||||
|
||||
// Check if clipboard contains valid info to paste as directories.
|
||||
bool pasteAvailable() const;
|
||||
|
||||
// Sort sub-directories of @p_dir.
|
||||
void sortItems(VDirectory *p_dir);
|
||||
|
||||
QPointer<VNotebook> m_notebook;
|
||||
QVector<QPointer<VDirectory> > m_copiedDirs;
|
||||
|
||||
VEditArea *m_editArea;
|
||||
|
||||
// Each notebook's current item's VDirectory.
|
||||
QHash<VNotebook *, VDirectory *> m_notebookCurrentDirMap;
|
||||
|
||||
// Magic number for clipboard operations.
|
||||
int m_magicForClipboard;
|
||||
|
||||
// Actions
|
||||
QAction *newRootDirAct;
|
||||
QAction *newSiblingDirAct;
|
||||
@ -125,6 +175,7 @@ private:
|
||||
QAction *cutAct;
|
||||
QAction *pasteAct;
|
||||
QAction *m_openLocationAct;
|
||||
QAction *m_sortAct;
|
||||
|
||||
// Reload content from disk.
|
||||
QAction *m_reloadAct;
|
||||
|
@ -702,15 +702,16 @@ void VFileList::pasteFilesFromClipboard()
|
||||
}
|
||||
|
||||
pasteFiles(m_directory, filesToPaste, isCut);
|
||||
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
clipboard->clear();
|
||||
}
|
||||
|
||||
void VFileList::pasteFiles(VDirectory *p_destDir,
|
||||
const QVector<QString> &p_files,
|
||||
bool p_isCut)
|
||||
{
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
if (!p_destDir || p_files.isEmpty()) {
|
||||
clipboard->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -721,7 +722,7 @@ void VFileList::pasteFiles(VDirectory *p_destDir,
|
||||
qWarning() << "Copied file is not an internal note" << p_files[i];
|
||||
VUtils::showMessage(QMessageBox::Warning,
|
||||
tr("Warning"),
|
||||
tr("Fail to copy note <span style=\"%1\">%2</span>.")
|
||||
tr("Fail to paste note <span style=\"%1\">%2</span>.")
|
||||
.arg(g_config->c_dataTextStyle)
|
||||
.arg(p_files[i]),
|
||||
tr("VNote could not find this note in any notebook."),
|
||||
@ -794,7 +795,7 @@ void VFileList::pasteFiles(VDirectory *p_destDir,
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "copy" << nrPasted << "files";
|
||||
qDebug() << "pasted" << nrPasted << "files";
|
||||
if (nrPasted > 0) {
|
||||
g_mainWin->showStatusMessage(tr("%1 %2 pasted")
|
||||
.arg(nrPasted)
|
||||
@ -802,7 +803,6 @@ void VFileList::pasteFiles(VDirectory *p_destDir,
|
||||
}
|
||||
|
||||
updateFileList();
|
||||
clipboard->clear();
|
||||
getNewMagic();
|
||||
}
|
||||
|
||||
@ -1021,7 +1021,6 @@ void VFileList::sortItems()
|
||||
QTreeWidget *tree = dialog.getTreeWidget();
|
||||
tree->clear();
|
||||
tree->setColumnCount(3);
|
||||
tree->header()->setStretchLastSection(true);
|
||||
QStringList headers;
|
||||
headers << tr("Name") << tr("Created Time") << tr("Modified Time");
|
||||
tree->setHeaderLabels(headers);
|
||||
|
@ -177,7 +177,7 @@ QWidget *VMainWindow::setupDirectoryPanel()
|
||||
notebookSelector->setProperty("NotebookPanel", true);
|
||||
notebookSelector->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
||||
|
||||
directoryTree = new VDirectoryTree(vnote);
|
||||
directoryTree = new VDirectoryTree;
|
||||
directoryTree->setProperty("NotebookPanel", true);
|
||||
|
||||
QVBoxLayout *nbLayout = new QVBoxLayout;
|
||||
@ -193,7 +193,11 @@ QWidget *VMainWindow::setupDirectoryPanel()
|
||||
nbContainer->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
||||
|
||||
connect(notebookSelector, &VNotebookSelector::curNotebookChanged,
|
||||
directoryTree, &VDirectoryTree::setNotebook);
|
||||
this, [this](VNotebook *p_notebook) {
|
||||
directoryTree->setNotebook(p_notebook);
|
||||
directoryTree->setFocus();
|
||||
});
|
||||
|
||||
connect(notebookSelector, &VNotebookSelector::curNotebookChanged,
|
||||
this, &VMainWindow::handleCurrentNotebookChanged);
|
||||
|
||||
@ -501,6 +505,14 @@ void VMainWindow::initHelpMenu()
|
||||
editArea->openFile(file, OpenFileMode::Read);
|
||||
});
|
||||
|
||||
QAction *wikiAct = new QAction(tr("&Wiki"), this);
|
||||
wikiAct->setToolTip(tr("View VNote's wiki on Github"));
|
||||
connect(wikiAct, &QAction::triggered,
|
||||
this, [this]() {
|
||||
QString url("https://github.com/tamlok/vnote/wiki");
|
||||
QDesktopServices::openUrl(url);
|
||||
});
|
||||
|
||||
QAction *updateAct = new QAction(tr("Check For &Updates"), this);
|
||||
updateAct->setToolTip(tr("Check for updates of VNote"));
|
||||
connect(updateAct, &QAction::triggered,
|
||||
@ -539,6 +551,7 @@ void VMainWindow::initHelpMenu()
|
||||
|
||||
helpMenu->addAction(shortcutAct);
|
||||
helpMenu->addAction(mdGuideAct);
|
||||
helpMenu->addAction(wikiAct);
|
||||
helpMenu->addAction(updateAct);
|
||||
helpMenu->addAction(starAct);
|
||||
helpMenu->addAction(feedbackAct);
|
||||
|
@ -325,3 +325,16 @@ VNoteFile *VNote::getInternalFile(const QString &p_path)
|
||||
return file;
|
||||
}
|
||||
|
||||
VDirectory *VNote::getInternalDirectory(const QString &p_path)
|
||||
{
|
||||
VDirectory *dir = NULL;
|
||||
for (auto & nb : m_notebooks) {
|
||||
dir = nb->tryLoadDirectory(p_path);
|
||||
if (dir) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
|
||||
}
|
||||
|
@ -88,6 +88,11 @@ public:
|
||||
// Otherwise, returns NULL.
|
||||
VNoteFile *getInternalFile(const QString &p_path);
|
||||
|
||||
// Given the path of a folder, try to find it in all notebooks.
|
||||
// Returns a VDirectory struct if it is a folder in one notebook.
|
||||
// Otherwise, returns NULL.
|
||||
VDirectory *getInternalDirectory(const QString &p_path);
|
||||
|
||||
public slots:
|
||||
void updateTemplate();
|
||||
|
||||
|
@ -14,8 +14,8 @@ VNotebook::VNotebook(const QString &name, const QString &path, QObject *parent)
|
||||
m_path = QDir::cleanPath(path);
|
||||
m_recycleBinFolder = g_config->getRecycleBinFolder();
|
||||
m_rootDir = new VDirectory(this,
|
||||
VUtils::directoryNameFromPath(path),
|
||||
NULL,
|
||||
VUtils::directoryNameFromPath(path),
|
||||
QDateTime::currentDateTimeUtc());
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ bool VNotebook::deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles)
|
||||
QVector<VDirectory *> subdirs = rootDir->getSubDirs();
|
||||
for (auto dir : subdirs) {
|
||||
// Skip recycle bin.
|
||||
rootDir->deleteSubDirectory(dir, true);
|
||||
VDirectory::deleteDirectory(dir, true);
|
||||
}
|
||||
|
||||
// Delete the recycle bin.
|
||||
@ -280,6 +280,37 @@ VNoteFile *VNotebook::tryLoadFile(const QString &p_path)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VDirectory *VNotebook::tryLoadDirectory(const QString &p_path)
|
||||
{
|
||||
QFileInfo fi(p_path);
|
||||
Q_ASSERT(fi.isAbsolute());
|
||||
if (!fi.exists()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QStringList filePath;
|
||||
if (VUtils::splitPathInBasePath(m_path, p_path, filePath)) {
|
||||
if (filePath.isEmpty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool opened = isOpened();
|
||||
if (!open()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VDirectory *dir = m_rootDir->tryLoadDirectory(filePath);
|
||||
|
||||
if (!dir && !opened) {
|
||||
close();
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const QString &VNotebook::getImageFolder() const
|
||||
{
|
||||
if (m_imageFolder.isEmpty()) {
|
||||
|
@ -36,6 +36,13 @@ public:
|
||||
// if @p_path is not inside this notebook.
|
||||
VNoteFile *tryLoadFile(const QString &p_path);
|
||||
|
||||
// Try to load the directory @p_path.
|
||||
// Returns the corresponding VDirectory struct if @p_path is a folder inside this notebook.
|
||||
// Otherwise, returns NULL.
|
||||
// If notebook is not opened currently, it will open itself and close itself
|
||||
// if @p_path is not inside this notebook.
|
||||
VDirectory *tryLoadDirectory(const QString &p_path);
|
||||
|
||||
const QString &getName() const;
|
||||
const QString &getPath() const;
|
||||
|
||||
@ -86,9 +93,6 @@ public:
|
||||
// Need to check if this notebook has been opened.
|
||||
QDateTime getCreatedTimeUtc();
|
||||
|
||||
signals:
|
||||
void contentChanged();
|
||||
|
||||
private:
|
||||
// Serialize current instance to json.
|
||||
QJsonObject toConfigJson() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user