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 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-09-30 13:47:45 +13:00
parent 63196bf4ac
commit cb5247e07c
6 changed files with 44 additions and 3 deletions
@@ -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))
@@ -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<ElementSearchHit> rankedSearch(const QString &text,
const QModelIndex &within = QModelIndex());
+15 -3
View File
@@ -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)
+4
View File
@@ -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 {
+11
View File
@@ -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.
+1
View File
@@ -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<KAutoSaveFile *> backup_files);