From cb5247e07c982b030c53f6e0feef5edf7703649f Mon Sep 17 00:00:00 2001 From: ispyisail Date: Wed, 30 Sep 2026 13:47:45 +1300 Subject: [PATCH] Place a template under the cursor, and list it as soon as it is saved A template (.qetmak) was previewed and placed offset from the cursor by the position its items had on the folio it was saved from: the preview pixmap kept that offset, and addMacro() added it back before handing the position to fromXml(). A template saved from the middle or the lower right of a folio therefore landed far below and to the right of the click, often off the folio, which reads as "the template does not drop" (forum topic 3190). Anchor both the preview and the placement on the template's own top-left corner instead. fromXml() skips translating for a null position, so a click on the folio origin is nudged by a fraction of a pixel that the grid snap removes. Also: - a template saved with "Create a template" only appeared in the templates tab after reloading the collections or restarting; it is now added to the tab of every open editor when it is saved; - the placement status bar message ended in an untranslated "(Makro-Anker)"; it now reads "x : y" like element placement. Co-Authored-By: Claude Opus 5.5 --- .../elementscollectionwidget.cpp | 12 ++++++++++++ .../elementscollectionwidget.h | 1 + sources/diagramevent/diagrameventaddmacro.cpp | 18 +++++++++++++++--- sources/diagramview.cpp | 4 ++++ sources/qetdiagrameditor.cpp | 11 +++++++++++ sources/qetdiagrameditor.h | 1 + 6 files changed, 44 insertions(+), 3 deletions(-) diff --git a/sources/ElementsCollection/elementscollectionwidget.cpp b/sources/ElementsCollection/elementscollectionwidget.cpp index 8183faaaa..0e9725ad6 100644 --- a/sources/ElementsCollection/elementscollectionwidget.cpp +++ b/sources/ElementsCollection/elementscollectionwidget.cpp @@ -172,6 +172,18 @@ void ElementsCollectionWidget::setCurrentLocation( m_model->indexFromLocation(location)); } +/** + @brief ElementsCollectionWidget::addTemplate + Show a newly saved template in the templates tab, which is otherwise + only read when the collections are loaded or reloaded. + @param location : the saved .qetmak file +*/ +void ElementsCollectionWidget::addTemplate(const ElementsLocation &location) +{ + if (m_macros_model && location.exist()) + m_macros_model->addLocation(location); +} + void ElementsCollectionWidget::leaveEvent(QEvent *event) { if (QETDiagramEditor *qde = QETApp::diagramEditorAncestorOf(this)) diff --git a/sources/ElementsCollection/elementscollectionwidget.h b/sources/ElementsCollection/elementscollectionwidget.h index 7c46a6e51..db6daa7dc 100644 --- a/sources/ElementsCollection/elementscollectionwidget.h +++ b/sources/ElementsCollection/elementscollectionwidget.h @@ -72,6 +72,7 @@ class ElementsCollectionWidget : public QWidget void removeProject (QETProject *project); void highlightUnusedElement(); void setCurrentLocation(const ElementsLocation &location); + void addTemplate(const ElementsLocation &location); QVector rankedSearch(const QString &text, const QModelIndex &within = QModelIndex()); diff --git a/sources/diagramevent/diagrameventaddmacro.cpp b/sources/diagramevent/diagrameventaddmacro.cpp index 6b629cb6d..ecdf7a007 100644 --- a/sources/diagramevent/diagrameventaddmacro.cpp +++ b/sources/diagramevent/diagrameventaddmacro.cpp @@ -88,7 +88,12 @@ m_preview_item(nullptr) dummy_diagram->render(&painter, QRectF(QPointF(0,0), scene_rect.size()), scene_rect); m_preview_item = new QGraphicsPixmapItem(pixmap); - m_preview_item->setOffset(scene_rect.topLeft()); + // Anchor the preview on the template's own top-left + // corner, where addMacro() puts it, not on the origin of + // the folio it was saved from: a template saved from the + // middle of a folio was otherwise shown, and placed, that + // far below and to the right of the cursor. + m_preview_item->setOffset(scene_rect.topLeft() - m_items_top_left); } } @@ -134,7 +139,7 @@ void DiagramEventAddMacro::mouseMoveEvent(QGraphicsSceneMouseEvent *event) m_preview_item->setPos(pos_); if (m_status_bar) { - m_status_bar->showMessage(QString("x %1 : y %2 (Makro-Anker)").arg(QString::number(pos_.x()), QString::number(pos_.y()))); + m_status_bar->showMessage(QString("x %1 : y %2").arg(QString::number(pos_.x()), QString::number(pos_.y()))); } } event->setAccepted(true); @@ -255,7 +260,14 @@ void DiagramEventAddMacro::addMacro(QPointF final_pos) QDomElement cloned_node = diagram_node.cloneNode(true).toElement(); DiagramContent pasted_content; - m_diagram->fromXml(cloned_node, final_pos + m_items_top_left, false, &pasted_content); + // fromXml() puts the template's top-left corner on final_pos, + // under the cursor. It skips that for a null position, which + // would leave the items where they were saved, so a click on + // the folio origin is nudged by less than it snaps away. + if (final_pos.isNull()) { + final_pos = QPointF(0.1, 0.1); + } + m_diagram->fromXml(cloned_node, final_pos, false, &pasted_content); m_diagram->refreshContents(); // Prevent PasteDiagramCommand from erasing labels (BMK) diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index d74e524b4..100001582 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -2086,6 +2086,10 @@ void DiagramView::createTemplateFromSelection() file.close(); qDebug() << "Template successfully saved to:" << full_path; + // List it right away, not only after the collections are reloaded + for (QETDiagramEditor *qde : QETApp::diagramEditors()) + qde->templateSaved(template_location); + QMessageBox::information(this, tr("Modèle enregistré"), tr("Le modèle a été enregistré avec succès sous :\n%1").arg(full_path)); } else { diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp index f08d00519..f826bbc52 100644 --- a/sources/qetdiagrameditor.cpp +++ b/sources/qetdiagrameditor.cpp @@ -1781,6 +1781,17 @@ ProjectView *QETDiagramEditor::currentProjectView() const return(nullptr); } +/** + @brief QETDiagramEditor::templateSaved + List a template saved from a folio in this editor's templates tab. + @param location : the saved .qetmak file +*/ +void QETDiagramEditor::templateSaved(const ElementsLocation &location) +{ + if (m_element_collection_widget) + m_element_collection_widget->addTemplate(location); +} + /** @brief QETDiagramEditor::currentProject @return the current edited project. diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h index ba35ea2f3..d8c59e29d 100644 --- a/sources/qetdiagrameditor.h +++ b/sources/qetdiagrameditor.h @@ -75,6 +75,7 @@ class QETDiagramEditor : public QETMainWindow ProjectView *viewForFile (const QString &) const; ProjectView *currentProjectView() const; QETProject *currentProject() const; + void templateSaved(const ElementsLocation &location); bool drawGrid() const; void openBackupFiles (QList backup_files);