#ifndef PERECHENTABLEMODEL_H #define PERECHENTABLEMODEL_H #include #include #include #include #include #include #include // Forward declaration class ComponentModel; // Forward declaration структуры для информации о переносе заголовков struct PageBreakInfo; // Структура для хранения данных ячейки struct PerechenCellData { QString value; // Значение ячейки int rowNumber; // Номер строки в документе int pageNumber; // Номер страницы bool isHeader; // Является ли заголовком bool isAutoGenerated; // Автоматически сгенерированное значение bool isEmpty; // Пустая ячейка int stretch; // Поджим по ширине (100 = нормальный, по умолчанию 100) bool isUnderline; // Подчеркивать ли текст (по умолчанию true для заголовков) PerechenCellData() : rowNumber(0), pageNumber(1), isHeader(false), isAutoGenerated(false), isEmpty(true), stretch(100), isUnderline(false) {} PerechenCellData(const QString &val, int row = 0, int page = 1, bool header = false, bool autoGen = false, bool empty = false, int cellStretch = 100, bool underline = false) : value(val), rowNumber(row), pageNumber(page), isHeader(header), isAutoGenerated(autoGen), isEmpty(empty), stretch(cellStretch), isUnderline(underline) {} }; // Структура для хранения строки таблицы struct PerechenRowData { PerechenCellData position; // Поз.обозначение PerechenCellData designation; // Наименование PerechenCellData quantity; // Кол. PerechenCellData note; // Примечание bool isHeader; // Является ли заголовком bool isEmpty; // Пустая строка int rowNumber; // Номер строки в документе int pageNumber; // Номер страницы PerechenRowData() : isHeader(false), isEmpty(false), rowNumber(0), pageNumber(1) {} }; class PerechenTableModel : public QAbstractTableModel { Q_OBJECT Q_PROPERTY(QStringList columnMappings READ columnMappings WRITE setColumnMappings NOTIFY columnMappingsChanged FINAL) public: explicit PerechenTableModel(QObject *parent = nullptr); // Константы для разбивки на страницы static const int ROWS_PER_FIRST_PAGE = 25; static const int ROWS_PER_OTHER_PAGE = 32; // Методы QAbstractTableModel int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, 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; // Методы для работы с данными void setColumnMappings(const QStringList &mappings); QStringList columnMappings() const; // Методы для работы со строками void addRow(const PerechenRowData &rowData); void insertRow(int position, const PerechenRowData &rowData); void removeRow(int row); void clear(); // Новые методы для управления строками void addEmptyRow(); void addEmptyRowAt(int position); PerechenRowData createEmptyRow() const; bool canEditRow(int row) const; // Методы для работы с компонентами void setComponents(const QList &components); // Методы для работы с настройками void setPropertyNames(const QStringList &propertyNames); QStringList availableProperties() const; // Методы для сохранения/загрузки QByteArray saveToDatabase() const; void loadFromDatabase(const QByteArray &data); // Методы для экспорта QString getDocumentTitle() const; QString getDocumentType() const; // Методы для проверки статуса строки bool isRowHeader(int row) const; // Метод для установки поджима ячейки bool setCellStretch(int row, int column, int stretch); // Метод для установки флага заголовка ячейки bool setCellHeader(int row, int column, bool isHeader); // Метод для установки флага подчеркивания ячейки bool setCellUnderline(int row, int column, bool isUnderline); // Метод для проверки переполнения ячейки (для подсветки в UI) bool isCellOverflow(int row, int column, qreal columnWidth, int fontSize = 12) const; // Метод для пометки ячейки как переполненной (вызывается из PDFController) void setCellOverflow(int row, int column, bool overflow); // Метод для очистки всех пометок о переполнении void clearOverflowMarks(); // Методы для работы с переносом страниц bool needsPageBreakProtection(int rowIndex) const; void addPageBreakProtection(); void optimizePageBreaks(); void updatePageDisplay(); // Новые методы для работы с разрывами страниц void updatePageNumbers(); void updateRowNumbers(); int getPageForRow(int rowNumber) const; signals: void columnMappingsChanged(); void modelDataChanged(); void requestPageBreakConfirmation(const QList &pageBreakInfos); private: void updateRowEmptyStatus(int row); PerechenCellData createCellData(const QString &value, bool isHeader = false, bool isAuto = false, bool isEmpty = false); QList m_rows; QStringList m_columnMappings; // Маппинг колонок на свойства компонентов QStringList m_propertyNames; // Доступные свойства компонентов QList m_components; // Компоненты для генерации QSet> m_overflowCells; // Множество переполненных ячеек (row, column) static const int COLUMN_COUNT = 4; static const QStringList DEFAULT_HEADERS; }; #endif // PERECHENTABLEMODEL_H