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; +}