From 489676b155678ca5a3d44bc454dc79ff702bec60 Mon Sep 17 00:00:00 2001 From: ispyisail Date: Thu, 22 Oct 2026 22:55:34 +1300 Subject: [PATCH] Move a folio's border dimensions into the project database Adds a folio_border table and wires BorderTitleBlock's column/row grid (counts, widths, header sizes, display flags) through it, the same way folio_titleblock already covers the title block itself. Closes the one gap DB-ACCESSORS 4.6 found still living only in the folio's own XML. Co-Authored-By: Claude Sonnet 5 --- sources/bordertitleblock.cpp | 59 ++++++++++++++++---- sources/bordertitleblock.h | 27 +++++---- sources/dataBase/projectdatabase.cpp | 82 +++++++++++++++++++++++++++- sources/dataBase/projectdatabase.h | 8 +++ 4 files changed, 151 insertions(+), 25 deletions(-) diff --git a/sources/bordertitleblock.cpp b/sources/bordertitleblock.cpp index 8747aa674..380b034e8 100644 --- a/sources/bordertitleblock.cpp +++ b/sources/bordertitleblock.cpp @@ -345,6 +345,18 @@ const TitleBlockProperties *BorderTitleBlock::stored() const return nullptr; } +/** + @brief BorderTitleBlock::storedBorder + @return the properties the project's store holds for this folio's + border, or nullptr if it is not placed. +*/ +const BorderProperties *BorderTitleBlock::storedBorder() const +{ + if (projectDataBase *store = placedStore()) + return store->storedFolioBorder(m_owner_folio->uuid()); + return nullptr; +} + /** @brief BorderTitleBlock::setOwnerFolio @param folio : the folio this border and title block belongs to @@ -378,6 +390,17 @@ void BorderTitleBlock::storeTitleBlock() store->storeFolioTitleBlock(m_owner_folio->uuid(), localTitleBlock()); } +/** + @brief BorderTitleBlock::storeBorder + Write this folio's border properties to its project's store, once its + folio is placed: every change of them comes through here. +*/ +void BorderTitleBlock::storeBorder() +{ + if (projectDataBase *store = placedStore()) + store->storeFolioBorder(m_owner_folio->uuid(), exportBorder()); +} + /** @brief BorderTitleBlock::importTitleBlock @param ip the new properties of titleblock @@ -418,15 +441,19 @@ void BorderTitleBlock::importTitleBlock(const TitleBlockProperties &ip) */ BorderProperties BorderTitleBlock::exportBorder() { + //Read the members directly, not the getters: a folio placed in a + //project reads those back from the store, which storeBorder() is + //about to update from this very value -- going through them here + //would echo back the old stored value instead of the new one. BorderProperties bp; - bp.columns_count = columnsCount(); - bp.columns_width = columnsWidth(); - bp.columns_header_height = columnsHeaderHeight(); - bp.display_columns = columnsAreDisplayed(); - bp.rows_count = rowsCount(); - bp.rows_height = rowsHeight(); - bp.rows_header_width = rowsHeaderWidth(); - bp.display_rows = rowsAreDisplayed(); + bp.columns_count = columns_count_; + bp.columns_width = columns_width_; + bp.columns_header_height = columns_header_height_; + bp.display_columns = display_columns_; + bp.rows_count = rows_count_; + bp.rows_height = rows_height_; + bp.rows_header_width = rows_header_width_; + bp.display_rows = display_rows_; return(bp); } @@ -530,7 +557,10 @@ void BorderTitleBlock::displayTitleBlock(bool di) { void BorderTitleBlock::displayColumns(bool dc) { bool change = (dc != display_columns_); display_columns_ = dc; - if (change) emit(displayChanged()); + if (change) { + storeBorder(); + emit(displayChanged()); + } } /** @@ -541,7 +571,10 @@ void BorderTitleBlock::displayColumns(bool dc) { void BorderTitleBlock::displayRows(bool dr) { bool change = (dr != display_rows_); display_rows_ = dr; - if (change) emit(displayChanged()); + if (change) { + storeBorder(); + emit(displayChanged()); + } } /** @@ -831,6 +864,7 @@ void BorderTitleBlock::setColumnsCount(int nb_c) { if (nb_c == columnsCount()) return; columns_count_ = qMax(MIN_COLUMN_COUNT , nb_c); updateRectangles(); + storeBorder(); } /** @@ -850,6 +884,7 @@ void BorderTitleBlock::setColumnsWidth(const qreal &new_cw) { if (new_cw == columnsWidth()) return; columns_width_ = qMax(MIN_COLUMN_WIDTH , new_cw); updateRectangles(); + storeBorder(); } /** @@ -865,6 +900,7 @@ void BorderTitleBlock::setColumnsWidth(const qreal &new_cw) { void BorderTitleBlock::setColumnsHeaderHeight(const qreal &new_chh) { columns_header_height_ = qBound(qreal(5.0), new_chh, qreal(50.0)); updateRectangles(); + storeBorder(); } /** @@ -884,6 +920,7 @@ void BorderTitleBlock::setRowsCount(int nb_r) { if (nb_r == rowsCount()) return; rows_count_ = qMax(MIN_ROW_COUNT, nb_r); updateRectangles(); + storeBorder(); } /** @@ -903,6 +940,7 @@ void BorderTitleBlock::setRowsHeight(const qreal &new_rh) { if (new_rh == rowsHeight()) return; rows_height_ = qMax(MIN_ROW_HEIGHT, new_rh); updateRectangles(); + storeBorder(); } /** @@ -918,6 +956,7 @@ void BorderTitleBlock::setRowsHeight(const qreal &new_rh) { void BorderTitleBlock::setRowsHeaderWidth(const qreal &new_rhw) { rows_header_width_ = qBound(qreal(5.0), new_rhw, qreal(50.0)); updateRectangles(); + storeBorder(); } /** diff --git a/sources/bordertitleblock.h b/sources/bordertitleblock.h index 009089c75..e25a77ed1 100644 --- a/sources/bordertitleblock.h +++ b/sources/bordertitleblock.h @@ -52,29 +52,30 @@ class BorderTitleBlock : public QObject void draw(QPainter *painter); void drawDxf(QString &, int); - //METHODS TO GET DIMENSION + //METHODS TO GET DIMENSION. A folio placed in a project reads them + //from the project's store, any other from its own copy. //COLUMNS /// @return the number of columns - int columnsCount() const { return(columns_count_); } + int columnsCount() const { const BorderProperties *s = storedBorder(); return(s ? s->columns_count : columns_count_); } /// @return the columns width, in pixels - qreal columnsWidth() const { return(columns_width_); } + qreal columnsWidth() const { const BorderProperties *s = storedBorder(); return(s ? s->columns_width : columns_width_); } /// @return the total width of all columns, headers excluded qreal columnsTotalWidth() const { - return(columns_count_ * columns_width_); } + return(columnsCount() * columnsWidth()); } /// @return the column headers height, in pixels qreal columnsHeaderHeight() const { - return(columns_header_height_); } - + const BorderProperties *s = storedBorder(); return(s ? s->columns_header_height : columns_header_height_); } + //ROWS /// @return the number of rows - int rowsCount() const { return(rows_count_); } + int rowsCount() const { const BorderProperties *s = storedBorder(); return(s ? s->rows_count : rows_count_); } /// @return the rows height, in pixels - qreal rowsHeight() const { return(rows_height_); } + qreal rowsHeight() const { const BorderProperties *s = storedBorder(); return(s ? s->rows_height : rows_height_); } /// @return the total height of all rows, headers excluded qreal rowsTotalHeight() const { - return(rows_count_ * rows_height_); } + return(rowsCount() * rowsHeight()); } /// @return la rows header width, in pixels - qreal rowsHeaderWidth() const { return(rows_header_width_); } + qreal rowsHeaderWidth() const { const BorderProperties *s = storedBorder(); return(s ? s->rows_header_width : rows_header_width_); } /// @return the edge where title block is docked Qt::Edge titleBlockEdge() const { return(m_edge); } @@ -148,10 +149,10 @@ class BorderTitleBlock : public QObject return(display_titleblock_); } /// @return true si les entetes des colonnes sont affiches, /// false sinon - bool columnsAreDisplayed() const { return(display_columns_); } + bool columnsAreDisplayed() const { const BorderProperties *s = storedBorder(); return(s ? s->display_columns : display_columns_); } /// @return true si les entetes des lignes sont affiches, /// false sinon - bool rowsAreDisplayed() const { return(display_rows_); } + bool rowsAreDisplayed() const { const BorderProperties *s = storedBorder(); return(s ? s->display_rows : display_rows_); } /// @return true si la bordure est affichee, false sinon bool borderIsDisplayed() const { return(display_border_); } @@ -298,7 +299,9 @@ class BorderTitleBlock : public QObject Diagram *m_owner_folio = nullptr; TitleBlockProperties current() const; const TitleBlockProperties *stored() const; + const BorderProperties *storedBorder() const; projectDataBase *placedStore() const; void storeTitleBlock(); + void storeBorder(); }; #endif diff --git a/sources/dataBase/projectdatabase.cpp b/sources/dataBase/projectdatabase.cpp index dd848a9cf..8457febca 100644 --- a/sources/dataBase/projectdatabase.cpp +++ b/sources/dataBase/projectdatabase.cpp @@ -2666,6 +2666,24 @@ bool projectDataBase::createDataBase() qDebug() << " folio_titleblock_table query : " << query_.lastError(); } + //Create the folio_border table: the border/grid dimensions of + //every folio (the column/row reference grid, e.g. "A1", "B2"), the + //store each folio's border is written through + //(storeFolioBorder()). One row per folio. + if (!query_.exec(QStringLiteral( + "CREATE TABLE folio_border (" + "diagram_uuid VARCHAR(50) PRIMARY KEY NOT NULL, " + "columns_count INTEGER NOT NULL, " + "columns_width REAL NOT NULL, " + "columns_header_height REAL NOT NULL, " + "display_columns INTEGER NOT NULL, " + "rows_count INTEGER NOT NULL, " + "rows_height REAL NOT NULL, " + "rows_header_width REAL NOT NULL, " + "display_rows INTEGER NOT NULL)"))) { + qDebug() << " folio_border_table query : " << query_.lastError(); + } + //Create the conductor_properties table: the properties of every //wire placed in the project, as the attributes a saved wire carries, //the store wires write through (storeConductorProperties()). @@ -3579,33 +3597,91 @@ void projectDataBase::storeFolioTitleBlock(const QUuid &folio, const TitleBlockP } } +/** + @brief projectDataBase::storedFolioBorder + @return the stored border properties of the folio @p folio, or nullptr; + valid until the store next changes +*/ +const BorderProperties *projectDataBase::storedFolioBorder(const QUuid &folio) const +{ + auto it = m_folio_borders.constFind(folio); + return it == m_folio_borders.constEnd() ? nullptr : &it.value(); +} + +/** + @brief projectDataBase::storeFolioBorder + Store @p properties as the border of the folio @p folio, in the + folio_border table and the cache in front of it. +*/ +void projectDataBase::storeFolioBorder(const QUuid &folio, const BorderProperties &properties) +{ + if (folio.isNull()) return; + auto known = m_folio_borders.find(folio); + if (known != m_folio_borders.end() && *known == properties) return; + m_folio_borders.insert(folio, properties); + + const QString uuid = folio.toString(); + QSqlQuery remove(m_data_base); + remove.prepare(QStringLiteral("DELETE FROM folio_border WHERE diagram_uuid = :uuid")); + remove.bindValue(QStringLiteral(":uuid"), uuid); + if (!remove.exec()) { + qDebug() << "projectDataBase::storeFolioBorder remove error : " << remove.lastError(); + } + QSqlQuery insert(m_data_base); + insert.prepare(QStringLiteral( + "INSERT INTO folio_border (diagram_uuid, columns_count, columns_width, " + "columns_header_height, display_columns, rows_count, rows_height, " + "rows_header_width, display_rows) VALUES (:uuid, :cc, :cw, :chh, :dc, " + ":rc, :rh, :rhw, :dr)")); + insert.bindValue(QStringLiteral(":uuid"), uuid); + insert.bindValue(QStringLiteral(":cc"), properties.columns_count); + insert.bindValue(QStringLiteral(":cw"), properties.columns_width); + insert.bindValue(QStringLiteral(":chh"), properties.columns_header_height); + insert.bindValue(QStringLiteral(":dc"), properties.display_columns ? 1 : 0); + insert.bindValue(QStringLiteral(":rc"), properties.rows_count); + insert.bindValue(QStringLiteral(":rh"), properties.rows_height); + insert.bindValue(QStringLiteral(":rhw"), properties.rows_header_width); + insert.bindValue(QStringLiteral(":dr"), properties.display_rows ? 1 : 0); + if (!insert.exec()) { + qDebug() << "projectDataBase::storeFolioBorder insert error : " << insert.lastError(); + } +} + /** @brief projectDataBase::placeFolio - @p folio is now a folio of the project: its title block is stored under - its uuid. + @p folio is now a folio of the project: its title block and border are + stored under its uuid. */ void projectDataBase::placeFolio(Diagram *folio) { m_placed_folios.insert(folio->uuid(), folio); storeFolioTitleBlock(folio->uuid(), folio->border_and_titleblock.localTitleBlock()); + storeFolioBorder(folio->uuid(), folio->border_and_titleblock.exportBorder()); } /** @brief projectDataBase::unplaceFolio @p folio no longer holds @p uuid (it was removed, or its uuid changed): - the title block stored under it goes. + the title block and border stored under it go. */ void projectDataBase::unplaceFolio(Diagram *folio, const QUuid &uuid) { if (m_placed_folios.value(uuid) != folio) return; m_placed_folios.remove(uuid); m_folio_titleblocks.remove(uuid); + m_folio_borders.remove(uuid); QSqlQuery remove(m_data_base); remove.prepare(QStringLiteral("DELETE FROM folio_titleblock WHERE diagram_uuid = :uuid")); remove.bindValue(QStringLiteral(":uuid"), uuid.toString()); if (!remove.exec()) { qDebug() << "projectDataBase::unplaceFolio error : " << remove.lastError(); } + QSqlQuery remove_border(m_data_base); + remove_border.prepare(QStringLiteral("DELETE FROM folio_border WHERE diagram_uuid = :uuid")); + remove_border.bindValue(QStringLiteral(":uuid"), uuid.toString()); + if (!remove_border.exec()) { + qDebug() << "projectDataBase::unplaceFolio border error : " << remove_border.lastError(); + } } /** diff --git a/sources/dataBase/projectdatabase.h b/sources/dataBase/projectdatabase.h index 6bc7c9112..8408ca351 100644 --- a/sources/dataBase/projectdatabase.h +++ b/sources/dataBase/projectdatabase.h @@ -34,6 +34,7 @@ #include "../diagramcontext.h" #include "../titleblockproperties.h" +#include "../borderproperties.h" #include "../conductorproperties.h" #include "../autoNum/assignvariables.h" #include "../autoNum/numerotationcontext.h" @@ -147,6 +148,12 @@ class projectDataBase : public QObject void folioUuidChanged(Diagram *folio, const QUuid &old_uuid); QStringList folioTitleBlockMismatches() const; + //The border properties of every folio of the project, by folio + //uuid: the store each folio's border is written through. A + //folio not in a project keeps its own. + const BorderProperties *storedFolioBorder(const QUuid &folio) const; + void storeFolioBorder(const QUuid &folio, const BorderProperties &properties); + //The properties of every wire placed in the project, by wire //uuid: the store each wire's properties are written through //A wire not placed keeps its own. @@ -422,6 +429,7 @@ class projectDataBase : public QObject struct UnbuiltWireEdit { ConductorProperties properties; QUuid folio; }; QHash m_unbuilt_wire_edits; QHash m_folio_titleblocks; + QHash m_folio_borders; QHash> m_placed_folios; QHash m_conductor_properties; //The rows of conductor_properties, to write only what changes