diff --git a/lang/qet_ar.ts b/lang/qet_ar.ts
index 4c98ff6a3..b65342b21 100644
--- a/lang/qet_ar.ts
+++ b/lang/qet_ar.ts
@@ -12279,6 +12279,16 @@ Available options:
Display or hide the grid of sheetعرض أو إخفاء شبكة الصفخات
+
+
+ Folio-wide crosshair
+ تقاطع خطين على كامل الورقة
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ يعرض خطين عبر الورقة بأكملها تحت مؤشر الفأرة لمعرفة ما إذا كانت العناصر على استقامة واحدة
+ Text grid
diff --git a/lang/qet_ca.ts b/lang/qet_ca.ts
index 2e5c983ba..69c0712f3 100644
--- a/lang/qet_ca.ts
+++ b/lang/qet_ca.ts
@@ -12303,6 +12303,16 @@ Opcions disponibles:
Display or hide the grid of sheetMostra o oculta la quadrícula
+
+
+ Folio-wide crosshair
+ Retícula a tot el full
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Mostra dues línies a tot el full sota el ratolí, per veure si els elements estan alineats
+ Text grid
diff --git a/lang/qet_cs.ts b/lang/qet_cs.ts
index c61d1dcff..87a23d8ef 100644
--- a/lang/qet_cs.ts
+++ b/lang/qet_cs.ts
@@ -12077,6 +12077,16 @@ Dostupné volby:
Display or hide the grid of sheetZobrazit/Skrýt mřížku listů
+
+
+ Folio-wide crosshair
+ Zaměřovací kříž přes celý list
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Zobrazí pod myší dvě čáry přes celý list, aby bylo vidět, zda jsou prvky zarovnané
+ Sheet properties
diff --git a/lang/qet_da.ts b/lang/qet_da.ts
index a22493f84..c6f35b9f3 100644
--- a/lang/qet_da.ts
+++ b/lang/qet_da.ts
@@ -12033,6 +12033,16 @@ Kommandovalg:
Display or hide the grid of sheetVis eller skjul ark gitter
+
+
+ Folio-wide crosshair
+ Trådkors over hele arket
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Viser to linjer over hele arket under musen for at se, om delene flugter
+ Sheet properties
diff --git a/lang/qet_de.ts b/lang/qet_de.ts
index dd75b6f52..9d09ac2ba 100644
--- a/lang/qet_de.ts
+++ b/lang/qet_de.ts
@@ -12557,6 +12557,16 @@ Verfügbare Optionen:
Display or hide the grid of sheetZeige den Hintergrundsraster der Seiten an
+
+
+ Folio-wide crosshair
+ Fadenkreuz über die ganze Seite
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Zeigt unter dem Mauszeiger zwei Linien über die ganze Seite, um zu sehen, ob Teile fluchten
+ Add row
diff --git a/lang/qet_el.ts b/lang/qet_el.ts
index 2b7d767a2..372cd8cee 100644
--- a/lang/qet_el.ts
+++ b/lang/qet_el.ts
@@ -13662,6 +13662,16 @@ To make a script of it, ask your AI assistant: the button below copies the reque
Display or hide the grid of sheetΕμφάνιση ή απόκρυψη του δικτυώματος της σελίδας
+
+
+ Folio-wide crosshair
+ Σταυρόνημα σε όλο το φύλλο
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Εμφανίζει δύο γραμμές σε όλο το φύλλο κάτω από το ποντίκι, για να φαίνεται αν τα στοιχεία είναι ευθυγραμμισμένα
+ View the guides
diff --git a/lang/qet_en.ts b/lang/qet_en.ts
index 03fa0d57c..073319f60 100644
--- a/lang/qet_en.ts
+++ b/lang/qet_en.ts
@@ -12162,6 +12162,16 @@ Available options:
Display or hide the grid of sheetDisplay or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Folio-wide crosshair
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Sheet properties
diff --git a/lang/qet_es.ts b/lang/qet_es.ts
index 5f25e7457..94479a1d4 100644
--- a/lang/qet_es.ts
+++ b/lang/qet_es.ts
@@ -12278,6 +12278,16 @@ Opciones disponibles:
Display or hide the grid of sheetMuestra u oculta la cuadrícula
+
+
+ Folio-wide crosshair
+ Retícula en toda la hoja
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Muestra dos líneas en toda la hoja bajo el ratón, para ver si los elementos están alineados
+ Text grid
diff --git a/lang/qet_fi.ts b/lang/qet_fi.ts
index 236b2209a..458c5a65b 100644
--- a/lang/qet_fi.ts
+++ b/lang/qet_fi.ts
@@ -11839,6 +11839,16 @@ Available options:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Hiusristikko koko arkin yli
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Näyttää hiiren kohdalla kaksi viivaa koko arkin yli, jotta näkee, ovatko osat linjassa
+ Sheet properties
diff --git a/lang/qet_fr.ts b/lang/qet_fr.ts
index f85d7059b..397092a04 100644
--- a/lang/qet_fr.ts
+++ b/lang/qet_fr.ts
@@ -12242,6 +12242,16 @@ Options disponibles :
Display or hide the grid of sheetAffiche ou masque la grille des folios
+
+
+ Folio-wide crosshair
+ Réticule sur tout le folio
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Affiche deux lignes sur tout le folio sous la souris, pour voir si les éléments sont alignés
+ Sheet properties
diff --git a/lang/qet_hr.ts b/lang/qet_hr.ts
index e4e031c60..5a2859f14 100644
--- a/lang/qet_hr.ts
+++ b/lang/qet_hr.ts
@@ -12101,6 +12101,16 @@ Dostupne opcije:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Križić preko cijelog lista
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Prikazuje dvije linije preko cijelog lista ispod miša, kako bi se vidjelo jesu li dijelovi poravnati
+ Text grid
diff --git a/lang/qet_hu.ts b/lang/qet_hu.ts
index 96af82793..b47305ef0 100644
--- a/lang/qet_hu.ts
+++ b/lang/qet_hu.ts
@@ -12019,6 +12019,16 @@ Elérhető lehetőségek:
Display or hide the grid of sheetMegjeleníti vagy elrejti a tervlap rácsát
+
+
+ Folio-wide crosshair
+ Szálkereszt a teljes lapon
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Két vonalat mutat a teljes lapon az egér alatt, hogy látszódjon, egy vonalban vannak-e az elemek
+ Sheet properties
diff --git a/lang/qet_it.ts b/lang/qet_it.ts
index 6fc0245ec..52a4638c8 100644
--- a/lang/qet_it.ts
+++ b/lang/qet_it.ts
@@ -12171,6 +12171,16 @@ Ecco gli ultimi messaggi registrati prima della chiusura — puoi salvarli per i
Display or hide the grid of sheetVisualizzare o nasacondere la griglia delle pagina
+
+
+ Folio-wide crosshair
+ Mirino su tutta la pagina
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Mostra due linee su tutta la pagina sotto il mouse, per vedere se gli elementi sono allineati
+ Select
diff --git a/lang/qet_ja.ts b/lang/qet_ja.ts
index 5fcf767e6..653b046b4 100644
--- a/lang/qet_ja.ts
+++ b/lang/qet_ja.ts
@@ -12303,6 +12303,16 @@ Available options:
Display or hide the grid of sheetフォリオのグリッドの表示/非表示
+
+
+ Folio-wide crosshair
+ シート全体の十字カーソル
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ マウス位置にシート全体を横切る2本の線を表示し、部品が揃っているか確認します
+ Text grid
diff --git a/lang/qet_ko.ts b/lang/qet_ko.ts
index df751ee0e..3a13de182 100644
--- a/lang/qet_ko.ts
+++ b/lang/qet_ko.ts
@@ -11935,6 +11935,16 @@ Available options:
Display or hide the grid of sheet시트의 격자를 표시하거나 숨깁니다
+
+
+ Folio-wide crosshair
+ 시트 전체 십자선
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ 마우스 아래에 시트 전체를 가로지르는 두 선을 표시하여 부품이 정렬되었는지 확인합니다
+ Sheet properties
diff --git a/lang/qet_mn.ts b/lang/qet_mn.ts
index ea25db2dc..200656576 100644
--- a/lang/qet_mn.ts
+++ b/lang/qet_mn.ts
@@ -12045,6 +12045,16 @@ Available options:
Display or hide the grid of sheetХуудасны хэрээсийг харуулах эсвэл нуух
+
+
+ Folio-wide crosshair
+ Бүтэн хуудасны загалмай заагч
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Хулганы доор бүтэн хуудсыг дайрсан хоёр шугам харуулж, эд ангиуд нэг шугамд байгаа эсэхийг харна
+ Sheet properties
diff --git a/lang/qet_nb.ts b/lang/qet_nb.ts
index ba9642481..5c410f7bb 100644
--- a/lang/qet_nb.ts
+++ b/lang/qet_nb.ts
@@ -12060,6 +12060,16 @@ Tilgjengelige opsjoner:
Display or hide the grid of sheetVis rasteret på sidene
+
+
+ Folio-wide crosshair
+ Trådkors over hele arket
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Viser to linjer over hele arket under musepekeren for å se om delene står på linje
+ Sheet properties
diff --git a/lang/qet_nl.ts b/lang/qet_nl.ts
index 55d95bfca..4b7119468 100644
--- a/lang/qet_nl.ts
+++ b/lang/qet_nl.ts
@@ -12029,6 +12029,16 @@ Opties :
Display or hide the grid of sheetToon of verberg het raster
+
+
+ Folio-wide crosshair
+ Dradenkruis over het hele blad
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Toont twee lijnen over het hele blad onder de muis, om te zien of onderdelen uitgelijnd zijn
+ Sheet properties
diff --git a/lang/qet_nl_BE.ts b/lang/qet_nl_BE.ts
index 7eb26c79f..4f43b7cd2 100644
--- a/lang/qet_nl_BE.ts
+++ b/lang/qet_nl_BE.ts
@@ -12076,6 +12076,16 @@ Beschikbare opties:
Display or hide the grid of sheetVerbergen of weergeven raster op de bladzijden
+
+
+ Folio-wide crosshair
+ Dradenkruis over het hele blad
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Toont twee lijnen over het hele blad onder de muis, om te zien of onderdelen uitgelijnd zijn
+ Sheet properties
diff --git a/lang/qet_nl_NL.ts b/lang/qet_nl_NL.ts
index aaaa4bc44..dca5baef9 100644
--- a/lang/qet_nl_NL.ts
+++ b/lang/qet_nl_NL.ts
@@ -10263,6 +10263,16 @@ Available options:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Dradenkruis over het hele blad
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Toont twee lijnen over het hele blad onder de muis, om te zien of onderdelen uitgelijnd zijn
+ Text grid
diff --git a/lang/qet_no.ts b/lang/qet_no.ts
index ab289bf7e..babec885c 100644
--- a/lang/qet_no.ts
+++ b/lang/qet_no.ts
@@ -12446,6 +12446,16 @@ Available options:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Trådkors over hele arket
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Viser to linjer over hele arket under musepekeren for å se om delene står på linje
+ Text grid
diff --git a/lang/qet_pl.ts b/lang/qet_pl.ts
index 172d7a5c1..78d48306a 100644
--- a/lang/qet_pl.ts
+++ b/lang/qet_pl.ts
@@ -12238,6 +12238,16 @@ Dostępne opcje:
Display or hide the grid of sheetPokaż lub ukryj sietkę arkuszy
+
+
+ Folio-wide crosshair
+ Krzyż celowniczy na całym arkuszu
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Pokazuje dwie linie przez cały arkusz pod kursorem, aby sprawdzić, czy elementy są wyrównane
+ Sheet properties
diff --git a/lang/qet_pt.ts b/lang/qet_pt.ts
index c1efb2bfc..6ce05c3f2 100644
--- a/lang/qet_pt.ts
+++ b/lang/qet_pt.ts
@@ -12243,6 +12243,16 @@ Opções disponiveis:
Display or hide the grid of sheetMostrar ou ocultar a grelha da folha
+
+
+ Folio-wide crosshair
+ Mira em toda a folha
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Mostra duas linhas em toda a folha sob o rato, para ver se os elementos estão alinhados
+ Text grid
diff --git a/lang/qet_pt_BR.ts b/lang/qet_pt_BR.ts
index 67123e2c6..11fc96ffd 100644
--- a/lang/qet_pt_BR.ts
+++ b/lang/qet_pt_BR.ts
@@ -12173,6 +12173,16 @@ Opções disponíveis:
Display or hide the grid of sheetMostrar ou ocultar a grade das páginas
+
+
+ Folio-wide crosshair
+ Mira em toda a folha
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Mostra duas linhas em toda a folha sob o mouse, para ver se os elementos estão alinhados
+ Sheet properties
diff --git a/lang/qet_ro.ts b/lang/qet_ro.ts
index ffa05a0c1..17aa10713 100644
--- a/lang/qet_ro.ts
+++ b/lang/qet_ro.ts
@@ -12458,6 +12458,16 @@ Opțiuni disponibile:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Reticul pe toată foaia
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Afișează două linii pe toată foaia sub mouse, pentru a vedea dacă elementele sunt aliniate
+ Text grid
diff --git a/lang/qet_rs.ts b/lang/qet_rs.ts
index 6da2153ca..55c85f480 100644
--- a/lang/qet_rs.ts
+++ b/lang/qet_rs.ts
@@ -12090,6 +12090,16 @@ Available options:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Nišanski krst preko celog lista
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Prikazuje dve linije preko celog lista ispod miša, da bi se videlo da li su delovi poravnati
+ Text grid
diff --git a/lang/qet_ru.ts b/lang/qet_ru.ts
index f6b37aa21..a011ba790 100644
--- a/lang/qet_ru.ts
+++ b/lang/qet_ru.ts
@@ -12382,6 +12382,16 @@ Available options:
Display or hide the grid of sheetПоказать или скрыть сетку листа
+
+
+ Folio-wide crosshair
+ Перекрестие на весь лист
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Показывает под указателем мыши две линии через весь лист, чтобы видеть, выровнены ли элементы
+ Text grid
diff --git a/lang/qet_sk.ts b/lang/qet_sk.ts
index f40cb0c22..204f00bca 100644
--- a/lang/qet_sk.ts
+++ b/lang/qet_sk.ts
@@ -12031,6 +12031,16 @@ Dostupné možnosti:
Display or hide the grid of sheetZobraziť/Schovať mriežku listov
+
+
+ Folio-wide crosshair
+ Zameriavací kríž cez celý list
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Zobrazí pod myšou dve čiary cez celý list, aby bolo vidieť, či sú prvky zarovnané
+ Sheet properties
diff --git a/lang/qet_sl.ts b/lang/qet_sl.ts
index 2030e62a9..734f724e6 100644
--- a/lang/qet_sl.ts
+++ b/lang/qet_sl.ts
@@ -12134,6 +12134,16 @@ Available options:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Merilni križ čez cel list
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Pod miško prikaže dve črti čez cel list, da se vidi, ali so deli poravnani
+ Text grid
diff --git a/lang/qet_sr.ts b/lang/qet_sr.ts
index c864b00d5..04a2942c0 100644
--- a/lang/qet_sr.ts
+++ b/lang/qet_sr.ts
@@ -12090,6 +12090,16 @@ Available options:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Нишански крст преко целог листа
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Приказује две линије преко целог листа испод миша, да би се видело да ли су делови поравнати
+ Text grid
diff --git a/lang/qet_sv.ts b/lang/qet_sv.ts
index 860ba56ab..1b17d28db 100644
--- a/lang/qet_sv.ts
+++ b/lang/qet_sv.ts
@@ -12274,6 +12274,16 @@ Tillgängliga alternativ :
Display or hide the grid of sheetVisar eller döljer rutnät på blad
+
+
+ Folio-wide crosshair
+ Hårkors över hela bladet
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Visar två linjer över hela bladet under musen för att se om delarna är i linje
+ Text grid
diff --git a/lang/qet_tr.ts b/lang/qet_tr.ts
index 6b1cb2b6a..a51874c31 100644
--- a/lang/qet_tr.ts
+++ b/lang/qet_tr.ts
@@ -12080,6 +12080,16 @@ Mevcut seçenekler:
Display or hide the grid of sheetSayfaların ızgarasını göster veya gizle
+
+
+ Folio-wide crosshair
+ Tüm sayfa boyunca artı imleç
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Parçaların hizalı olup olmadığını görmek için farenin altında tüm sayfa boyunca iki çizgi gösterir
+ Sheet properties
diff --git a/lang/qet_uk.ts b/lang/qet_uk.ts
index 48c576c4f..dbf9a4b55 100644
--- a/lang/qet_uk.ts
+++ b/lang/qet_uk.ts
@@ -12440,6 +12440,16 @@ Available options:
Display or hide the grid of sheet
+
+
+ Folio-wide crosshair
+ Перехрестя на весь аркуш
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ Показує під вказівником миші дві лінії через увесь аркуш, щоб бачити, чи вирівняні елементи
+ Text grid
diff --git a/lang/qet_zh.ts b/lang/qet_zh.ts
index d7c60f815..7641bea0d 100644
--- a/lang/qet_zh.ts
+++ b/lang/qet_zh.ts
@@ -12089,6 +12089,16 @@ Available options:
Display or hide the grid of sheet显示或隐藏页面网格
+
+
+ Folio-wide crosshair
+ 整页十字光标
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ 在鼠标处显示贯穿整页的两条线,以查看元件是否对齐
+ Sheet properties
diff --git a/lang/qet_zh_TW.ts b/lang/qet_zh_TW.ts
index 1ea518956..0009b1cc7 100644
--- a/lang/qet_zh_TW.ts
+++ b/lang/qet_zh_TW.ts
@@ -12089,6 +12089,16 @@ Available options:
Display or hide the grid of sheet顯示或隱藏頁面網格
+
+
+ Folio-wide crosshair
+ 整頁十字游標
+
+
+
+ Show two lines across the whole folio under the mouse, to see whether parts are in line
+ 在滑鼠處顯示貫穿整頁的兩條線,以檢查元件是否對齊
+ Sheet properties
diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp
index 288ee0915..115cf47ac 100644
--- a/sources/diagramview.cpp
+++ b/sources/diagramview.cpp
@@ -47,6 +47,7 @@
#include "utils/conductorcreator.h"
#include "undocommand/addgraphicsobjectcommand.h"
#include "diagram.h"
+#include
#include "foliogrid.h"
#include "diagramcontexttoolbar.h"
#include "imagedrop.h"
@@ -1040,6 +1041,7 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e)
{
m_last_mouse_pos = e->pos();
setToolTip(tr("X: %1 Y: %2").arg(e->pos().x()).arg(e->pos().y()));
+ moveCrosshair(e->pos());
if (m_event_interface && m_event_interface->mouseMoveEvent(e)) return;
if (m_gesture_tracking)
@@ -1840,6 +1842,117 @@ void DiagramView::setCellLinesShown(bool shown)
viewport()->update();
}
+namespace {
+ /// The setting, read once and then kept here for every view
+ int s_crosshair = -1;
+}
+
+/**
+ @brief DiagramView::crosshairShown
+ @return true when the folio-wide crosshair follows the mouse: two thin
+ lines across the whole folio, through the grid point under the mouse,
+ to see at a glance whether symbols and terminals are in line. Drawn
+ on screen only, never exported nor printed.
+*/
+bool DiagramView::crosshairShown()
+{
+ if (s_crosshair < 0) {
+ QSettings settings;
+ s_crosshair = settings.value(QStringLiteral("diagrameditor/crosshair"), false).toBool();
+ }
+ return s_crosshair;
+}
+
+/**
+ @brief DiagramView::setCrosshairShown
+ @param shown : show the folio-wide crosshair in every view; kept in
+ the settings. The views repaint themselves at the next mouse move.
+*/
+void DiagramView::setCrosshairShown(bool shown)
+{
+ s_crosshair = shown;
+ QSettings settings;
+ settings.setValue(QStringLiteral("diagrameditor/crosshair"), shown);
+}
+
+/**
+ @brief DiagramView::crosshairArea
+ @return the part of the viewport the two lines through @a scene_pos
+ cover, a little wider than the lines
+*/
+QRect DiagramView::crosshairArea(const QPointF &scene_pos) const
+{
+ const QPoint p = mapFromScene(scene_pos);
+ const QRect all = viewport()->rect();
+ return QRect(all.left(), p.y() - 2, all.width(), 5)
+ | QRect(p.x() - 2, all.top(), 5, all.height());
+}
+
+/**
+ @brief DiagramView::moveCrosshair
+ Follow the mouse with the crosshair, on the grid, repainting only the
+ lines it leaves and the lines it draws.
+ @param viewport_pos : the mouse, in viewport coordinates
+*/
+void DiagramView::moveCrosshair(const QPoint &viewport_pos)
+{
+ if (!crosshairShown()) {
+ hideCrosshair();
+ return;
+ }
+ const QPointF pos = Diagram::snapToGrid(mapToScene(viewport_pos));
+ if (m_crosshair_visible && pos == m_crosshair_pos)
+ return;
+ if (m_crosshair_visible)
+ viewport()->update(crosshairArea(m_crosshair_pos));
+ m_crosshair_pos = pos;
+ m_crosshair_visible = true;
+ viewport()->update(crosshairArea(m_crosshair_pos));
+}
+
+/**
+ @brief DiagramView::hideCrosshair
+ Take the crosshair away, when the mouse leaves the view or the
+ setting is switched off.
+*/
+void DiagramView::hideCrosshair()
+{
+ if (!m_crosshair_visible)
+ return;
+ m_crosshair_visible = false;
+ viewport()->update(crosshairArea(m_crosshair_pos));
+}
+
+/**
+ @brief DiagramView::drawForeground
+ Over everything else, the folio-wide crosshair, inside the folio's
+ border only.
+ @param painter
+ @param rect
+*/
+void DiagramView::drawForeground(QPainter *painter, const QRectF &rect)
+{
+ PaletteGraphicsView::drawForeground(painter, rect);
+ if (!m_crosshair_visible || !crosshairShown() || !m_diagram)
+ return;
+
+ const QRectF area = m_diagram->border_and_titleblock.insideBorderRect();
+ if (!area.contains(m_crosshair_pos))
+ return;
+
+ QPainter *p = scenePainter(painter);
+ p->save();
+ QPen pen(Diagram::background_color == Qt::darkGray ? QColor(Qt::lightGray)
+ : QColor(0, 120, 215));
+ pen.setCosmetic(true);
+ pen.setWidthF(0);
+ p->setPen(pen);
+ p->setRenderHint(QPainter::Antialiasing, false);
+ p->drawLine(QLineF(area.left(), m_crosshair_pos.y(), area.right(), m_crosshair_pos.y()));
+ p->drawLine(QLineF(m_crosshair_pos.x(), area.top(), m_crosshair_pos.x(), area.bottom()));
+ p->restore();
+}
+
/**
@brief DiagramView::drawBackground
Reimplemented from PaletteGraphicsView: over the folio background, the
@@ -1976,6 +2089,9 @@ bool DiagramView::viewportEvent(QEvent *event)
if (event->type() == QEvent::Resize) {
placeCellRulers();
}
+ if (event->type() == QEvent::Leave) {
+ hideCrosshair();
+ }
return PaletteGraphicsView::viewportEvent(event);
}
diff --git a/sources/diagramview.h b/sources/diagramview.h
index 2453e7b4b..6a00b4b0f 100644
--- a/sources/diagramview.h
+++ b/sources/diagramview.h
@@ -74,6 +74,11 @@ class DiagramView : public PaletteGraphicsView
QPoint m_gesture_origin;
DiagramGestureOverlay *m_gesture_overlay = nullptr;
QPoint m_last_mouse_pos = QPoint(-1, -1);
+ QPointF m_crosshair_pos;
+ bool m_crosshair_visible = false;
+ void moveCrosshair(const QPoint &viewport_pos);
+ void hideCrosshair();
+ QRect crosshairArea(const QPointF &scene_pos) const;
QPointF m_drag_last_pos;
bool m_fresh_focus_in,
m_first_activation = true;
@@ -111,6 +116,12 @@ class DiagramView : public PaletteGraphicsView
QPointF defaultPlacementPos() const;
void setCellRulersShown(bool shown);
void setCellLinesShown(bool shown);
+ /// The folio-wide crosshair under the mouse (Display menu),
+ /// one setting for every view
+ static bool crosshairShown();
+ static void setCrosshairShown(bool shown);
+ bool crosshairVisible() const { return m_crosshair_visible; }
+ QPointF crosshairPos() const { return m_crosshair_pos; }
protected:
void mouseDoubleClickEvent(QMouseEvent *) override;
@@ -127,6 +138,7 @@ class DiagramView : public PaletteGraphicsView
void paintEvent(QPaintEvent *event) override;
bool viewportEvent(QEvent *event) override;
void drawBackground(QPainter *painter, const QRectF &rect) override;
+ void drawForeground(QPainter *painter, const QRectF &rect) override;
void paintingInverted(bool inverted) override;
void mousePressEvent(QMouseEvent *) override;
void mouseMoveEvent(QMouseEvent *) override;
diff --git a/sources/qetdiagrameditor.cpp b/sources/qetdiagrameditor.cpp
index 955d61159..527623837 100644
--- a/sources/qetdiagrameditor.cpp
+++ b/sources/qetdiagrameditor.cpp
@@ -590,6 +590,19 @@ void QETDiagramEditor::setUpActions()
}
});
+ //A crosshair across the whole folio under the mouse, to see
+ //whether symbols and terminals are in line
+ m_crosshair = new QAction(tr("Folio-wide crosshair"), this);
+ ShortcutManager::instance().registerAction(m_crosshair, "diagrameditor.crosshair", tr("Diagram editors"), QKeySequence());
+ m_crosshair->setStatusTip(tr("Show two lines across the whole folio under the mouse, to see whether parts are in line"));
+ m_crosshair->setCheckable(true);
+ m_crosshair->setChecked(DiagramView::crosshairShown());
+ connect(m_crosshair, &QAction::triggered, [this](bool checked) {
+ DiagramView::setCrosshairShown(checked);
+ for (DiagramView *view : findChildren())
+ view->viewport()->update();
+ });
+
//Snap step for dragged texts, as a fraction of the folio grid
m_text_grid_menu = new QMenu(tr("Text grid"), this);
m_text_grid_menu->setIcon(QET::Icons::Grid);
@@ -1703,6 +1716,7 @@ void QETDiagramEditor::setUpMenu()
menu_affichage -> addAction(m_mode_visualise);
menu_affichage -> addSeparator();
menu_affichage -> addAction(m_draw_grid);
+ menu_affichage -> addAction(m_crosshair);
menu_affichage -> addMenu(m_text_grid_menu);
menu_affichage -> addAction(m_draw_guides);
menu_affichage -> addAction(m_cell_rulers);
diff --git a/sources/qetdiagrameditor.h b/sources/qetdiagrameditor.h
index 891d02e7a..df1d2c1bb 100644
--- a/sources/qetdiagrameditor.h
+++ b/sources/qetdiagrameditor.h
@@ -264,6 +264,7 @@ class QETDiagramEditor : public QETMainWindow
*m_configure_duplicate, ///< Reopen the duplicate offset/direction dialog (#991)
*m_auto_conductor, ///< Enable/Disable the use of auto conductor
*m_auto_break_conductor, ///< Enable/Disable the use of auto break conductor
+ *m_crosshair, ///< Show the folio-wide crosshair
*m_add_cable = nullptr, ///< Draw the trunk line of a cable
*m_draw_grid, ///< Switch the background grid display or not
*m_draw_guides = nullptr, ///< Switch the custom guides display or not
diff --git a/tests/qttest/CMakeLists.txt b/tests/qttest/CMakeLists.txt
index 55b60d702..644cf4725 100644
--- a/tests/qttest/CMakeLists.txt
+++ b/tests/qttest/CMakeLists.txt
@@ -103,6 +103,15 @@ if(Python3_Interpreter_FOUND AND CMAKE_GENERATOR STREQUAL "Ninja")
--source ${CMAKE_CURRENT_SOURCE_DIR}/cable_undo_probe.cpp
--fixture ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/unlinked_contact_label.qet)
set_tests_properties(tst_cableundointegration PROPERTIES TIMEOUT 300 RUN_SERIAL TRUE)
+ # The folio-wide crosshair follows the mouse on the grid, on screen
+ # only, and goes when the mouse leaves or the option is off.
+ add_test(NAME tst_crosshairintegration
+ COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/run_crosshair_probe.py
+ --build ${CMAKE_BINARY_DIR} --binary $
+ --source ${CMAKE_CURRENT_SOURCE_DIR}/crosshair_probe.cpp
+ --fixture ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/unlinked_contact_label.qet)
+ set_tests_properties(tst_crosshairintegration 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/crosshair_probe.cpp b/tests/qttest/crosshair_probe.cpp
new file mode 100644
index 000000000..66573e45d
--- /dev/null
+++ b/tests/qttest/crosshair_probe.cpp
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// The folio-wide crosshair, linked against the application's objects.
+//
+// With the Display option on, two lines cross the whole folio through the
+// grid point under the mouse, to see at a glance whether parts are in
+// line. They are drawn on screen only: no item is added to the folio, so
+// nothing of them is saved, exported or printed. They go when the mouse
+// leaves the view and when the option is off, and the option is kept in
+// the settings.
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "../../sources/diagram.h"
+#include "../../sources/diagramview.h"
+#include "../../sources/qetproject.h"
+#include "../../sources/qetmessagebox.h"
+
+static void check(bool value, const char *message)
+{
+ if (!value) throw std::runtime_error(message);
+ std::printf("ok: %s\n", message);
+}
+
+static void moveTo(DiagramView &view, const QPoint &p)
+{
+ QMouseEvent event(QEvent::MouseMove, QPointF(p), view.viewport()->mapToGlobal(QPointF(p)),
+ Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ QApplication::sendEvent(view.viewport(), &event);
+}
+
+/// How many pixels of the crosshair colour lie along one row of the view
+static int bluePixels(const QImage &image, int row)
+{
+ int n = 0;
+ for (int x = 0; x < image.width(); ++x) {
+ const QColor c = image.pixelColor(x, row);
+ if (c.blue() > 150 && c.red() < 80) ++n;
+ }
+ return n;
+}
+
+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("QETCrosshairRegression");
+ 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 *folio = project.diagrams().first();
+
+ DiagramView view(folio);
+ view.resize(800, 600);
+ view.centerOn(folio->border_and_titleblock.insideBorderRect().center());
+ QApplication::processEvents();
+ const int items = folio->items().size();
+
+ check(!DiagramView::crosshairShown(), "off by default");
+ const QPoint mouse(403, 297);
+ moveTo(view, mouse);
+ check(!view.crosshairVisible(), "no crosshair while the option is off");
+
+ DiagramView::setCrosshairShown(true);
+ moveTo(view, mouse);
+ check(view.crosshairVisible(), "the crosshair follows the mouse once on");
+ const QPointF at = view.crosshairPos();
+ check(at == Diagram::snapToGrid(view.mapToScene(mouse)), "it stands on the grid point under the mouse");
+ check(folio->items().size() == items, "nothing is added to the folio");
+
+ const QImage image = view.viewport()->grab().toImage();
+ const int row = view.mapFromScene(at).y();
+ check(bluePixels(image, row) > image.width() / 2, "a line crosses the view through that point");
+ check(bluePixels(image, row + 20) < image.width() / 4, "and not elsewhere");
+
+ QEvent leave(QEvent::Leave);
+ QApplication::sendEvent(view.viewport(), &leave);
+ check(!view.crosshairVisible(), "it goes when the mouse leaves the view");
+
+ DiagramView::setCrosshairShown(false);
+ moveTo(view, mouse);
+ check(!view.crosshairVisible(), "and when the option is switched off");
+ check(!QSettings().value("diagrameditor/crosshair").toBool(), "the option is kept in the settings");
+ 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;
+}
diff --git a/tests/qttest/run_crosshair_probe.py b/tests/qttest/run_crosshair_probe.py
new file mode 100755
index 000000000..ad7efb2f7
--- /dev/null
+++ b/tests/qttest/run_crosshair_probe.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python3
+"""Link the crosshair 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.', 'crosshair_probe.cpp.')
+probe_binary = binary.with_name('crosshair_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 / 'crosshair-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 / 'crosshair'
+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)