From 87625e8bc46fe595297d9d4fc80249a9adf1ef06 Mon Sep 17 00:00:00 2001
From: taynpg <taynpg@163.com>
Date: Tue, 20 Aug 2024 16:47:09 +0800
Subject: [PATCH] =?UTF-8?q?change=EF=BC=9A=E6=9B=B4=E6=94=B9=E4=BB=A5key?=
 =?UTF-8?q?=E7=9A=84=E5=89=8D=E4=BA=9B=E9=83=A8=E5=88=86=E6=8E=92=E5=BA=8F?=
 =?UTF-8?q?=E8=80=8C=E4=B8=8D=E6=98=AF=E5=85=A8=E9=83=A8=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .clang-format         |  35 +++--------
 .vscode/settings.json |  18 +++++-
 CMakeLists.txt        |   7 ---
 MainWidget.cpp        | 141 +++++++++++++++++++++---------------------
 MainWidget.h          |   4 ++
 5 files changed, 98 insertions(+), 107 deletions(-)

diff --git a/.clang-format b/.clang-format
index c13b964..9d7a6b0 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,38 +1,17 @@
-# .clang-format
-
-# 风格格式化
-BasedOnStyle: LLVM 
-# 4 空格缩进
-IndentWidth: 4 
-# 连续对齐变量的声明
-AlignConsecutiveDeclarations: true
-# 指针左侧对齐
-PointerAlignment: Left 
-# 访问说明符(public、private等)的偏移
+BasedOnStyle: Google
+IndentWidth: 4
+PointerAlignment: Left
 AccessModifierOffset: -4
-# 大括号
 BreakBeforeBraces: Custom
 BraceWrapping:
-    # 函数定义后面大括号在新行
     AfterFunction: true
-    # class定义后面
     AfterClass: true
-    
-# 去除C++11的列表初始化的大括号{后和}前的空格
 Cpp11BracedListStyle: true
-# 允许重新排版注释
 ReflowComments: true
-# 允许排序#include
-SortIncludes: false
-# 在尾随的评论前添加的空格数(只适用于//)
 SpacesBeforeTrailingComments: 3
-# tab宽度
 TabWidth: 4
-# 构造函数的初始化列表要么都在同一行,要么都各自一行
 ConstructorInitializerAllOnOneLineOrOnePerLine: true
-# 每行字符的限制,0表示没有限制
-ColumnLimit: 110
-# 允许短的块放在同一行
-AllowShortBlocksOnASingleLine: false
-# 是否允许短函数在一行
-AllowShortFunctionsOnASingleLine: InlineOnly
\ No newline at end of file
+ColumnLimit: 150
+AllowShortBlocksOnASingleLine: Never
+AllowShortFunctionsOnASingleLine: None
+AllowShortEnumsOnASingleLine: false
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 93b07de..f074984 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,7 +1,7 @@
 {
     "files.autoSave": "onFocusChange",
     "editor.fontSize": 14,
-    "editor.fontFamily": "'Cousine Nerd Font Mono', 'IBM Plex Mono', 'MIBM Plex Mono'",
+    "editor.fontFamily": "'BlexMono Nerd Font Mono', 'BlexMono Nerd Font Mono', 'BlexMono Nerd Font Mono'",
     "cmake.configureOnOpen": true,
     "cmake.debugConfig": {
         "console": "integratedTerminal",
@@ -101,6 +101,20 @@
         "qaction": "cpp",
         "codecvt": "cpp",
         "qregexp": "cpp",
-        "qregularexpression": "cpp"
+        "qregularexpression": "cpp",
+        "array": "cpp",
+        "bit": "cpp",
+        "charconv": "cpp",
+        "clocale": "cpp",
+        "compare": "cpp",
+        "concepts": "cpp",
+        "condition_variable": "cpp",
+        "format": "cpp",
+        "forward_list": "cpp",
+        "future": "cpp",
+        "optional": "cpp",
+        "sstream": "cpp",
+        "stop_token": "cpp",
+        "regex": "cpp"
     }
 }
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb835b9..3970745 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,19 +2,12 @@ cmake_minimum_required(VERSION 3.5)
 
 project(OneLevelXmlOpr VERSION 0.1 LANGUAGES CXX)
 
-# 获取环境变量 HOME
-if (DEFINED ENV{HOME})
-    set(USER_HOME $ENV{HOME})
-else()
-    message(FATAL_ERROR "HOME environment variable is not set.")
-endif()
 
 # 打印用户目录
 message(STATUS "User home directory: ${USER_HOME}")
 
 set(CMAKE_PREFIX_PATH
     "C:/Qt/6.6.3/msvc2019_64"
-    "${USER_HOME}/Qt5.14.2/5.14.2/gcc_64/"
 )
 
 set(CMAKE_AUTOUIC ON)
diff --git a/MainWidget.cpp b/MainWidget.cpp
index 92e0d92..29ee01a 100644
--- a/MainWidget.cpp
+++ b/MainWidget.cpp
@@ -1,14 +1,17 @@
 #include "MainWidget.h"
+
 #include <QClipboard>
-#include <QSettings>
+#include <QDateTime>
 #include <QFile>
 #include <QKeyEvent>
-#include <QDateTime>
-#include <QScreen>
 #include <QRegularExpression>
+#include <QScreen>
+#include <QSettings>
 #include <filesystem>
-#include "src/data_edit.h"
+#include <regex>
+
 #include "./ui_MainWidget.h"
+#include "src/data_edit.h"
 
 constexpr std::size_t g_OnePage = 100;
 namespace fs = std::filesystem;
@@ -16,11 +19,11 @@ MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget
 {
     ui->setupUi(this);
 
-    setWindowTitle(u8"OneLevelXmlOpr v1.2.17");
+    setWindowTitle(u8"OneLevelXmlOpr v1.2.18");
     setWindowIcon(QIcon("://resource/xml.ico"));
 
     QScreen* primaryScreen = QGuiApplication::primaryScreen();
-    QRect    screenGeometry = primaryScreen->geometry();
+    QRect screenGeometry = primaryScreen->geometry();
 
     setBaseSize(screenGeometry.width() * 0.6, screenGeometry.height() * 0.9);
 
@@ -103,10 +106,10 @@ MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget
     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());
+        qApp->setStyleSheet(qss_file.readAll());
     }
 
     init_menu();
@@ -144,11 +147,11 @@ void MainWidget::closeEvent(QCloseEvent* event)
 void MainWidget::keyPressEvent(QKeyEvent* event)
 {
     switch (event->key()) {
-    case Qt::Key_Return:
-        search(ui->edSearchKey->text());
-        break;
-    default:
-        break;
+        case Qt::Key_Return:
+            search(ui->edSearchKey->text());
+            break;
+        default:
+            break;
     }
     QWidget::keyPressEvent(event);
 }
@@ -185,8 +188,7 @@ void MainWidget::generate_table_widget()
     metrics_ = std::make_shared<QFontMetrics>(tab_widget_->font());
     tab_widget_->setContextMenuPolicy(Qt::CustomContextMenu);
 
-    connect(tab_widget_, &QTableWidget::itemChanged, this,
-            [&](QTableWidgetItem* item) { item_changed_handle(item); });
+    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 = CUtil::splitString(config.purpose, ",");
@@ -341,7 +343,7 @@ void MainWidget::search(const QString& key)
     for (const auto& item : vec_) {
         for (auto i = 0; i < keys_.size(); ++i) {
             const char* data = item->Attribute(keys_[i].c_str());
-            QString     qdata(data);
+            QString qdata(data);
             if (!ui->cbCaseSensitive->isChecked()) {
                 qdata = qdata.toUpper();
             }
@@ -366,7 +368,7 @@ void MainWidget::item_changed_handle(QTableWidgetItem* item)
     int row = item->row();
     int col = item->column();
 
-    QString    xml_key = tab_widget_->item(row, 0)->text();
+    QString xml_key = tab_widget_->item(row, 0)->text();
     Element_t* result = get_element_by_key(xml_key);
     if (result == nullptr) {
         return;
@@ -457,7 +459,6 @@ bool MainWidget::edit_property(Element_t* target, int row)
     return true;
 }
 
-
 // ele_update_gui 的 row 参数暂时废弃,无意义。
 void MainWidget::ele_update_gui(Element_t* target, int row)
 {
@@ -482,7 +483,7 @@ void MainWidget::ele_update_gui(Element_t* target, int row)
 
     for (auto i = 0; i < keys_.size(); ++i) {
         const char* v = target->Attribute(keys_[i].c_str());
-        auto*       qitem = tab_widget_->item(target_row, i);
+        auto* qitem = tab_widget_->item(target_row, i);
         qitem->setText(QString(v));
     }
 }
@@ -526,7 +527,7 @@ void MainWidget::insert_one_line(Element_t* ele, int row)
         return;
     }
     for (auto i = 0; i < keys_.size(); ++i) {
-        const char*       data = ele->Attribute(keys_[i].c_str());
+        const char* data = ele->Attribute(keys_[i].c_str());
         QTableWidgetItem* wgItem = new QTableWidgetItem();
 
         if (i == 0) {
@@ -535,8 +536,8 @@ void MainWidget::insert_one_line(Element_t* ele, int row)
             // wgItem->setCheckState(Qt::Checked);
         }
         QString sda(data);
-        int     dwidth = metrics_->horizontalAdvance(sda) + blank_with_;
-        int     need_set_width = dwidth > allow_max_with_ ? allow_max_with_ : dwidth;
+        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];
         wgItem->setText(sda);
         tab_widget_->setItem(row, i, wgItem);
@@ -549,8 +550,8 @@ void MainWidget::del_select_line()
         return;
     }
 
-    QModelIndexList  indexList = tab_widget_->selectionModel()->selectedRows();
-    int              size = indexList.size();
+    QModelIndexList indexList = tab_widget_->selectionModel()->selectedRows();
+    int size = indexList.size();
     std::vector<int> erase_row;
     for (auto i = size - 1; i > -1; --i) {
         Element_t* target = get_element_by_row(indexList[i].row());
@@ -577,7 +578,7 @@ void MainWidget::del_select_line()
 
 Element_t* MainWidget::get_current_select_key()
 {
-    Element_t*        ret = nullptr;
+    Element_t* ret = nullptr;
     QTableWidgetItem* item = get_current_select_item();
     if (item == nullptr) {
         return ret;
@@ -613,7 +614,7 @@ tinyxml2::XMLElement* MainWidget::get_element_by_key(const QString& key)
     Element_t* ret = nullptr;
     for (const auto& ele : current_) {
         const char* data = ele->Attribute(keys_[0].c_str());
-        QString     qdata(data);
+        QString qdata(data);
         if (qdata != key) {
             continue;
         }
@@ -636,27 +637,13 @@ Element_t* MainWidget::get_element_by_row(int row)
 
 void MainWidget::sort_by_repeat(std::vector<Element_t*>& vec)
 {
-
     std::vector<SElement_t> turn_vec{};
     for (const auto& item : vec) {
         const char* str = item->Attribute(keys_[0].c_str());
         std::string d(str);
         turn_vec.emplace_back(item, d);
     }
-
-    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);
+    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);
@@ -712,7 +699,7 @@ void MainWidget::replace_content(bool is_common)
         return;
     }
     auto handle = [&](const std::vector<OperElement*>& vec, bool is_search) {
-        //qDebug() << "要处理的数量为:" << vec.size();
+        // qDebug() << "要处理的数量为:" << vec.size();
         for (auto& item : vec) {
             if (is_common) {
                 replace_str(key, after, item->element_);
@@ -764,7 +751,7 @@ void MainWidget::replace_str(const QString& pre, const QString& after, Element_t
         return;
     }
     for (auto i = 0; i < keys_.size(); ++i) {
-        auto*   value = ele->Attribute(keys_[i].c_str());
+        auto* value = ele->Attribute(keys_[i].c_str());
         QString content(value);
         if (content.contains(pre)) {
             content.replace(pre, after);
@@ -780,12 +767,12 @@ void MainWidget::replace_str(Element_t* ele, const QString& rg, const QString& a
         return;
     }
     for (auto i = 0; i < keys_.size(); ++i) {
-        auto*   value = ele->Attribute(keys_[i].c_str());
+        auto* value = ele->Attribute(keys_[i].c_str());
         QString content(value);
         // qDebug() << content;
         content.replace(rx, after);
-        //qDebug() << content;
-        //qDebug() << "\n";
+        // qDebug() << content;
+        // qDebug() << "\n";
         ele->SetAttribute(keys_[i].c_str(), content.toStdString().c_str());
     }
 }
@@ -795,32 +782,30 @@ void MainWidget::get_related_elements(std::vector<OperElement*>& out, ReplaceAre
     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); });
-        break;
-    }
-    case AREA_CUR_PAGE: {
-        int rows = tab_widget_->rowCount();
-        for (int i = 0; i < rows; ++i) {
-            out.emplace_back(new OperElement(get_element_by_row(i), i));
+        case AREA_ALL_PAGE: {
+            out.resize(current_.size());
+            std::transform(current_.begin(), current_.end(), out.begin(), [](Element_t* ele) { return new OperElement(ele, 0); });
+            break;
         }
-        break;
-    }
-    case AREA_ALL: {
-        out.resize(vec_.size());
-        std::transform(vec_.begin(), vec_.end(), out.begin(),
-                       [](Element_t* ele) { return new OperElement(ele, 0); });
-        break;
-    }
-    default: {
-        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()));
+        case AREA_CUR_PAGE: {
+            int rows = tab_widget_->rowCount();
+            for (int i = 0; i < rows; ++i) {
+                out.emplace_back(new OperElement(get_element_by_row(i), i));
+            }
+            break;
+        }
+        case AREA_ALL: {
+            out.resize(vec_.size());
+            std::transform(vec_.begin(), vec_.end(), out.begin(), [](Element_t* ele) { return new OperElement(ele, 0); });
+            break;
+        }
+        default: {
+            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()));
+            }
+            break;
         }
-        break;
-    }
     }
 }
 
@@ -838,6 +823,22 @@ void MainWidget::backup_file()
     }
 }
 
+std::string MainWidget::extract_prefix(const std::string& name)
+{
+    auto pos = name.find('.');
+    return (pos == std::string::npos) ? name : name.substr(0, pos);
+}
+
+bool MainWidget::compare_by_prefix(const SElement_t& se1, const SElement_t& se2)
+{
+    std::string a = extract_prefix(se1.str);
+    std::string b = extract_prefix(se2.str);
+    if (a != b) {
+        return a < b;
+    }
+    return se1.str < se2.str;   // 按照原始顺序排序
+}
+
 OperElement::OperElement(Element_t* ele, int row)
 {
     element_ = ele;
diff --git a/MainWidget.h b/MainWidget.h
index 3e23958..5e13db3 100644
--- a/MainWidget.h
+++ b/MainWidget.h
@@ -65,6 +65,10 @@ private:
     void replace_content(bool is_common = true);
     void backup_file();
 
+private:
+    std::string extract_prefix(const std::string& name);
+    bool compare_by_prefix(const SElement_t& se1, const SElement_t& se2);
+
 protected:
     void closeEvent(QCloseEvent* event);
     void keyPressEvent(QKeyEvent* event);