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 sheet Mostra 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 sheet Zobrazit/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 sheet Vis 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 sheet Zeige 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 sheet Display 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 sheet Muestra 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 sheet Affiche 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 sheet Megjelení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 sheet Visualizzare 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 sheet Vis 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 sheet Toon 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 sheet Verbergen 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 sheet Pokaż 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 sheet Mostrar 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 sheet Mostrar 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 sheet Zobraziť/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 sheet Visar 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 sheet Sayfaları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)