diff --git a/cmake/qet_compilation_vars.cmake b/cmake/qet_compilation_vars.cmake
index eebec6489..44a3186cb 100644
--- a/cmake/qet_compilation_vars.cmake
+++ b/cmake/qet_compilation_vars.cmake
@@ -386,6 +386,8 @@ set(QET_SRC_FILES
${QET_DIR}/sources/autobreakconductor.cpp
${QET_DIR}/sources/autobreakconductor.h
+ ${QET_DIR}/sources/symboltextplacement.cpp
+ ${QET_DIR}/sources/symboltextplacement.h
${QET_DIR}/sources/diagramevent/diagrameventaddelement.cpp
${QET_DIR}/sources/diagramevent/diagrameventaddelement.h
diff --git a/lang/qet_ar.ts b/lang/qet_ar.ts
index 70f4baf34..558ba8c2a 100644
--- a/lang/qet_ar.ts
+++ b/lang/qet_ar.ts
@@ -11972,6 +11972,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ وضع نصوص الرمز
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ وضع التسمية والملاحظات للرموز المحددة ككتلة واحدة بجانبها
+
+
+
+ Above, left
+ أعلى، يسار
+
+
+
+ Above
+ أعلى
+
+
+
+ Above, right
+ أعلى، يمين
+
+
+
+ Left
+ يسار
+
+
+
+ On the symbol
+ على الرمز
+
+
+
+ Right
+ يمين
+
+
+
+ Below, left
+ أسفل، يسار
+
+
+
+ Below
+ أسفل
+
+
+
+ Below, right
+ أسفل، يمين
+
@@ -24776,4 +24832,12 @@ The following variables can be used:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ وضع نصوص الرمز
+
+
diff --git a/lang/qet_ca.ts b/lang/qet_ca.ts
index 3a1cf99e5..1ba3ea190 100644
--- a/lang/qet_ca.ts
+++ b/lang/qet_ca.ts
@@ -12054,6 +12054,62 @@ Opcions disponibles:
QETDiagramEditor
+
+
+ Place symbol texts
+ Col·locar els textos del símbol
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Col·loca l'etiqueta i les notes dels símbols seleccionats com un sol bloc al costat
+
+
+
+ Above, left
+ A dalt, a l'esquerra
+
+
+
+ Above
+ A dalt
+
+
+
+ Above, right
+ A dalt, a la dreta
+
+
+
+ Left
+ Esquerra
+
+
+
+ On the symbol
+ Sobre el símbol
+
+
+
+ Right
+ Dreta
+
+
+
+ Below, left
+ A baix, a l'esquerra
+
+
+
+ Below
+ A baix
+
+
+
+ Below, right
+ A baix, a la dreta
+
@@ -24823,4 +24879,12 @@ associar el nom "volta" amb el valor "1745" substituirà %{v
Què :
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Col·locar els textos del símbol
+
+
diff --git a/lang/qet_cs.ts b/lang/qet_cs.ts
index 47a96f8b9..f37ca087d 100644
--- a/lang/qet_cs.ts
+++ b/lang/qet_cs.ts
@@ -12069,6 +12069,62 @@ Dostupné volby:
QETDiagramEditor
+
+
+ Place symbol texts
+ Umístit texty symbolu
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Umístí označení a poznámky vybraných symbolů jako jeden blok vedle nich
+
+
+
+ Above, left
+ Nahoře vlevo
+
+
+
+ Above
+ Nahoře
+
+
+
+ Above, right
+ Nahoře vpravo
+
+
+
+ Left
+ Vlevo
+
+
+
+ On the symbol
+ Na symbolu
+
+
+
+ Right
+ Vpravo
+
+
+
+ Below, left
+ Dole vlevo
+
+
+
+ Below
+ Dole
+
+
+
+ Below, right
+ Dole vpravo
+ Displ&ay
@@ -24871,4 +24927,12 @@ Přiřazení názvu "volta" a hodnoty "1745" v záhlaví vý
Co:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Umístit texty symbolu
+
+
diff --git a/lang/qet_da.ts b/lang/qet_da.ts
index 51cad3a5b..38f41e744 100644
--- a/lang/qet_da.ts
+++ b/lang/qet_da.ts
@@ -11921,6 +11921,62 @@ Kommandovalg:
QETDiagramEditor
+
+
+ Place symbol texts
+ Placer symboltekster
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Placerer mærkat og noter for de valgte symboler som én blok ved siden af dem
+
+
+
+ Above, left
+ Over, til venstre
+
+
+
+ Above
+ Over
+
+
+
+ Above, right
+ Over, til højre
+
+
+
+ Left
+ Venstre
+
+
+
+ On the symbol
+ På symbolet
+
+
+
+ Right
+ Højre
+
+
+
+ Below, left
+ Under, til venstre
+
+
+
+ Below
+ Under
+
+
+
+ Below, right
+ Under, til højre
+ Displ&ay
@@ -24552,4 +24608,12 @@ Eksempel: forbind navn "volta" og værdi "1745" erstat %{vol
Hvad:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Placer symboltekster
+
+
diff --git a/lang/qet_de.ts b/lang/qet_de.ts
index bad84db1e..747912959 100644
--- a/lang/qet_de.ts
+++ b/lang/qet_de.ts
@@ -12040,6 +12040,62 @@ Verfügbare Optionen:
QETDiagramEditor
+
+
+ Place symbol texts
+ Symboltexte platzieren
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Setzt BMK und Anmerkungen der ausgewählten Symbole als einen Block neben das Symbol
+
+
+
+ Above, left
+ Oben links
+
+
+
+ Above
+ Oben
+
+
+
+ Above, right
+ Oben rechts
+
+
+
+ Left
+ Links
+
+
+
+ On the symbol
+ Auf dem Symbol
+
+
+
+ Right
+ Rechts
+
+
+
+ Below, left
+ Unten links
+
+
+
+ Below
+ Unten
+
+
+
+ Below, right
+ Unten rechts
+ Copy text format
@@ -24876,4 +24932,12 @@ die Variable "volta" kombiniert mit dem Wert "1745" lässt i
Was:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Symboltexte platzieren
+
+
diff --git a/lang/qet_el.ts b/lang/qet_el.ts
index 294546ad7..73f0aaf39 100644
--- a/lang/qet_el.ts
+++ b/lang/qet_el.ts
@@ -12012,6 +12012,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Τοποθέτηση κειμένων συμβόλου
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Τοποθετεί την ετικέτα και τις σημειώσεις των επιλεγμένων συμβόλων ως ένα μπλοκ δίπλα τους
+
+
+
+ Above, left
+ Πάνω, αριστερά
+
+
+
+ Above
+ Πάνω
+
+
+
+ Above, right
+ Πάνω, δεξιά
+
+
+
+ Left
+ Αριστερά
+
+
+
+ On the symbol
+ Πάνω στο σύμβολο
+
+
+
+ Right
+ Δεξιά
+
+
+
+ Below, left
+ Κάτω, αριστερά
+
+
+
+ Below
+ Κάτω
+
+
+
+ Below, right
+ Κάτω, δεξιά
+ Displ&ay
@@ -24747,4 +24803,12 @@ The following variables can be used:
Τι:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Τοποθέτηση κειμένων συμβόλου
+
+
diff --git a/lang/qet_en.ts b/lang/qet_en.ts
index d46a8ab2d..595e603c1 100644
--- a/lang/qet_en.ts
+++ b/lang/qet_en.ts
@@ -12052,6 +12052,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Place symbol texts
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Place the label and the notes of the selected symbols as one block beside them
+
+
+
+ Above, left
+ Above, left
+
+
+
+ Above
+ Above
+
+
+
+ Above, right
+ Above, right
+
+
+
+ Left
+ Left
+
+
+
+ On the symbol
+ On the symbol
+
+
+
+ Right
+ Right
+
+
+
+ Below, left
+ Below, left
+
+
+
+ Below
+ Below
+
+
+
+ Below, right
+ Below, right
+ Displ&ay
@@ -24888,4 +24944,12 @@ The following variables can be used:
What:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Place symbol texts
+
+
diff --git a/lang/qet_es.ts b/lang/qet_es.ts
index c7c2bc00b..123e65718 100644
--- a/lang/qet_es.ts
+++ b/lang/qet_es.ts
@@ -12055,6 +12055,62 @@ Opciones disponibles:
QETDiagramEditor
+
+
+ Place symbol texts
+ Colocar los textos del símbolo
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Coloca la etiqueta y las notas de los símbolos seleccionados como un solo bloque a su lado
+
+
+
+ Above, left
+ Arriba, izquierda
+
+
+
+ Above
+ Arriba
+
+
+
+ Above, right
+ Arriba, derecha
+
+
+
+ Left
+ Izquierda
+
+
+
+ On the symbol
+ Sobre el símbolo
+
+
+
+ Right
+ Derecha
+
+
+
+ Below, left
+ Abajo, izquierda
+
+
+
+ Below
+ Abajo
+
+
+
+ Below, right
+ Abajo, derecha
+ No modification
@@ -24826,4 +24882,12 @@ asociar el nombre de "volta" y el valor "1745" reemplazara %
Que:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Colocar los textos del símbolo
+
+
diff --git a/lang/qet_fi.ts b/lang/qet_fi.ts
index 725f5019e..a3cbacc62 100644
--- a/lang/qet_fi.ts
+++ b/lang/qet_fi.ts
@@ -11694,6 +11694,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Sijoita symbolin tekstit
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Sijoittaa valittujen symbolien tunnuksen ja huomautukset yhtenä lohkona niiden viereen
+
+
+
+ Above, left
+ Yllä vasemmalla
+
+
+
+ Above
+ Yllä
+
+
+
+ Above, right
+ Yllä oikealla
+
+
+
+ Left
+ Vasemmalla
+
+
+
+ On the symbol
+ Symbolin päällä
+
+
+
+ Right
+ Oikealla
+
+
+
+ Below, left
+ Alla vasemmalla
+
+
+
+ Below
+ Alla
+
+
+
+ Below, right
+ Alla oikealla
+
@@ -24228,4 +24284,12 @@ The following variables can be used:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Sijoita symbolin tekstit
+
+
diff --git a/lang/qet_fr.ts b/lang/qet_fr.ts
index fe3cb9ade..6c49e975d 100644
--- a/lang/qet_fr.ts
+++ b/lang/qet_fr.ts
@@ -12064,6 +12064,62 @@ Options disponibles :
QETDiagramEditor
+
+
+ Place symbol texts
+ Placer les textes du symbole
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Place le repère et les notes des symboles sélectionnés en un seul bloc à côté d'eux
+
+
+
+ Above, left
+ En haut à gauche
+
+
+
+ Above
+ En haut
+
+
+
+ Above, right
+ En haut à droite
+
+
+
+ Left
+ À gauche
+
+
+
+ On the symbol
+ Sur le symbole
+
+
+
+ Right
+ À droite
+
+
+
+ Below, left
+ En bas à gauche
+
+
+
+ Below
+ En bas
+
+
+
+ Below, right
+ En bas à droite
+ Copy text format
@@ -24904,4 +24960,12 @@ associer le nom "volta" et la valeur "1745" remplacera %{vol
Quoi :
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Placer les textes du symbole
+
+
diff --git a/lang/qet_hr.ts b/lang/qet_hr.ts
index d1965e3cc..8d36a9dbd 100644
--- a/lang/qet_hr.ts
+++ b/lang/qet_hr.ts
@@ -11786,6 +11786,62 @@ Dostupne opcije:
QETDiagramEditor
+
+
+ Place symbol texts
+ Postavi tekstove simbola
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Postavlja oznaku i napomene odabranih simbola kao jedan blok pokraj njih
+
+
+
+ Above, left
+ Gore lijevo
+
+
+
+ Above
+ Gore
+
+
+
+ Above, right
+ Gore desno
+
+
+
+ Left
+ Lijevo
+
+
+
+ On the symbol
+ Na simbolu
+
+
+
+ Right
+ Desno
+
+
+
+ Below, left
+ Dolje lijevo
+
+
+
+ Below
+ Dolje
+
+
+
+ Below, right
+ Dolje desno
+
@@ -24386,4 +24442,12 @@ The following variables can be used:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Postavi tekstove simbola
+
+
diff --git a/lang/qet_hu.ts b/lang/qet_hu.ts
index a52dd1e40..ea6bca5ad 100644
--- a/lang/qet_hu.ts
+++ b/lang/qet_hu.ts
@@ -11979,6 +11979,62 @@ Elérhető lehetőségek:
QETDiagramEditor
+
+
+ Place symbol texts
+ Szimbólumszövegek elhelyezése
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ A kijelölt szimbólumok jelölését és megjegyzéseit egy blokként melléjük helyezi
+
+
+
+ Above, left
+ Fent balra
+
+
+
+ Above
+ Fent
+
+
+
+ Above, right
+ Fent jobbra
+
+
+
+ Left
+ Balra
+
+
+
+ On the symbol
+ A szimbólumon
+
+
+
+ Right
+ Jobbra
+
+
+
+ Below, left
+ Lent balra
+
+
+
+ Below
+ Lent
+
+
+
+ Below, right
+ Lent jobbra
+
@@ -24666,4 +24722,12 @@ A következő változók használhatók:
Adatai :
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Szimbólumszövegek elhelyezése
+
+
diff --git a/lang/qet_it.ts b/lang/qet_it.ts
index 0c98a3da9..64641487d 100644
--- a/lang/qet_it.ts
+++ b/lang/qet_it.ts
@@ -12026,6 +12026,62 @@ Ecco gli ultimi messaggi registrati prima della chiusura — puoi salvarli per i
QETDiagramEditor
+
+
+ Place symbol texts
+ Posiziona i testi del simbolo
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Posiziona la sigla e le note dei simboli selezionati come un unico blocco accanto a essi
+
+
+
+ Above, left
+ In alto a sinistra
+
+
+
+ Above
+ In alto
+
+
+
+ Above, right
+ In alto a destra
+
+
+
+ Left
+ A sinistra
+
+
+
+ On the symbol
+ Sul simbolo
+
+
+
+ Right
+ A destra
+
+
+
+ Below, left
+ In basso a sinistra
+
+
+
+ Below
+ In basso
+
+
+
+ Below, right
+ In basso a destra
+ No modification
@@ -24779,4 +24835,12 @@ si possono utilizzare le seguenti variabili:
Conduttore
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Posiziona i testi del simbolo
+
+
diff --git a/lang/qet_ja.ts b/lang/qet_ja.ts
index 6cd2f459b..99c819f1f 100644
--- a/lang/qet_ja.ts
+++ b/lang/qet_ja.ts
@@ -11953,6 +11953,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ シンボルのテキストを配置
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ 選択したシンボルのラベルと注記を1つのブロックとして横に配置します
+
+
+
+ Above, left
+ 左上
+
+
+
+ Above
+ 上
+
+
+
+ Above, right
+ 右上
+
+
+
+ Left
+ 左
+
+
+
+ On the symbol
+ シンボル上
+
+
+
+ Right
+ 右
+
+
+
+ Below, left
+ 左下
+
+
+
+ Below
+ 下
+
+
+
+ Below, right
+ 右下
+
@@ -24642,4 +24698,12 @@ The following variables can be used:
項目 :
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ シンボルのテキストを配置
+
+
diff --git a/lang/qet_ko.ts b/lang/qet_ko.ts
index 9ba95a949..8bd2c7497 100644
--- a/lang/qet_ko.ts
+++ b/lang/qet_ko.ts
@@ -11955,6 +11955,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ 심볼 텍스트 배치
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ 선택한 심볼의 라벨과 메모를 하나의 블록으로 옆에 배치합니다
+
+
+
+ Above, left
+ 위, 왼쪽
+
+
+
+ Above
+ 위
+
+
+
+ Above, right
+ 위, 오른쪽
+
+
+
+ Left
+ 왼쪽
+
+
+
+ On the symbol
+ 심볼 위
+
+
+
+ Right
+ 오른쪽
+
+
+
+ Below, left
+ 아래, 왼쪽
+
+
+
+ Below
+ 아래
+
+
+
+ Below, right
+ 아래, 오른쪽
+ Displ&ay
@@ -24592,4 +24648,12 @@ The following variables can be used:
검색어 :
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ 심볼 텍스트 배치
+
+
diff --git a/lang/qet_mn.ts b/lang/qet_mn.ts
index c67b519c3..576800b31 100644
--- a/lang/qet_mn.ts
+++ b/lang/qet_mn.ts
@@ -11876,6 +11876,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Тэмдгийн текстийг байрлуулах
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Сонгосон тэмдгүүдийн шошго, тэмдэглэлийг нэг блок болгон хажууд нь байрлуулна
+
+
+
+ Above, left
+ Дээд зүүн
+
+
+
+ Above
+ Дээд
+
+
+
+ Above, right
+ Дээд баруун
+
+
+
+ Left
+ Зүүн
+
+
+
+ On the symbol
+ Тэмдэг дээр
+
+
+
+ Right
+ Баруун
+
+
+
+ Below, left
+ Доод зүүн
+
+
+
+ Below
+ Доод
+
+
+
+ Below, right
+ Доод баруун
+
@@ -24472,4 +24528,12 @@ The following variables can be used:
Юу :
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Тэмдгийн текстийг байрлуулах
+
+
diff --git a/lang/qet_nb.ts b/lang/qet_nb.ts
index c87188f36..5c3d9fc6c 100644
--- a/lang/qet_nb.ts
+++ b/lang/qet_nb.ts
@@ -11891,6 +11891,62 @@ Tilgjengelige opsjoner:
QETDiagramEditor
+
+
+ Place symbol texts
+ Plasser symboltekster
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Plasserer merke og merknader for de valgte symbolene som én blokk ved siden av dem
+
+
+
+ Above, left
+ Over, til venstre
+
+
+
+ Above
+ Over
+
+
+
+ Above, right
+ Over, til høyre
+
+
+
+ Left
+ Venstre
+
+
+
+ On the symbol
+ På symbolet
+
+
+
+ Right
+ Høyre
+
+
+
+ Below, left
+ Under, til venstre
+
+
+
+ Below
+ Under
+
+
+
+ Below, right
+ Under, til høyre
+
@@ -24508,4 +24564,12 @@ variablen "volta" kombiniert med verdi "1745" I tegningsmale
Hva:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Plasser symboltekster
+
+
diff --git a/lang/qet_nl.ts b/lang/qet_nl.ts
index 302ecee1f..08c5e8d7d 100644
--- a/lang/qet_nl.ts
+++ b/lang/qet_nl.ts
@@ -11917,6 +11917,62 @@ Opties :
QETDiagramEditor
+
+
+ Place symbol texts
+ Symbolteksten plaatsen
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Plaatst het label en de opmerkingen van de geselecteerde symbolen als één blok ernaast
+
+
+
+ Above, left
+ Boven, links
+
+
+
+ Above
+ Boven
+
+
+
+ Above, right
+ Boven, rechts
+
+
+
+ Left
+ Links
+
+
+
+ On the symbol
+ Op het symbool
+
+
+
+ Right
+ Rechts
+
+
+
+ Below, left
+ Onder, links
+
+
+
+ Below
+ Onder
+
+
+
+ Below, right
+ Onder, rechts
+ Displ&ay
@@ -24549,4 +24605,12 @@ Door de associatie van de naam "volta" met de waarde "1745"
Welke :
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Symbolteksten plaatsen
+
+
diff --git a/lang/qet_nl_BE.ts b/lang/qet_nl_BE.ts
index 9969bcc7a..5c96dced5 100644
--- a/lang/qet_nl_BE.ts
+++ b/lang/qet_nl_BE.ts
@@ -12039,6 +12039,62 @@ Beschikbare opties:
QETDiagramEditor
+
+
+ Place symbol texts
+ Symbolteksten plaatsen
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Plaatst het label en de opmerkingen van de geselecteerde symbolen als één blok ernaast
+
+
+
+ Above, left
+ Boven, links
+
+
+
+ Above
+ Boven
+
+
+
+ Above, right
+ Boven, rechts
+
+
+
+ Left
+ Links
+
+
+
+ On the symbol
+ Op het symbool
+
+
+
+ Right
+ Rechts
+
+
+
+ Below, left
+ Onder, links
+
+
+
+ Below
+ Onder
+
+
+
+ Below, right
+ Onder, rechts
+ Displ&ay
@@ -24791,4 +24847,12 @@ De volgende variabelen kunnen gebruikt worden:
Wat :
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Symbolteksten plaatsen
+
+
diff --git a/lang/qet_nl_NL.ts b/lang/qet_nl_NL.ts
index dca5baef9..d44405c00 100644
--- a/lang/qet_nl_NL.ts
+++ b/lang/qet_nl_NL.ts
@@ -9936,6 +9936,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Symbolteksten plaatsen
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Plaatst het label en de opmerkingen van de geselecteerde symbolen als één blok ernaast
+
+
+
+ Above, left
+ Boven, links
+
+
+
+ Above
+ Boven
+
+
+
+ Above, right
+ Boven, rechts
+
+
+
+ Left
+ Links
+
+
+
+ On the symbol
+ Op het symbool
+
+
+
+ Right
+ Rechts
+
+
+
+ Below, left
+ Onder, links
+
+
+
+ Below
+ Onder
+
+
+
+ Below, right
+ Onder, rechts
+
@@ -21749,4 +21805,12 @@ The following variables can be used:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Symbolteksten plaatsen
+
+
diff --git a/lang/qet_no.ts b/lang/qet_no.ts
index 16a35735c..46cbdd84d 100644
--- a/lang/qet_no.ts
+++ b/lang/qet_no.ts
@@ -11694,6 +11694,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Plasser symboltekster
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Plasserer merke og merknader for de valgte symbolene som én blokk ved siden av dem
+
+
+
+ Above, left
+ Over, til venstre
+
+
+
+ Above
+ Over
+
+
+
+ Above, right
+ Over, til høyre
+
+
+
+ Left
+ Venstre
+
+
+
+ On the symbol
+ På symbolet
+
+
+
+ Right
+ Høyre
+
+
+
+ Below, left
+ Under, til venstre
+
+
+
+ Below
+ Under
+
+
+
+ Below, right
+ Under, til høyre
+
@@ -24228,4 +24284,12 @@ The following variables can be used:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Plasser symboltekster
+
+
diff --git a/lang/qet_pl.ts b/lang/qet_pl.ts
index 2bd93b3e5..fdee219fe 100644
--- a/lang/qet_pl.ts
+++ b/lang/qet_pl.ts
@@ -12141,6 +12141,62 @@ Dostępne opcje:
QETDiagramEditor
+
+
+ Place symbol texts
+ Rozmieść teksty symbolu
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Umieszcza oznaczenie i uwagi zaznaczonych symboli jako jeden blok obok nich
+
+
+
+ Above, left
+ U góry po lewej
+
+
+
+ Above
+ U góry
+
+
+
+ Above, right
+ U góry po prawej
+
+
+
+ Left
+ Po lewej
+
+
+
+ On the symbol
+ Na symbolu
+
+
+
+ Right
+ Po prawej
+
+
+
+ Below, left
+ Na dole po lewej
+
+
+
+ Below
+ Na dole
+
+
+
+ Below, right
+ Na dole po prawej
+ Displ&ay
@@ -25099,4 +25155,12 @@ skojarzenie nazwy "volta" i wartości "1745" spowoduje zast
Dane:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Rozmieść teksty symbolu
+
+
diff --git a/lang/qet_pt.ts b/lang/qet_pt.ts
index 9c5def165..228fa076a 100644
--- a/lang/qet_pt.ts
+++ b/lang/qet_pt.ts
@@ -11927,6 +11927,62 @@ Opções disponiveis:
QETDiagramEditor
+
+
+ Place symbol texts
+ Posicionar os textos do símbolo
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Posiciona a etiqueta e as notas dos símbolos selecionados como um só bloco ao lado deles
+
+
+
+ Above, left
+ Em cima, à esquerda
+
+
+
+ Above
+ Em cima
+
+
+
+ Above, right
+ Em cima, à direita
+
+
+
+ Left
+ À esquerda
+
+
+
+ On the symbol
+ Sobre o símbolo
+
+
+
+ Right
+ À direita
+
+
+
+ Below, left
+ Em baixo, à esquerda
+
+
+
+ Below
+ Em baixo
+
+
+
+ Below, right
+ Em baixo, à direita
+ Displ&ay
@@ -24678,4 +24734,12 @@ Podem ser usadas as seguintes variáveis:
O quê:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Posicionar os textos do símbolo
+
+
diff --git a/lang/qet_pt_BR.ts b/lang/qet_pt_BR.ts
index 212342d9d..a4b82f8e9 100644
--- a/lang/qet_pt_BR.ts
+++ b/lang/qet_pt_BR.ts
@@ -12030,6 +12030,62 @@ Opções disponíveis:
QETDiagramEditor
+
+
+ Place symbol texts
+ Posicionar os textos do símbolo
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Posiciona a etiqueta e as notas dos símbolos selecionados como um só bloco ao lado deles
+
+
+
+ Above, left
+ Acima, à esquerda
+
+
+
+ Above
+ Acima
+
+
+
+ Above, right
+ Acima, à direita
+
+
+
+ Left
+ À esquerda
+
+
+
+ On the symbol
+ Sobre o símbolo
+
+
+
+ Right
+ À direita
+
+
+
+ Below, left
+ Abaixo, à esquerda
+
+
+
+ Below
+ Abaixo
+
+
+
+ Below, right
+ Abaixo, à direita
+
@@ -24869,4 +24925,12 @@ associar o nome "variável_personalizada" e o valor "1745" v
O que:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Posicionar os textos do símbolo
+
+
diff --git a/lang/qet_ro.ts b/lang/qet_ro.ts
index 9697d297e..725f28f87 100644
--- a/lang/qet_ro.ts
+++ b/lang/qet_ro.ts
@@ -11800,6 +11800,62 @@ Opțiuni disponibile:
QETDiagramEditor
+
+
+ Place symbol texts
+ Plasează textele simbolului
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Plasează eticheta și notele simbolurilor selectate ca un singur bloc lângă ele
+
+
+
+ Above, left
+ Sus, stânga
+
+
+
+ Above
+ Sus
+
+
+
+ Above, right
+ Sus, dreapta
+
+
+
+ Left
+ Stânga
+
+
+
+ On the symbol
+ Pe simbol
+
+
+
+ Right
+ Dreapta
+
+
+
+ Below, left
+ Jos, stânga
+
+
+
+ Below
+ Jos
+
+
+
+ Below, right
+ Jos, dreapta
+
@@ -24404,4 +24460,12 @@ asociind numele "volta" cu valoarea "1745" se va înlocui %{
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Plasează textele simbolului
+
+
diff --git a/lang/qet_rs.ts b/lang/qet_rs.ts
index 3dd8f1181..f98b83674 100644
--- a/lang/qet_rs.ts
+++ b/lang/qet_rs.ts
@@ -11738,6 +11738,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Postavi tekstove simbola
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Postavlja oznaku i napomene izabranih simbola kao jedan blok pored njih
+
+
+
+ Above, left
+ Gore levo
+
+
+
+ Above
+ Gore
+
+
+
+ Above, right
+ Gore desno
+
+
+
+ Left
+ Levo
+
+
+
+ On the symbol
+ Na simbolu
+
+
+
+ Right
+ Desno
+
+
+
+ Below, left
+ Dole levo
+
+
+
+ Below
+ Dole
+
+
+
+ Below, right
+ Dole desno
+
@@ -24330,4 +24386,12 @@ The following variables can be used:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Postavi tekstove simbola
+
+
diff --git a/lang/qet_ru.ts b/lang/qet_ru.ts
index ecfbbe428..0376d4638 100644
--- a/lang/qet_ru.ts
+++ b/lang/qet_ru.ts
@@ -12132,6 +12132,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Разместить тексты символа
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Размещает обозначение и примечания выбранных символов одним блоком рядом с ними
+
+
+
+ Above, left
+ Сверху слева
+
+
+
+ Above
+ Сверху
+
+
+
+ Above, right
+ Сверху справа
+
+
+
+ Left
+ Слева
+
+
+
+ On the symbol
+ На символе
+
+
+
+ Right
+ Справа
+
+
+
+ Below, left
+ Снизу слева
+
+
+
+ Below
+ Снизу
+
+
+
+ Below, right
+ Снизу справа
+
@@ -24979,4 +25035,12 @@ The following variables can be used:
Где:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Разместить тексты символа
+
+
diff --git a/lang/qet_sk.ts b/lang/qet_sk.ts
index 3c66aeac1..99b7650d1 100644
--- a/lang/qet_sk.ts
+++ b/lang/qet_sk.ts
@@ -11921,6 +11921,62 @@ Dostupné možnosti:
QETDiagramEditor
+
+
+ Place symbol texts
+ Umiestniť texty symbolu
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Umiestni označenie a poznámky vybraných symbolov ako jeden blok vedľa nich
+
+
+
+ Above, left
+ Hore vľavo
+
+
+
+ Above
+ Hore
+
+
+
+ Above, right
+ Hore vpravo
+
+
+
+ Left
+ Vľavo
+
+
+
+ On the symbol
+ Na symbole
+
+
+
+ Right
+ Vpravo
+
+
+
+ Below, left
+ Dole vľavo
+
+
+
+ Below
+ Dole
+
+
+
+ Below, right
+ Dole vpravo
+ Displ&ay
@@ -24734,4 +24790,12 @@ Používajú sa nasledujúce premenné:
Čo:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Umiestniť texty symbolu
+
+
diff --git a/lang/qet_sl.ts b/lang/qet_sl.ts
index e879adf61..349d867f7 100644
--- a/lang/qet_sl.ts
+++ b/lang/qet_sl.ts
@@ -11782,6 +11782,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Postavi besedila simbola
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Postavi oznako in opombe izbranih simbolov kot en blok poleg njih
+
+
+
+ Above, left
+ Zgoraj levo
+
+
+
+ Above
+ Zgoraj
+
+
+
+ Above, right
+ Zgoraj desno
+
+
+
+ Left
+ Levo
+
+
+
+ On the symbol
+ Na simbolu
+
+
+
+ Right
+ Desno
+
+
+
+ Below, left
+ Spodaj levo
+
+
+
+ Below
+ Spodaj
+
+
+
+ Below, right
+ Spodaj desno
+
@@ -24432,4 +24488,12 @@ The following variables can be used:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Postavi besedila simbola
+
+
diff --git a/lang/qet_sr.ts b/lang/qet_sr.ts
index 47460d10d..2c0703bd3 100644
--- a/lang/qet_sr.ts
+++ b/lang/qet_sr.ts
@@ -11738,6 +11738,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Постави текстове симбола
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Поставља ознаку и напомене изабраних симбола као један блок поред њих
+
+
+
+ Above, left
+ Горе лево
+
+
+
+ Above
+ Горе
+
+
+
+ Above, right
+ Горе десно
+
+
+
+ Left
+ Лево
+
+
+
+ On the symbol
+ На симболу
+
+
+
+ Right
+ Десно
+
+
+
+ Below, left
+ Доле лево
+
+
+
+ Below
+ Доле
+
+
+
+ Below, right
+ Доле десно
+
@@ -24330,4 +24386,12 @@ The following variables can be used:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Постави текстове симбола
+
+
diff --git a/lang/qet_sv.ts b/lang/qet_sv.ts
index 8cd8e0913..f2690c1d0 100644
--- a/lang/qet_sv.ts
+++ b/lang/qet_sv.ts
@@ -11922,6 +11922,62 @@ Tillgängliga alternativ :
QETDiagramEditor
+
+
+ Place symbol texts
+ Placera symboltexter
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Placerar märkning och anteckningar för de valda symbolerna som ett block bredvid dem
+
+
+
+ Above, left
+ Ovanför, vänster
+
+
+
+ Above
+ Ovanför
+
+
+
+ Above, right
+ Ovanför, höger
+
+
+
+ Left
+ Vänster
+
+
+
+ On the symbol
+ På symbolen
+
+
+
+ Right
+ Höger
+
+
+
+ Below, left
+ Nedanför, vänster
+
+
+
+ Below
+ Nedanför
+
+
+
+ Below, right
+ Nedanför, höger
+
@@ -24574,4 +24630,12 @@ du associerar namnet ”volta” med värdet ”1745” kommer %{volta} att ers
Vad:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Placera symboltexter
+
+
diff --git a/lang/qet_tr.ts b/lang/qet_tr.ts
index 50e850b91..a987082d2 100644
--- a/lang/qet_tr.ts
+++ b/lang/qet_tr.ts
@@ -11984,6 +11984,62 @@ Mevcut seçenekler:
QETDiagramEditor
+
+
+ Place symbol texts
+ Sembol metinlerini yerleştir
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Seçili sembollerin etiketini ve notlarını tek blok olarak yanlarına yerleştirir
+
+
+
+ Above, left
+ Üst, sol
+
+
+
+ Above
+ Üst
+
+
+
+ Above, right
+ Üst, sağ
+
+
+
+ Left
+ Sol
+
+
+
+ On the symbol
+ Sembolün üstünde
+
+
+
+ Right
+ Sağ
+
+
+
+ Below, left
+ Alt, sol
+
+
+
+ Below
+ Alt
+
+
+
+ Below, right
+ Alt, sağ
+
@@ -24681,4 +24737,12 @@ Aşağıdaki değişkenler kullanılabilir:
Ne ile:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Sembol metinlerini yerleştir
+
+
diff --git a/lang/qet_uk.ts b/lang/qet_uk.ts
index c48faea7d..7b5bdc34e 100644
--- a/lang/qet_uk.ts
+++ b/lang/qet_uk.ts
@@ -12089,6 +12089,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ Розмістити тексти символу
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ Розміщує позначення та примітки вибраних символів одним блоком поруч із ними
+
+
+
+ Above, left
+ Згори ліворуч
+
+
+
+ Above
+ Згори
+
+
+
+ Above, right
+ Згори праворуч
+
+
+
+ Left
+ Ліворуч
+
+
+
+ On the symbol
+ На символі
+
+
+
+ Right
+ Праворуч
+
+
+
+ Below, left
+ Знизу ліворуч
+
+
+
+ Below
+ Знизу
+
+
+
+ Below, right
+ Знизу праворуч
+
@@ -24919,4 +24975,12 @@ The following variables can be used:
Де:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ Розмістити тексти символу
+
+
diff --git a/lang/qet_zh.ts b/lang/qet_zh.ts
index 1f6f232c3..d9420fc1e 100644
--- a/lang/qet_zh.ts
+++ b/lang/qet_zh.ts
@@ -11987,6 +11987,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ 放置符号文本
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ 将所选符号的标签和注释作为一个整体放在其旁边
+
+
+
+ Above, left
+ 左上
+
+
+
+ Above
+ 上
+
+
+
+ Above, right
+ 右上
+
+
+
+ Left
+ 左
+
+
+
+ On the symbol
+ 在符号上
+
+
+
+ Right
+ 右
+
+
+
+ Below, left
+ 左下
+
+
+
+ Below
+ 下
+
+
+
+ Below, right
+ 右下
+
@@ -24681,4 +24737,12 @@ The following variables can be used:
类型:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ 放置符号文本
+
+
diff --git a/lang/qet_zh_TW.ts b/lang/qet_zh_TW.ts
index 797f74cb8..09e05c3e0 100644
--- a/lang/qet_zh_TW.ts
+++ b/lang/qet_zh_TW.ts
@@ -11987,6 +11987,62 @@ Available options:
QETDiagramEditor
+
+
+ Place symbol texts
+ 放置符號文字
+
+
+
+ Place the label and the notes of the selected symbols as one block beside them
+ status bar tip
+ 將所選符號的標籤與註解作為一個區塊放在其旁邊
+
+
+
+ Above, left
+ 左上
+
+
+
+ Above
+ 上
+
+
+
+ Above, right
+ 右上
+
+
+
+ Left
+ 左
+
+
+
+ On the symbol
+ 在符號上
+
+
+
+ Right
+ 右
+
+
+
+ Below, left
+ 左下
+
+
+
+ Below
+ 下
+
+
+
+ Below, right
+ 右下
+
@@ -24681,4 +24737,12 @@ The following variables can be used:
型別:
+
+ SymbolTextPlacement
+
+
+ Place symbol texts
+ 放置符號文字
+
+
diff --git a/sources/diagramtoolbarsettings.cpp b/sources/diagramtoolbarsettings.cpp
index 95964b227..d49ef3e38 100644
--- a/sources/diagramtoolbarsettings.cpp
+++ b/sources/diagramtoolbarsettings.cpp
@@ -17,6 +17,9 @@
*/
#include "diagramtoolbarsettings.h"
+#include
+#include
+
#include "shortcutmanager.h"
#include
@@ -198,7 +201,9 @@ QStringList DiagramToolbarSettings::defaultIds(const QString &name)
//the shapes of the "Ajouter" toolbar.
sep,
QStringLiteral("diagrameditor.add_cable"),
- QStringLiteral("widget:conductor_color")};
+ QStringLiteral("widget:conductor_color"),
+ sep,
+ QStringLiteral("diagrameditor.place_symbol_texts")};
}
if (name == QLatin1String("adding")) {
//add_pdf is skipped when built without QtPdf, as before
@@ -330,6 +335,11 @@ void DiagramToolbarSettings::fill(QToolBar *toolbar, const QStringList &ids,
pending_separator = false;
}
toolbar->addAction(action);
+ //A command with a menu of choices: a click does it again,
+ //the arrow beside it opens the choices
+ if (action->menu())
+ if (auto *button = qobject_cast(toolbar->widgetForAction(action)))
+ button->setPopupMode(QToolButton::MenuButtonPopup);
}
}
diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp
index 527623837..0b3c27b89 100644
--- a/sources/qetdiagrameditor.cpp
+++ b/sources/qetdiagrameditor.cpp
@@ -20,6 +20,7 @@
#include "container/qetzip.h"
#include "utils/previousversions.h"
#include "shownkinds.h"
+#include "symboltextplacement.h"
#ifdef QET_HAS_SCRIPTING
#include "scripting/qetscripting.h"
#include "scripting/scriptlibrary.h"
@@ -33,6 +34,7 @@
#include
#include
#include
+#include
#include "ElementsCollection/elementscollectionwidget.h"
#include "ElementsCollection/elementpickerpopup.h"
#include "shortcutbarsettings.h"
@@ -489,6 +491,62 @@ void QETDiagramEditor::setUpActions()
connect(m_copy_text_format, &QAction::triggered, this, &QETDiagramEditor::copyTextFormat);
connect(m_apply_text_format, &QAction::triggered, this, &QETDiagramEditor::applyTextFormat);
+ //The texts of the selected symbols, label and notes, as one block at
+ //one of nine points around the symbol: the nine points of the text
+ //alignment dialog. A click places them at the point chosen last.
+ const auto chosen_point = []() {
+ return Qt::Alignment(QSettings().value(QStringLiteral("diagrameditor/place_texts_point"),
+ int(Qt::AlignLeft | Qt::AlignVCenter)).toInt());
+ };
+ //The button shows where its click will put the texts
+ m_place_texts = new QAction(SymbolTextPlacement::icon(chosen_point()), tr("Place symbol texts"), this);
+ m_place_texts->setStatusTip(tr("Place the label and the notes of the selected symbols as one block beside them", "status bar tip"));
+ ShortcutManager::instance().registerAction(m_place_texts, "diagrameditor.place_symbol_texts", tr("Diagram editors"), QKeySequence());
+ {
+ auto *menu = new QMenu(this);
+ auto *grid_widget = new QWidget(menu);
+ auto *grid = new QGridLayout(grid_widget);
+ grid->setContentsMargins(6, 6, 6, 6);
+ grid->setSpacing(2);
+ const struct { Qt::Alignment where; const char *tip; } points[] = {
+ {Qt::AlignLeft | Qt::AlignTop, QT_TR_NOOP("Above, left")},
+ {Qt::AlignHCenter | Qt::AlignTop, QT_TR_NOOP("Above")},
+ {Qt::AlignRight | Qt::AlignTop, QT_TR_NOOP("Above, right")},
+ {Qt::AlignLeft | Qt::AlignVCenter, QT_TR_NOOP("Left")},
+ {Qt::AlignCenter, QT_TR_NOOP("On the symbol")},
+ {Qt::AlignRight | Qt::AlignVCenter, QT_TR_NOOP("Right")},
+ {Qt::AlignLeft | Qt::AlignBottom, QT_TR_NOOP("Below, left")},
+ {Qt::AlignHCenter | Qt::AlignBottom, QT_TR_NOOP("Below")},
+ {Qt::AlignRight | Qt::AlignBottom, QT_TR_NOOP("Below, right")}};
+ int n = 0;
+ for (const auto &point : points)
+ {
+ auto *button = new QToolButton(grid_widget);
+ button->setIcon(SymbolTextPlacement::icon(point.where));
+ button->setIconSize(QSize(32, 32));
+ button->setToolTip(tr(point.tip));
+ button->setObjectName(QStringLiteral("place_texts_%1").arg(n));
+ button->setFixedSize(38, 38);
+ button->setAutoRaise(true);
+ const Qt::Alignment where = point.where;
+ connect(button, &QToolButton::clicked, this, [this, menu, where]() {
+ menu->close();
+ QSettings().setValue(QStringLiteral("diagrameditor/place_texts_point"), int(where));
+ m_place_texts->setIcon(SymbolTextPlacement::icon(where));
+ placeSymbolTexts(where);
+ });
+ grid->addWidget(button, n / 3, n % 3);
+ ++n;
+ }
+ auto *grid_action = new QWidgetAction(menu);
+ grid_action->setDefaultWidget(grid_widget);
+ menu->addAction(grid_action);
+ m_place_texts->setMenu(menu);
+ }
+ connect(m_place_texts, &QAction::triggered, this, [this, chosen_point]() {
+ placeSymbolTexts(chosen_point());
+ });
+
//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):
@@ -1585,6 +1643,7 @@ void QETDiagramEditor::setUpMenu()
menu_edition -> addAction(m_paste);
menu_edition -> addAction(m_copy_text_format);
menu_edition -> addAction(m_apply_text_format);
+ menu_edition -> addAction(m_place_texts);
menu_edition -> addAction(m_paste_origin);
menu_edition -> addAction(m_paste_element_info);
menu_edition -> addAction(m_duplicate);
@@ -3187,6 +3246,7 @@ void QETDiagramEditor::slot_updateComplexActions()
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_place_texts->setEnabled(!ro && selected_elements_count >= 1);
m_mirror_horizontal->setEnabled(!ro && selected_elements_count);
m_mirror_vertical->setEnabled(!ro && selected_elements_count);
@@ -5014,6 +5074,27 @@ void QETDiagramEditor::copyTextFormat()
* @brief QETDiagramEditor::applyTextFormat
* Applies the stored text formatting template to all selected elements in the active diagram.
*/
+/**
+ @brief QETDiagramEditor::placeSymbolTexts
+ Place the texts of the selected symbols as one block at @a where,
+ one of nine points around each symbol, in one undo step.
+ @param where : see SymbolTextPlacement::place()
+*/
+void QETDiagramEditor::placeSymbolTexts(Qt::Alignment where)
+{
+ DiagramView *dv = currentDiagramView();
+ if (!dv || !dv->diagram() || dv->diagram()->isReadOnly()) return;
+
+ QList elements;
+ for (QGraphicsItem *item : dv->diagram()->selectedItems())
+ if (Element *element = qgraphicsitem_cast(item))
+ elements.append(element);
+ if (elements.isEmpty()) return;
+
+ if (QUndoCommand *undo = SymbolTextPlacement::place(elements, where))
+ dv->diagram()->undoStack().push(undo);
+}
+
void QETDiagramEditor::applyTextFormat()
{
if (!ElementTextFormatPattern::hasPattern()) return;
diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h
index df1d2c1bb..e848d212b 100644
--- a/sources/qetdiagrameditor.h
+++ b/sources/qetdiagrameditor.h
@@ -210,6 +210,7 @@ class QETDiagramEditor : public QETMainWindow
void subWindowActivated(QMdiSubWindow *subWindows);
void copyTextFormat();
void applyTextFormat();
+ void placeSymbolTexts(Qt::Alignment where);
private slots:
void updateTextGridButton();
@@ -225,7 +226,8 @@ class QETDiagramEditor : public QETMainWindow
*m_paste_element_info, ///< Copy the information of the copied element onto the selected elements (#1375)
*m_insert_last_element = nullptr, ///< Place the last placed element again
*m_copy_text_format = nullptr, ///< Copy label/text formatting template
- *m_apply_text_format = nullptr; ///< Apply label/text formatting template
+ *m_apply_text_format = nullptr, ///< Apply label/text formatting template
+ *m_place_texts = nullptr; ///< Place the texts of the selected symbols at one of nine points
QActionGroup
m_row_column_actions_group, /// Action related to add/remove rows/column in diagram
diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp
index 125c069a0..3e0b541ac 100644
--- a/sources/qetgraphicsitem/element.cpp
+++ b/sources/qetgraphicsitem/element.cpp
@@ -620,6 +620,18 @@ void Element::paint(
/**
@return Le rectangle delimitant le contour de l'element
*/
+/**
+ @brief Element::drawingRect
+ @return the area its drawing covers, in this symbol's coordinates:
+ tighter than boundingRect(), which is rounded up to the grid. The
+ bounding rect for a symbol with nothing drawn.
+*/
+QRectF Element::drawingRect() const
+{
+ const QRect drawn = m_picture.isNull() ? QRect() : m_picture.boundingRect();
+ return drawn.isEmpty() ? boundingRect() : QRectF(drawn);
+}
+
QRectF Element::boundingRect() const
{
return(QRectF(QPointF(-hotspot_coord.x(), -hotspot_coord.y()),
diff --git a/sources/qetgraphicsitem/element.h b/sources/qetgraphicsitem/element.h
index a18653d3b..29c29bb1f 100644
--- a/sources/qetgraphicsitem/element.h
+++ b/sources/qetgraphicsitem/element.h
@@ -185,6 +185,8 @@ class Element : public QetGraphicsItem
QPixmap pixmap();
QPoint setHotspot(QPoint);
QPoint hotspot() const;
+ /// The area the symbol is drawn on, in its own coordinates
+ QRectF drawingRect() const;
void editProperty() override;
static bool valideXml(QDomElement &);
static QUuid savedTerminalUuid(const QList &records, int index);
diff --git a/sources/symboltextplacement.cpp b/sources/symboltextplacement.cpp
new file mode 100644
index 000000000..0823f7d1d
--- /dev/null
+++ b/sources/symboltextplacement.cpp
@@ -0,0 +1,183 @@
+/*
+ Copyright 2006-2026 The QElectroTech Team
+ This file is part of QElectroTech.
+
+ QElectroTech is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ QElectroTech is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QElectroTech. If not, see .
+*/
+#include "symboltextplacement.h"
+
+#include "QPropertyUndoCommand/qpropertyundocommand.h"
+#include "qetgraphicsitem/dynamicelementtextitem.h"
+#include "qetgraphicsitem/element.h"
+#include "qetgraphicsitem/elementtextitemgroup.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace {
+
+ /// How the lines of the block line up, for a block placed at @a where
+Qt::Alignment linesFor(Qt::Alignment where)
+{
+ if (where & Qt::AlignLeft) return Qt::AlignRight;
+ if (where & Qt::AlignRight) return Qt::AlignLeft;
+ return Qt::AlignHCenter;
+}
+
+ /// One line of the block: a text, or a group of texts
+struct Line
+{
+ QObject *object; ///< for its properties
+ QGraphicsItem *item; ///< for where it stands
+ QPointF old_pos;
+ QVariant old_alignment;
+ /// For a group, where its texts lay: a new alignment lays them out
+ /// anew, and undoing it to AlignJustify lays out nothing
+ QList> old_texts;
+};
+
+ /// Move @a item so that the top left of its box in the folio is at @a to
+void moveTo(QGraphicsItem *item, const QPointF &to)
+{
+ const QPointF by = to - item->sceneBoundingRect().topLeft();
+ QGraphicsItem *parent = item->parentItem();
+ const QPointF step = parent ? parent->mapFromScene(by) - parent->mapFromScene(QPointF(0, 0))
+ : by;
+ item->setPos(item->pos() + step);
+}
+
+bool placeOne(Element *element, Qt::Alignment where, QUndoCommand *parent)
+{
+ const Qt::Alignment lines_alignment = linesFor(where);
+
+ QList lines;
+ for (DynamicElementTextItem *text : element->dynamicTextItems())
+ if (!text->parentGroup() && text->isVisible())
+ lines.append({text, text, text->pos(), text->property("alignment"), {}});
+ for (ElementTextItemGroup *group : element->textGroups())
+ if (group->isVisible())
+ {
+ Line line {group, group, group->pos(), group->property("alignment"), {}};
+ for (DynamicElementTextItem *text : group->texts())
+ line.old_texts.append({text, text->pos()});
+ lines.append(line);
+ }
+ if (lines.isEmpty())
+ return false;
+
+ //The lines first take the alignment of the block: a group lays its
+ //texts out anew, and later changes of a text keep that side.
+ for (const Line &line : lines)
+ {
+ Qt::Alignment a = line.old_alignment.value();
+ if (qobject_cast(line.object))
+ a = lines_alignment == Qt::AlignHCenter ? Qt::AlignVCenter : lines_alignment;
+ else
+ a = (a & Qt::AlignVertical_Mask) | lines_alignment;
+ line.object->setProperty("alignment", QVariant::fromValue(a));
+ }
+
+ QRectF block;
+ for (const Line &line : lines)
+ block |= line.item->sceneBoundingRect();
+
+ const QRectF body = element->mapRectToScene(element->drawingRect());
+ const qreal gap = SymbolTextPlacement::gap;
+ QRectF to = block;
+ if (where & Qt::AlignLeft) to.moveRight(body.left() - gap);
+ else if (where & Qt::AlignRight) to.moveLeft(body.right() + gap);
+ else to.moveLeft(body.center().x() - block.width() / 2);
+ if (where & Qt::AlignTop) to.moveBottom(body.top() - gap);
+ else if (where & Qt::AlignBottom) to.moveTop(body.bottom() + gap);
+ else to.moveTop(body.center().y() - block.height() / 2);
+
+ for (const Line &line : lines)
+ {
+ const QRectF box = line.item->sceneBoundingRect();
+ const qreal y = to.top() + box.top() - block.top();
+ const qreal x = lines_alignment == Qt::AlignRight ? to.right() - box.width()
+ : lines_alignment == Qt::AlignLeft ? to.left()
+ : to.center().x() - box.width() / 2;
+ moveTo(line.item, QPointF(x, y));
+
+ const QVariant alignment = line.object->property("alignment");
+ if (alignment != line.old_alignment)
+ new QPropertyUndoCommand(line.object, "alignment", line.old_alignment, alignment, parent);
+ if (line.item->pos() != line.old_pos)
+ new QPropertyUndoCommand(line.object, "pos", line.old_pos, line.item->pos(), parent);
+ //The group's texts too: undoing its alignment to AlignJustify
+ //would leave them where the new alignment put them
+ for (const auto &text : line.old_texts)
+ if (text.first->pos() != text.second)
+ new QPropertyUndoCommand(text.first, "pos", text.second, text.first->pos(), parent);
+ }
+ return true;
+}
+
+} // namespace
+
+QUndoCommand *SymbolTextPlacement::place(const QList &elements, Qt::Alignment where)
+{
+ auto *undo = new QUndoCommand(
+ QCoreApplication::translate("SymbolTextPlacement", "Place symbol texts"));
+ bool any = false;
+ for (Element *element : elements)
+ any |= placeOne(element, where, undo);
+ if (!any || !undo->childCount()) {
+ delete undo;
+ return nullptr;
+ }
+ return undo;
+}
+
+QIcon SymbolTextPlacement::icon(Qt::Alignment where)
+{
+ const Qt::Alignment lines = linesFor(where);
+ const QPalette palette = QApplication::palette();
+ QIcon icon;
+ for (int size : {16, 22, 24, 32, 48})
+ {
+ QPixmap pixmap(size, size);
+ pixmap.fill(Qt::transparent);
+ QPainter painter(&pixmap);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.scale(size / 24.0, size / 24.0);
+
+ //The symbol
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(palette.color(QPalette::Mid));
+ painter.drawRect(QRectF(8, 8, 8, 8));
+
+ //Two lines of text, a long one over a short one
+ const qreal right = (where & Qt::AlignLeft) ? 6.8 : (where & Qt::AlignRight) ? 24 : 19;
+ const qreal left = (where & Qt::AlignLeft) ? 0 : (where & Qt::AlignRight) ? 17.2 : 5;
+ const qreal top = (where & Qt::AlignTop) ? 0 : (where & Qt::AlignBottom) ? 16.6 : 8.3;
+ painter.setBrush(palette.color(QPalette::WindowText));
+ for (int i = 0; i < 2; ++i)
+ {
+ const qreal width = i == 0 ? right - left : (right - left) * 0.6;
+ const qreal x = lines == Qt::AlignRight ? right - width
+ : lines == Qt::AlignLeft ? left
+ : (left + right - width) / 2;
+ painter.drawRect(QRectF(x, top + i * 4.2, width, 3.2));
+ }
+ painter.end();
+ icon.addPixmap(pixmap);
+ }
+ return icon;
+}
diff --git a/sources/symboltextplacement.h b/sources/symboltextplacement.h
new file mode 100644
index 000000000..5100c98d3
--- /dev/null
+++ b/sources/symboltextplacement.h
@@ -0,0 +1,60 @@
+/*
+ Copyright 2006-2026 The QElectroTech Team
+ This file is part of QElectroTech.
+
+ QElectroTech is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ QElectroTech is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with QElectroTech. If not, see .
+*/
+#ifndef SYMBOLTEXTPLACEMENT_H
+#define SYMBOLTEXTPLACEMENT_H
+
+#include
+#include
+#include
+
+class Element;
+class QUndoCommand;
+
+/**
+ Place the texts of a symbol -- its label and the notes beside it -- as
+ one block at one of nine points around its drawing, the nine of the
+ text alignment dialog. Left of the symbol, the lines are aligned right,
+ so that the block hangs on the symbol and a longer text grows away
+ from it; right of it, aligned left; above, below and on it, centred.
+ The lines keep their order and their spacing; a group of texts is
+ placed as one line of the block, with the same alignment.
+*/
+namespace SymbolTextPlacement
+{
+ /// Room between the drawing of the symbol and the block
+ constexpr double gap = 3;
+
+ /**
+ @param elements : the symbols whose texts to place
+ @param where : the side of the drawing, as a 9-point alignment:
+ Qt::AlignLeft | Qt::AlignVCenter is left of the symbol, halfway
+ up; Qt::AlignCenter is on it
+ @return one undo step that places them (already placed), or
+ nullptr when none of the symbols has a text
+ */
+ QUndoCommand *place(const QList &elements, Qt::Alignment where);
+
+ /**
+ @return a picture of @a where: a grey square for the symbol, and
+ two bars for the lines of text where they will go, lined up as
+ they will be (left of the symbol, aligned right)
+ */
+ QIcon icon(Qt::Alignment where);
+}
+
+#endif // SYMBOLTEXTPLACEMENT_H
diff --git a/tests/qttest/CMakeLists.txt b/tests/qttest/CMakeLists.txt
index 4ca44ded7..62b1db945 100644
--- a/tests/qttest/CMakeLists.txt
+++ b/tests/qttest/CMakeLists.txt
@@ -122,6 +122,15 @@ if(Python3_Interpreter_FOUND AND CMAKE_GENERATOR STREQUAL "Ninja")
--fixture ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/linked_reports.qet)
set_tests_properties(tst_reportjumpintegration PROPERTIES TIMEOUT 300 RUN_SERIAL TRUE
ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
+ # "Place symbol texts": label and notes as one block at one of nine
+ # points beside the drawing, aligned to hang on it; one undo step.
+ add_test(NAME tst_symboltextplacementintegration
+ COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_symbol_text_placement_probe.py
+ --build ${CMAKE_BINARY_DIR} --binary $
+ --source ${CMAKE_CURRENT_SOURCE_DIR}/symbol_text_placement_probe.cpp
+ --fixture ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/unlinked_contact_label.qet)
+ set_tests_properties(tst_symboltextplacementintegration PROPERTIES TIMEOUT 300 RUN_SERIAL TRUE
+ ENVIRONMENT "QT_QPA_PLATFORM=offscreen")
endif()
if(Python3_Interpreter_FOUND AND CMAKE_GENERATOR STREQUAL "Ninja")
add_test(NAME tst_darkimageintegration
diff --git a/tests/qttest/run_symbol_text_placement_probe.py b/tests/qttest/run_symbol_text_placement_probe.py
new file mode 100755
index 000000000..789954e6b
--- /dev/null
+++ b/tests/qttest/run_symbol_text_placement_probe.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+"""Link the symbol text placement integration probe using an existing Ninja app build.
+
+Reuses app objects without duplicating the app or introducing a core-library
+refactor. No application source or existing executable is replaced. The
+generated manifest, probe binary, reports and export fixtures stay in build/.
+"""
+import argparse
+import pathlib
+import re
+import shutil
+import subprocess
+import sys
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--build', required=True)
+parser.add_argument('--binary', required=True)
+parser.add_argument('--source', required=True)
+parser.add_argument('--fixture', required=True)
+args = parser.parse_args()
+build = pathlib.Path(args.build).resolve()
+binary = pathlib.Path(args.binary).resolve()
+source = pathlib.Path(args.source).resolve()
+fixture = pathlib.Path(args.fixture).resolve()
+manifest = (build / 'build.ninja').read_text(encoding='utf-8')
+match = re.search(r'^build (\S*?/sources/main\.cpp\.(?:obj|o)):', manifest, re.MULTILINE)
+if not match:
+ sys.exit('Cannot find the application main object in the Ninja build.')
+main_object = match.group(1)
+probe_object = main_object.replace('main.cpp.', 'symbol_text_placement_probe.cpp.')
+probe_binary = binary.with_name('symbol_text_placement_probe' + binary.suffix)
+def escape(path):
+ return pathlib.Path(path).as_posix().replace('$', '$$').replace(':', '$:').replace(' ', '$ ')
+main_source = source.parents[2] / 'sources' / 'main.cpp'
+manifest = manifest.replace(main_object, probe_object)
+manifest = manifest.replace(escape(main_source), escape(source))
+if binary.suffix:
+ manifest = manifest.replace(binary.name, probe_binary.name)
+else:
+ old_target = escape(binary.name if binary.parent == build else binary)
+ new_target = escape(probe_binary.name if probe_binary.parent == build else probe_binary)
+ manifest = manifest.replace('build ' + old_target + ':', 'build ' + new_target + ':')
+ old_file = binary.name if binary.parent == build else binary.as_posix()
+ new_file = probe_binary.name if probe_binary.parent == build else probe_binary.as_posix()
+ manifest = re.sub(r'^ TARGET_FILE = ' + re.escape(old_file) + r'$',
+ ' TARGET_FILE = ' + new_file, manifest, flags=re.MULTILINE)
+probe_manifest = build / 'symbol-text-placement-probe.ninja'
+probe_manifest.write_text(manifest, encoding='utf-8')
+ninja = shutil.which('ninja')
+if not ninja:
+ sys.exit('Ninja is required for the integration probe.')
+target = probe_binary.name if probe_binary.parent == build else str(probe_binary)
+subprocess.run([ninja, '-C', str(build), '-f', probe_manifest.name, target], check=True)
+output = build / 'symbol-text-placement'
+output.mkdir(exist_ok=True)
+report = output / 'results.txt'
+result = subprocess.run([str(probe_binary), str(fixture), str(report), str(output)], timeout=90)
+if report.exists():
+ print(report.read_text(encoding='utf-8', errors='replace'))
+sys.exit(result.returncode)
diff --git a/tests/qttest/symbol_text_placement_probe.cpp b/tests/qttest/symbol_text_placement_probe.cpp
new file mode 100644
index 000000000..1b5271ebc
--- /dev/null
+++ b/tests/qttest/symbol_text_placement_probe.cpp
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Placing the texts of a symbol at one of nine points, linked against the
+// application's objects.
+//
+// "Place symbol texts" puts the label and the notes of a symbol as one
+// block beside its drawing, 3 px away, at one of the nine points of the
+// text alignment dialog. Left of the symbol the lines are aligned right,
+// so that they hang on it and a longer text grows away from it; right of
+// it aligned left; above it centred. The lines keep their order and their
+// spacing, a group of texts is placed as one line, a turned symbol is
+// placed in the folio's directions, and one undo puts everything back.
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../../sources/diagram.h"
+#include "../../sources/qetproject.h"
+#include "../../sources/qetmessagebox.h"
+#include "../../sources/symboltextplacement.h"
+#include "../../sources/qetgraphicsitem/element.h"
+#include "../../sources/qetgraphicsitem/dynamicelementtextitem.h"
+#include "../../sources/qetgraphicsitem/elementtextitemgroup.h"
+
+static void check(bool value, const char *message)
+{
+ if (!value) throw std::runtime_error(message);
+ std::printf("ok: %s\n", message);
+}
+
+static bool same(qreal a, qreal b) { return qAbs(a - b) < 0.6; }
+
+static QRectF body(Element *e) { return e->mapRectToScene(e->drawingRect()); }
+
+static QRectF block(const QList &texts)
+{
+ QRectF r;
+ for (DynamicElementTextItem *t : texts) r |= t->sceneBoundingRect();
+ return r;
+}
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ std::freopen(argv[2], "w", stdout);
+
+ QTemporaryDir settings;
+ QSettings::setDefaultFormat(QSettings::IniFormat);
+ QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, settings.path());
+ QCoreApplication::setOrganizationName("QETSymbolTextPlacementRegression");
+ QETProject::setBackupEnabled(false);
+ QET::QetMessageBox::setNonInteractive(true);
+ QFontDatabase::addApplicationFont(":/fonts/LiberationSans-Regular.ttf");
+
+ try
+ {
+ QETProject project(QString::fromLocal8Bit(argv[1]));
+ check(project.state() == QETProject::Ok, "fixture opens");
+ project.buildFolios(project.diagrams());
+ Diagram *scene = project.diagrams().first();
+ Element *element = scene->elements().first();
+ check(element && !element->drawingRect().isEmpty(), "the fixture has a drawn symbol");
+ check(element->drawingRect().width() <= element->boundingRect().width(),
+ "the drawing is no wider than the frame");
+
+ //The symbol's own texts and three of ours, to the right of it
+ for (DynamicElementTextItem *t : element->dynamicTextItems()) t->setVisible(false);
+ QList texts;
+ const QStringList lines {"-FI1", "40 A / 30 mA, type A", "FI UG"};
+ for (int i = 0; i < lines.size(); ++i) {
+ auto *t = new DynamicElementTextItem(element);
+ t->setTextFrom(DynamicElementTextItem::UserText);
+ t->setText(lines[i]);
+ t->setPos(80 + 5 * i, -20 + 12 * i);
+ element->addDynamicTextItem(t);
+ texts << t;
+ }
+ QList start;
+ for (DynamicElementTextItem *t : texts) start << t->pos();
+ const QRectF before = block(texts);
+
+ // Left of the symbol, halfway up: aligned right, 3 px away.
+ QUndoCommand *undo = SymbolTextPlacement::place({element}, Qt::AlignLeft | Qt::AlignVCenter);
+ check(undo, "placing gives one undo step");
+ scene->undoStack().push(undo);
+ QRectF b = block(texts);
+ check(same(b.right(), body(element).left() - SymbolTextPlacement::gap), "left: the block ends 3 px before the drawing");
+ check(same(b.center().y(), body(element).center().y()), "left: halfway up the drawing");
+ bool right_aligned = true, keeps_order = true;
+ for (int i = 0; i < texts.size(); ++i) {
+ right_aligned &= same(texts[i]->sceneBoundingRect().right(), b.right());
+ right_aligned &= bool(texts[i]->alignment() & Qt::AlignRight);
+ if (i) keeps_order &= same(texts[i]->sceneBoundingRect().top() - texts[i-1]->sceneBoundingRect().top(), 12);
+ }
+ check(right_aligned, "left: the lines are aligned right, on the screen and as their alignment");
+ check(keeps_order, "the lines keep their order and their spacing");
+ check(same(b.height(), before.height()), "the block keeps its height");
+
+ scene->undoStack().undo();
+ bool back = true;
+ for (int i = 0; i < texts.size(); ++i) back &= texts[i]->pos() == start[i] && !(texts[i]->alignment() & Qt::AlignRight);
+ check(back, "one undo puts every text and its alignment back");
+ scene->undoStack().redo();
+
+ // Right of it: aligned left. Above it: centred.
+ scene->undoStack().push(SymbolTextPlacement::place({element}, Qt::AlignRight | Qt::AlignVCenter));
+ b = block(texts);
+ check(same(b.left(), body(element).right() + SymbolTextPlacement::gap), "right: the block starts 3 px after the drawing");
+ check(same(texts[1]->sceneBoundingRect().left(), b.left()) && (texts[1]->alignment() & Qt::AlignLeft),
+ "right: the lines are aligned left");
+ scene->undoStack().push(SymbolTextPlacement::place({element}, Qt::AlignHCenter | Qt::AlignTop));
+ b = block(texts);
+ check(same(b.bottom(), body(element).top() - SymbolTextPlacement::gap), "above: the block ends 3 px above the drawing");
+ check(same(texts[0]->sceneBoundingRect().center().x(), body(element).center().x()), "above: the lines are centred on it");
+
+ // A turned symbol: left in the folio is still left.
+ element->setRotation(90);
+ scene->undoStack().push(SymbolTextPlacement::place({element}, Qt::AlignLeft | Qt::AlignVCenter));
+ b = block(texts);
+ check(same(b.right(), body(element).left() - SymbolTextPlacement::gap), "turned symbol: the block is left of it in the folio");
+ element->setRotation(0);
+
+ // A group of texts is one line of the block, aligned like it.
+ ElementTextItemGroup *group = element->addTextGroup(QStringLiteral("g"));
+ element->addTextToGroup(texts[1], group);
+ element->addTextToGroup(texts[2], group);
+ scene->undoStack().push(SymbolTextPlacement::place({element}, Qt::AlignLeft | Qt::AlignVCenter));
+ QRectF with_group = texts[0]->sceneBoundingRect() | group->sceneBoundingRect();
+ check(same(with_group.right(), body(element).left() - SymbolTextPlacement::gap)
+ && same(group->sceneBoundingRect().right(), with_group.right()),
+ "a group is placed as one line of the block");
+ check(group->alignment() == Qt::AlignRight, "and is aligned right too");
+
+ // A group whose texts lie freely (AlignJustify, the default of the
+ // "Label and comment" group): placing it lays its texts out anew,
+ // and one undo puts them back where they lay, not only the group.
+ scene->undoStack().undo();
+ group->setAlignment(Qt::AlignJustify);
+ texts[1]->setPos(0, 0);
+ texts[2]->setPos(5, 12);
+ const QPointF group_pos = group->pos();
+ scene->undoStack().push(SymbolTextPlacement::place({element}, Qt::AlignRight | Qt::AlignVCenter));
+ check(texts[2]->pos() != QPointF(5, 12), "placing lays the group's texts out anew");
+ scene->undoStack().undo();
+ check(group->alignment() == Qt::AlignJustify && group->pos() == group_pos,
+ "undo puts the group's alignment and place back");
+ check(texts[1]->pos() == QPointF(0, 0) && texts[2]->pos() == QPointF(5, 12),
+ "undo puts the group's texts back where they lay");
+ scene->undoStack().redo();
+ check(group->alignment() == Qt::AlignLeft && texts[2]->pos() != QPointF(5, 12),
+ "redo places them again");
+
+ // A symbol with no texts: nothing to undo.
+ Element *other = nullptr;
+ for (Element *e : scene->elements()) if (e != element) other = e;
+ if (other) {
+ for (DynamicElementTextItem *t : other->dynamicTextItems()) t->setVisible(false);
+ check(SymbolTextPlacement::place({other}, Qt::AlignLeft) == nullptr, "a symbol without texts gives no undo step");
+ }
+ // The icons show where the texts go: bars left of the grey square
+ // for "left", right of it for "right", above it for "above".
+ auto dark = [](const QImage &img, const QRect &r) {
+ int n = 0;
+ for (int y = r.top(); y <= r.bottom(); ++y)
+ for (int x = r.left(); x <= r.right(); ++x) {
+ const QColor c = img.pixelColor(x, y);
+ if (c.alpha() > 128 && c.lightness() < 60) ++n;
+ }
+ return n;
+ };
+ const QImage left = SymbolTextPlacement::icon(Qt::AlignLeft | Qt::AlignVCenter).pixmap(24, 24).toImage();
+ const QImage right = SymbolTextPlacement::icon(Qt::AlignRight | Qt::AlignVCenter).pixmap(24, 24).toImage();
+ const QImage above = SymbolTextPlacement::icon(Qt::AlignHCenter | Qt::AlignTop).pixmap(24, 24).toImage();
+ check(dark(left, QRect(0, 8, 7, 8)) > 10 && dark(left, QRect(17, 0, 7, 24)) == 0, "the icon for left has its bars left of the symbol");
+ check(dark(right, QRect(17, 8, 7, 8)) > 10 && dark(right, QRect(0, 0, 7, 24)) == 0, "the icon for right has them right of it");
+ check(dark(above, QRect(6, 0, 12, 7)) > 10 && dark(above, QRect(0, 17, 24, 7)) == 0, "the icon for above has them above it");
+
+ //All nine side by side, to look at
+ QImage sheet(3 * 52, 3 * 52, QImage::Format_ARGB32);
+ sheet.fill(Qt::white);
+ QPainter p(&sheet);
+ const Qt::Alignment nine[] = {
+ Qt::AlignLeft | Qt::AlignTop, Qt::AlignHCenter | Qt::AlignTop, Qt::AlignRight | Qt::AlignTop,
+ Qt::AlignLeft | Qt::AlignVCenter, Qt::AlignCenter, Qt::AlignRight | Qt::AlignVCenter,
+ Qt::AlignLeft | Qt::AlignBottom, Qt::AlignHCenter | Qt::AlignBottom, Qt::AlignRight | Qt::AlignBottom};
+ for (int i = 0; i < 9; ++i)
+ p.drawPixmap((i % 3) * 52 + 2, (i / 3) * 52 + 2, SymbolTextPlacement::icon(nine[i]).pixmap(48, 48));
+ p.end();
+ if (argc > 3) sheet.save(QString::fromLocal8Bit(argv[3]) + "/icons.png");
+
+ std::puts("PASS");
+ }
+ catch (const std::exception &error)
+ {
+ std::printf("FAIL: %s\n", error.what());
+ std::fflush(stdout);
+ return 1;
+ }
+ std::fflush(stdout);
+ return 0;
+}