QtNovelUI/WordsIDE/projectview.cpp

223 lines
6.5 KiB
C++

#include "projectview.h"
#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
#include <QVBoxLayout>
Components::ProjectView::ProjectView(Core::AppCore *src, Project::ProjectManager *project, QWidget *parent)
: QTreeView(parent), rtcore(src), pjtins(project)
{
setModel(pjtins->model());
setHeaderHidden(true);
setIconSize(QSize(24, 24));
// 右键菜单
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &QWidget::customContextMenuRequested, this, &ProjectView::contexMenuPopup);
// 双击打开
connect(this, &QTreeView::doubleClicked, this, &ProjectView::explicit_active_document);
}
void Components::ProjectView::explicit_active_document(const QModelIndex &curr)
{
if(!curr.isValid())
return;
auto root = pjtins->model()->item(0);
auto item = pjtins->model()->itemFromIndex(curr);
QList<QString> path;
while (item != root){
path.insert(0, item->text());
item = item->parent();
}
auto xinfo = pjtins->queryWith(path);
if(xinfo.isFile() && xinfo.exists()){
emit this->activeDocument(xinfo.absoluteFilePath(), curr.data().toString());
}
}
void Components::ProjectView::contexMenuPopup(const QPoint &pos)
{
auto idx_it = indexAt(pos);
if(!idx_it.isValid())
return;
QMenu popup;
auto npath = popup.addAction("新建路径");
connect(npath, &QAction::triggered, [this](){
auto packages = QInputDialog::getText(this, "输入包路径名称", "名称A#名称B#名称C");
if(packages == "")
return;
QList<QString> names;
QRegExp exp("([^#]+)");
auto idx=0;
while ((idx = exp.indexIn(packages, idx)) != -1) {
names << exp.capturedTexts()[1];
idx += names.last().length();
}
pjtins->newPath(names);
});
popup.addSeparator();
auto newm = popup.addMenu("新建文件");
newm->addAction("新建章节", [this, &idx_it](){ alloc_file(idx_it, "章节", "txt"); });
newm->addSeparator();
newm->addAction("新建脉络", [this, &idx_it](){ alloc_file(idx_it, "脉络", "storychain"); });
newm->addAction("新建单元", [this, &idx_it](){ alloc_file(idx_it, "单元", "storyunit"); });
newm->addAction("新建故事", [this, &idx_it](){ alloc_file(idx_it, "故事", "storyboard"); });
newm->addAction("新建行文", [this, &idx_it](){ alloc_file(idx_it, "行文", "storyvolume"); });
newm->addAction("新建概念", [this, &idx_it](){ alloc_file(idx_it, "概念", "storyconcept"); });
popup.addSeparator();
popup.addAction("修改名称", [this, &idx_it](){
if(!idx_it.isValid())
return;
auto name = QInputDialog::getText(this, "输入名称", "节点名称");
if(name == "")
return;
auto item = pjtins->model()->itemFromIndex(idx_it);
auto pnode = item->parent();
if(pnode == nullptr){
item->setText(name);
}
else
{
for(auto idx=0; idx<pnode->rowCount(); ++idx)
if(pnode->child(idx)->text() == name)
{
QMessageBox::critical(this, "系统提示", "发现重名节点");
return;
}
item->setText(name);
}
});
popup.addSeparator();
popup.addAction("删除节点与文件", [this, &idx_it](){
auto btn = QMessageBox::warning(this, "系统提示", "删除操作涉及文件变更,无法找回,请慎重对待!\n"
"是否坚持删除指定节点以及包含的所有文件?", QMessageBox::Yes|QMessageBox::No);
if(btn == QMessageBox::No)
return;
auto root = pjtins->model()->item(0);
auto seli = pjtins->model()->itemFromIndex(idx_it);
auto query_path = [root](QStandardItem *item)->QList<QString>
{
QList<QString> paths;
while (root != item) {
paths.insert(0, item->text());
item = item->parent();
}
return paths;
};
QList<QFileInfo> files;
for(auto &it : nodes_contained(seli)){
auto path = query_path(it);
auto info = pjtins->queryWith(path);
if(info.exists())
files << info;
}
emit this->aboutToBoDelete(files);
this->pjtins->deletePath(query_path(seli));
});
auto item = this->pjtins->model()->itemFromIndex(idx_it);
if(item->parent() == nullptr){
popup.addSeparator();
popup.addAction("项目配置", this, &ProjectView::project_configration);
}
popup.exec(mapToGlobal(pos));
}
void Components::ProjectView::alloc_file(const QModelIndex &idx_it, const QString &type, const QString &suffix)
{
auto name = QInputDialog::getText(this, "输入" + type + "名称", type + "名称:");
if(name == "")
return;
auto root = pjtins->model()->item(0);
auto seli = pjtins->model()->itemFromIndex(idx_it);
QList<QString> paths;
while (root != seli) {
paths.insert(0, seli->text());
seli = seli->parent();
}
auto indi = this->pjtins->createFile(paths, name, suffix);
switch (indi) {
case -1:
QMessageBox::critical(this, "系统错误", "传入的指定路径无效");
return;
case -2:
QMessageBox::critical(this, "系统错误", "在文件下建立文件");
return;
case -3:
QMessageBox::critical(this, "系统错误", "指定名称重复");
return;
}
paths.append(name);
auto xinfo = this->pjtins->queryWith(paths);
emit this->activeDocument(xinfo.absoluteFilePath(), name);
}
void Components::ProjectView::project_configration()
{
QDialog dia(this);
auto layout = new QVBoxLayout(&dia);
auto tab = new QTabWidget(&dia);
tab->setTabPosition(QTabWidget::West);
layout->addWidget(tab);
auto extions = rtcore->extensions();
auto project = pjtins;
for(auto &ext : extions){
auto widget = ext->getNewPanel(project->configraions());
if(widget)
tab->addTab(widget, ext->extensionName());
}
dia.exec();
}
QList<QStandardItem *> Components::ProjectView::nodes_contained(QStandardItem *root)
{
QList<QStandardItem *> coll;
coll << root;
for(auto idx=0; idx<root->rowCount(); ++idx)
{
coll << root->child(idx);
coll.append(nodes_contained(root->child(idx)));
}
return coll;
}