QtNovelUI/libConfig/xmlconfig.cpp

251 lines
6.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "xmlconfig.h"
#include <QFile>
#include <QDebug>
using namespace Config;
class Impl_ParseException : public ParseException
{
public:
Impl_ParseException(const QString &title, const QString &reason)
{
temp_string = QString("%1%2").arg(title, reason);
title_length = title.length();
}
virtual ~Impl_ParseException() = default;
// exception interface
public:
virtual const char *what() const noexcept override {
return temp_string.toLocal8Bit();
}
// ParseException interface
public:
virtual QString reason() const override{ return temp_string.mid(title_length+1);}
virtual QString title() const override{ return temp_string.mid(0, title_length);}
private:
int title_length;
QString temp_string;
};
XMLConfig::XMLConfig(QObject *parent)
: Configration(parent)
{
}
void XMLConfig::loadFile(const QString &path)
{
file_path = path;
QFile config(path);
if(!config.exists()){
if(!config.open(QIODevice::WriteOnly|QIODevice::Text))
throw new Impl_ParseException("解析错误", QString("指定路径无法创建配置文件:%1").arg(path));
QTextStream tout(&config);
tout.setCodec("UTF-8");
tout << "<?xml version='1.0'?>" << endl;
tout << "<config />" << endl;
tout.flush();
config.flush();
config.close();
}
if(!config.open(QIODevice::Text|QIODevice::ReadOnly))
throw new Impl_ParseException("解析错误", QString("指定路径:%1配置文件无法打开").arg(path));
QString err_str; int err_row, err_col;
if(!doc_ins.setContent(&config, false, &err_str, &err_row, &err_col))
throw new Impl_ParseException("解析错误", QString("指定配置文件:%1row:%2,col:%3,格式错误。").arg(err_col).arg(err_row).arg(err_col));
}
QDir XMLConfig::currentDir() const
{
return QFileInfo(file_path).dir();
}
void XMLConfig::save() const
{
QFile fout(this->file_path);
if(!fout.open(QIODevice::WriteOnly | QIODevice::Text))
throw new Impl_ParseException("配置文件保存错误", QString("指定配置文件%1保存过程中无法打开").arg(file_path));
QTextStream tout(&fout);
tout.setCodec("UTF-8");
tout << this->doc_ins.toString(4);
tout.flush();
fout.flush();
fout.close();
}
void XMLConfig::deleteX(const QList<QString> &path)
{
auto elm = local_exists_elm(doc_ins.documentElement(), path);
if(elm.isNull())
return;
elm.parentNode().removeChild(elm);
}
void XMLConfig::setConfig(const QList<QString> &path, const QString &value)
{
auto doc = doc_ins.documentElement();
auto elm = rebuild_exists_elms(doc, path);
elm.setAttribute("value", value);
}
QString XMLConfig::getConfig(const QList<QString> &path) const
{
auto elm = local_exists_elm(doc_ins.documentElement(), path);
if(elm.isNull())
return "";
return elm.attribute("value");
}
void XMLConfig::setList(const QList<QString> &path, const QList<QString> &list)
{
auto root = doc_ins.documentElement();
auto telm = rebuild_exists_elms(root, path);
auto childs = telm.elementsByTagName("list");
for (auto idx = childs.count() - 1; idx >= 0; --idx) {
auto node = childs.at(idx);
telm.removeChild(node);
}
for(auto &it : list){
auto nelm = doc_ins.createElement("list");
nelm.setAttribute("value", it);
telm.appendChild(nelm);
}
}
QList<QString> XMLConfig::getList(const QList<QString> &path) const
{
auto elm = local_exists_elm(doc_ins.documentElement(), path);
QList<QString> rets;
auto childs = elm.childNodes();
for(auto idx=0; idx<childs.count(); ++idx){
auto node = childs.at(idx);
if(node.isElement() && node.toElement().tagName() == "list"){
rets << node.toElement().attribute("value");
}
}
return rets;
}
void XMLConfig::setMap(const QList<QString> &path, const QHash<QString, QString> &map)
{
auto root = doc_ins.documentElement();
auto telm = rebuild_exists_elms(root, path);
auto childs = telm.elementsByTagName("list");
for (auto idx = childs.count() - 1; idx >= 0; --idx) {
auto node = childs.at(idx);
telm.removeChild(node);
}
for(auto &key : map.keys()){
auto nelm = doc_ins.createElement("map");
nelm.setAttribute("key", key);
nelm.setAttribute("value", map[key]);
telm.appendChild(nelm);
}
}
QHash<QString, QString> XMLConfig::getMap(const QList<QString> &path) const
{
auto elm = local_exists_elm(doc_ins.documentElement(), path);
QHash<QString, QString> rets;
auto childs = elm.childNodes();
for(auto idx=0; idx<childs.count(); ++idx){
auto node = childs.at(idx);
if(node.isElement()){
auto elm = node.toElement();
if(elm.tagName() == "map")
rets[elm.attribute("key")] = elm.attribute("value");
}
}
return rets;
}
QDomElement XMLConfig::local_exists_elm(const QDomElement &elm_base, const QList<QString> &path, int level) const
{
auto child = elm_base.childNodes();
for(auto idx=0; idx<child.count(); ++idx){
auto ins = child.at(idx);
if(ins.isElement()){
auto elm = ins.toElement();
if(elm.tagName() == "path" && elm.attribute("key") == path[level]){
// 完成过滤,进行匹配
if(level == path.size()-1)
return elm;
return local_exists_elm(elm, path, level+1);
}
}
}
return QDomElement();
}
QDomElement XMLConfig::rebuild_exists_elms(QDomElement &elm_base, const QList<QString> &path, int level)
{
auto childnodes = elm_base.childNodes();
for(auto idx=0; idx<childnodes.count(); ++idx){
auto ins = childnodes.at(idx);
if(ins.isElement()){
auto eins = ins.toElement();
if(eins.tagName() == "path" && eins.attribute("key") == path[level]){
// 完成过滤,进行匹配
if(level == path.size() - 1)
return eins;
return rebuild_exists_elms(eins, path, level+1);
}
}
}
auto nelm = elm_base.ownerDocument().createElement("path");
nelm.setAttribute("key", path[level]);
elm_base.appendChild(nelm);
if(level < path.count() -1)
return rebuild_exists_elms(nelm, path, level+1);
return nelm;
}