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);