From 6469683b4cca6aaae9d27e34c17b8f75a988fa81 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 30 Dec 2020 20:04:07 +0800 Subject: import(life): ... --- works/life/cpp-practicum/Record.cpp | 179 ++++++++++++++++++++++++++++++++++-- works/life/cpp-practicum/Record.hpp | 31 ++++++- works/life/cpp-practicum/main.cpp | 98 ++++++++++++++++---- 3 files changed, 279 insertions(+), 29 deletions(-) diff --git a/works/life/cpp-practicum/Record.cpp b/works/life/cpp-practicum/Record.cpp index 4d7d4a9..bdee28b 100644 --- a/works/life/cpp-practicum/Record.cpp +++ b/works/life/cpp-practicum/Record.cpp @@ -1,10 +1,8 @@ #include "Record.hpp" -void Record::WriteTo(QFile file) { - file.open(QFile::ReadWrite | QFile::Text | QFile::Truncate); - QTextStream stream(&file); - stream.setCodec("UTF-8"); +#include +void Record::WriteTo(QTextStream &stream) { stream << books_.size() << ' ' << vendors_.size() << '\n'; for (const auto &book : books_) { stream << book << '\n'; @@ -14,11 +12,7 @@ void Record::WriteTo(QFile file) { } } -void Record::ReadFrom(QFile file) { - file.open(QFile::ReadOnly | QFile::Text); - QTextStream stream(&file); - stream.setCodec("UTF-8"); - +void Record::ReadFrom(QTextStream &stream) { books_.clear(); vendors_.clear(); @@ -180,3 +174,170 @@ bool BookModel::removeRows(int row, int count, const QModelIndex &parent) { endRemoveRows(); return true; } + +void BookModel::sort(int column, Qt::SortOrder order) { + if (column == 0) { + beginResetModel(); + if (order == Qt::AscendingOrder) { + std::sort(record_->GetBooks().begin(), record_->GetBooks().end(), + [](const Book &left, const Book &right) { + return left.GetIsbn() < right.GetIsbn(); + }); + } else { + std::sort(record_->GetBooks().begin(), record_->GetBooks().end(), + [](const Book &left, const Book &right) { + return left.GetIsbn() > right.GetIsbn(); + }); + } + endResetModel(); + } else if (column == 1) { + beginResetModel(); + if (order == Qt::AscendingOrder) { + std::sort(record_->GetBooks().begin(), record_->GetBooks().end(), + [](const Book &left, const Book &right) { + return left.GetTitle() < right.GetTitle(); + }); + } else { + std::sort(record_->GetBooks().begin(), record_->GetBooks().end(), + [](const Book &left, const Book &right) { + return left.GetTitle() > right.GetTitle(); + }); + } + endResetModel(); + } +} + +int VendorModel::rowCount(const QModelIndex &parent) const { + if (parent.isValid()) + return 0; + return static_cast(record_->GetVendors().size()); +} + +int VendorModel::columnCount(const QModelIndex &parent) const { + if (parent.isValid()) + return 0; + return 5; +} + +QVariant VendorModel::headerData(int section, Qt::Orientation orientation, + int role) const { + if (role != Qt::DisplayRole) + return QVariant(); + if (orientation == Qt::Horizontal) { + switch (section) { + case 0: + return QStringLiteral("编号"); + case 1: + return QStringLiteral("名称"); + case 2: + return QStringLiteral("类型"); + case 3: + return QStringLiteral("地址"); + case 4: + return QStringLiteral("电话"); + default: + return QVariant(); + } + } + return QVariant(); +} + +QVariant VendorModel::data(const QModelIndex &index, int role) const { + if (role != Qt::DisplayRole) + return QVariant(); + + if (!index.isValid()) + return QVariant(); + + if (index.row() >= static_cast(record_->GetVendors().size()) || + index.row() < 0) + return QVariant(); + + int row = index.row(); + const Vendor &vendor = record_->GetVendors()[row]; + + int col = index.column(); + switch (col) { + case 0: + return vendor.GetId(); + case 1: + return QString::fromStdU16String(vendor.GetName()); + case 2: + return QString::fromStdU16String(vendor.GetType()); + case 3: + return QString::fromStdU16String(vendor.GetAddress()); + case 4: + return QString::fromStdU16String(vendor.GetPhone()); + default: + return QVariant(); + } +} + +bool VendorModel::setData(const QModelIndex &index, const QVariant &value, + int role) { + if (index.isValid() && role == Qt::EditRole) { + int row = index.row(); + Vendor &vendor = record_->GetVendors()[row]; + + int col = index.column(); + switch (col) { + case 0: + if (!value.canConvert()) + return false; + vendor.SetId(value.toInt()); + return true; + case 1: + if (!value.canConvert()) + return false; + vendor.SetName(value.toString().toStdU16String()); + emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole}); + return true; + case 2: + if (!value.canConvert()) + return false; + vendor.SetType(value.toString().toStdU16String()); + emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole}); + return true; + case 3: + if (!value.canConvert()) + return false; + vendor.SetAddress(value.toString().toStdU16String()); + emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole}); + return true; + case 4: + if (!value.canConvert()) + return false; + vendor.SetPhone(value.toString().toStdU16String()); + emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole}); + return true; + default: + return false; + } + } + return false; +} + +Qt::ItemFlags VendorModel::flags(const QModelIndex &index) const { + if (!index.isValid()) + return Qt::ItemIsEnabled; + + return QAbstractTableModel::flags(index) | Qt::ItemIsEditable; +} + +bool VendorModel::insertRows(int row, int count, const QModelIndex &parent) { + beginInsertRows(parent, row, row + count - 1); + for (int i = 0; i < count; i++) { + record_->GetVendors().insert(record_->GetVendors().cbegin() + row, + Vendor()); + } + endInsertRows(); + return true; +} + +bool VendorModel::removeRows(int row, int count, const QModelIndex &parent) { + beginRemoveRows(parent, row, row + count - 1); + record_->GetVendors().erase(record_->GetVendors().cbegin() + row, + record_->GetVendors().cbegin() + row + count); + endRemoveRows(); + return true; +} diff --git a/works/life/cpp-practicum/Record.hpp b/works/life/cpp-practicum/Record.hpp index 78b70ba..c379f04 100644 --- a/works/life/cpp-practicum/Record.hpp +++ b/works/life/cpp-practicum/Record.hpp @@ -5,7 +5,7 @@ #include "Vendor.hpp" #include -#include +#include #include #include @@ -19,8 +19,8 @@ public: ~Record() = default; public: - void WriteTo(QFile file); - void ReadFrom(QFile file); + void WriteTo(QTextStream &stream); + void ReadFrom(QTextStream &stream); std::vector &GetBooks() { return books_; } std::vector &GetVendors() { return vendors_; } @@ -47,7 +47,30 @@ public: const QModelIndex &parent = QModelIndex()) override; bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; private: Record *record_; -}; \ No newline at end of file +}; + +class VendorModel : public QAbstractTableModel { +public: + explicit VendorModel(Record *record) : record_(record) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex &index, + int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + bool insertRows(int row, int count, + const QModelIndex &parent = QModelIndex()) override; + bool removeRows(int row, int count, + const QModelIndex &parent = QModelIndex()) override; + +private: + Record *record_; +}; diff --git a/works/life/cpp-practicum/main.cpp b/works/life/cpp-practicum/main.cpp index 9ecc308..399c82c 100644 --- a/works/life/cpp-practicum/main.cpp +++ b/works/life/cpp-practicum/main.cpp @@ -1,6 +1,8 @@ #include "Record.hpp" #include +#include +#include #include #include #include @@ -8,49 +10,113 @@ #include #include #include +#include int main(int argc, char *argv[]) { QApplication application(argc, argv); + Record record; + + QDir app_dir(application.applicationDirPath()); + QFile data_file = app_dir.filePath("data.txt"); + std::unique_ptr stream; + if (data_file.exists()) { + data_file.open(QFile::ReadWrite); + stream.reset(new QTextStream(&data_file)); + stream->setCodec("UTF-8"); + try { + record.ReadFrom(*stream); + } catch (...) { + } + } else { + data_file.open(QFile::ReadWrite); + stream.reset(new QTextStream(&data_file)); + stream->setCodec("UTF-8"); + } + QWidget window; QVBoxLayout window_layout; window.setLayout(&window_layout); - QHBoxLayout top_bar; - window_layout.addLayout(&top_bar); + QHBoxLayout center_area; + window_layout.addLayout(¢er_area); - QPushButton import_button(QStringLiteral("导入")); - QPushButton export_button(QStringLiteral("导出")); - QPushButton add_book_button(QStringLiteral("添加书")); + QVBoxLayout book_area; + QVBoxLayout vendor_area; + center_area.addLayout(&book_area); + center_area.addLayout(&vendor_area); - top_bar.addWidget(&import_button); - top_bar.addWidget(&export_button); - top_bar.addStretch(1); - top_bar.addWidget(&add_book_button); + QHBoxLayout book_top_area; + QHBoxLayout vendor_top_area; + book_area.addLayout(&book_top_area); + vendor_area.addLayout(&vendor_top_area); - QHBoxLayout center_area; - window_layout.addLayout(¢er_area); + QPushButton book_add_button(QStringLiteral("添加")); + QPushButton book_remove_button(QStringLiteral("删除")); + + book_top_area.addStretch(1); + book_top_area.addWidget(&book_add_button); + book_top_area.addWidget(&book_remove_button); + + QPushButton vendor_add_button(QStringLiteral("添加")); + QPushButton vendor_remove_button(QStringLiteral("删除")); + + vendor_top_area.addStretch(1); + vendor_top_area.addWidget(&vendor_add_button); + vendor_top_area.addWidget(&vendor_remove_button); QTableView book_view; book_view.verticalHeader()->hide(); book_view.setSelectionBehavior(QAbstractItemView::SelectRows); book_view.setEditTriggers(QAbstractItemView::DoubleClicked); book_view.setSelectionMode(QAbstractItemView::SingleSelection); + book_view.setSortingEnabled(true); + QTableView vendor_view; + vendor_view.verticalHeader()->hide(); + vendor_view.setSelectionBehavior(QAbstractItemView::SelectRows); + vendor_view.setEditTriggers(QAbstractItemView::DoubleClicked); + vendor_view.setSelectionMode(QAbstractItemView::SingleSelection); - center_area.addWidget(&book_view); - center_area.addWidget(&vendor_view); + book_area.addWidget(&book_view, 1); + vendor_area.addWidget(&vendor_view, 1); - Record record; BookModel book_model(&record); + VendorModel vendor_model(&record); book_view.setModel(&book_model); + vendor_view.setModel(&vendor_model); - QObject::connect(&add_book_button, &QPushButton::clicked, [&book_model]() { + QObject::connect(&book_add_button, &QPushButton::clicked, [&book_model]() { book_model.insertRow(book_model.rowCount()); }); + QObject::connect( + &book_remove_button, &QPushButton::clicked, [&book_view, &book_model]() { + auto selected_rows = book_view.selectionModel()->selectedRows(); + for (const auto &row : selected_rows) { + book_model.removeRow(row.row()); + } + }); + + QObject::connect( + &vendor_add_button, &QPushButton::clicked, + [&vendor_model]() { vendor_model.insertRow(vendor_model.rowCount()); }); + + QObject::connect(&vendor_remove_button, &QPushButton::clicked, + [&vendor_view, &vendor_model]() { + auto selected_rows = + vendor_view.selectionModel()->selectedRows(); + for (const auto &row : selected_rows) { + vendor_model.removeRow(row.row()); + } + }); + window.show(); - return application.exec(); + int result = application.exec(); + + record.WriteTo(*stream); + + return result; } -- cgit v1.2.3