Add Element Text Format Painter tool

- Implement ElementTextFormatPattern to capture and reapply dynamic element text formats (font, color, alignment, rotation, frame, positions, groups) across elements.
- When applying a format, missing ElementInfo texts present on the source template are added to the target element with the template's layout and styling, matching other texts in order.
- Register actions under Edit menu, diagram context menu, and ShortcutManager (customizable via Toolbar settings).
- Bind default shortcuts Ctrl+Alt+C (copy text format) and Ctrl+Alt+V (apply text format).
- Provide full undo/redo support via ApplyElementTextFormatCommand.
- Add SVG icons format-copy and format-apply.
- Include English source strings and German/French translations.
This commit is contained in:
Itsego
2026-10-13 13:04:10 +02:00
parent b8dd03923a
commit 8d56d927e1
12 changed files with 984 additions and 1 deletions
+71
View File
@@ -53,6 +53,7 @@
#include "cable/editcablecommand.h"
#include "diagramevent/diagrameventaddpaste.h"
#include "diagramview.h"
#include "elementtextpattern.h"
#include "elementspanelwidget.h"
#include "factory/elementpicturefactory.h"
#include "factory/qetgraphicstablefactory.h"
@@ -469,6 +470,19 @@ void QETDiagramEditor::setUpActions()
connect(m_paste_element_info, &QAction::triggered,
this, &QETDiagramEditor::pasteElementInformations);
//Format painter actions
m_copy_text_format = new QAction(QET::Icons::CopyElementTextFormat, tr("Copy text format"), this);
m_apply_text_format = new QAction(QET::Icons::ApplyElementTextFormat, tr("Apply text format"), this);
ShortcutManager::instance().registerAction(m_copy_text_format, "diagrameditor.copy_text_format", tr("Diagram editors"), QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_C));
ShortcutManager::instance().registerAction(m_apply_text_format, "diagrameditor.apply_text_format", tr("Diagram editors"), QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_V));
m_copy_text_format -> setStatusTip(tr("Copy the text format of the selected element as a template", "status bar tip"));
m_apply_text_format -> setStatusTip(tr("Apply the copied text format to the selected elements", "status bar tip"));
connect(m_copy_text_format, &QAction::triggered, this, &QETDiagramEditor::copyTextFormat);
connect(m_apply_text_format, &QAction::triggered, this, &QETDiagramEditor::applyTextFormat);
//Duplicate: copy the selection and place it at a configured,
//grid-step offset immediately -- no interactive follow-the-
//cursor step, unlike Ctrl+V above. That is deliberate (#991):
@@ -1531,6 +1545,8 @@ void QETDiagramEditor::setUpMenu()
menu_edition -> addAction(m_cut);
menu_edition -> addAction(m_copy);
menu_edition -> addAction(m_paste);
menu_edition -> addAction(m_copy_text_format);
menu_edition -> addAction(m_apply_text_format);
menu_edition -> addAction(m_paste_origin);
menu_edition -> addAction(m_paste_element_info);
menu_edition -> addAction(m_duplicate);
@@ -2871,6 +2887,8 @@ void QETDiagramEditor::slot_updateComplexActions()
// number of selected elements
int selected_elements_count = dc.count(DiagramContent::Elements);
m_find_element->setEnabled(selected_elements_count == 1);
m_copy_text_format->setEnabled(selected_elements_count >= 1);
m_apply_text_format->setEnabled(!ro && selected_elements_count >= 1 && ElementTextFormatPattern::hasPattern());
m_mirror_horizontal->setEnabled(!ro && selected_elements_count);
m_mirror_vertical->setEnabled(!ro && selected_elements_count);
@@ -4690,3 +4708,56 @@ void QETDiagramEditor::updateTextGridButton()
//A divisor the menu does not offer, set by hand in the config file
m_text_grid_button->setText(tr("Texts %1").arg(TextGrid::ratioLabel(divisor)));
}
/**
* @brief QETDiagramEditor::copyTextFormat
* Copies the text/label layout and formatting from the currently selected element as a template.
*/
void QETDiagramEditor::copyTextFormat()
{
DiagramView *dv = currentDiagramView();
if (!dv || !dv->diagram()) return;
Element *sourceElmt = nullptr;
for (QGraphicsItem *item : dv->diagram()->selectedItems()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(item)) {
sourceElmt = elmt;
break;
}
}
if (!sourceElmt) return;
ElementTextFormatPattern pattern = ElementTextFormatPattern::fromElement(sourceElmt);
if (pattern.isValid()) {
ElementTextFormatPattern::setCurrentPattern(pattern);
slot_updateComplexActions();
statusBar()->showMessage(tr("Text format of \"%1\" copied").arg(sourceElmt->name()), 3000);
}
}
/**
* @brief QETDiagramEditor::applyTextFormat
* Applies the stored text formatting template to all selected elements in the active diagram.
*/
void QETDiagramEditor::applyTextFormat()
{
if (!ElementTextFormatPattern::hasPattern()) return;
DiagramView *dv = currentDiagramView();
if (!dv || !dv->diagram()) return;
if (dv->diagram()->isReadOnly()) return;
QList<Element *> targetElements;
for (QGraphicsItem *item : dv->diagram()->selectedItems()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(item)) {
targetElements.append(elmt);
}
}
if (targetElements.isEmpty()) return;
const ElementTextFormatPattern &pattern = ElementTextFormatPattern::currentPattern();
dv->diagram()->undoStack().push(new ApplyElementTextFormatCommand(targetElements, pattern));
statusBar()->showMessage(tr("Text format applied to %n element(s)", "", targetElements.size()), 3000);
}