From 4976b5548e716d303f0c48e58a8f1d0fad0e88f9 Mon Sep 17 00:00:00 2001 From: taynpg Date: Sat, 18 May 2024 01:26:52 +0800 Subject: [PATCH] =?UTF-8?q?func=EF=BC=9A=E5=AE=9E=E7=8E=B0=E4=BA=86?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .clang-format | 2 +- .gitignore | 3 +- CMakeLists.txt.user | 257 -------------------------------------------- MainWidget.cpp | 64 +++++++++-- MainWidget.h | 1 + MainWidget.ui | 2 +- public_def.cpp | 22 ++++ public_def.h | 1 + src/xml_opr.cpp | 27 +++++ src/xml_opr.h | 1 + 10 files changed, 112 insertions(+), 268 deletions(-) delete mode 100644 CMakeLists.txt.user diff --git a/.clang-format b/.clang-format index f5dc2a2..fff25a0 100644 --- a/.clang-format +++ b/.clang-format @@ -31,7 +31,7 @@ TabWidth: 4 # 构造函数的初始化列表要么都在同一行,要么都各自一行 ConstructorInitializerAllOnOneLineOrOnePerLine: true # 每行字符的限制,0表示没有限制 -ColumnLimit: 150 +ColumnLimit: 100 # 允许短的块放在同一行 AllowShortBlocksOnASingleLine: false # 是否允许短函数在一行 diff --git a/.gitignore b/.gitignore index ff8bda6..63a369b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build .vs -.cache \ No newline at end of file +.cache +*.user \ No newline at end of file diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user deleted file mode 100644 index 260949c..0000000 --- a/CMakeLists.txt.user +++ /dev/null @@ -1,257 +0,0 @@ - - - - - - EnvironmentId - {ba65acc4-67f8-4483-9557-68f8d8f20560} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - 0 - false - true - false - 2 - true - true - 0 - 8 - true - false - 1 - true - true - true - *.md, *.MD, Makefile - false - true - true - - - - ProjectExplorer.Project.PluginSettings - - - true - false - true - true - true - true - - - 0 - true - - true - true - Builtin.DefaultTidyAndClazy - 6 - true - - - - true - - - - - ProjectExplorer.Project.Target.0 - - Desktop - vc64 - vc64 - {244185d3-0e22-42f6-99cc-1b986ffe29c6} - 0 - 0 - 0 - - Debug - 2 - false - - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_BUILD_TYPE:STRING=Debug --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - 0 - E:\code\OneLevelXmlOpr\build\vc64-Debug - - - - - all - - false - - true - 构建 - CMakeProjectManager.MakeStep - - 1 - 构建 - 构建 - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - 构建 - CMakeProjectManager.MakeStep - - 1 - 清除 - 清除 - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Debug - CMakeProjectManager.CMakeBuildConfiguration - - - Release - 2 - false - - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_BUILD_TYPE:STRING=Release --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - E:\code\OneLevelXmlOpr\build\vc64-Release - - - - - all - - false - - true - CMakeProjectManager.MakeStep - - 1 - 构建 - 构建 - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - CMakeProjectManager.MakeStep - - 1 - 清除 - 清除 - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release - CMakeProjectManager.CMakeBuildConfiguration - - 2 - - - 0 - 部署 - 部署 - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - 0 - true - - 2 - - false - -e cpu-cycles --call-graph "dwarf,4096" -F 250 - OneLevelXmlOpr - CMakeProjectManager.CMakeRunConfiguration.OneLevelXmlOpr - OneLevelXmlOpr - false - true - true - true - E:/code/OneLevelXmlOpr/build/vc64-Debug - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.FileVersion - 22 - - - Version - 22 - - diff --git a/MainWidget.cpp b/MainWidget.cpp index 14a08b4..f0124d6 100644 --- a/MainWidget.cpp +++ b/MainWidget.cpp @@ -11,7 +11,7 @@ MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget { ui->setupUi(this); - setWindowTitle(u8"OneLevelXmlOpr v1.2.7"); + setWindowTitle(u8"OneLevelXmlOpr v1.2.8"); setWindowIcon(QIcon("://resource/xml.ico")); setMinimumWidth(900); @@ -37,7 +37,8 @@ MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget read(file); }); connect(ui->btnSearch, &QPushButton::clicked, this, [&]() { search(); }); - connect(ui->btnRead, &QPushButton::clicked, this, [&]() { read(ui->edStatus->text().trimmed()); }); + 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->btnReset, &QPushButton::clicked, this, &MainWidget::reset); @@ -53,13 +54,22 @@ MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget unsigned int cur = ui->edCurPage->text().toUInt(); push_content(current_, cur); }); + connect(ui->btnResort, &QPushButton::clicked, this, [&]() { + sort_by_repeat(vec_); + std::vector nvec{}; + xml_.copy_and_del(vec_, nvec); + vec_.clear(); + std::swap(vec_, nvec); + current_ = vec_; + push_content(current_); + }); QSettings settings; settings.beginGroup("xmlopr"); restoreGeometry(settings.value("geometry").toByteArray()); settings.endGroup(); - //QFile qss_file("://qss/lightblue.css"); + // QFile qss_file("://qss/lightblue.css"); QFile qss_file("://qss/flatgray.css"); if (qss_file.open(QFile::ReadOnly)) { qApp->setStyleSheet(qss_file.readAll()); @@ -132,8 +142,10 @@ void MainWidget::generate_table_widget() { tab_widget_ = new QTableWidget(); 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 config = ini_.get_config(); auto keys = splitString(config.purpose, ","); keys_.clear(); @@ -149,7 +161,7 @@ void MainWidget::generate_table_widget() tab_widget_->setColumnCount(list.size()); tab_widget_->setHorizontalHeaderLabels(list); tab_widget_->setSelectionBehavior(QAbstractItemView::SelectRows); - //tab_widget_->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); + // tab_widget_->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); for (auto i = 0; i < keys.size(); ++i) { tab_widget_->setColumnWidth(i, width_[i]); @@ -433,8 +445,8 @@ void MainWidget::insert_one_line(Element_t* ele, int row) if (i == 0) { wgItem->setFlags(wgItem->flags() & ~Qt::ItemIsEditable); - //wgItem->setFlags(wgItem->flags() | Qt::ItemIsUserCheckable); - //wgItem->setCheckState(Qt::Checked); + // wgItem->setFlags(wgItem->flags() | Qt::ItemIsUserCheckable); + // wgItem->setCheckState(Qt::Checked); } wgItem->setText(QString(data)); @@ -517,3 +529,39 @@ tinyxml2::XMLElement* MainWidget::get_element_bykey(const QString& key) } return ret; } + +void MainWidget::sort_by_repeat(std::vector& vec) +{ + struct SElement_t { + SElement_t(Element_t* e, std::string& s) + { + ele = e; + str = std::move(s); + } + Element_t* ele{}; + std::string str{}; + }; + std::vector turn_vec{}; + for (const auto& item : vec) { + const char* str = item->Attribute(keys_[0].c_str()); + turn_vec.emplace_back(item, std::string(str)); + } + + auto compare = [&](const SElement_t& se1, const SElement_t& se2) { + std::size_t i = 0; + // 逐个字符比较,直到找到不同的字符或者某个字符串到达结尾 + while (i < se1.str.length() && i < se2.str.length()) { + if (se1.str[i] != se2.str[i]) { + return se1.str[i] < se2.str[i]; + } + ++i; + } + // 如果有一个字符串到达结尾,而另一个还没有,则较短的字符串排在前面 + return se1.str.length() < se2.str.length(); + }; + std::sort(turn_vec.begin(), turn_vec.end(), compare); + vec.clear(); + for (const auto& item : turn_vec) { + vec.push_back(item.ele); + } +} \ No newline at end of file diff --git a/MainWidget.h b/MainWidget.h index 9f69df3..35b0c8e 100644 --- a/MainWidget.h +++ b/MainWidget.h @@ -44,6 +44,7 @@ private: void init_menu(); void ele_update_gui(Element_t* target, int row); void show_custom_menu(); + void sort_by_repeat(std::vector& vec); protected: void closeEvent(QCloseEvent* event); diff --git a/MainWidget.ui b/MainWidget.ui index e84a98c..8a27ca9 100644 --- a/MainWidget.ui +++ b/MainWidget.ui @@ -147,7 +147,7 @@ - + 重新排序 diff --git a/public_def.cpp b/public_def.cpp index 97086ee..3a5ec0a 100644 --- a/public_def.cpp +++ b/public_def.cpp @@ -46,3 +46,25 @@ QString CUtil::select_file(QWidget* parent, const QString& info, const QString& QFileDialog::getOpenFileName(parent, info, QDir::homePath(), filter); return filePath; } + +void CUtil::sort_by_repeat(std::vector& vec) +{ + std::size_t len1 = 0; + std::size_t len2 = 0; + std::size_t cur = 0; + auto compare = [&](const std::string& str1, const std::string& str2) { + len1 = str1.size(); + len2 = str2.size(); + if (cur >= len1 || cur >= len2) { + return len1 > len2; + } + return str1[cur] > str2[cur]; + }; + std::size_t max_len = 0; + for (const auto& data : vec) { + max_len = data.size() > max_len ? data.size() : max_len; + } + for (cur = 0; cur < max_len; ++cur) { + std::sort(vec.begin(), vec.end(), compare); + } +} \ No newline at end of file diff --git a/public_def.h b/public_def.h index c959de7..8d947fb 100644 --- a/public_def.h +++ b/public_def.h @@ -23,6 +23,7 @@ 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 void sort_by_repeat(std::vector& vec); }; #endif diff --git a/src/xml_opr.cpp b/src/xml_opr.cpp index 6bde3ce..b7c1f74 100644 --- a/src/xml_opr.cpp +++ b/src/xml_opr.cpp @@ -52,6 +52,33 @@ bool CXmlOpr::parse_xml(std::vector& vec) return true; } +// 排序后(仅指针排序)的节点进行复制(让实际内容有序),删除原始节点 +void CXmlOpr::copy_and_del(std::vector& vec, std::vector& out) +{ + out.clear(); + // 先找到最后一个节点 + Element_t* last_node = parent_node_->LastChildElement(opr_base_.the_node.c_str()); + Element_t* last_node_bk = last_node; + if (last_node == nullptr) { + return; + } + for (const auto& data : vec) { + Element_t* n = copy_element(data); + out.push_back(n); + insert_brother_node(last_node, n); + last_node = n; + } + // 删除原有的节点 + Element_t* fnode = parent_node_->FirstChildElement(opr_base_.the_node.c_str()); + Element_t* fnext = fnode->NextSiblingElement(); + while (fnode != last_node_bk) { + parent_node_->DeleteChild(fnode); + fnode = fnext; + fnext = fnode->NextSiblingElement(); + } + parent_node_->DeleteChild(last_node_bk); +} + void CXmlOpr::insert_brother_node(Element_t* brother, Element_t* newer) { if (!brother || !newer) { diff --git a/src/xml_opr.h b/src/xml_opr.h index 4832c2c..61dca23 100644 --- a/src/xml_opr.h +++ b/src/xml_opr.h @@ -24,6 +24,7 @@ public: bool open(const std::string& xml_path); void set_baseinfo(const OprBase& base); bool parse_xml(std::vector& vec); + void copy_and_del(std::vector& vec, std::vector& out); void insert_brother_node(Element_t* brother, Element_t* newer); Element_t* copy_element(Element_t* ele); void del_element(Element_t* ele);