Files
qelectrotech-source-mirror/sources/editor/ui/qetelementeditor.ui
T
ispyisail 8a72230916 Add "Export to SVG" to the element editor
Implements discussion #605. The diagram editor can already export a folio
to SVG; the element editor, where a single .elmt symbol is drawn, had no
export capability at all -- confirmed by grepping its header for "export"
before starting: nothing.

## Renders the live scene, not ElementPictureFactory's cache

The discussion proposed sourcing this from ElementPictureFactory's cached
per-element QPicture (m_pictures_H), the one used for the elements-panel
preview icons. Checked that cache's actual invalidation before building on
it: nothing in the editor ever tells it to drop an entry on edit, and it is
keyed by the element's on-disk uuid. So for any element already previewed
once in the panel, exporting from the cache would silently produce stale
content after any edit; for a brand-new, never-saved element, no entry
would exist at all. Neither is acceptable for a File > Export action a
user expects to reflect what's on screen right now.

Renders ElementScene directly instead, the same way
ExportDialog::generateSvg() already renders the live Diagram for the
diagram editor's own SVG export: no new drawing logic, only a new playback
target (QSvgGenerator instead of the screen), sized to the element's own
content bounds via the existing elementSceneGeometricRect() helper.

## Hotspot cross excluded from the export

ElementScene::drawForeground() draws the red origin/hotspot cross on every
render() call, unconditionally -- it's an editing aid, not part of the
element being drawn, and diagram editor's SVG export has no equivalent
problem since Diagram doesn't draw one. Added a settable
hotspotVisible flag, defaulting to true (the existing editing view is
completely unaffected) and turned off only for the duration of the export
render() call.

## Verified end-to-end via a real Xvfb session, not just a build

Opened a real shipped element (en_60617_05_06_04.elmt, "Phototransistor"),
exported it, and rendered the resulting SVG back to a bitmap with a small
QSvgRenderer-based harness -- pixel-identical in shape to the element as
shown in the editor. Confirmed the file is valid XML and contains no
red/#ff0000 stroke (the hotspot cross did not leak in).

Then the case the whole "render live, not cached" decision was about:
opened the same element, drew a new line with the line tool, and exported
again *without saving*. The new line is present in the exported SVG.
git status on the source .elmt file after both exports shows it completely
untouched -- the export is read-only and reflects live, unsaved editor
state, exactly the property a cache-based implementation would have gotten
wrong.

Built clean, no new warnings.
2026-08-02 23:06:12 +12:00

560 lines
19 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QETElementEditor</class>
<widget class="QMainWindow" name="QETElementEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>QElectroTech - Éditeur d'élément</string>
</property>
<property name="windowIcon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/qet.png</normaloff>:/ico/16x16/qet.png</iconset>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="m_file_menu">
<property name="title">
<string>&amp;Fichier</string>
</property>
<addaction name="m_new_action"/>
<addaction name="m_open_action"/>
<addaction name="m_open_from_file_action"/>
<addaction name="m_import_scaled_element"/>
<addaction name="m_import_dxf"/>
<addaction name="m_save_action"/>
<addaction name="m_save_as_action"/>
<addaction name="m_save_as_file_action"/>
<addaction name="m_export_svg_action"/>
<addaction name="separator"/>
<addaction name="m_reload_action"/>
<addaction name="separator"/>
<addaction name="m_quit_action"/>
</widget>
<widget class="QMenu" name="m_edit_menu">
<property name="title">
<string>&amp;Édition</string>
</property>
<widget class="QMenu" name="m_paste_from_menu">
<property name="title">
<string>Coller depuis...</string>
</property>
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/edit-paste.png</normaloff>:/ico/16x16/edit-paste.png</iconset>
</property>
<addaction name="m_paste_from_file_action"/>
<addaction name="m_paste_from_element_action"/>
</widget>
<addaction name="separator"/>
<addaction name="m_select_all_act"/>
<addaction name="m_deselect_all_action"/>
<addaction name="m_revert_selection_action"/>
<addaction name="separator"/>
<addaction name="m_cut_action"/>
<addaction name="m_copy_action"/>
<addaction name="m_paste_action"/>
<addaction name="m_paste_in_area_action"/>
<addaction name="m_paste_from_menu"/>
<addaction name="separator"/>
<addaction name="m_delete_action"/>
<addaction name="separator"/>
<addaction name="m_edit_names_action"/>
<addaction name="m_edit_author_action"/>
<addaction name="m_edit_element_properties_action"/>
<addaction name="m_rotate_action"/>
<addaction name="m_rotateFine_action"/>
<addaction name="m_mirror_action"/>
<addaction name="m_flip_action"/>
</widget>
<widget class="QMenu" name="m_display_menu">
<property name="title">
<string>Afficha&amp;ge</string>
</property>
<addaction name="m_zoom_in_action"/>
<addaction name="m_zoom_out_action"/>
<addaction name="m_zoom_fit_best_action"/>
<addaction name="m_zoom_original_action"/>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menu_Aide">
<property name="title">
<string>&amp;Aide</string>
</property>
<addaction name="separator"/>
<addaction name="m_online_manual"/>
<addaction name="m_youtube_action"/>
<addaction name="m_donate_action"/>
<addaction name="m_about_qt_action"/>
<addaction name="m_about_qet_action"/>
</widget>
<addaction name="m_file_menu"/>
<addaction name="m_edit_menu"/>
<addaction name="m_display_menu"/>
<addaction name="menu_Aide"/>
</widget>
<widget class="QDockWidget" name="m_undo_dock">
<property name="allowedAreas">
<set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Annulations</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents"/>
</widget>
<widget class="QDockWidget" name="m_parts_dock">
<property name="allowedAreas">
<set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Parties</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2"/>
</widget>
<widget class="QDockWidget" name="m_tools_dock">
<property name="allowedAreas">
<set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set>
</property>
<property name="windowTitle">
<string>Informations</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_3"/>
</widget>
<widget class="QToolBar" name="m_main_toolbar">
<property name="windowTitle">
<string>Outils</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="m_new_action"/>
<addaction name="m_open_action"/>
<addaction name="m_save_action"/>
<addaction name="m_save_as_action"/>
<addaction name="m_reload_action"/>
<addaction name="m_delete_action"/>
</widget>
<widget class="QToolBar" name="m_view_toolbar">
<property name="windowTitle">
<string>Affichage</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="m_zoom_in_action"/>
<addaction name="m_zoom_out_action"/>
<addaction name="m_zoom_fit_best_action"/>
<addaction name="m_zoom_original_action"/>
</widget>
<widget class="QToolBar" name="m_element_toolbar">
<property name="windowTitle">
<string>Élément</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="m_edit_names_action"/>
<addaction name="m_edit_element_properties_action"/>
</widget>
<widget class="QToolBar" name="m_undo_toolbar">
<property name="windowTitle">
<string>Annulation</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<action name="m_select_all_act">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/edit-select-all.png</normaloff>:/ico/16x16/edit-select-all.png</iconset>
</property>
<property name="text">
<string>Tout sélectionner</string>
</property>
</action>
<action name="m_new_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/document-new.png</normaloff>:/ico/22x22/document-new.png</iconset>
</property>
<property name="text">
<string>&amp;Nouveau</string>
</property>
</action>
<action name="m_open_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/folder-open.png</normaloff>:/ico/22x22/folder-open.png</iconset>
</property>
<property name="text">
<string>&amp;Ouvrir</string>
</property>
</action>
<action name="m_open_from_file_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/folder-open.png</normaloff>:/ico/22x22/folder-open.png</iconset>
</property>
<property name="text">
<string>&amp;Ouvrir depuis un fichier</string>
</property>
</action>
<action name="m_save_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/document-save.png</normaloff>:/ico/22x22/document-save.png</iconset>
</property>
<property name="text">
<string>&amp;Enregistrer</string>
</property>
</action>
<action name="m_save_as_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/document-save-as.png</normaloff>:/ico/22x22/document-save-as.png</iconset>
</property>
<property name="text">
<string>Enregistrer sous</string>
</property>
</action>
<action name="m_save_as_file_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/document-save.png</normaloff>:/ico/22x22/document-save.png</iconset>
</property>
<property name="text">
<string>Enregistrer dans un fichier</string>
</property>
</action>
<action name="m_export_svg_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/document-export.png</normaloff>:/ico/22x22/document-export.png</iconset>
</property>
<property name="text">
<string>Exporter en SVG</string>
</property>
</action>
<action name="m_reload_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/view-refresh.png</normaloff>:/ico/22x22/view-refresh.png</iconset>
</property>
<property name="text">
<string>Recharger</string>
</property>
</action>
<action name="m_quit_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/application-exit.png</normaloff>:/ico/16x16/application-exit.png</iconset>
</property>
<property name="text">
<string>&amp;Fermer cet éditeur</string>
</property>
<property name="toolTip">
<string>Fermer cet éditeur</string>
</property>
</action>
<action name="m_deselect_all_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/edit-select-none.png</normaloff>:/ico/16x16/edit-select-none.png</iconset>
</property>
<property name="text">
<string>Désélectionner tout</string>
</property>
</action>
<action name="m_cut_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/edit-cut.png</normaloff>:/ico/16x16/edit-cut.png</iconset>
</property>
<property name="text">
<string>Co&amp;uper</string>
</property>
</action>
<action name="m_copy_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/edit-copy.png</normaloff>:/ico/16x16/edit-copy.png</iconset>
</property>
<property name="text">
<string>Cop&amp;ier</string>
</property>
</action>
<action name="m_paste_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/edit-paste.png</normaloff>:/ico/16x16/edit-paste.png</iconset>
</property>
<property name="text">
<string>C&amp;oller</string>
</property>
</action>
<action name="m_paste_in_area_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/edit-paste.png</normaloff>:/ico/16x16/edit-paste.png</iconset>
</property>
<property name="text">
<string>C&amp;oller dans la zone</string>
</property>
</action>
<action name="m_paste_from_file_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/text-xml.png</normaloff>:/ico/16x16/text-xml.png</iconset>
</property>
<property name="text">
<string>Un fichier</string>
</property>
</action>
<action name="m_paste_from_element_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/element.png</normaloff>:/ico/16x16/element.png</iconset>
</property>
<property name="text">
<string>Un élément</string>
</property>
</action>
<action name="m_revert_selection_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/edit-select-invert.png</normaloff>:/ico/16x16/edit-select-invert.png</iconset>
</property>
<property name="text">
<string>Inverser la sélection</string>
</property>
</action>
<action name="m_delete_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/edit-delete.png</normaloff>:/ico/22x22/edit-delete.png</iconset>
</property>
<property name="text">
<string>&amp;Supprimer</string>
</property>
</action>
<action name="m_edit_names_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/names.png</normaloff>:/ico/22x22/names.png</iconset>
</property>
<property name="text">
<string>Éditer le nom et les traductions de l'élément</string>
</property>
</action>
<action name="m_edit_author_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/preferences-desktop-user.png</normaloff>:/ico/16x16/preferences-desktop-user.png</iconset>
</property>
<property name="text">
<string>Éditer les informations sur l'auteur</string>
</property>
</action>
<action name="m_edit_element_properties_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/element-edit.png</normaloff>:/ico/22x22/element-edit.png</iconset>
</property>
<property name="text">
<string>Éditer les propriétés de l'élément</string>
</property>
</action>
<action name="m_zoom_in_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/zoom-in.png</normaloff>:/ico/22x22/zoom-in.png</iconset>
</property>
<property name="text">
<string>Zoom avant</string>
</property>
</action>
<action name="m_zoom_out_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/zoom-out.png</normaloff>:/ico/22x22/zoom-out.png</iconset>
</property>
<property name="text">
<string>Zoom arrière</string>
</property>
</action>
<action name="m_zoom_fit_best_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/zoom-fit-best.png</normaloff>:/ico/22x22/zoom-fit-best.png</iconset>
</property>
<property name="text">
<string>Zoom adapté</string>
</property>
</action>
<action name="m_zoom_original_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/zoom-original.png</normaloff>:/ico/22x22/zoom-original.png</iconset>
</property>
<property name="text">
<string>Pas de zoom</string>
</property>
</action>
<action name="m_about_qet_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/qet.png</normaloff>:/ico/16x16/qet.png</iconset>
</property>
<property name="text">
<string>À &amp;propos de QElectroTech</string>
</property>
<property name="statusTip">
<string>Affiche des informations sur QElectroTech</string>
</property>
</action>
<action name="m_online_manual">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/help-contents.png</normaloff>:/ico/16x16/help-contents.png</iconset>
</property>
<property name="text">
<string>Manuel en ligne</string>
</property>
<property name="statusTip">
<string>Lance le navigateur par défaut vers le manuel en ligne de QElectroTech</string>
</property>
</action>
<action name="m_youtube_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/kdenlive-show-video.png</normaloff>:/ico/16x16/kdenlive-show-video.png</iconset>
</property>
<property name="text">
<string>Chaine Youtube</string>
</property>
<property name="statusTip">
<string>Lance le navigateur par défaut vers la chaine Youtube de QElectroTech</string>
</property>
</action>
<action name="m_donate_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/help-donate.png</normaloff>:/ico/16x16/help-donate.png</iconset>
</property>
<property name="text">
<string>Soutenir le projet par un don</string>
</property>
<property name="statusTip">
<string>Soutenir le projet QElectroTech par un don</string>
</property>
</action>
<action name="m_about_qt_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/qt.png</normaloff>:/ico/16x16/qt.png</iconset>
</property>
<property name="text">
<string>À propos de &amp;Qt</string>
</property>
<property name="statusTip">
<string>Affiche des informations sur la bibliothèque Qt</string>
</property>
</action>
<action name="m_rotate_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/orientations.png</normaloff>:/ico/16x16/orientations.png</iconset>
</property>
<property name="text">
<string>Rotation</string>
</property>
</action>
<action name="m_rotateFine_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/orientations.png</normaloff>:/ico/16x16/orientations.png</iconset>
</property>
<property name="text">
<string>Fine-Rotation</string>
</property>
</action>
<action name="m_mirror_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/mirror.png</normaloff>:/ico/16x16/mirror.png</iconset>
</property>
<property name="text">
<string>Mirror</string>
</property>
</action>
<action name="m_flip_action">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/flip.png</normaloff>:/ico/16x16/flip.png</iconset>
</property>
<property name="text">
<string>Flip</string>
</property>
</action>
<action name="m_import_dxf">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/16x16/run-dxf.png</normaloff>:/ico/16x16/run-dxf.png</iconset>
</property>
<property name="text">
<string>Importer un dxf</string>
</property>
</action>
<action name="m_import_scaled_element">
<property name="icon">
<iconset resource="../../../qelectrotech.qrc">
<normaloff>:/ico/22x22/folder-open.png</normaloff>:/ico/22x22/folder-open.png</iconset>
</property>
<property name="text">
<string>importer un élément à redimensionner</string>
</property>
</action>
</widget>
<resources>
<include location="../../../qelectrotech.qrc"/>
</resources>
<connections/>
</ui>