diff --git a/MainWidget.cpp b/MainWidget.cpp index 4f3166d..8b5855d 100644 --- a/MainWidget.cpp +++ b/MainWidget.cpp @@ -15,10 +15,14 @@ MainWidget::MainWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MainWidget ui->edStatus->setEnabled(false); ui->btnSave->setEnabled(false); + ui->btnCopySelectLine->setEnabled(false); + ui->btnDelSelectLine->setEnabled(false); connect(ui->btnRead, &QPushButton::clicked, this, [&]() { read(); }); connect(ui->btnSearch, &QPushButton::clicked, this, [&]() { search(); }); connect(ui->btnSave, &QPushButton::clicked, this, [&]() { save(); }); + connect(ui->btnCopySelectLine, &QPushButton::clicked, this, [&]() { copy_select_line(); }); + connect(ui->btnDelSelectLine, &QPushButton::clicked, this, [&]() { del_select_line(); }); } MainWidget::~MainWidget() @@ -51,6 +55,8 @@ 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); for (auto i = 0; i < keys.size(); ++i) { tab_widget_->setColumnWidth(i, width_[i]); @@ -109,6 +115,8 @@ void MainWidget::read() ui->btnRead->setEnabled(false); ui->btnSave->setEnabled(true); + ui->btnCopySelectLine->setEnabled(true); + ui->btnDelSelectLine->setEnabled(true); } void MainWidget::search() @@ -146,24 +154,72 @@ void MainWidget::item_changed_handle(QTableWidgetItem* item) int row = item->row(); int col = item->column(); - QString xml_key = tab_widget_->item(row, 0)->text(); - for (const auto& ele : current_) { - const char* data = ele->Attribute(keys_[0].c_str()); - QString qdata(data); - if (qdata != xml_key) { - continue; - } - ele->SetAttribute(keys_[col].c_str(), item->text().toLocal8Bit().constData()); - break; + QString xml_key = tab_widget_->item(row, 0)->text(); + element* result = get_element_bykey(xml_key); + if (result == nullptr) { + return; } + result->SetAttribute(keys_[col].c_str(), item->text().toLocal8Bit().constData()); } void MainWidget::save() { if (xml_.save()) { - QMessageBox::information(this, u8"提示", u8"保存成功"); - } - else { - QMessageBox::information(this, u8"提示", u8"保存失败"); + CUtil::msg(this, u8"保存成功"); + } else { + CUtil::msg(this, u8"保存失败"); } } + +void MainWidget::copy_select_line() +{ + element* target = get_current_select_key(); + if (target == nullptr) { + return; + } + element* newer = xml_.copy_element(target); + xml_.insert_brother_node(target, newer); + + // TODO: 添加到界面 + CUtil::msg(this, u8"已复制"); +} + +void MainWidget::del_select_line() +{ + element* target = get_current_select_key(); + if (target == nullptr) { + return; + } +} + +element* MainWidget::get_current_select_key() +{ + element* ret = nullptr; + if (tab_widget_ == nullptr) { + return ret; + } + QList selectedItems = tab_widget_->selectedItems(); + if (selectedItems.size() < 1) { + CUtil::msg(this, u8"没有选中数据"); + return ret; + } + QTableWidgetItem* item = selectedItems[0]; + int row = item->row(); + ret = get_element_bykey(item->text()); + return ret; +} + +tinyxml2::XMLElement* MainWidget::get_element_bykey(const QString& key) +{ + element* ret = nullptr; + for (const auto& ele : current_) { + const char* data = ele->Attribute(keys_[0].c_str()); + QString qdata(data); + if (qdata != key) { + continue; + } + ret = ele; + break; + } + return ret; +} diff --git a/MainWidget.h b/MainWidget.h index 39d99da..e3d967a 100644 --- a/MainWidget.h +++ b/MainWidget.h @@ -24,23 +24,30 @@ public: public: void set_work_exe(char* path); void generate_table_widget(); - void push_content(const std::vector& eles); + void push_content(const std::vector& eles); private: - void read(); - void search(); - void item_changed_handle(QTableWidgetItem *item); - void save(); + void read(); + void search(); + void item_changed_handle(QTableWidgetItem* item); + void save(); + void copy_select_line(); + void del_select_line(); + element* get_current_select_key(); + private: - Ui::MainWidget* ui; - ConfigIni ini_{}; - CXmlOpr xml_{}; - std::string exe_path_{}; - QTableWidget* tab_widget_{}; - std::vector vec_{}; - std::vector current_{}; - std::vector keys_{}; - std::vector width_{}; - bool auto_add_{false}; + element* get_element_bykey(const QString& key); + +private: + Ui::MainWidget* ui; + ConfigIni ini_{}; + CXmlOpr xml_{}; + std::string exe_path_{}; + QTableWidget* tab_widget_{}; + std::vector vec_{}; + std::vector current_{}; + std::vector keys_{}; + std::vector width_{}; + bool auto_add_{false}; }; #endif // MAINWIDGET_H diff --git a/MainWidget.ui b/MainWidget.ui index 7b27942..d2c261f 100644 --- a/MainWidget.ui +++ b/MainWidget.ui @@ -67,6 +67,20 @@ + + + + 复制选定行 + + + + + + + 删除选定行 + + + diff --git a/main.cpp b/main.cpp index ba5f177..4cf99c8 100644 --- a/main.cpp +++ b/main.cpp @@ -7,9 +7,9 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); #ifdef _WIN32 - QFont font("Microsoft YaHei", 10); + QFont font("Microsoft YaHei", 9); a.setFont(font); - a.setStyle("windows"); + a.setStyle("fusion"); #endif MainWidget w; diff --git a/public_def.cpp b/public_def.cpp index de5550b..c3365b8 100644 --- a/public_def.cpp +++ b/public_def.cpp @@ -1,4 +1,5 @@ #include "public_def.h" +#include std::vector splitString(const std::string& input, const std::string& delimiter) { std::vector tokens; @@ -15,4 +16,9 @@ std::vector splitString(const std::string& input, const std::string tokens.push_back(backup); return tokens; -} \ No newline at end of file +} + +void CUtil::msg(QWidget* parent, const QString& content) +{ + QMessageBox::information(parent, u8"提示", content); +} diff --git a/public_def.h b/public_def.h index d5cd3cc..e87c35f 100644 --- a/public_def.h +++ b/public_def.h @@ -3,6 +3,7 @@ #include #include +#include struct OprBase { std::string node_path{}; @@ -13,4 +14,13 @@ struct OprBase { std::vector splitString(const std::string& input, const std::string& delimiter); +class CUtil +{ +public: + CUtil() = default; + ~CUtil() = default; +public: + static void msg(QWidget* parent, const QString& content); +}; + #endif \ No newline at end of file diff --git a/src/xml_opr.cpp b/src/xml_opr.cpp index 18bf458..933d053 100644 --- a/src/xml_opr.cpp +++ b/src/xml_opr.cpp @@ -21,7 +21,6 @@ bool CXmlOpr::parse_xml(std::vector& vec) { std::string next_node{}; std::string node_path = opr_base_.node_path; - tinyxml2::XMLElement* node = nullptr; auto nodes = splitString(opr_base_.node_path, "/"); for (const auto& item : nodes) { @@ -30,15 +29,15 @@ bool CXmlOpr::parse_xml(std::vector& vec) continue; } - if (node == nullptr) { - node = doc_.FirstChildElement(item.c_str()); + if (parent_node_ == nullptr) { + parent_node_ = doc_.FirstChildElement(item.c_str()); } else { - node = node->FirstChildElement(item.c_str()); + parent_node_ = parent_node_->FirstChildElement(item.c_str()); } } vec.clear(); - tinyxml2::XMLElement* purpose_node = node->FirstChildElement(opr_base_.the_node.c_str()); + element* purpose_node = parent_node_->FirstChildElement(opr_base_.the_node.c_str()); while (purpose_node) { vec.push_back(purpose_node); @@ -47,6 +46,28 @@ bool CXmlOpr::parse_xml(std::vector& vec) return true; } +void CXmlOpr::insert_brother_node(element* brother, element* newer) +{ + if (!brother || !newer) { + return; + } + parent_node_->InsertAfterChild(brother, newer); +} + +element* CXmlOpr::copy_element(element* ele) +{ + if (!ele) { + return nullptr; + } + element* ret = doc_.NewElement(ele->Name()); + const auto* attribute = ele->FirstAttribute(); + while (attribute) { + ret->SetAttribute(attribute->Name(), attribute->Value()); + attribute = attribute->Next(); + } + return ret; +} + bool CXmlOpr::save() { auto ret = doc_.SaveFile(xml_path_.c_str()); diff --git a/src/xml_opr.h b/src/xml_opr.h index c7a65c6..1e916ef 100644 --- a/src/xml_opr.h +++ b/src/xml_opr.h @@ -6,6 +6,7 @@ #include #include "../public_def.h" +typedef tinyxml2::XMLElement element; class CXmlOpr { public: @@ -13,15 +14,18 @@ public: ~CXmlOpr(); public: - bool open(const std::string& xml_path); - void set_baseinfo(const OprBase& base); - bool parse_xml(std::vector& vec); - bool save(); + bool open(const std::string& xml_path); + void set_baseinfo(const OprBase& base); + bool parse_xml(std::vector& vec); + void insert_brother_node(element* brother, element* newer); + element* copy_element(element* ele); + bool save(); private: tinyxml2::XMLDocument doc_{}; OprBase opr_base_{}; std::string xml_path_{}; + element* parent_node_{}; }; #endif \ No newline at end of file