diff options
Diffstat (limited to 'works')
| -rw-r--r-- | works/life/cpp-practicum/Record.cpp | 179 | ||||
| -rw-r--r-- | works/life/cpp-practicum/Record.hpp | 31 | ||||
| -rw-r--r-- | 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 <algorithm>
 +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<int>(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<int>(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<int>())
 +        return false;
 +      vendor.SetId(value.toInt());
 +      return true;
 +    case 1:
 +      if (!value.canConvert<QString>())
 +        return false;
 +      vendor.SetName(value.toString().toStdU16String());
 +      emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
 +      return true;
 +    case 2:
 +      if (!value.canConvert<QString>())
 +        return false;
 +      vendor.SetType(value.toString().toStdU16String());
 +      emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
 +      return true;
 +    case 3:
 +      if (!value.canConvert<QString>())
 +        return false;
 +      vendor.SetAddress(value.toString().toStdU16String());
 +      emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
 +      return true;
 +    case 4:
 +      if (!value.canConvert<QString>())
 +        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 <QAbstractTableModel>
 -#include <QFile>
 +#include <QTextStream>
  #include <optional>
  #include <vector>
 @@ -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<Book> &GetBooks() { return books_; }
    std::vector<Vendor> &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 <QApplication>
 +#include <QDir>
 +#include <QFile>
  #include <QHBoxLayout>
  #include <QHeaderView>
  #include <QMainWindow>
 @@ -8,49 +10,113 @@  #include <QTableView>
  #include <QVBoxLayout>
  #include <QWidget>
 +#include <memory>
  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<QTextStream> 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;
  }
 | 
