2022-11-17 08:26:05 +00:00
|
|
|
|
#include "xmlprojectmanager.h"
|
|
|
|
|
|
|
|
|
|
#include <xmlconfig.h>
|
|
|
|
|
#include <QDir>
|
|
|
|
|
#include <QRandomGenerator>
|
|
|
|
|
#include <QDateTime>
|
|
|
|
|
#include <QTextStream>
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
|
#include <QIcon>
|
|
|
|
|
|
|
|
|
|
using namespace Project;
|
|
|
|
|
using namespace Config;
|
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
class Impl_ProjectException : public ProjectException
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
Impl_ProjectException(const QString& title, const QString& reason)
|
2023-02-26 14:44:00 +00:00
|
|
|
|
{
|
|
|
|
|
temp_string = QString("%1:%2").arg(title, reason);
|
|
|
|
|
title_length = title.length();
|
|
|
|
|
}
|
2023-02-25 07:19:27 +00:00
|
|
|
|
|
|
|
|
|
private:
|
2023-02-26 14:44:00 +00:00
|
|
|
|
int title_length;
|
|
|
|
|
QString temp_string;
|
2023-02-25 07:19:27 +00:00
|
|
|
|
|
|
|
|
|
// exception interface
|
|
|
|
|
public:
|
2023-02-26 14:44:00 +00:00
|
|
|
|
virtual const char *what() const override{
|
|
|
|
|
return temp_string.toLocal8Bit();
|
|
|
|
|
}
|
2023-02-25 07:19:27 +00:00
|
|
|
|
|
|
|
|
|
// ParseException interface
|
|
|
|
|
public:
|
2023-02-26 14:44:00 +00:00
|
|
|
|
virtual QString reason() const override{return temp_string.mid(title_length+1);}
|
|
|
|
|
virtual QString title() const override{ return temp_string.mid(0, title_length);}
|
2023-02-25 07:19:27 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
XMLProjectManager::XMLProjectManager(QObject *parent)
|
2023-02-25 07:19:27 +00:00
|
|
|
|
: QObject(parent),
|
2022-11-17 08:26:05 +00:00
|
|
|
|
project_config(new XMLConfig(this)),
|
2023-02-25 07:19:27 +00:00
|
|
|
|
project_structure(new QStandardItemModel(this)),
|
2023-02-26 14:44:00 +00:00
|
|
|
|
open_status(false)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
XMLProjectManager::~XMLProjectManager(){
|
|
|
|
|
delete project_config;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
QStandardItemModel *XMLProjectManager::model() const
|
|
|
|
|
{
|
|
|
|
|
return this->project_structure;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString XMLProjectManager::suffix() const
|
|
|
|
|
{
|
|
|
|
|
return "nsf";
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
bool XMLProjectManager::isOpenning() const noexcept { return open_status; }
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
bool XMLProjectManager::isModified() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
/*
|
|
|
|
|
* <?xml version='1.0'?>
|
|
|
|
|
* <project name="project-name" config="xml-path">
|
|
|
|
|
* <package name="name" path="filepath">
|
|
|
|
|
* <file name="name" path="filepath"/>
|
|
|
|
|
* <package name="name2" path="filepath" />
|
|
|
|
|
* </package>
|
|
|
|
|
* </project>
|
|
|
|
|
*/
|
2023-02-25 07:19:27 +00:00
|
|
|
|
void XMLProjectManager::openProject(const QString &project_file)
|
2022-11-17 08:26:05 +00:00
|
|
|
|
{
|
2023-02-25 07:19:27 +00:00
|
|
|
|
filepath_store = project_file;
|
2022-11-17 08:26:05 +00:00
|
|
|
|
QFileInfo info(project_file);
|
|
|
|
|
if(!info.exists())
|
2023-02-25 07:19:27 +00:00
|
|
|
|
throw new Impl_ProjectException("打开失败", "指定的项目文件不存在:"+project_file);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
// 获取项目文件内容
|
|
|
|
|
QFile project_in(project_file);
|
|
|
|
|
if(!project_in.open(QIODevice::ReadOnly|QIODevice::Text))
|
2023-02-25 07:19:27 +00:00
|
|
|
|
throw new Impl_ProjectException("打开失败", "指定的项目文件无法打开:" + project_file);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
// 载入文件内容
|
|
|
|
|
QDomDocument doc;
|
|
|
|
|
QString err; int row, col;
|
|
|
|
|
if(!doc.setContent(&project_in, false, &err, &row, &col))
|
2023-02-25 07:19:27 +00:00
|
|
|
|
throw new Impl_ProjectException("打开失败", QString("项目文件格式错误:%1,row:%2,col:%3").arg(err).arg(row).arg(col));
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
// 构建项目组织树
|
|
|
|
|
auto root_elm = doc.documentElement();
|
|
|
|
|
auto name = root_elm.attribute("name");
|
2023-02-26 14:44:00 +00:00
|
|
|
|
auto pnode = new ProjectNode(NodeType::ROOT, name);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
pnode->setFile(root_elm.attribute("config"));
|
2023-02-25 07:19:27 +00:00
|
|
|
|
project_structure->appendRow(pnode);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
// 载入项目配置
|
|
|
|
|
auto config = root_elm.attribute("config");
|
|
|
|
|
auto config_path = info.dir().filePath(config);
|
|
|
|
|
project_config->loadFile(config_path);
|
|
|
|
|
|
|
|
|
|
structure_parser(root_elm, pnode);
|
|
|
|
|
|
|
|
|
|
open_status = true;
|
|
|
|
|
pnode->setIcon(QIcon(":/icons/toplevel.png"));
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
void XMLProjectManager::newProject(const QString &path_holder, const QString &name) {
|
2022-11-17 08:26:05 +00:00
|
|
|
|
// 确定目标项目文件
|
2023-08-12 13:01:01 +00:00
|
|
|
|
filepath_store = path_holder;
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
QFileInfo info(filepath_store);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
if(info.exists())
|
2023-02-25 07:19:27 +00:00
|
|
|
|
throw new Impl_ProjectException("新建错误", "指定路径的项目文件已经存在,无法构建新项目");
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
// 构建项目表示树
|
2023-02-26 14:44:00 +00:00
|
|
|
|
auto project_node = new ProjectNode(NodeType::ROOT, name);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
project_node->setFile(".project_config.xml");
|
2023-02-25 07:19:27 +00:00
|
|
|
|
project_structure->appendRow(project_node);
|
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
QDir root = info.absoluteDir();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
project_config->loadFile(root.filePath(project_node->file()));
|
|
|
|
|
|
|
|
|
|
// 写出到磁盘
|
|
|
|
|
save();
|
|
|
|
|
open_status = true;
|
|
|
|
|
project_node->setIcon(QIcon(":/icons/toplevel.png"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLProjectManager::closeProject()
|
|
|
|
|
{
|
|
|
|
|
open_status = false;
|
2023-02-25 07:19:27 +00:00
|
|
|
|
project_structure->clear();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLProjectManager::save()
|
|
|
|
|
{
|
|
|
|
|
project_config->save();
|
|
|
|
|
|
|
|
|
|
QDomDocument doc;
|
2023-02-25 07:19:27 +00:00
|
|
|
|
auto pnode = static_cast<ProjectNode*>(project_structure->item(0));
|
2022-11-17 08:26:05 +00:00
|
|
|
|
doc.appendChild(doc.createProcessingInstruction("xml", "version='1.0'"));
|
|
|
|
|
auto project_elm = doc.createElement("project");
|
|
|
|
|
project_elm.setAttribute("name", pnode->text());
|
|
|
|
|
project_elm.setAttribute("config", pnode->file());
|
|
|
|
|
doc.appendChild(project_elm);
|
|
|
|
|
|
|
|
|
|
structure_severlize(pnode, project_elm);
|
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
QFile records(filepath_store);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
if(!records.open(QIODevice::WriteOnly|QIODevice::Text))
|
2023-02-25 07:19:27 +00:00
|
|
|
|
throw new Impl_ProjectException("保存错误", "保存过程中,指定项目文件无法打开保存:" + filepath_store);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
QTextStream txout(&records);
|
|
|
|
|
doc.save(txout, 4);
|
2023-02-25 07:19:27 +00:00
|
|
|
|
txout.flush();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
QString XMLProjectManager::name() const { return project_structure->item(0)->text(); }
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
void XMLProjectManager::resetName(const QString &name) { this->project_structure->item(0)->setText(name); }
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
Configration *XMLProjectManager::configraions() const
|
2022-11-17 08:26:05 +00:00
|
|
|
|
{
|
2023-02-26 14:44:00 +00:00
|
|
|
|
return this->project_config;
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
QDir XMLProjectManager::directory() const
|
2023-03-05 14:32:20 +00:00
|
|
|
|
{
|
|
|
|
|
return QFileInfo(filepath_store).absoluteDir();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
FilesOperate *XMLProjectManager::operateAccess() const { return const_cast<XMLProjectManager *>(this); }
|
|
|
|
|
|
|
|
|
|
FilesQuery *XMLProjectManager::queryAccess() const { return const_cast<XMLProjectManager *>(this); }
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
void XMLProjectManager::structure_parser(QDomElement struct_elm, ProjectNode *pnode)
|
|
|
|
|
{
|
|
|
|
|
auto children = struct_elm.childNodes();
|
|
|
|
|
|
|
|
|
|
for(auto idx=0; idx<children.count(); ++idx) {
|
|
|
|
|
auto node = children.at(idx);
|
|
|
|
|
if(node.isElement()){
|
|
|
|
|
auto xnode = node.toElement();
|
|
|
|
|
|
|
|
|
|
ProjectNode *node = nullptr;
|
|
|
|
|
if(xnode.tagName()=="package"){
|
|
|
|
|
node = new ProjectNode(NodeType::GROUP, xnode.attribute("name"));
|
|
|
|
|
}
|
2023-02-25 07:19:27 +00:00
|
|
|
|
else if(xnode.tagName() == "file"){
|
2022-11-17 08:26:05 +00:00
|
|
|
|
node = new ProjectNode(NodeType::FILE, xnode.attribute("name"));
|
|
|
|
|
node->setFile(xnode.attribute("path"));
|
2023-02-26 14:44:00 +00:00
|
|
|
|
all_files_managed << node->file();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pnode->appendRow(node);
|
|
|
|
|
structure_parser(xnode, node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLProjectManager::structure_severlize(ProjectNode *pnode, QDomElement &elm)
|
|
|
|
|
{
|
|
|
|
|
auto doc = elm.ownerDocument();
|
|
|
|
|
for(auto idx=0; idx<pnode->rowCount(); ++idx){
|
|
|
|
|
auto item = static_cast<ProjectNode*>(pnode->child(idx));
|
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
QDomElement e = doc.createElement("package");
|
2022-11-17 08:26:05 +00:00
|
|
|
|
e.setAttribute("name", item->text());
|
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
if(item->nodeType() == NodeType::FILE){
|
|
|
|
|
e.setTagName("file");
|
|
|
|
|
e.setAttribute("path", item->file());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
elm.appendChild(e);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
structure_severlize(item, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
QModelIndex XMLProjectManager::appendFile(const QModelIndex &package_path, const QString &name, const QString &path_on_disk) {
|
2023-02-26 14:44:00 +00:00
|
|
|
|
if(!package_path.isValid())
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "指定的package_path无效");
|
2022-11-29 03:47:12 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
auto group = static_cast<ProjectNode*>(project_structure->itemFromIndex(package_path));
|
2022-11-29 03:47:12 +00:00
|
|
|
|
if(group->nodeType() == NodeType::FILE)
|
2023-02-26 14:44:00 +00:00
|
|
|
|
throw new Impl_ProjectException("参数错误", "传入了文件逻辑路径,而不是包路径");
|
2022-11-29 03:47:12 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
for(auto idx=0; idx<group->rowCount(); ++idx){
|
|
|
|
|
auto child = static_cast<ProjectNode*>(group->child(idx));
|
|
|
|
|
if(child->text() == name)
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "传入了重复的节点名称:" + name);
|
|
|
|
|
}
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
if(all_files_managed.contains(path_on_disk))
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "指定路径文件已经纳入项目管理:"+path_on_disk);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
auto filenode = new ProjectNode(NodeType::FILE, name);
|
2023-02-26 14:44:00 +00:00
|
|
|
|
filenode->setFile(path_on_disk);
|
|
|
|
|
all_files_managed << path_on_disk;
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
group->appendRow(filenode);
|
2023-03-05 14:32:20 +00:00
|
|
|
|
|
|
|
|
|
return filenode->index();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void XMLProjectManager::rename(const QModelIndex &node, const QString &name)
|
|
|
|
|
{
|
|
|
|
|
auto item = this->model()->itemFromIndex(node);
|
|
|
|
|
|
|
|
|
|
auto parent = item->parent();
|
|
|
|
|
for(auto idx=0; idx<parent->rowCount(); ++idx)
|
|
|
|
|
if(item != parent->child(idx) && item->text() == parent->child(idx)->text())
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "传入了重复的节点名称:" + name);
|
|
|
|
|
|
|
|
|
|
item->setText(name);
|
2023-02-26 14:44:00 +00:00
|
|
|
|
}
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-03-05 14:32:20 +00:00
|
|
|
|
QList<QModelIndex> XMLProjectManager::filesGather(const QModelIndex &node) const
|
2023-02-26 14:44:00 +00:00
|
|
|
|
{
|
2023-03-05 14:32:20 +00:00
|
|
|
|
QList<QModelIndex> rets;
|
2023-02-26 14:44:00 +00:00
|
|
|
|
if(!node .isValid())
|
|
|
|
|
return rets;
|
|
|
|
|
|
|
|
|
|
auto item = static_cast<ProjectNode*>(project_structure->itemFromIndex(node));
|
|
|
|
|
switch (item->nodeType()) {
|
|
|
|
|
case NodeType::ROOT:
|
|
|
|
|
case NodeType::GROUP:
|
|
|
|
|
for(auto idx=0; idx<item->rowCount(); ++idx)
|
|
|
|
|
rets.append(filesGather(item->child(idx)->index()));
|
|
|
|
|
break;
|
|
|
|
|
case NodeType::FILE:
|
2023-03-05 14:32:20 +00:00
|
|
|
|
rets.append(item->index());
|
2023-02-26 14:44:00 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return rets;
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-12 13:01:01 +00:00
|
|
|
|
void XMLProjectManager::deleteT(const QModelIndex &node_path) {
|
2023-02-26 14:44:00 +00:00
|
|
|
|
if(!node_path.isValid())
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "指定的节点路径无效");
|
|
|
|
|
|
|
|
|
|
auto xnode = static_cast<ProjectNode*>(project_structure->itemFromIndex(node_path));
|
|
|
|
|
if(xnode->nodeType() == NodeType::ROOT)
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "不允许删除项目节点");
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
xnode->parent()->removeRow(xnode->row());
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
QList<std::tuple<QString, QFileInfo> > XMLProjectManager::filesWithEnds(const QString &suffix) const
|
2022-11-17 08:26:05 +00:00
|
|
|
|
{
|
2023-02-25 07:19:27 +00:00
|
|
|
|
auto root_project = project_structure->item(0);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
return nodes_search(static_cast<ProjectNode*>(root_project), suffix);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
QModelIndex XMLProjectManager::newPackage(const QList<QString> &path)
|
2022-11-17 08:26:05 +00:00
|
|
|
|
{
|
2023-02-25 07:19:27 +00:00
|
|
|
|
auto pnode = project_structure->item(0);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
return groups_rebuild(static_cast<ProjectNode*>(pnode), path);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
QStringList XMLProjectManager::packagePath(const QModelIndex &path) const
|
|
|
|
|
{
|
|
|
|
|
auto item = static_cast<ProjectNode*>(project_structure->itemFromIndex(path));
|
|
|
|
|
|
|
|
|
|
auto project_node = project_structure->item(0);
|
|
|
|
|
auto query_path = [project_node](QStandardItem *it) -> QStringList{
|
|
|
|
|
QStringList values;
|
|
|
|
|
while (it != project_node) {
|
|
|
|
|
values.insert(0, it->text());
|
|
|
|
|
it = it->parent();
|
|
|
|
|
}
|
|
|
|
|
return values;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if(item->nodeType() == NodeType::GROUP)
|
|
|
|
|
return query_path(item);
|
|
|
|
|
else if(item->nodeType() == NodeType::FILE)
|
|
|
|
|
return query_path(item->parent());
|
|
|
|
|
else
|
|
|
|
|
return QStringList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QFileInfo XMLProjectManager::queryInfo(const QModelIndex &path)
|
2022-11-17 08:26:05 +00:00
|
|
|
|
{
|
2023-02-26 14:44:00 +00:00
|
|
|
|
if(!path.isValid())
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "指定的路径参数无效");
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
auto item = static_cast<ProjectNode*>(project_structure->itemFromIndex(path));
|
|
|
|
|
if(item->nodeType() == NodeType::GROUP){
|
|
|
|
|
return QFileInfo(QFileInfo(filepath_store).canonicalPath());
|
|
|
|
|
}
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-25 07:19:27 +00:00
|
|
|
|
return QFileInfo(QFileInfo(filepath_store).dir().filePath(item->file()));
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-10 12:53:54 +00:00
|
|
|
|
QModelIndex XMLProjectManager::queryIndex(const QFileInfo &file)
|
|
|
|
|
{
|
|
|
|
|
auto xinfo = query_index(file, project_structure->item(0)->index());
|
|
|
|
|
|
|
|
|
|
if(xinfo.isValid())
|
|
|
|
|
return xinfo;
|
|
|
|
|
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
ProjectNode *XMLProjectManager::node_follows(ProjectNode *pnode, const QList<QString> &path_remains)
|
|
|
|
|
{
|
|
|
|
|
if(path_remains.size()==0)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
for(auto idx=0; idx<pnode->rowCount(); ++idx){
|
|
|
|
|
auto node = static_cast<ProjectNode*>(pnode->child(idx));
|
|
|
|
|
if(node->text() == path_remains[0]){
|
|
|
|
|
if(path_remains.size() == 1)
|
|
|
|
|
return node;
|
|
|
|
|
else
|
|
|
|
|
return node_follows(node, path_remains.mid(1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
QList<std::tuple<QString, QFileInfo>> XMLProjectManager::nodes_search(ProjectNode *pnode, const QString &suffix) const
|
2022-11-17 08:26:05 +00:00
|
|
|
|
{
|
2023-02-26 14:44:00 +00:00
|
|
|
|
QDir root_dir = QFileInfo(this->filepath_store).absoluteDir();
|
|
|
|
|
QList<std::tuple<QString, QFileInfo>> infos_return;
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
for(auto idx=0; idx<pnode->rowCount(); ++idx){
|
|
|
|
|
auto item = static_cast<ProjectNode*>(pnode->child(idx));
|
|
|
|
|
|
|
|
|
|
if(item->nodeType() == NodeType::FILE){
|
|
|
|
|
auto file_path = root_dir.filePath(item->file());
|
|
|
|
|
QFileInfo xinfo(file_path);
|
|
|
|
|
if(xinfo.suffix() == suffix)
|
2023-02-26 14:44:00 +00:00
|
|
|
|
infos_return << std::make_tuple(item->text(), xinfo);
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
auto elist = nodes_search(item, suffix);
|
|
|
|
|
infos_return.append(elist);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return infos_return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
QModelIndex XMLProjectManager::groups_rebuild(ProjectNode *pnode, const QList<QString> &path_remains)
|
2022-11-17 08:26:05 +00:00
|
|
|
|
{
|
|
|
|
|
// 查找对匹配结果
|
|
|
|
|
for(auto idx=0; idx<pnode->rowCount(); ++idx){
|
|
|
|
|
auto item = static_cast<ProjectNode*>(pnode->child(idx));
|
|
|
|
|
if(item->text() == path_remains[0] && item->nodeType() == NodeType::GROUP){
|
|
|
|
|
if(path_remains.size() > 1)
|
|
|
|
|
return groups_rebuild(item, path_remains.mid(1));
|
2023-02-26 14:44:00 +00:00
|
|
|
|
return item->index();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto item = new ProjectNode(NodeType::GROUP, path_remains[0]);
|
|
|
|
|
pnode->appendRow(item);
|
|
|
|
|
|
|
|
|
|
if(path_remains.size() > 1)
|
|
|
|
|
return groups_rebuild(item, path_remains.mid(1));
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
return item->index();
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
2023-03-10 12:53:54 +00:00
|
|
|
|
|
|
|
|
|
QModelIndex XMLProjectManager::query_index(const QFileInfo &file, const QModelIndex &base)
|
|
|
|
|
{
|
|
|
|
|
if(!base.isValid())
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
|
|
auto item = static_cast<ProjectNode*>(project_structure->itemFromIndex(base));
|
|
|
|
|
if(item->nodeType() == NodeType::FILE) {
|
|
|
|
|
auto dir = QFileInfo(filepath_store).absoluteDir();
|
|
|
|
|
auto target_info = QFileInfo(dir.filePath(item->file()));
|
|
|
|
|
if(target_info == file)
|
|
|
|
|
return item->index();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for(auto idx=0; idx<item->rowCount(); ++idx)
|
|
|
|
|
{
|
|
|
|
|
auto idx_m = query_index(file, item->child(idx)->index());
|
|
|
|
|
if(idx_m.isValid())
|
|
|
|
|
return idx_m;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
void XMLProjectManager::moveTo(const QModelIndex &item_path, const QModelIndex &target_group, int index)
|
|
|
|
|
{
|
|
|
|
|
if(!item_path.isValid())
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "传入的源文件路径无效");
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
if(!target_group.isValid())
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "传入的目标包路径无效");
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
auto file = static_cast<ProjectNode*>(project_structure->itemFromIndex(item_path));
|
|
|
|
|
if(file->nodeType() == NodeType::GROUP)
|
|
|
|
|
throw new Impl_ProjectException("参数错误","传入的源文件节点路径无效");
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
auto group = static_cast<ProjectNode*>(project_structure->itemFromIndex(target_group));
|
|
|
|
|
if(group->nodeType() != NodeType::GROUP)
|
|
|
|
|
throw new Impl_ProjectException("参数错误", "传入的目标包路径无效");
|
2022-11-17 08:26:05 +00:00
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
if(index >= 0 && index < group->rowCount())
|
2022-11-17 08:26:05 +00:00
|
|
|
|
group->insertRow(index, file);
|
|
|
|
|
else
|
|
|
|
|
group->appendRow(file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-02-26 14:44:00 +00:00
|
|
|
|
|
|
|
|
|
// 完成线 =======================================================================================================
|
|
|
|
|
|
|
|
|
|
|
2022-11-17 08:26:05 +00:00
|
|
|
|
ProjectNode::ProjectNode(NodeType t, const QString &name)
|
|
|
|
|
: QStandardItem(name),type_indi(t)
|
|
|
|
|
{
|
|
|
|
|
if(t == NodeType::FILE)
|
|
|
|
|
{
|
|
|
|
|
setIcon(QIcon(":/icons/文件.png"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
setIcon(QIcon(":/icons/集合.png"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setEditable(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NodeType ProjectNode::nodeType() const
|
|
|
|
|
{return type_indi;}
|
|
|
|
|
|
|
|
|
|
void ProjectNode::setFile(const QString &name)
|
|
|
|
|
{
|
|
|
|
|
this->filename = name;
|
|
|
|
|
|
|
|
|
|
if(name.endsWith("storychain"))
|
|
|
|
|
setIcon(QIcon(":/icons/脉络.png"));
|
|
|
|
|
if(name.endsWith("storyunit"))
|
|
|
|
|
setIcon(QIcon(":/icons/单元.png"));
|
|
|
|
|
if(name.endsWith("storyboard"))
|
|
|
|
|
setIcon(QIcon(":/icons/故事.png"));
|
|
|
|
|
if(name.endsWith("storyvolume"))
|
|
|
|
|
setIcon(QIcon(":/icons/叙述.png"));
|
|
|
|
|
if(name.endsWith("txt"))
|
|
|
|
|
setIcon(QIcon(":/icons/文件.png"));
|
2022-11-25 07:30:33 +00:00
|
|
|
|
if(name.endsWith("storyconcept"))
|
|
|
|
|
setIcon(QIcon(":/icons/概念.png"));
|
2022-11-17 08:26:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString ProjectNode::file() const
|
|
|
|
|
{return filename;}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|