From 50ceea3f7516de401550e389d6431b93b94ff8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=89=E5=AE=87=E6=B8=85=E9=9F=B3?= <2422523675@qq.com> Date: Mon, 14 Aug 2023 22:09:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3ProjectManager=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E4=BD=BF=E7=94=A8=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libProjectManager/libProjectManager.h | 24 +++--- libProjectManager/xmlprojectmanager.cpp | 98 +++++++++++++++---------- libProjectManager/xmlprojectmanager.h | 46 ++++++------ 3 files changed, 94 insertions(+), 74 deletions(-) diff --git a/libProjectManager/libProjectManager.h b/libProjectManager/libProjectManager.h index 3beedff..85c6727 100644 --- a/libProjectManager/libProjectManager.h +++ b/libProjectManager/libProjectManager.h @@ -24,18 +24,17 @@ namespace Project { * @return */ virtual QModelIndex newPackage(const QList &path_defs) = 0; + /** - * @brief 转换QModexIndex为逻辑路径 - * @param path - * @return - */ - virtual QStringList packagePath(const QModelIndex &path) const = 0; - /** - * @brief 在指定包路径下建立创建文本文件记录 + * @brief 在指定包路径下建立创建空白文本文件占位,并将路径地址记录入项目树 * @param package_appoint 指定包节点路径 + * @param node 节点名称 + * @param suffix 文件类型,使用文件拓展名 + * @return 树节点索引 * @throw ProjectException */ - virtual QModelIndex appendFile(const QModelIndex &package_appoint, const QString &name, const QString &path_on_disk) = 0; + virtual QModelIndex newFile(const QModelIndex &package_appoint, const QString &node, const QString &suffix = "txt") = 0; + /** * @brief 重命名该节点名称 * @param node @@ -90,6 +89,13 @@ namespace Project { * @return */ virtual QModelIndex queryIndex(const QFileInfo &file) = 0; + + /** + * @brief 转换QModexIndex为逻辑路径 + * @param path + * @return + */ + virtual QStringList packagePath(const QModelIndex &path) const = 0; }; /** @@ -140,7 +146,7 @@ namespace Project { * @param name 项目文件名 * @throw ProjectException*, ParseException* */ - virtual void newProject(const QString &path_holder, const QString &name) = 0; + virtual void newProject(const QDir &project_dir, const QString &name) = 0; /** * @brief 关闭当前项目 diff --git a/libProjectManager/xmlprojectmanager.cpp b/libProjectManager/xmlprojectmanager.cpp index ea3d508..0379d76 100644 --- a/libProjectManager/xmlprojectmanager.cpp +++ b/libProjectManager/xmlprojectmanager.cpp @@ -62,10 +62,7 @@ QString XMLProjectManager::suffix() const bool XMLProjectManager::isOpenning() const noexcept { return open_status; } -bool XMLProjectManager::isModified() const noexcept -{ - return true; -} +bool XMLProjectManager::isModified() const noexcept { return unsaved_status; } /* * @@ -109,12 +106,13 @@ void XMLProjectManager::openProject(const QString &project_file) structure_parser(root_elm, pnode); open_status = true; + unsaved_status = false; pnode->setIcon(QIcon(":/icons/toplevel.png")); } -void XMLProjectManager::newProject(const QString &path_holder, const QString &name) { +void XMLProjectManager::newProject(const QDir &project_dir, const QString &name) { // 确定目标项目文件 - filepath_store = path_holder; + filepath_store = project_dir.filePath("novel.nsf"); QFileInfo info(filepath_store); if(info.exists()) @@ -137,6 +135,7 @@ void XMLProjectManager::newProject(const QString &path_holder, const QString &na void XMLProjectManager::closeProject() { open_status = false; + unsaved_status = false; project_structure->clear(); } @@ -158,6 +157,7 @@ void XMLProjectManager::save() if(!records.open(QIODevice::WriteOnly|QIODevice::Text)) throw new Impl_ProjectException("保存错误", "保存过程中,指定项目文件无法打开保存:" + filepath_store); + unsaved_status = false; QTextStream txout(&records); doc.save(txout, 4); txout.flush(); @@ -196,7 +196,6 @@ void XMLProjectManager::structure_parser(QDomElement struct_elm, ProjectNode *pn } else if (xnode.tagName() == "file") { node = new ProjectNode(NodeType::FILE, xnode.attribute("name")); node->setFile(xnode.attribute("path")); - all_files_managed << node->file(); } else { throw new Impl_ProjectException("项目解析错误", "未对指定节点类型进行解析:" + xnode.tagName()); } @@ -226,32 +225,6 @@ void XMLProjectManager::structure_severlize(ProjectNode *pnode, QDomElement &elm } } -QModelIndex XMLProjectManager::appendFile(const QModelIndex &package_path, const QString &name, const QString &path_on_disk) { - if(!package_path.isValid()) - throw new Impl_ProjectException("参数错误", "指定的package_path无效"); - - auto group = static_cast(project_structure->itemFromIndex(package_path)); - if(group->nodeType() == NodeType::FILE) - throw new Impl_ProjectException("参数错误", "传入了文件逻辑路径,而不是包路径"); - - for(auto idx=0; idxrowCount(); ++idx){ - auto child = static_cast(group->child(idx)); - if(child->text() == name) - throw new Impl_ProjectException("参数错误", "传入了重复的节点名称:" + name); - } - - if(all_files_managed.contains(path_on_disk)) - throw new Impl_ProjectException("参数错误", "指定路径文件已经纳入项目管理:"+path_on_disk); - - auto filenode = new ProjectNode(NodeType::FILE, name); - filenode->setFile(path_on_disk); - all_files_managed << path_on_disk; - - group->appendRow(filenode); - - return filenode->index(); -} - void XMLProjectManager::rename(const QModelIndex &node, const QString &name) { auto item = this->model()->itemFromIndex(node); @@ -261,6 +234,7 @@ void XMLProjectManager::rename(const QModelIndex &node, const QString &name) if(item != parent->child(idx) && item->text() == parent->child(idx)->text()) throw new Impl_ProjectException("参数错误", "传入了重复的节点名称:" + name); + unsaved_status = true; item->setText(name); } @@ -293,6 +267,7 @@ void XMLProjectManager::deleteT(const QModelIndex &node_path) { throw new Impl_ProjectException("参数错误", "不允许删除项目节点"); xnode->parent()->removeRow(xnode->row()); + unsaved_status = true; } QList > XMLProjectManager::filesWithEnds(const QString &suffix) const @@ -303,6 +278,7 @@ QList > XMLProjectManager::filesWithEnds(const QS QModelIndex XMLProjectManager::newPackage(const QList &path) { + unsaved_status = true; auto pnode = project_structure->item(0); return groups_rebuild(static_cast(pnode), path); } @@ -329,8 +305,43 @@ QStringList XMLProjectManager::packagePath(const QModelIndex &path) const return QStringList(); } -QFileInfo XMLProjectManager::queryInfo(const QModelIndex &path) -{ +QModelIndex XMLProjectManager::newFile(const QModelIndex &package_path, const QString &name, const QString &suffix) { + auto node = static_cast(model()->itemFromIndex(package_path)); + if (node->nodeType() == NodeType::FILE) { + node = static_cast(node->parent()); + } + + for (auto idx = 0; idx < node->rowCount(); ++idx) { + auto current = node->child(idx); + if (current->text() == name) { + throw new Impl_ProjectException("新建文件错误", "该路径下指定节点名称已存在,不可重复命名:" + name); + } + } + + auto dir = directory(); + auto filenames = dir.entryList(QDir::Filter::Files, QDir::SortFlag::Name); + QRandomGenerator gen(QDateTime::currentDateTime().secsTo(QDateTime(QDate(1992, 12, 04)))); + auto target_file = "file_zero." + suffix; + while (filenames.contains(target_file)) { + target_file = QString("file_%1.%2").arg(gen.generate64()).arg(suffix); + } + + QFile target_f(dir.filePath(target_file)); + if (!target_f.open(QIODevice::WriteOnly)) + throw new Impl_ProjectException("新建文件错误", "指定路径无法创建文件:" + dir.filePath(target_file)); + target_f.write("空白文件"); + target_f.flush(); + target_f.close(); + + auto leaf = new ProjectNode(NodeType::FILE, name); + leaf->setFile(target_file); + node->appendRow(leaf); + + unsaved_status = true; + return leaf->index(); +} + +QFileInfo XMLProjectManager::queryInfo(const QModelIndex &path) { if(!path.isValid()) throw new Impl_ProjectException("参数错误", "指定的路径参数无效"); @@ -447,18 +458,25 @@ void XMLProjectManager::moveTo(const QModelIndex &item_path, const QModelIndex & if(!target_group.isValid()) throw new Impl_ProjectException("参数错误", "传入的目标包路径无效"); - auto file = static_cast(project_structure->itemFromIndex(item_path)); - if(file->nodeType() == NodeType::GROUP) - throw new Impl_ProjectException("参数错误","传入的源文件节点路径无效"); + auto node = static_cast(project_structure->itemFromIndex(item_path)); auto group = static_cast(project_structure->itemFromIndex(target_group)); if(group->nodeType() != NodeType::GROUP) throw new Impl_ProjectException("参数错误", "传入的目标包路径无效"); + QStandardItem *tgroup = group; + while (tgroup != nullptr) { + if (tgroup == node) + throw new Impl_ProjectException("参数错误", "无法将父节点移动到子节点下"); + tgroup = tgroup->parent(); + } + if(index >= 0 && index < group->rowCount()) - group->insertRow(index, file); + group->insertRow(index, node); else - group->appendRow(file); + group->appendRow(node); + + unsaved_status = true; } diff --git a/libProjectManager/xmlprojectmanager.h b/libProjectManager/xmlprojectmanager.h index a3d2a00..60ae083 100644 --- a/libProjectManager/xmlprojectmanager.h +++ b/libProjectManager/xmlprojectmanager.h @@ -38,47 +38,44 @@ namespace Project { XMLProjectManager(QObject *parent = nullptr); virtual ~XMLProjectManager(); + // FilesQuery interface + public: + virtual QList filesGather(const QModelIndex &node) const override; + virtual QList> filesWithEnds(const QString &suffix) const override; + virtual QFileInfo queryInfo(const QModelIndex &path) override; + virtual QModelIndex queryIndex(const QFileInfo &file) override; + virtual QStringList packagePath(const QModelIndex &path) const override; + + // FilesOperate interface + public: + virtual QModelIndex newPackage(const QList &path_defs) override; + virtual QModelIndex newFile(const QModelIndex &package_appoint, const QString &node, const QString &suffix) override; + virtual void rename(const QModelIndex &node, const QString &name) override; + virtual void moveTo(const QModelIndex &node_frompath, const QModelIndex &target_group, int index) override; + virtual void deleteT(const QModelIndex &node_path) override; // ProjectManager interface public: - virtual QStandardItemModel* model() const override; + virtual QStandardItemModel *model() const override; virtual Config::Configration *configraions() const override; - virtual QDir directory() const override; - virtual FilesOperate *operateAccess() const override; - virtual FilesQuery *queryAccess() const override; - virtual QString suffix() const override; - virtual bool isOpenning() const noexcept override; - virtual bool isModified() const noexcept override; virtual void openProject(const QString &project_file) override; - virtual void newProject(const QString &path_holder, const QString &name) override; + virtual void newProject(const QDir &project_dir, const QString &name) override; virtual void closeProject() override; virtual void save() override; virtual QString name() const override; virtual void resetName(const QString &name) override; - - virtual QModelIndex newPackage(const QList &path) override; - virtual QStringList packagePath(const QModelIndex &path) const override; - - virtual QModelIndex appendFile(const QModelIndex &package_path, const QString &name, const QString &path_on_disk) override; - virtual void rename(const QModelIndex &node, const QString &name) override; - virtual QList filesGather(const QModelIndex &node) const override; - virtual void moveTo(const QModelIndex &node_frompath, const QModelIndex &target_group, int index) override; - virtual void deleteT(const QModelIndex &node_path) override; - - virtual QList> filesWithEnds(const QString &suffix) const override; - - virtual QFileInfo queryInfo(const QModelIndex &path) override; - virtual QModelIndex queryIndex(const QFileInfo &file) override; + virtual QDir directory() const override; + virtual bool isOpenning() const noexcept override; + virtual bool isModified() const noexcept override; private: Config::Configration *const project_config; QStandardItemModel*const project_structure; QString filepath_store; - bool open_status; - QList all_files_managed; + bool open_status, unsaved_status; void structure_parser(QDomElement struct_elm, ProjectNode *pnode); void structure_severlize(ProjectNode *pnode, QDomElement &elm); @@ -88,7 +85,6 @@ namespace Project { QModelIndex groups_rebuild(ProjectNode *pnode, const QList &path_remains); - virtual QModelIndex query_index(const QFileInfo &file, const QModelIndex &base); }; }