diff --git a/.clang-format b/.clang-format index 9d7a6b0..da60dac 100644 --- a/.clang-format +++ b/.clang-format @@ -11,7 +11,7 @@ ReflowComments: true SpacesBeforeTrailingComments: 3 TabWidth: 4 ConstructorInitializerAllOnOneLineOrOnePerLine: true -ColumnLimit: 150 +ColumnLimit: 80 AllowShortBlocksOnASingleLine: Never AllowShortFunctionsOnASingleLine: None AllowShortEnumsOnASingleLine: false diff --git a/.vscode/settings.json b/.vscode/settings.json index 4fd3205..383a49f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "files.autoSave": "onFocusChange", "editor.fontSize": 14, - "editor.fontFamily": "'BlexMono Nerd Font Mono', 'BlexMono Nerd Font Mono', 'BlexMono Nerd Font Mono'", + "editor.fontFamily": "'FiraCode Nerd Font Mono', 'FiraCode Nerd Font Mono', 'FiraCode Nerd Font Mono'", "cmake.configureOnOpen": true, "cmake.debugConfig": { "console": "integratedTerminal", diff --git a/MainWidget.cpp b/MainWidget.cpp index f2097a1..4418d1f 100644 --- a/MainWidget.cpp +++ b/MainWidget.cpp @@ -15,11 +15,12 @@ constexpr std::size_t g_OnePage = 100; namespace fs = std::filesystem; -MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget) +MainWidget::MainWidget(QWidget* parent) + : QWidget(parent), ui(new Ui::MainWidget) { ui->setupUi(this); - setWindowTitle(u8"OneLevelXmlOpr v1.3.4"); + setWindowTitle(u8"OneLevelXmlOpr v1.3.5"); setWindowIcon(QIcon("://resource/xml.ico")); QScreen* primaryScreen = QGuiApplication::primaryScreen(); @@ -50,22 +51,33 @@ MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget ui->btnSearch->setFixedWidth(120); connect(ui->btnSelectFile, &QPushButton::clicked, this, [&]() { - QString file = CUtil::select_file(this, u8"请选择xml文件", u8"XML(*.xml);;所有文件 (*)"); + QString file = CUtil::select_file(this, u8"请选择xml文件", + u8"XML(*.xml);;所有文件 (*)"); if (file.isEmpty()) { return; } ui->edStatus->setText(file); }); - connect(ui->btnSearch, &QPushButton::clicked, this, [&]() { search(ui->edSearchKey->text()); }); - connect(ui->btnBackup, &QPushButton::clicked, this, [&]() { backup_file(); }); - connect(ui->btnRead, &QPushButton::clicked, this, [&]() { read(ui->edStatus->text().trimmed()); }); + connect(ui->btnSearch, &QPushButton::clicked, this, + [&]() { search(ui->edSearchKey->text()); }); + connect(ui->btnBackup, &QPushButton::clicked, this, + [&]() { backup_file(); }); + connect(ui->btnFormat, &QPushButton::clicked, this, + [&]() { format_xml(); }); + connect(ui->btnRead, &QPushButton::clicked, this, + [&]() { read(ui->edStatus->text().trimmed()); }); connect(ui->btnSave, &QPushButton::clicked, this, [&]() { save(); }); - connect(ui->btnExit, &QPushButton::clicked, this, [&]() { QApplication::exit(0); }); + connect(ui->btnExit, &QPushButton::clicked, this, + [&]() { QApplication::exit(0); }); connect(ui->btnReset, &QPushButton::clicked, this, &MainWidget::reset); - connect(ui->btnReplace, &QPushButton::clicked, this, [&]() { replace_content(true); }); - connect(ui->btnRxReplace, &QPushButton::clicked, this, [&]() { replace_content(false); }); - connect(ui->cbUnit, &QComboBox::currentTextChanged, this, [&](const QString& content) { unit_change(); }); - connect(ui->btnExport, &QPushButton::clicked, this, &MainWidget::copy_multi_data); + connect(ui->btnReplace, &QPushButton::clicked, this, + [&]() { replace_content(true); }); + connect(ui->btnRxReplace, &QPushButton::clicked, this, + [&]() { replace_content(false); }); + connect(ui->cbUnit, &QComboBox::currentTextChanged, this, + [&](const QString& content) { unit_change(); }); + connect(ui->btnExport, &QPushButton::clicked, this, + &MainWidget::copy_multi_data); connect(ui->btnPagePre, &QPushButton::clicked, this, [&]() { unsigned int cur = ui->edCurPage->text().toUInt(); push_content(current_, cur - 1); @@ -81,7 +93,8 @@ MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget } if (cur_config_.is_same) { - xml_.get_all_elements(vec_, ui->cbUnit->currentText().toStdString()); + xml_.get_all_elements(vec_, + ui->cbUnit->currentText().toStdString()); } else { xml_.get_all_elements(vec_); } @@ -211,8 +224,10 @@ void MainWidget::generate_table_widget() metrics_ = std::make_shared(tab_widget_->font()); tab_widget_->setContextMenuPolicy(Qt::CustomContextMenu); - connect(tab_widget_, &QTableWidget::itemChanged, this, [&](QTableWidgetItem* item) { item_changed_handle(item); }); - connect(tab_widget_, &QTableWidget::customContextMenuRequested, this, &MainWidget::show_custom_menu); + connect(tab_widget_, &QTableWidget::itemChanged, this, + [&](QTableWidgetItem* item) { item_changed_handle(item); }); + connect(tab_widget_, &QTableWidget::customContextMenuRequested, this, + &MainWidget::show_custom_menu); auto keys = CUtil::splitString(cur_config_.propertis, ","); keys_.clear(); @@ -244,7 +259,8 @@ void MainWidget::generate_table_widget() ui->widget->setLayout(lay); } -void MainWidget::push_content(const std::vector& eles, std::size_t page, bool auto_jump_pre) +void MainWidget::push_content(const std::vector& eles, + std::size_t page, bool auto_jump_pre) { if (tab_widget_ == nullptr || page == 0) { return; @@ -426,7 +442,8 @@ void MainWidget::item_changed_handle(QTableWidgetItem* item) if (result == nullptr) { return; } - result->SetAttribute(keys_[col].c_str(), item->text().toStdString().c_str()); + result->SetAttribute(keys_[col].c_str(), + item->text().toStdString().c_str()); } void MainWidget::save() @@ -523,9 +540,9 @@ void MainWidget::ele_update_gui(Element_t* target, const QString& pre_value) QString search_key; if (pre_value.isEmpty()) { - search_key = QString::fromLocal8Bit(target->Attribute(keys_[0].c_str())); - } - else { + search_key = + QString::fromLocal8Bit(target->Attribute(keys_[0].c_str())); + } else { search_key = pre_value; } @@ -578,8 +595,10 @@ void MainWidget::init_menu() } edit_property(target, cur_item->row(), false); }); - connect(ac_copy_curline_, &QAction::triggered, this, [&]() { copy_select_line(); }); - connect(ac_del_curline_, &QAction::triggered, this, [&]() { del_select_line(); }); + connect(ac_copy_curline_, &QAction::triggered, this, + [&]() { copy_select_line(); }); + connect(ac_del_curline_, &QAction::triggered, this, + [&]() { del_select_line(); }); connect(ac_copy_key_, &QAction::triggered, this, [&]() { copy_key(); }); } @@ -599,8 +618,10 @@ void MainWidget::insert_one_line(Element_t* ele, int row) } QString sda(data); int dwidth = metrics_->horizontalAdvance(sda) + blank_with_; - int need_set_width = dwidth > allow_max_with_ ? allow_max_with_ : dwidth; - col_with_[i] = col_with_[i] < need_set_width ? need_set_width : col_with_[i]; + int need_set_width = + dwidth > allow_max_with_ ? allow_max_with_ : dwidth; + col_with_[i] = + col_with_[i] < need_set_width ? need_set_width : col_with_[i]; wgItem->setText(sda); tab_widget_->setItem(row, i, wgItem); } @@ -705,7 +726,10 @@ void MainWidget::sort_by_repeat(std::vector& vec) std::string d(str); turn_vec.emplace_back(item, d); } - std::sort(turn_vec.begin(), turn_vec.end(), [&](const SElement_t& se1, const SElement_t& se2) { return compare_by_prefix(se1, se2); }); + std::sort(turn_vec.begin(), turn_vec.end(), + [&](const SElement_t& se1, const SElement_t& se2) { + return compare_by_prefix(se1, se2); + }); vec.clear(); for (const auto& item : turn_vec) { vec.push_back(item.ele); @@ -777,7 +801,8 @@ void MainWidget::replace_content(bool is_common) std::vector vec; if (ui->rbReplaceSelect->isChecked()) { - QModelIndexList indexList = tab_widget_->selectionModel()->selectedRows(); + QModelIndexList indexList = + tab_widget_->selectionModel()->selectedRows(); if (indexList.size() < 1) { CUtil::msg(this, u8"无选择数据"); return; @@ -807,7 +832,8 @@ void MainWidget::replace_content(bool is_common) } } -void MainWidget::replace_str(const QString& pre, const QString& after, Element_t* ele) +void MainWidget::replace_str(const QString& pre, const QString& after, + Element_t* ele) { if (ele == nullptr) { return; @@ -822,7 +848,8 @@ void MainWidget::replace_str(const QString& pre, const QString& after, Element_t } } -void MainWidget::replace_str(Element_t* ele, const QString& rg, const QString& after) +void MainWidget::replace_str(Element_t* ele, const QString& rg, + const QString& after) { QRegularExpression rx(rg); if (ele == nullptr) { @@ -839,14 +866,17 @@ void MainWidget::replace_str(Element_t* ele, const QString& rg, const QString& a } } -void MainWidget::get_related_elements(std::vector& out, ReplaceArea area) +void MainWidget::get_related_elements(std::vector& out, + ReplaceArea area) { assert(tab_widget_); out.clear(); switch (area) { case AREA_ALL_PAGE: { out.resize(current_.size()); - std::transform(current_.begin(), current_.end(), out.begin(), [](Element_t* ele) { return new OperElement(ele, 0); }); + std::transform( + current_.begin(), current_.end(), out.begin(), + [](Element_t* ele) { return new OperElement(ele, 0); }); break; } case AREA_CUR_PAGE: { @@ -858,13 +888,18 @@ void MainWidget::get_related_elements(std::vector& out, ReplaceAre } case AREA_ALL: { out.resize(vec_.size()); - std::transform(vec_.begin(), vec_.end(), out.begin(), [](Element_t* ele) { return new OperElement(ele, 0); }); + std::transform( + vec_.begin(), vec_.end(), out.begin(), + [](Element_t* ele) { return new OperElement(ele, 0); }); break; } default: { - QModelIndexList indexList = tab_widget_->selectionModel()->selectedRows(); + QModelIndexList indexList = + tab_widget_->selectionModel()->selectedRows(); for (int i = 0; i < indexList.size(); ++i) { - out.emplace_back(new OperElement(get_element_by_row(indexList[i].row()), indexList[i].row())); + out.emplace_back( + new OperElement(get_element_by_row(indexList[i].row()), + indexList[i].row())); } break; } @@ -878,7 +913,9 @@ void MainWidget::backup_file() } QString time = QDateTime::currentDateTime().toString("yyyy-MMdd-hhmmss"); - if (!xml_.backup_file(fs::path(exe_path_).parent_path().append("backup").string(), time.toStdString())) { + if (!xml_.backup_file( + fs::path(exe_path_).parent_path().append("backup").string(), + time.toStdString())) { CUtil::msg(this, u8"备份失败。"); } else { CUtil::msg(this, u8"备份完成。"); @@ -918,6 +955,20 @@ void MainWidget::unit_change() current_ = vec_; } +bool MainWidget::format_xml() +{ + std::string xml_path = ui->edStatus->text().toStdString(); + if (xml_path.empty()) { + return false; + } + if (!xml_.handle_save(xml_path)) { + CUtil::msg(this, u8"格式化失败"); + return false; + } + CUtil::msg(this, u8"格式化结束"); + return true; +} + std::string MainWidget::extract_prefix(const std::string& name) { auto pos = name.find('.'); diff --git a/MainWidget.h b/MainWidget.h index c59925c..c7d9af3 100644 --- a/MainWidget.h +++ b/MainWidget.h @@ -1,12 +1,6 @@ #ifndef MAINWIDGET_H #define MAINWIDGET_H -#include "conf_setting.h" -#include "src/attribute_edit.h" -#include "src/config.h" -#include "src/xml_opr.h" -#include "src/history.h" -#include "src/uhistory.h" #include #include #include @@ -14,6 +8,13 @@ #include #include +#include "conf_setting.h" +#include "src/attribute_edit.h" +#include "src/config.h" +#include "src/history.h" +#include "src/uhistory.h" +#include "src/xml_opr.h" + struct SElement_t { SElement_t(Element_t* e, std::string& s); Element_t* ele; @@ -51,7 +52,8 @@ public: public: void set_work_exe(char* path); void generate_table_widget(); - void push_content(const std::vector& eles, std::size_t page = 1, bool auto_jump_pre = false); + void push_content(const std::vector& eles, std::size_t page = 1, + bool auto_jump_pre = false); private: bool read(const QString& file_path); @@ -74,6 +76,7 @@ private: void backup_file(); void base_init(); void unit_change(); + bool format_xml(); private: std::string extract_prefix(const std::string& name); diff --git a/MainWidget.ui b/MainWidget.ui index 5211c91..03fae1c 100644 --- a/MainWidget.ui +++ b/MainWidget.ui @@ -54,6 +54,13 @@ + + + + + + + diff --git a/conf_setting.cpp b/conf_setting.cpp index 1281ac6..11c620a 100644 --- a/conf_setting.cpp +++ b/conf_setting.cpp @@ -1,18 +1,23 @@ #include "conf_setting.h" + #include "public_def.h" #include "ui_conf_setting.h" -CGroupSetting::CGroupSetting(QWidget* parent, CGroupIni* oper) : QDialog(parent), ui(new Ui::CGroupSetting) +CGroupSetting::CGroupSetting(QWidget* parent, CGroupIni* oper) + : QDialog(parent), ui(new Ui::CGroupSetting) { ini_opr_ = oper; ui->setupUi(this); setWindowTitle(u8"配置编辑"); - connect(ui->btnAddConfig, &QPushButton::clicked, this, [&]() { add_item(); }); - connect(ui->btnDelConfig, &QPushButton::clicked, this, [&]() { del_item(); }); + connect(ui->btnAddConfig, &QPushButton::clicked, this, + [&]() { add_item(); }); + connect(ui->btnDelConfig, &QPushButton::clicked, this, + [&]() { del_item(); }); connect(ui->btnExit, &QPushButton::clicked, this, [&]() { close(); }); - connect(ui->cbConfig, &QComboBox::currentTextChanged, this, [&](const QString& content) { change_ini(); }); + connect(ui->cbConfig, &QComboBox::currentTextChanged, this, + [&](const QString& content) { change_ini(); }); } CGroupSetting::~CGroupSetting() @@ -82,8 +87,7 @@ void CGroupSetting::set_ui(const OneGroupIni& gp) if (gp.is_same) { ui->chbIsSame->setChecked(true); - } - else { + } else { ui->chbIsSame->setChecked(false); } } diff --git a/conf_setting.h b/conf_setting.h index 37785e1..3ef4ee0 100644 --- a/conf_setting.h +++ b/conf_setting.h @@ -2,6 +2,7 @@ #define CONF_SETTING_H #include + #include "src/config.h" namespace Ui { @@ -13,7 +14,7 @@ class CGroupSetting : public QDialog Q_OBJECT public: - explicit CGroupSetting(QWidget *parent, CGroupIni* oper); + explicit CGroupSetting(QWidget* parent, CGroupIni* oper); ~CGroupSetting(); protected: @@ -28,7 +29,7 @@ private: private: bool auto_add_{false}; - Ui::CGroupSetting *ui; + Ui::CGroupSetting* ui; CGroupIni* ini_opr_{}; }; diff --git a/main.cpp b/main.cpp index 4cf99c8..103c98a 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,7 @@ -#include "MainWidget.h" - #include +#include "MainWidget.h" + int main(int argc, char *argv[]) { QApplication a(argc, argv); diff --git a/public_def.cpp b/public_def.cpp index f4ed16b..c08c30c 100644 --- a/public_def.cpp +++ b/public_def.cpp @@ -1,4 +1,5 @@ #include "public_def.h" + #include #include @@ -11,7 +12,8 @@ void CUtil::msg(QWidget* parent, const QString& content) QMessageBox::information(parent, u8"提示", content); } -bool CUtil::affirm(QWidget* parent, const QString& titile, const QString& content) +bool CUtil::affirm(QWidget* parent, const QString& titile, + const QString& content) { QMessageBox questionBox(parent); questionBox.setText(content); @@ -26,9 +28,11 @@ bool CUtil::affirm(QWidget* parent, const QString& titile, const QString& conten } } -QString CUtil::select_file(QWidget* parent, const QString& info, const QString& filter) +QString CUtil::select_file(QWidget* parent, const QString& info, + const QString& filter) { - QString filePath = QFileDialog::getOpenFileName(parent, info, QDir::homePath(), filter); + QString filePath = + QFileDialog::getOpenFileName(parent, info, QDir::homePath(), filter); return filePath; } @@ -58,22 +62,26 @@ void CUtil::sort_by_repeat(std::vector& vec) std::string CUtil::utf8_to_gbk(const std::string& utf8_str) { // UTF-8 to Wide Char (UTF-16) - int wide_char_len = MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, nullptr, 0); + int wide_char_len = + MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, nullptr, 0); if (wide_char_len == 0) { return ""; } std::wstring wide_str(wide_char_len, 0); - MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, &wide_str[0], wide_char_len); + MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, &wide_str[0], + wide_char_len); // Wide Char (UTF-16) to GBK - int gbk_len = WideCharToMultiByte(CP_ACP, 0, wide_str.c_str(), -1, nullptr, 0, nullptr, nullptr); + int gbk_len = WideCharToMultiByte(CP_ACP, 0, wide_str.c_str(), -1, nullptr, + 0, nullptr, nullptr); if (gbk_len == 0) { return ""; } std::string gbk_str(gbk_len, 0); - WideCharToMultiByte(CP_ACP, 0, wide_str.c_str(), -1, &gbk_str[0], gbk_len, nullptr, nullptr); + WideCharToMultiByte(CP_ACP, 0, wide_str.c_str(), -1, &gbk_str[0], gbk_len, + nullptr, nullptr); return gbk_str; } @@ -84,7 +92,8 @@ std::string CUtil::utf8_to_gbk(const std::string& utf8_str) } #endif -std::vector CUtil::splitString(const std::string& input, const std::string& delimiter) +std::vector CUtil::splitString(const std::string& input, + const std::string& delimiter) { std::vector tokens; size_t pos = 0; diff --git a/public_def.h b/public_def.h index 0fa9f92..952d471 100644 --- a/public_def.h +++ b/public_def.h @@ -13,13 +13,16 @@ public: public: static void msg(QWidget* parent, const QString& content); - static bool affirm(QWidget* parent, const QString& titile, const QString& content); - static QString select_file(QWidget* parent, const QString& info, const QString& filter); + static bool affirm(QWidget* parent, const QString& titile, + const QString& content); + static QString select_file(QWidget* parent, const QString& info, + const QString& filter); static void sort_by_repeat(std::vector& vec); public: static std::string utf8_to_gbk(const std::string& utf8_str); - static std::vector splitString(const std::string& input, const std::string& delimiter); + static std::vector splitString(const std::string& input, + const std::string& delimiter); }; #endif diff --git a/src/attribute_edit.cpp b/src/attribute_edit.cpp index 3fcd516..18eec80 100644 --- a/src/attribute_edit.cpp +++ b/src/attribute_edit.cpp @@ -2,7 +2,8 @@ #include "ui_attribute_edit.h" -CAttributeEdit::CAttributeEdit(QWidget* parent) : QDialog(parent), ui(new Ui::CAttributeEdit) +CAttributeEdit::CAttributeEdit(QWidget* parent) + : QDialog(parent), ui(new Ui::CAttributeEdit) { ui->setupUi(this); @@ -23,7 +24,8 @@ void CAttributeEdit::handle_ok() for (int i = 0; i < row; ++i) { QString key = table_->item(i, 0)->text(); QString value = table_->item(i, 1)->text(); - property_.emplace_back(key.toStdString().c_str(), value.toStdString().c_str()); + property_.emplace_back(key.toStdString().c_str(), + value.toStdString().c_str()); } is_ok_ = true; close(); @@ -87,7 +89,8 @@ void CAttributeEdit::init_table() table_->setColumnCount(list.size()); table_->setHorizontalHeaderLabels(list); table_->setSelectionBehavior(QAbstractItemView::SelectRows); - table_->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); + table_->setSelectionMode( + QAbstractItemView::SelectionMode::SingleSelection); table_->setColumnWidth(0, 100); table_->setColumnWidth(1, 550); QHBoxLayout* ly = new QHBoxLayout(); diff --git a/src/config.cpp b/src/config.cpp index 8d11e84..17b99c3 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -52,7 +52,8 @@ void CGroupIni::get_all_node(StrVec_t& vec) bool CGroupIni::add_item(const OneGroupIni& group) { ini_.SetValue(group.name.c_str(), "MainNodes", group.main_nodes.c_str()); - ini_.SetValue(group.name.c_str(), "RelativeNodes", group.relative_nodes.c_str()); + ini_.SetValue(group.name.c_str(), "RelativeNodes", + group.relative_nodes.c_str()); ini_.SetValue(group.name.c_str(), "ItemKey", group.item_key.c_str()); ini_.SetValue(group.name.c_str(), "Properties", group.propertis.c_str()); ini_.SetLongValue(group.name.c_str(), "MaxColLen", group.max_col_len); diff --git a/src/config.h b/src/config.h index 51fec0e..e1e5041 100644 --- a/src/config.h +++ b/src/config.h @@ -1,8 +1,9 @@ #ifndef CONIFG_HEADER #define CONIFG_HEADER -#include #include + +#include #include /* diff --git a/src/data_edit.cpp b/src/data_edit.cpp index 081d12d..6282157 100644 --- a/src/data_edit.cpp +++ b/src/data_edit.cpp @@ -19,7 +19,8 @@ CDataEdit::CDataEdit(QWidget* parent) : QDialog(parent), ui(new Ui::CDataEdit) connect(ui->btnExit, &QPushButton::clicked, this, [&]() { close(); }); connect(ui->btnReplace, &QPushButton::clicked, this, [&]() { replace(); }); - connect(ui->btnWithDraw, &QPushButton::clicked, this, [&]() { with_draw(); }); + connect(ui->btnWithDraw, &QPushButton::clicked, this, + [&]() { with_draw(); }); connect(ui->btnAdd, &QPushButton::clicked, this, [&]() { import_data(); }); connect(ui->btnCopy, &QPushButton::clicked, this, [&]() { QClipboard* clip = QApplication::clipboard(); @@ -56,7 +57,8 @@ void CDataEdit::import_data() return; } - if (!CUtil::affirm(this, u8"提示", u8"如果出现重复的 key 将跳过,继续吗?")) { + if (!CUtil::affirm(this, u8"提示", + u8"如果出现重复的 key 将跳过,继续吗?")) { return; } @@ -79,7 +81,9 @@ void CDataEdit::import_data() CUtil::msg(this, u8"导入失败。"); return; } - QString info = QString(u8"需要导入 %1 条数据,成功导入 %2 条。").arg(task_count).arg(success_count); + QString info = QString(u8"需要导入 %1 条数据,成功导入 %2 条。") + .arg(task_count) + .arg(success_count); CUtil::msg(this, info); close(); is_import_sucess_ = true; diff --git a/src/data_edit.h b/src/data_edit.h index 2996a0c..255f1eb 100644 --- a/src/data_edit.h +++ b/src/data_edit.h @@ -39,8 +39,8 @@ public: private: Ui::CDataEdit* ui; - QString data_{}; - CXmlOpr* xml_opr_{}; + QString data_{}; + CXmlOpr* xml_opr_{}; }; #endif // DATA_EDIT_H diff --git a/src/history.cpp b/src/history.cpp index c3bccc6..aa26378 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -1,4 +1,5 @@ #include "history.h" + #include #include #include diff --git a/src/uhistory.cpp b/src/uhistory.cpp index 2fe3d86..6eece4e 100644 --- a/src/uhistory.cpp +++ b/src/uhistory.cpp @@ -3,7 +3,8 @@ #include "src/ui_uhistory.h" #include "ui_uhistory.h" -CUIHistory::CUIHistory(QWidget* parent, CHistory* his) : QDialog(parent), ui(new Ui::CUIHistory) +CUIHistory::CUIHistory(QWidget* parent, CHistory* his) + : QDialog(parent), ui(new Ui::CUIHistory) { ui->setupUi(this); his_ = his; @@ -38,7 +39,7 @@ void CUIHistory::select_ok() { auto re = ui->listWidget->selectedItems(); if (re.empty()) { - return ; + return; } cur_ = re[0]->text(); close(); @@ -48,7 +49,7 @@ void CUIHistory::del_item() { auto re = ui->listWidget->selectedItems(); if (re.empty()) { - return ; + return; } for (auto& item : re) { delete ui->listWidget->takeItem(ui->listWidget->row(item)); diff --git a/src/uhistory.h b/src/uhistory.h index fe4bdc3..e753ce2 100644 --- a/src/uhistory.h +++ b/src/uhistory.h @@ -2,6 +2,7 @@ #define UHISTORY_H #include + #include "history.h" namespace Ui { @@ -13,7 +14,7 @@ class CUIHistory : public QDialog Q_OBJECT public: - explicit CUIHistory(QWidget *parent, CHistory* his); + explicit CUIHistory(QWidget* parent, CHistory* his); ~CUIHistory(); private: @@ -25,7 +26,7 @@ public: QString cur_{}; private: - Ui::CUIHistory *ui; + Ui::CUIHistory* ui; CHistory* his_{}; }; diff --git a/src/xml_opr.cpp b/src/xml_opr.cpp index 3b66e7e..5b2d217 100644 --- a/src/xml_opr.cpp +++ b/src/xml_opr.cpp @@ -1,6 +1,9 @@ #include "xml_opr.h" #include +#include +#include +#include #include "../public_def.h" @@ -12,7 +15,8 @@ CXmlOpr::~CXmlOpr() = default; bool CXmlOpr::open(const std::string& xml_path) { #ifdef _WIN32 - if (doc_.LoadFile(CUtil::utf8_to_gbk(xml_path).c_str()) != tinyxml2::XML_SUCCESS) { + if (doc_.LoadFile(CUtil::utf8_to_gbk(xml_path).c_str()) != + tinyxml2::XML_SUCCESS) { return false; } xml_path_ = CUtil::utf8_to_gbk(xml_path); @@ -25,7 +29,8 @@ bool CXmlOpr::open(const std::string& xml_path) return true; } -bool CXmlOpr::backup_file(const std::string& desti_folder, const std::string& time) +bool CXmlOpr::backup_file(const std::string& desti_folder, + const std::string& time) { if (!fs::exists(xml_path_)) { return false; @@ -34,7 +39,8 @@ bool CXmlOpr::backup_file(const std::string& desti_folder, const std::string& ti fs::create_directories(desti_folder); } fs::path file_path = fs::path(xml_path_); - fs::path des = fs::path(desti_folder).append(file_path.stem().string() + "_" + time + ".xml"); + fs::path des = fs::path(desti_folder) + .append(file_path.stem().string() + "_" + time + ".xml"); return fs::copy_file(xml_path_, des); } @@ -43,7 +49,8 @@ void CXmlOpr::set_baseinfo(const OneGroupIni& base) opr_base_ = base; } -bool CXmlOpr::get_all_elements(std::vector& vec, const std::string& unit) +bool CXmlOpr::get_all_elements(std::vector& vec, + const std::string& unit) { vec.clear(); @@ -61,7 +68,8 @@ bool CXmlOpr::get_all_elements(std::vector& vec, const std::string& } } - auto purpose_node = parent_node2_->FirstChildElement(opr_base_.item_key.c_str()); + auto purpose_node = + parent_node2_->FirstChildElement(opr_base_.item_key.c_str()); while (purpose_node) { vec.push_back(purpose_node); purpose_node = purpose_node->NextSiblingElement(); @@ -123,11 +131,13 @@ bool CXmlOpr::get_all_unit(std::vector& units) } // 排序后(仅指针排序)的节点进行复制(让实际内容有序),删除原始节点 -void CXmlOpr::copy_and_del(std::vector& vec, std::vector& out) +void CXmlOpr::copy_and_del(std::vector& vec, + std::vector& out) { out.clear(); // 先找到最后一个节点 - Element_t* last_node = parent_node2_->LastChildElement(opr_base_.item_key.c_str()); + Element_t* last_node = + parent_node2_->LastChildElement(opr_base_.item_key.c_str()); Element_t* last_node_bk = last_node; if (last_node == nullptr) { return; @@ -139,7 +149,8 @@ void CXmlOpr::copy_and_del(std::vector& vec, std::vector last_node = n; } // 删除原有的节点 - Element_t* fnode = parent_node2_->FirstChildElement(opr_base_.item_key.c_str()); + Element_t* fnode = + parent_node2_->FirstChildElement(opr_base_.item_key.c_str()); Element_t* fnext = fnode->NextSiblingElement(); while (fnode != last_node_bk) { parent_node2_->DeleteChild(fnode); @@ -183,7 +194,8 @@ bool CXmlOpr::check_valid_xml_data(const std::string& data) bool CXmlOpr::check_same_struct(const std::string& data) { - auto* own_ele = parent_node2_->FirstChildElement(opr_base_.item_key.c_str()); + auto* own_ele = + parent_node2_->FirstChildElement(opr_base_.item_key.c_str()); if (own_ele == nullptr) { return true; } @@ -222,10 +234,12 @@ bool CXmlOpr::check_same_struct(const std::string& data) // Warning: 不检查 xml 格式合法性,请自行调用 check_valid_xml_data // 且导入前每条数据请自行使用 check_same_struct 检测。 -bool CXmlOpr::import_newer_data(const std::vector& vec, std::size_t& success_count) +bool CXmlOpr::import_newer_data(const std::vector& vec, + std::size_t& success_count) { success_count = 0; - auto* last_item = parent_node2_->LastChildElement(opr_base_.item_key.c_str()); + auto* last_item = + parent_node2_->LastChildElement(opr_base_.item_key.c_str()); if (last_item == nullptr) { return false; } @@ -248,6 +262,114 @@ bool CXmlOpr::import_newer_data(const std::vector& vec, std::size_t } return true; } +std::string CXmlOpr::handle_space(const std::string& content) +{ + std::string result; + size_t pos = 0; + size_t len = content.length(); + + // Define a regular expression for the operators + std::regex operators_regex(R"(&&|!=|==|<|>|\|\||\+|-|\*|/)"); + + while (pos < len) { + size_t start_quote = content.find('"', pos); + if (start_quote == std::string::npos) { + result.append(content.substr(pos)); + break; + } + + // Append everything before the first quote + result.append(content.substr(pos, start_quote - pos)); + + // Find the ending quote + size_t end_quote = content.find('"', start_quote + 1); + if (end_quote == std::string::npos) { + result.append(content.substr(start_quote)); + break; + } + + // Extract the quoted content + std::string quoted_content = + content.substr(start_quote + 1, end_quote - start_quote - 1); + std::string processed_content = + std::regex_replace(quoted_content, operators_regex, " $& "); + + // Process quoted content to replace multiple spaces with a single space + std::istringstream iss(processed_content); + std::ostringstream oss; + std::string word; + bool first = true; + while (iss >> word) { + if (!first) { + oss << ' '; + } + oss << word; + first = false; + } + + // Append processed content with quotes + result.append("\"" + oss.str() + "\""); + + // Move past the ending quote + pos = end_quote + 1; + } + + return result; +} +bool CXmlOpr::handle_transfer(const std::string& path) +{ + std::ifstream file(path); + if (!file.is_open()) { + return false; + } + + std::istreambuf_iterator ifter(file); + std::istreambuf_iterator iter; + std::string content(ifter, iter); + file.close(); + + size_t pos = 0; + std::string result = content; + + // Replace XML entities with their corresponding characters + while ((pos = result.find("&", pos)) != std::string::npos) { + result.replace(pos, 5, "&"); + pos += 1; // Move past the replaced character + } + + pos = 0; + while ((pos = result.find("<", pos)) != std::string::npos) { + result.replace(pos, 4, "<"); + pos += 1; // Move past the replaced character + } + + pos = 0; + while ((pos = result.find(">", pos)) != std::string::npos) { + result.replace(pos, 4, ">"); + pos += 1; // Move past the replaced character + } + + pos = 0; + while ((pos = result.find(""", pos)) != std::string::npos) { + result.replace(pos, 6, "\""); + pos += 1; // Move past the replaced character + } + + pos = 0; + while ((pos = result.find("'", pos)) != std::string::npos) { + result.replace(pos, 6, "'"); + pos += 1; // Move past the replaced character + } + + // 处理空格格式化 + std::string sec_handle = handle_space(result); + std::ofstream ofile(path); + if (!ofile.is_open()) { + return false; + } + ofile << sec_handle; + return true; +} void CXmlOpr::del_element(Element_t* ele) { @@ -267,7 +389,8 @@ bool CXmlOpr::check_key_exists(const std::string& key) if (keys_.size() < 1 || key.empty()) { return false; } - Element_t* purpose_node = parent_node2_->FirstChildElement(opr_base_.item_key.c_str()); + Element_t* purpose_node = + parent_node2_->FirstChildElement(opr_base_.item_key.c_str()); while (purpose_node) { const char* value = purpose_node->Attribute(keys_[0].c_str()); if (key == std::string(value)) { @@ -287,6 +410,21 @@ bool CXmlOpr::save() return true; } +bool CXmlOpr::handle_save(const std::string& path) +{ + if (!open(path)) { + return false; + } + auto ret = doc_.SaveFile(xml_path_.c_str()); + if (ret != tinyxml2::XML_SUCCESS) { + return false; + } + if (!handle_transfer(xml_path_)) { + return false; + } + return true; +} + void CXmlOpr::get_attributes(Element_t* ele, Property_t& vec) { if (ele == nullptr) { diff --git a/src/xml_opr.h b/src/xml_opr.h index d9f92d8..dfe3e6a 100644 --- a/src/xml_opr.h +++ b/src/xml_opr.h @@ -1,11 +1,13 @@ #ifndef XML_OPERT_HEADER #define XML_OPERT_HEADER -#include "config.h" -#include #include + +#include #include +#include "config.h" + struct SKeyValue { SKeyValue(const char* pkey, const char* pvalue); std::string key; @@ -26,13 +28,17 @@ public: void set_baseinfo(const OneGroupIni& base); bool parse_xml(std::vector& vec); bool get_all_unit(std::vector& units); - bool get_all_elements(std::vector& vec, const std::string& unit = ""); - void copy_and_del(std::vector& vec, std::vector& out); + bool get_all_elements(std::vector& vec, + const std::string& unit = ""); + void copy_and_del(std::vector& vec, + std::vector& out); void insert_brother_node(Element_t* brother, Element_t* newer); void del_element(Element_t* ele); bool check_key_exists(const Property_t& property); bool check_key_exists(const std::string& key); bool save(); + bool handle_save(const std::string& path); + std::string handle_space(const std::string& content); public: Element_t* copy_element(Element_t* ele); @@ -41,7 +47,10 @@ public: // 不检查 xml 格式合法性,请自行调用 check_valid_xml_data bool check_same_struct(const std::string& data); // 不检查 xml 格式合法性,请自行调用 check_valid_xml_data - bool import_newer_data(const std::vector& vec, std::size_t& success_count); + bool import_newer_data(const std::vector& vec, + std::size_t& success_count); + // 处理转义 + bool handle_transfer(const std::string& path); public: void get_attributes(Element_t* ele, Property_t& vec);