From aa50562e38218bb95fe14c22df6ea2f649678eba Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 20 May 2026 22:52:34 +0200 Subject: [PATCH 01/12] [consider merging] Fixed a type bug in l2n reader --- src/db/db/dbLayoutToNetlistReader.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/db/dbLayoutToNetlistReader.cc b/src/db/db/dbLayoutToNetlistReader.cc index b4dcf2608..2a62e55ef 100644 --- a/src/db/db/dbLayoutToNetlistReader.cc +++ b/src/db/db/dbLayoutToNetlistReader.cc @@ -458,7 +458,7 @@ void LayoutToNetlistStandardReader::read_netlist (db::Netlist *netlist, db::Layo std::string param_name; read_word_or_quoted (param_name); int primary = read_int (); - int default_value = read_double (); + double default_value = read_double (); if (! dc->has_parameter_with_name (param_name)) { db::DeviceParameterDefinition pd; pd.set_name (param_name); From 014f3d064426e0faf94bba587a143671c92d6d27 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 21 May 2026 19:27:48 +0200 Subject: [PATCH 02/12] [consider merging] tab order in density map dialog --- src/plugins/tools/density_map/lay_plugin/DensityMapDialog.ui | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/tools/density_map/lay_plugin/DensityMapDialog.ui b/src/plugins/tools/density_map/lay_plugin/DensityMapDialog.ui index ded9b81ce..b099be6a8 100644 --- a/src/plugins/tools/density_map/lay_plugin/DensityMapDialog.ui +++ b/src/plugins/tools/density_map/lay_plugin/DensityMapDialog.ui @@ -552,6 +552,8 @@ le_pixel_size + le_window_size + cb_boundary_mode sb_threads layer_cb cb_source_layer From b5be4fc497c92e858bee9c6e6303090bf775d50e Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 00:00:30 +0200 Subject: [PATCH 03/12] Small bugfix on object snap - observe snap directions Problem: snapping with angle constraints and object snapping sometimes gave results not conforming to the angle constaints. This happened when shape edges are parallel to the cutlines that define the angle constraint. --- src/laybasic/laybasic/laySnap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/laybasic/laybasic/laySnap.cc b/src/laybasic/laybasic/laySnap.cc index 7088b5fe9..e53b25794 100644 --- a/src/laybasic/laybasic/laySnap.cc +++ b/src/laybasic/laybasic/laySnap.cc @@ -554,7 +554,7 @@ private: } } - if (! any_point) { + if (! any_point && ! m_projection_constraint) { // no certain direction to look into: // compute the projection of the point and if within a From 4d77056da1e1f8030be955820566a0192e8011d7 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 00:11:57 +0200 Subject: [PATCH 04/12] For more clarity change 'snap to objects (unless disabled in template)' to 'never snap to object' (inverted) in rulers config. --- src/ant/ant/RulerConfigPage4.ui | 6 +++--- src/ant/ant/antConfigPage.cc | 4 ++-- src/doc/doc/manual/ruler_properties.xml | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ant/ant/RulerConfigPage4.ui b/src/ant/ant/RulerConfigPage4.ui index 1f5ec4a29..c732cebde 100644 --- a/src/ant/ant/RulerConfigPage4.ui +++ b/src/ant/ant/RulerConfigPage4.ui @@ -594,12 +594,12 @@ - + If checked, snap to edges or vertices of objects unless disabled above - Snap to objects + Never snap to objects @@ -893,7 +893,7 @@ style_cb outline_cb t_angle_cb - t_snap_cbx + t_never_snap_cbx diff --git a/src/ant/ant/antConfigPage.cc b/src/ant/ant/antConfigPage.cc index f92c2c58e..9706615ef 100644 --- a/src/ant/ant/antConfigPage.cc +++ b/src/ant/ant/antConfigPage.cc @@ -375,7 +375,7 @@ ConfigPage4::show () mp_ui->style_cb->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].style ()); mp_ui->outline_cb->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].outline ()); mp_ui->t_angle_cb->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].angle_constraint ()); - mp_ui->t_snap_cbx->setChecked (m_ruler_templates [m_current_template].snap ()); + mp_ui->t_never_snap_cbx->setChecked (! m_ruler_templates [m_current_template].snap ()); mp_ui->t_mode_cb->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].mode ()); mp_ui->main_position->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].main_position ()); @@ -410,7 +410,7 @@ ConfigPage4::commit () ant::Template::ruler_mode_type mode = ant::Template::ruler_mode_type (mp_ui->t_mode_cb->currentIndex ()); m_ruler_templates [m_current_template].set_mode (mode); - m_ruler_templates [m_current_template].snap (mp_ui->t_snap_cbx->isChecked ()); + m_ruler_templates [m_current_template].snap (! mp_ui->t_never_snap_cbx->isChecked ()); m_ruler_templates [m_current_template].set_main_position (Object::position_type (mp_ui->main_position->currentIndex ())); m_ruler_templates [m_current_template].set_main_xalign (Object::alignment_type (mp_ui->main_xalign->currentIndex ())); diff --git a/src/doc/doc/manual/ruler_properties.xml b/src/doc/doc/manual/ruler_properties.xml index 8a23920d4..184c02f41 100644 --- a/src/doc/doc/manual/ruler_properties.xml +++ b/src/doc/doc/manual/ruler_properties.xml @@ -33,14 +33,14 @@ just being horizontal. By default, the ruler uses the global setting. It can however be configured to provide its own constraint. -
  • Object snapping: each ruler can be configure to snap to the closest object edge or vertex. - By default, the rulers use the global setting. It may be disabled however for each ruler. -
  • Mode: in normal mode, two clicks are required to define a ruler: to set the first point and to set the second one. In "Single click" mode, a single click will set both points to the same. In "Auto measure" mode, the points will be determined by looking for edges in the vicinity of the click point and adjusting the points accordingly.
  • +
  • Never snap to objects: if this option is on, the ruler never snaps to drawing + objects, even if that global option is enabled. +
  • From e42bb63e8a1e0d53e4c98db6c8c138b64f20ce40 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 00:13:51 +0200 Subject: [PATCH 05/12] Renaming 'editor options' to 'tool options' --- src/lay/lay/layMainWindow.cc | 4 ++-- src/layview/layview/layEditorOptionsPages.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index f63026e95..2ad58023c 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -290,7 +290,7 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) connect (mp_libs_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); m_libs_visible = true; - mp_eo_dock_widget = new QDockWidget (QObject::tr ("Editor Options"), this); + mp_eo_dock_widget = new QDockWidget (QObject::tr ("Tool Options"), this); mp_eo_dock_widget->setObjectName (QString::fromUtf8 ("eo_dock_widget")); mp_eo_dock_widget->setMinimumHeight (150); mp_eo_stack = new ControlWidgetStack (mp_eo_dock_widget, "eo_stack"); @@ -4502,7 +4502,7 @@ public: at = "edit_menu.end"; menu_entries.push_back (lay::separator ("edit_options_group:edit_mode", "edit_menu.end")); - menu_entries.push_back (lay::menu_item ("cm_edit_options", "edit_options:edit_mode", "edit_menu.end", tl::to_string (QObject::tr ("Editor Options")) + "(F3)")); + menu_entries.push_back (lay::menu_item ("cm_edit_options", "edit_options:edit_mode", "edit_menu.end", tl::to_string (QObject::tr ("Tool Options")) + "(F3)")); at = "file_menu.end"; menu_entries.push_back (lay::menu_item ("cm_new_layout", "new_layout:edit:edit_mode", at, tl::to_string (QObject::tr ("New Layout")))); diff --git a/src/layview/layview/layEditorOptionsPages.cc b/src/layview/layview/layEditorOptionsPages.cc index 6e3dd2d6a..3bc397f9b 100644 --- a/src/layview/layview/layEditorOptionsPages.cc +++ b/src/layview/layview/layEditorOptionsPages.cc @@ -482,7 +482,7 @@ EditorOptionsModalPages::update_title () if (mp_single_page) { setWindowTitle (tl::to_qstring (mp_single_page->title ())); } else { - setWindowTitle (tr ("Editor Options")); + setWindowTitle (tr ("Tool Options")); } } From 3371333dd7a2878eb99173e4e90f82fc8f4601b3 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 00:14:18 +0200 Subject: [PATCH 06/12] img plugin does not need editor options pages. --- src/img/img/imgPlugin.cc | 9 --------- src/img/img/imgPlugin.h | 1 - 2 files changed, 10 deletions(-) diff --git a/src/img/img/imgPlugin.cc b/src/img/img/imgPlugin.cc index 3438f7343..ea435d66a 100644 --- a/src/img/img/imgPlugin.cc +++ b/src/img/img/imgPlugin.cc @@ -62,15 +62,6 @@ PluginDeclaration::get_options (std::vector < std::pair (cfg_images_visible, "true")); } -std::vector -PluginDeclaration::additional_editor_options_pages () const -{ - std::vector names; - // TODO: provide in a central place instead of borrowing from the edt module - names.push_back ("GenericEditorOptions"); - return names; -} - static tl::RegisteredClass config_decl (new img::PluginDeclaration (), 4000, "img::Plugin"); } diff --git a/src/img/img/imgPlugin.h b/src/img/img/imgPlugin.h index 0214662fc..3302cbc3c 100644 --- a/src/img/img/imgPlugin.h +++ b/src/img/img/imgPlugin.h @@ -39,7 +39,6 @@ public: virtual lay::Plugin *create_plugin (db::Manager *manager, lay::Dispatcher *, lay::LayoutViewBase *view) const; virtual bool implements_editable (std::string &title) const; virtual void get_options (std::vector < std::pair > &options) const; - virtual std::vector additional_editor_options_pages () const; }; } From 98a8d370aaed52a05b6f7c7108901418916b228a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 00:15:51 +0200 Subject: [PATCH 07/12] Tweaking the snap behavior on ruler move a little. --- src/ant/ant/antService.cc | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/ant/ant/antService.cc b/src/ant/ant/antService.cc index fe45fbecb..faed89a27 100644 --- a/src/ant/ant/antService.cc +++ b/src/ant/ant/antService.cc @@ -1610,7 +1610,7 @@ Service::move_transform (const db::DPoint & /*p*/, db::DFTrans tr, lay::angle_co return; } - auto ac_eff = ac == lay::AC_Global ? m_snap_mode : ac; + auto ac_eff = ac == lay::AC_Global ? lay::AC_Any : ac; clear_mouse_cursors (); if (m_move_mode == MoveSelected) { @@ -1634,11 +1634,12 @@ Service::move (const db::DPoint &p, lay::angle_constraint_type ac) return; } - auto ac_eff = ac == lay::AC_Global ? m_snap_mode : ac; clear_mouse_cursors (); if (m_move_mode == MoveSelected) { + auto ac_eff = ac == lay::AC_Global ? lay::AC_Any : ac; + db::DVector dp = p - m_p1; dp = lay::snap_angle (dp, ac_eff); @@ -1656,7 +1657,28 @@ Service::move (const db::DPoint &p, lay::angle_constraint_type ac) } else if (m_move_mode != MoveNone) { - db::DPoint ps = snap2_visual (m_p1, p, &m_current, ac); + db::DPoint ps; + + if (m_move_mode == MoveP1 && m_current.segments () == 1) { + + // when moving p1 in a normal ruler, observe the currently active angle constraints and use p2 as reference + db::DPoint pref = m_current.seg_p2 (m_seg_index); + ps = snap2_visual (pref, p, &m_current, ac); + + } else if (m_move_mode == MoveP2 && m_current.segments () == 1) { + + // when moving p2 in a normal ruler, observe the currently active angle constraints and use p1 as reference + db::DPoint pref = m_current.seg_p1 (m_seg_index); + ps = snap2_visual (pref, p, &m_current, ac); + + } else { + + // other move modes use the angle constraint imposed by the modifier buttons + // and the start point for reference + ps = snap2_visual (m_p1, p, &m_current, ac == lay::AC_Global ? lay::AC_Any : ac); + + } + m_trans = db::DTrans (ps - m_p1); apply_partial_move (ps); From c8362d16f133a41e4ce94812be0b9c7f2ad25ce0 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 00:16:35 +0200 Subject: [PATCH 08/12] Adding a ruler options widget page --- src/ant/ant/RulerOptions.ui | 242 +++++++++++++++++++++++++++++ src/ant/ant/ant.pro | 3 + src/ant/ant/antRulerOptionsPage.cc | 114 ++++++++++++++ src/ant/ant/antRulerOptionsPage.h | 62 ++++++++ 4 files changed, 421 insertions(+) create mode 100644 src/ant/ant/RulerOptions.ui create mode 100644 src/ant/ant/antRulerOptionsPage.cc create mode 100644 src/ant/ant/antRulerOptionsPage.h diff --git a/src/ant/ant/RulerOptions.ui b/src/ant/ant/RulerOptions.ui new file mode 100644 index 000000000..151f8f658 --- /dev/null +++ b/src/ant/ant/RulerOptions.ui @@ -0,0 +1,242 @@ + + + RulerOptions + + + + 0 + 0 + 400 + 446 + + + + + 0 + 0 + + + + Form + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + + + 0 + 0 + 400 + 446 + + + + + 2 + + + 4 + + + 4 + + + 4 + + + 4 + + + + + Snapping + + + + 4 + + + 4 + + + 4 + + + 4 + + + 6 + + + 2 + + + + + Snap to grid + + + + + + + Snap to edge/vertex + + + + + + + + + + Angle Constraints + + + + 4 + + + 4 + + + 4 + + + 4 + + + 6 + + + 2 + + + + + + 1 + 0 + + + + QComboBox::AdjustToContents + + + + Any Angle + + + + + Diagonal + + + + + Diagonal only + + + + + Orthogonal + + + + + Horizontal only + + + + + Vertical only + + + + + + + + Ruler direction + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Note: certain rulers may ignore these options + + + true + + + + + + + Qt::Vertical + + + + 121 + 70 + + + + + + + + + + + + scrollArea + snap_to_grid_cbx + snap_to_objects_cbx + angle_cb + + + + diff --git a/src/ant/ant/ant.pro b/src/ant/ant/ant.pro index 1d1286c73..dbd46c374 100644 --- a/src/ant/ant/ant.pro +++ b/src/ant/ant/ant.pro @@ -14,6 +14,7 @@ FORMS = \ RulerConfigPage3.ui \ RulerConfigPage4.ui \ RulerPropertiesPage.ui \ + RulerOptions.ui \ } @@ -22,10 +23,12 @@ FORMS = \ HEADERS = \ antConfigPage.h \ antPropertiesPage.h \ + antRulerOptionsPage.h SOURCES = \ antConfigPage.cc \ antPropertiesPage.cc \ + antRulerOptionsPage.cc # Enabled without Qt: diff --git a/src/ant/ant/antRulerOptionsPage.cc b/src/ant/ant/antRulerOptionsPage.cc new file mode 100644 index 000000000..4fa248315 --- /dev/null +++ b/src/ant/ant/antRulerOptionsPage.cc @@ -0,0 +1,114 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2026 Matthias Koefferlein + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "antRulerOptionsPage.h" +#include "antConfig.h" +#include "laySnap.h" +#include "layConverters.h" +#include "layDispatcher.h" +#include "tlString.h" +#include "tlClassRegistry.h" + +#include "ui_RulerOptions.h" + +namespace ant +{ + +// ------------------------------------------------------------------ +// RulerOptionsPage implementation + +RulerOptionsPage::RulerOptionsPage (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher) + : lay::EditorOptionsPageWidget (view, dispatcher) +{ + mp_ui = new Ui::RulerOptions (); + mp_ui->setupUi (this); + + connect (mp_ui->angle_cb, SIGNAL (activated (int)), this, SLOT (edited ())); + connect (mp_ui->snap_to_grid_cbx, SIGNAL (clicked ()), this, SLOT (edited ())); + connect (mp_ui->snap_to_objects_cbx, SIGNAL (clicked ()), this, SLOT (edited ())); +} + +RulerOptionsPage::~RulerOptionsPage () +{ + delete mp_ui; + mp_ui = 0; +} + +std::string +RulerOptionsPage::title () const +{ + return tl::to_string (QObject::tr ("Ruler Options")); +} + +// Must match order in angle_cb +static std::vector s_ac_options = +{ + lay::AC_Any, + lay::AC_Diagonal, + lay::AC_DiagonalOnly, + lay::AC_Ortho, + lay::AC_Horizontal, + lay::AC_Vertical +}; + +void +RulerOptionsPage::apply (lay::Dispatcher *root) +{ + lay::angle_constraint_type ac = lay::AC_Any; + int ai = mp_ui->angle_cb->currentIndex (); + if (ai >= 0 && ai < int (s_ac_options.size ())) { + ac = s_ac_options [ai]; + } + + lay::ACConverter acc; + root->config_set (cfg_ruler_snap_mode, acc.to_string (ac)); + + root->config_set (cfg_ruler_obj_snap, tl::to_string (mp_ui->snap_to_objects_cbx->isChecked ())); + root->config_set (cfg_ruler_grid_snap, tl::to_string (mp_ui->snap_to_grid_cbx->isChecked ())); +} + +void +RulerOptionsPage::setup (lay::Dispatcher *root) +{ + lay::ACConverter acc; + lay::angle_constraint_type ac; + + ac = lay::AC_Any; + root->config_get (cfg_ruler_snap_mode, ac, acc); + for (int ai = 0; ai < int (s_ac_options.size ()); ++ai) { + if (s_ac_options [ai] == ac) { + mp_ui->angle_cb->setCurrentIndex (ai); + } + } + + bool snap_to_grid = false; + root->config_get (cfg_ruler_grid_snap, snap_to_grid); + mp_ui->snap_to_grid_cbx->setChecked (snap_to_grid); + + bool snap_to_objects = false; + root->config_get (cfg_ruler_obj_snap, snap_to_objects); + mp_ui->snap_to_objects_cbx->setChecked (snap_to_objects); +} + +static tl::RegisteredClass s_factory_ruler_options (new lay::EditorOptionsPageFactory ("ant::RulerOptions"), 0); + +} diff --git a/src/ant/ant/antRulerOptionsPage.h b/src/ant/ant/antRulerOptionsPage.h new file mode 100644 index 000000000..cd934adbc --- /dev/null +++ b/src/ant/ant/antRulerOptionsPage.h @@ -0,0 +1,62 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2026 Matthias Koefferlein + + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + + +#ifndef HDR_antRulerOptionsPage +#define HDR_antRulerOptionsPage + +#include "antCommon.h" + +#include "layEditorOptionsPageWidget.h" + +namespace Ui +{ + class RulerOptions; +} + +namespace ant +{ + +/** + * @brief The generic properties page + */ +class RulerOptionsPage + : public lay::EditorOptionsPageWidget +{ +Q_OBJECT + +public: + RulerOptionsPage (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher); + ~RulerOptionsPage (); + + virtual std::string title () const; + virtual int order () const { return -10; } + void apply (lay::Dispatcher *root); + void setup (lay::Dispatcher *root); + +private: + Ui::RulerOptions *mp_ui; +}; + +} + +#endif From cb918203c715b9856d12f79820e12942909f97f7 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 00:17:25 +0200 Subject: [PATCH 09/12] Adding the ruler options widget and disabling editor options in viewer mode --- src/ant/ant/antPlugin.cc | 6 +++--- src/ant/ant/antPlugin.h | 2 +- src/edt/edt/edtPlugin.cc | 6 +++--- src/laybasic/laybasic/layMove.cc | 10 +++++++--- src/laybasic/laybasic/layPlugin.h | 2 +- src/laybasic/laybasic/laySelector.cc | 8 +++++--- src/layview/layview/gsiDeclLayPluginFactory.cc | 2 +- src/layview/layview/layEditorOptionsFrame.cc | 2 +- 8 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/ant/ant/antPlugin.cc b/src/ant/ant/antPlugin.cc index 0fc87fed9..8235a563f 100644 --- a/src/ant/ant/antPlugin.cc +++ b/src/ant/ant/antPlugin.cc @@ -25,6 +25,7 @@ #include "layConverters.h" #include "layDispatcher.h" #include "layAbstractMenu.h" +#include "layLayoutViewBase.h" #include "tlColor.h" #include "tlLog.h" #if defined(HAVE_QT) @@ -139,11 +140,10 @@ PluginDeclaration::create_plugin (db::Manager *manager, lay::Dispatcher *, lay:: } std::vector -PluginDeclaration::additional_editor_options_pages () const +PluginDeclaration::additional_editor_options_pages (lay::LayoutViewBase * /*view*/) const { std::vector names; - // TODO: provide in a central place instead of borrowing from the edt module - names.push_back ("GenericEditorOptions"); + names.push_back ("ant::RulerOptions"); return names; } diff --git a/src/ant/ant/antPlugin.h b/src/ant/ant/antPlugin.h index 334a46002..25a13a7a5 100644 --- a/src/ant/ant/antPlugin.h +++ b/src/ant/ant/antPlugin.h @@ -54,7 +54,7 @@ public: virtual void uninitialize (lay::Dispatcher *); virtual bool menu_activated (const std::string &symbol) const; - virtual std::vector additional_editor_options_pages () const; + virtual std::vector additional_editor_options_pages (lay::LayoutViewBase *view) const; void register_annotation_template (const ant::Template &t, lay::Plugin *plugin = 0); void unregister_annotation_template (const std::string &category, lay::Plugin *plugin = 0); diff --git a/src/edt/edt/edtPlugin.cc b/src/edt/edt/edtPlugin.cc index 7b803db76..1eeb20541 100644 --- a/src/edt/edt/edtPlugin.cc +++ b/src/edt/edt/edtPlugin.cc @@ -142,8 +142,8 @@ public: } } - virtual std::vector additional_editor_options_pages () const - { + virtual std::vector additional_editor_options_pages (lay::LayoutViewBase *) const + { std::vector names; names.push_back ("GenericEditorOptions"); return names; @@ -415,7 +415,7 @@ public: return true; } - virtual std::vector additional_editor_options_pages () const + virtual std::vector additional_editor_options_pages (lay::LayoutViewBase *) const { std::vector names; names.push_back ("GenericEditorOptions"); diff --git a/src/laybasic/laybasic/layMove.cc b/src/laybasic/laybasic/layMove.cc index b270ab585..f5eb6489a 100644 --- a/src/laybasic/laybasic/layMove.cc +++ b/src/laybasic/laybasic/layMove.cc @@ -482,11 +482,15 @@ public: return new MoveService (view); } - virtual std::vector additional_editor_options_pages () const + virtual std::vector additional_editor_options_pages (lay::LayoutViewBase *view) const { std::vector names; - // TODO: provide in a central place instead of borrowing from the edt module - names.push_back ("GenericEditorOptions"); + if (view->is_editable ()) { + // TODO: provide in a central place instead of borrowing from the edt module + names.push_back ("GenericEditorOptions"); + } + // TODO: provide in a central place instead of borrowing from the ant module + names.push_back ("ant::RulerOptions"); return names; } }; diff --git a/src/laybasic/laybasic/layPlugin.h b/src/laybasic/laybasic/layPlugin.h index 8b8812bed..c2a1407d2 100644 --- a/src/laybasic/laybasic/layPlugin.h +++ b/src/laybasic/laybasic/layPlugin.h @@ -354,7 +354,7 @@ public: * In addition to providing pages through "get_editor_options_pages", the plugin can request pages * from globally registered factories by name. */ - virtual std::vector additional_editor_options_pages () const + virtual std::vector additional_editor_options_pages (lay::LayoutViewBase * /*view*/) const { return std::vector (); } diff --git a/src/laybasic/laybasic/laySelector.cc b/src/laybasic/laybasic/laySelector.cc index 241b9f496..287dab404 100644 --- a/src/laybasic/laybasic/laySelector.cc +++ b/src/laybasic/laybasic/laySelector.cc @@ -333,11 +333,13 @@ public: return new SelectionService (view); } - virtual std::vector additional_editor_options_pages () const + virtual std::vector additional_editor_options_pages (lay::LayoutViewBase *view) const { std::vector names; - // TODO: provide in a central place instead of borrowing from the edt module - names.push_back ("GenericEditorOptions"); + if (view->is_editable ()) { + // TODO: provide in a central place instead of borrowing from the edt module + names.push_back ("GenericEditorOptions"); + } return names; } }; diff --git a/src/layview/layview/gsiDeclLayPluginFactory.cc b/src/layview/layview/gsiDeclLayPluginFactory.cc index ce4f81afd..bc72cd656 100644 --- a/src/layview/layview/gsiDeclLayPluginFactory.cc +++ b/src/layview/layview/gsiDeclLayPluginFactory.cc @@ -318,7 +318,7 @@ public: m_additional_editor_options_pages.push_back (name); } - virtual std::vector additional_editor_options_pages () const + virtual std::vector additional_editor_options_pages (lay::LayoutViewBase *) const { return m_additional_editor_options_pages; } diff --git a/src/layview/layview/layEditorOptionsFrame.cc b/src/layview/layview/layEditorOptionsFrame.cc index 2d6fab391..ab527000a 100644 --- a/src/layview/layview/layEditorOptionsFrame.cc +++ b/src/layview/layview/layEditorOptionsFrame.cc @@ -56,7 +56,7 @@ EditorOptionsFrame::populate (LayoutViewBase *view) for (tl::Registrar::iterator cls = tl::Registrar::begin (); cls != tl::Registrar::end (); ++cls) { cls->get_editor_options_pages (editor_options_pages, view, view->dispatcher ()); - std::vector ap = cls->additional_editor_options_pages (); + std::vector ap = cls->additional_editor_options_pages (view); for (auto i = ap.begin (); i != ap.end (); ++i) { additional_pages [*i].push_back (cls.operator-> ()); } From 4cc1d2ff9a9820ee7bc8dde44fb614e7e279a5d9 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 14:09:08 +0200 Subject: [PATCH 10/12] Fixed a potential crash This bug was triggered during development and happened because the tool bar build code was invalidating QAction objects indirectly while they are used for building the main menu. Solution is to separate building of menu bar and tool bar / context menus. --- src/laybasic/laybasic/layAbstractMenu.cc | 224 ++++++++++++----------- 1 file changed, 121 insertions(+), 103 deletions(-) diff --git a/src/laybasic/laybasic/layAbstractMenu.cc b/src/laybasic/laybasic/layAbstractMenu.cc index 637f9ab8f..3ab6d1c06 100644 --- a/src/laybasic/laybasic/layAbstractMenu.cc +++ b/src/laybasic/laybasic/layAbstractMenu.cc @@ -1280,32 +1280,139 @@ AbstractMenu::extra_menu_name () void AbstractMenu::build (QMenuBar *mbar, QToolBar *tbar) { - if (tbar) { - tbar->clear (); - } - - std::set > present_actions; + // Build the menu bar if (mbar) { + std::set > present_actions; + QList a = mbar->actions (); for (QList::const_iterator i = a.begin (); i != a.end (); ++i) { present_actions.insert (std::make_pair (id_from_action (*i), *i)); } + // NOTE: on MacOS, once the top level menu is created, we should not + // modify it and place menu items into the "Extras" menu instead. + bool menu_frozen = ! s_can_move_menu && ! present_actions.empty (); + + // NOTE: the "extras" menu is relevant on MacOS only + QMenu *extras_menu = find_extras_menu (mbar); + if (extras_menu) { + extras_menu->clear (); + } + + QAction *prev_action = 0; + + for (std::list::iterator c = m_root.children.begin (); c != m_root.children.end (); ++c) { + + if (c->has_submenu ()) { + + if (c->name ().find ("@") == 0) { + + // done later. + + } else { + + if (c->menu () == 0) { + + // NOTE: we intentionally do not make the item owner of the menu action + // as implicitly deleting it might cause trouble on MacOS. Instead we + // explicitly delete below or keep the action. + QMenu *menu = new QMenu (mp_dispatcher->menu_parent_widget ()); + menu->setTitle (tl::to_qstring (c->action ()->get_title ())); + c->set_action (new Action (menu, false), true); + + // This case happens when we dynamically create menus. + // MacOS does not like generating top-level menus dynamically, so + // we put them into the "_extra" top level one. + if (menu_frozen) { + if (extras_menu) { + extras_menu->addMenu (menu); + } + } else { + prev_action = insert_action_after (mbar, prev_action, menu->menuAction ()); + } + + } else { + + // Move the action to the end if present in the menu already + std::set >::iterator a = present_actions.find (std::make_pair (id_from_action (c->menu ()->menuAction ()), c->menu ()->menuAction ())); + if (a != present_actions.end ()) { + if (s_can_move_menu) { + mbar->removeAction (a->second); + insert_action_after (mbar, prev_action, a->second); + } + prev_action = a->second; + present_actions.erase (*a); + } else if (menu_frozen) { + if (extras_menu) { + extras_menu->addMenu (c->menu ()); + } + } else { + prev_action = insert_action_after (mbar, prev_action, c->menu ()->menuAction ()); + } + + } + + // NOTE: the "extras" menu is built implicitly. You cannot put anything there. + if (c->menu () != extras_menu) { + build (c->menu (), c->children); + } + + } + + } else { + + // Move the action to the end if present in the menu already + std::set >::iterator a = present_actions.find (std::make_pair (id_from_action (c->action ()->qaction ()), c->action ()->qaction ())); + if (a != present_actions.end ()) { + if (s_can_move_menu) { + mbar->removeAction (a->second); + insert_action_after (mbar, prev_action, a->second); + } + prev_action = a->second; + present_actions.erase (*a); + } else if (menu_frozen) { + QMenu *extras_menu = find_extras_menu (mbar); + if (extras_menu) { + extras_menu->addAction (c->action ()->qaction ()); + } + } else { + prev_action = insert_action_after (mbar, prev_action, c->action ()->qaction ()); + } + + } + + } + + // Disable the (maybe new) "extras" menu if empty + extras_menu = find_extras_menu (mbar); + if (extras_menu) { + extras_menu->setEnabled (! extras_menu->isEmpty ()); + } + + // Remove all actions that have vanished + for (std::set >::iterator a = present_actions.begin (); a != present_actions.end (); ++a) { + if (s_can_move_menu) { + mbar->removeAction (a->second); + delete a->second; + } else { + if (a->second->menu ()) { + a->second->menu ()->clear (); + } + a->second->setEnabled (false); + } + } + } - // NOTE: on MacOS, once the top level menu is created, we should not - // modify it and place menu items into the "Extras" menu instead. - bool menu_frozen = ! s_can_move_menu && ! present_actions.empty (); + // Finally build the context menus and toolbar. + // NOTE: this is done afterwards, as generating the submenus, specifically for the toolbar menu buttons + // messes with the QActions stored in "present_actions". - // NOTE: the "extras" menu is relevant on MacOS only - QMenu *extras_menu = find_extras_menu (mbar); - if (extras_menu) { - extras_menu->clear (); + if (tbar) { + tbar->clear (); } - QAction *prev_action = 0; - for (std::list::iterator c = m_root.children.begin (); c != m_root.children.end (); ++c) { if (c->has_submenu ()) { @@ -1338,100 +1445,11 @@ AbstractMenu::build (QMenuBar *mbar, QToolBar *tbar) // prepare a detached menu which can be used as context menus build (c->menu (), c->children); - } else if (mbar) { - - if (c->menu () == 0) { - - // NOTE: we intentionally do not make the item owner of the menu action - // as implicitly deleting it might cause trouble on MacOS. Instead we - // explicitly delete below or keep the action. - QMenu *menu = new QMenu (mp_dispatcher->menu_parent_widget ()); - menu->setTitle (tl::to_qstring (c->action ()->get_title ())); - c->set_action (new Action (menu, false), true); - - // This case happens when we dynamically create menus. - // MacOS does not like generating top-level menus dynamically, so - // we put them into the "_extra" top level one. - if (menu_frozen) { - if (extras_menu) { - extras_menu->addMenu (menu); - } - } else { - prev_action = insert_action_after (mbar, prev_action, menu->menuAction ()); - } - - } else { - - // Move the action to the end if present in the menu already - std::set >::iterator a = present_actions.find (std::make_pair (id_from_action (c->menu ()->menuAction ()), c->menu ()->menuAction ())); - if (a != present_actions.end ()) { - if (s_can_move_menu) { - mbar->removeAction (a->second); - insert_action_after (mbar, prev_action, a->second); - } - prev_action = a->second; - present_actions.erase (*a); - } else if (menu_frozen) { - if (extras_menu) { - extras_menu->addMenu (c->menu ()); - } - } else { - prev_action = insert_action_after (mbar, prev_action, c->menu ()->menuAction ()); - } - - } - - // NOTE: the "extras" menu is built implicitly. You cannot put anything there. - if (c->menu () != extras_menu) { - build (c->menu (), c->children); - } - - } - - } else if (mbar) { - - // Move the action to the end if present in the menu already - std::set >::iterator a = present_actions.find (std::make_pair (id_from_action (c->action ()->qaction ()), c->action ()->qaction ())); - if (a != present_actions.end ()) { - if (s_can_move_menu) { - mbar->removeAction (a->second); - insert_action_after (mbar, prev_action, a->second); - } - prev_action = a->second; - present_actions.erase (*a); - } else if (menu_frozen) { - QMenu *extras_menu = find_extras_menu (mbar); - if (extras_menu) { - extras_menu->addAction (c->action ()->qaction ()); - } - } else { - prev_action = insert_action_after (mbar, prev_action, c->action ()->qaction ()); } } } - - // Disable the (maybe new) "extras" menu if empty - extras_menu = find_extras_menu (mbar); - if (extras_menu) { - extras_menu->setEnabled (! extras_menu->isEmpty ()); - } - - // Remove all actions that have vanished - if (mbar) { - for (std::set >::iterator a = present_actions.begin (); a != present_actions.end (); ++a) { - if (s_can_move_menu) { - mbar->removeAction (a->second); - delete a->second; - } else { - if (a->second->menu ()) { - a->second->menu ()->clear (); - } - a->second->setEnabled (false); - } - } - } } void From 378d2cd961dc026799e7c49ff26d481154475524 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 14:10:45 +0200 Subject: [PATCH 11/12] Changed visibility management of tool options (aka "Editor options") Now, the tool options dock is either visible or not. Visibility can be configured like for the other docks. Key binding stays "F3" by default for the dock visibility. The dock is populated with pages depending on the tool. It may also be empty. --- src/lay/lay/layConfig.h | 1 + src/lay/lay/layMainConfigPages.cc | 1 + src/lay/lay/layMainWindow.cc | 123 +++++++++++++----------------- src/lay/lay/layMainWindow.h | 1 - src/lay/lay/layNavigator.cc | 1 + 5 files changed, 54 insertions(+), 73 deletions(-) diff --git a/src/lay/lay/layConfig.h b/src/lay/lay/layConfig.h index 86850a4e2..7ef712ab2 100644 --- a/src/lay/lay/layConfig.h +++ b/src/lay/lay/layConfig.h @@ -56,6 +56,7 @@ static const std::string cfg_show_hierarchy_panel ("show-hierarchy-panel"); static const std::string cfg_show_libraries_view ("show-libraries-view"); static const std::string cfg_show_bookmarks_view ("show-bookmarks-view"); static const std::string cfg_show_layer_panel ("show-layer-panel"); +static const std::string cfg_show_tool_options ("show-tool-options"); static const std::string cfg_window_state ("window-state"); static const std::string cfg_layout_file_watcher_enabled ("layout-file-watcher-enabled"); static const std::string cfg_window_geometry ("window-geometry"); diff --git a/src/lay/lay/layMainConfigPages.cc b/src/lay/lay/layMainConfigPages.cc index c56f48357..ffe99975b 100644 --- a/src/lay/lay/layMainConfigPages.cc +++ b/src/lay/lay/layMainConfigPages.cc @@ -74,6 +74,7 @@ public: options.push_back (std::pair (cfg_show_libraries_view, "true")); options.push_back (std::pair (cfg_show_bookmarks_view, "false")); options.push_back (std::pair (cfg_show_layer_panel, "true")); + options.push_back (std::pair (cfg_show_tool_options, "true")); options.push_back (std::pair (cfg_layout_file_watcher_enabled, "true")); options.push_back (std::pair (cfg_window_state, "")); options.push_back (std::pair (cfg_window_geometry, "")); diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 2ad58023c..6a2582643 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -274,6 +274,34 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) connect (action, SIGNAL (triggered ()), this, SLOT (clone ())); mp_tab_bar->addAction (action); + mp_view_stack = new ViewWidgetStack (mp_main_frame); + mp_view_stack->setObjectName (QString::fromUtf8 ("view_stack")); + vbl->addWidget (mp_view_stack); + + mp_navigator_dock_widget = new QDockWidget (QObject::tr ("Navigator"), this); + mp_navigator_dock_widget->setObjectName (QString::fromUtf8 ("navigator_dock_widget")); + mp_navigator = new Navigator (this); + mp_navigator_dock_widget->setWidget (mp_navigator); + mp_navigator_dock_widget->setFocusProxy (mp_navigator); + connect (mp_navigator_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); + m_navigator_visible = true; + + mp_lp_dock_widget = new QDockWidget (QObject::tr ("Layers"), this); + mp_lp_dock_widget->setObjectName (QString::fromUtf8 ("lp_dock_widget")); + mp_lp_stack = new ControlWidgetStack (mp_lp_dock_widget, "lp_stack"); + mp_lp_dock_widget->setWidget (mp_lp_stack); + mp_lp_dock_widget->setFocusProxy (mp_lp_stack); + connect (mp_lp_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); + m_lp_visible = true; + + mp_layer_toolbox_dock_widget = new QDockWidget (QObject::tr ("Layer Toolbox"), this); + mp_layer_toolbox_dock_widget->setObjectName (QString::fromUtf8 ("lt_dock_widget")); + mp_layer_toolbox_stack = new ControlWidgetStack (mp_layer_toolbox_dock_widget, "layer_toolbox_stack", true); + mp_layer_toolbox_dock_widget->setWidget (mp_layer_toolbox_stack); + mp_layer_toolbox_dock_widget->setFocusProxy (mp_layer_toolbox_stack); + connect (mp_layer_toolbox_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); + m_layer_toolbox_visible = true; + mp_hp_dock_widget = new QDockWidget (QObject::tr ("Cells"), this); mp_hp_dock_widget->setObjectName (QString::fromUtf8 ("hp_dock_widget")); mp_hp_stack = new ControlWidgetStack (mp_hp_dock_widget, "hp_stack"); @@ -290,15 +318,6 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) connect (mp_libs_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); m_libs_visible = true; - mp_eo_dock_widget = new QDockWidget (QObject::tr ("Tool Options"), this); - mp_eo_dock_widget->setObjectName (QString::fromUtf8 ("eo_dock_widget")); - mp_eo_dock_widget->setMinimumHeight (150); - mp_eo_stack = new ControlWidgetStack (mp_eo_dock_widget, "eo_stack"); - mp_eo_dock_widget->setWidget (mp_eo_stack); - mp_eo_dock_widget->setFocusProxy (mp_eo_stack); - connect (mp_eo_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); - m_eo_visible = true; - mp_bm_dock_widget = new QDockWidget (QObject::tr ("Bookmarks"), this); mp_bm_dock_widget->setObjectName (QString::fromUtf8 ("bookmarks_dock_widget")); mp_bm_stack = new ControlWidgetStack (mp_bm_dock_widget, "bookmarks_stack"); @@ -307,33 +326,14 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) connect (mp_bm_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); m_bm_visible = true; - mp_view_stack = new ViewWidgetStack (mp_main_frame); - mp_view_stack->setObjectName (QString::fromUtf8 ("view_stack")); - vbl->addWidget (mp_view_stack); - - mp_layer_toolbox_dock_widget = new QDockWidget (QObject::tr ("Layer Toolbox"), this); - mp_layer_toolbox_dock_widget->setObjectName (QString::fromUtf8 ("lt_dock_widget")); - mp_layer_toolbox_stack = new ControlWidgetStack (mp_layer_toolbox_dock_widget, "layer_toolbox_stack", true); - mp_layer_toolbox_dock_widget->setWidget (mp_layer_toolbox_stack); - mp_layer_toolbox_dock_widget->setFocusProxy (mp_layer_toolbox_stack); - connect (mp_layer_toolbox_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); - m_layer_toolbox_visible = true; - - mp_lp_dock_widget = new QDockWidget (QObject::tr ("Layers"), this); - mp_lp_dock_widget->setObjectName (QString::fromUtf8 ("lp_dock_widget")); - mp_lp_stack = new ControlWidgetStack (mp_lp_dock_widget, "lp_stack"); - mp_lp_dock_widget->setWidget (mp_lp_stack); - mp_lp_dock_widget->setFocusProxy (mp_lp_stack); - connect (mp_lp_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); - m_lp_visible = true; - - mp_navigator_dock_widget = new QDockWidget (QObject::tr ("Navigator"), this); - mp_navigator_dock_widget->setObjectName (QString::fromUtf8 ("navigator_dock_widget")); - mp_navigator = new Navigator (this); - mp_navigator_dock_widget->setWidget (mp_navigator); - mp_navigator_dock_widget->setFocusProxy (mp_navigator); - connect (mp_navigator_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); - m_navigator_visible = true; + mp_eo_dock_widget = new QDockWidget (QObject::tr ("Tool Options"), this); + mp_eo_dock_widget->setObjectName (QString::fromUtf8 ("eo_dock_widget")); + mp_eo_dock_widget->setMinimumHeight (150); + mp_eo_stack = new ControlWidgetStack (mp_eo_dock_widget, "eo_stack"); + mp_eo_dock_widget->setWidget (mp_eo_stack); + mp_eo_dock_widget->setFocusProxy (mp_eo_stack); + connect (mp_eo_dock_widget, SIGNAL (visibilityChanged (bool)), this, SLOT (dock_widget_visibility_changed (bool))); + m_eo_visible = true; // Add dock widgets #if QT_VERSION >= 0x040500 @@ -567,7 +567,7 @@ MainWindow::technology_changed () } void -MainWindow::dock_widget_visibility_changed (bool visible) +MainWindow::dock_widget_visibility_changed (bool /*visible*/) { if (sender () == mp_lp_dock_widget) { dispatcher ()->config_set (cfg_show_layer_panel, tl::to_string (!mp_lp_dock_widget->isHidden ())); @@ -582,7 +582,7 @@ MainWindow::dock_widget_visibility_changed (bool visible) } else if (sender () == mp_layer_toolbox_dock_widget) { dispatcher ()->config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ())); } else if (sender () == mp_eo_dock_widget) { - m_eo_visible = visible; + dispatcher ()->config_set (cfg_show_tool_options, tl::to_string (!mp_eo_dock_widget->isHidden ())); } } @@ -1133,6 +1133,17 @@ MainWindow::configure (const std::string &name, const std::string &value) return true; + } else if (name == cfg_show_tool_options) { + + tl::from_string (value, m_eo_visible); + if (m_eo_visible) { + mp_eo_dock_widget->show (); + } else { + mp_eo_dock_widget->hide (); + } + + return true; + } else if (name == cfg_navigator_show_images) { bool flag = false; @@ -1321,6 +1332,7 @@ MainWindow::read_dock_widget_state () dispatcher ()->config_set (cfg_show_bookmarks_view, tl::to_string (!mp_bm_dock_widget->isHidden ())); dispatcher ()->config_set (cfg_show_navigator, tl::to_string (!mp_navigator_dock_widget->isHidden ())); dispatcher ()->config_set (cfg_show_layer_toolbox, tl::to_string (!mp_layer_toolbox_dock_widget->isHidden ())); + dispatcher ()->config_set (cfg_show_tool_options, tl::to_string (!mp_eo_dock_widget->isHidden ())); } void @@ -1699,38 +1711,6 @@ MainWindow::select_mode (int m) } } - update_editor_options_dock (); - - } -} - -void -MainWindow::update_editor_options_dock () -{ - // if the current mode supports editing, show the editor options panel - - const lay::PluginDeclaration *pd_sel = 0; - for (tl::Registrar::iterator cls = tl::Registrar::begin (); cls != tl::Registrar::end (); ++cls) { - const lay::PluginDeclaration *pd = cls.operator-> (); - if (pd->id () == m_mode) { - pd_sel = pd; - } - } - - bool eo_visible = false; - if (mp_eo_stack && pd_sel) { - eo_visible = pd_sel->editable_enabled (); - } - if (current_view () && eo_visible) { - lay::EditorOptionsPageCollection *eo_pages = current_view ()->editor_options_pages (); - if (! eo_pages || ! eo_pages->has_content ()) { - eo_visible = false; - } - } - - if (eo_visible != m_eo_visible) { - m_eo_visible = eo_visible; - show_dock_widget (mp_eo_dock_widget, m_eo_visible); } } @@ -2499,7 +2479,6 @@ MainWindow::select_view (int index) current_view_changed (); - update_editor_options_dock (); clear_current_pos (); edits_enabled_changed (); clear_messages (); @@ -4502,7 +4481,6 @@ public: at = "edit_menu.end"; menu_entries.push_back (lay::separator ("edit_options_group:edit_mode", "edit_menu.end")); - menu_entries.push_back (lay::menu_item ("cm_edit_options", "edit_options:edit_mode", "edit_menu.end", tl::to_string (QObject::tr ("Tool Options")) + "(F3)")); at = "file_menu.end"; menu_entries.push_back (lay::menu_item ("cm_new_layout", "new_layout:edit:edit_mode", at, tl::to_string (QObject::tr ("New Layout")))); @@ -4568,6 +4546,7 @@ public: menu_entries.push_back (lay::config_menu_item ("show_hierarchy_panel", at, tl::to_string (QObject::tr ("Cells")), cfg_show_hierarchy_panel, "?")); menu_entries.push_back (lay::config_menu_item ("show_libraries_view", at, tl::to_string (QObject::tr ("Libraries")), cfg_show_libraries_view, "?")); menu_entries.push_back (lay::config_menu_item ("show_bookmarks_view", at, tl::to_string (QObject::tr ("Bookmarks")), cfg_show_bookmarks_view, "?")); + menu_entries.push_back (lay::config_menu_item ("show_tool_options", at, tl::to_string (QObject::tr ("Tool Options(F3)")), cfg_show_tool_options, "?")); menu_entries.push_back (lay::menu_item ("cm_reset_window_state", "reset_window_state", at, tl::to_string (QObject::tr ("Restore Window")))), menu_entries.push_back (lay::separator ("selection_group", at)); menu_entries.push_back (lay::config_menu_item ("transient_selection", at, tl::to_string (QObject::tr ("Highlight Object Under Mouse")), cfg_sel_transient_mode, "?")); diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index a22ac7bc9..ade27bd24 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -859,7 +859,6 @@ private: void interactive_close_view (int from, int to, bool invert_range, bool all_cellviews); void call_on_current_view (void (lay::LayoutView::*func) (), const std::string &op_desc); void current_view_changed (); - void update_editor_options_dock (); void update_window_title (); void update_tab_title (int i); void add_view (LayoutViewWidget *view); diff --git a/src/lay/lay/layNavigator.cc b/src/lay/lay/layNavigator.cc index 1de9b1a2b..31f571560 100644 --- a/src/lay/lay/layNavigator.cc +++ b/src/lay/lay/layNavigator.cc @@ -576,6 +576,7 @@ Navigator::showEvent (QShowEvent *) void Navigator::closeEvent (QCloseEvent *) { + // TODO: this is most likely never called mp_main_window->dispatcher ()->config_set (cfg_show_navigator, "false"); mp_main_window->dispatcher ()->config_end (); } From 8992222d9d69fdc88a86ae19ef0e5de5c48cd542 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 24 May 2026 15:10:21 +0200 Subject: [PATCH 12/12] Enabling Qt-less builds --- src/ant/ant/antRulerOptionsPage.cc | 5 +++++ src/ant/ant/antRulerOptionsPage.h | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/ant/ant/antRulerOptionsPage.cc b/src/ant/ant/antRulerOptionsPage.cc index 4fa248315..199525ad3 100644 --- a/src/ant/ant/antRulerOptionsPage.cc +++ b/src/ant/ant/antRulerOptionsPage.cc @@ -20,6 +20,8 @@ */ +#if defined(HAVE_QT) + #include "antRulerOptionsPage.h" #include "antConfig.h" #include "laySnap.h" @@ -112,3 +114,6 @@ RulerOptionsPage::setup (lay::Dispatcher *root) static tl::RegisteredClass s_factory_ruler_options (new lay::EditorOptionsPageFactory ("ant::RulerOptions"), 0); } + +#endif + diff --git a/src/ant/ant/antRulerOptionsPage.h b/src/ant/ant/antRulerOptionsPage.h index cd934adbc..4c20b573a 100644 --- a/src/ant/ant/antRulerOptionsPage.h +++ b/src/ant/ant/antRulerOptionsPage.h @@ -20,6 +20,7 @@ */ +#if defined(HAVE_QT) #ifndef HDR_antRulerOptionsPage #define HDR_antRulerOptionsPage @@ -60,3 +61,6 @@ private: } #endif + +#endif +