From d0cb17b38641cd372d38c51feff98bde2e702b9f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 24 Feb 2018 18:09:50 +0100 Subject: [PATCH 1/8] ut_runner: Added -r option, fixed help text --- src/unit_tests/unit_test_main.cc | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/unit_tests/unit_test_main.cc b/src/unit_tests/unit_test_main.cc index 2459dbd20..e64406a91 100644 --- a/src/unit_tests/unit_test_main.cc +++ b/src/unit_tests/unit_test_main.cc @@ -70,8 +70,22 @@ main (int argc, char **argv) return ret; } +static bool +run_test (tl::TestBase *t, bool editable, bool slow, int repeat) +{ + for (int i = 0; i < repeat; ++i) { + if (repeat > 0) { + ut::noctrl << "Repeat iteration " << i + 1 << " of " << repeat; + } + if (! t->do_test (editable, slow)) { + return false; + } + } + return true; +} + static int -run_tests (const std::vector &selected_tests, bool editable, bool non_editable, bool slow, lay::ApplicationBase &app, bool gsi_coverage, const std::vector &class_names_vector) +run_tests (const std::vector &selected_tests, bool editable, bool non_editable, bool slow, int repeat, lay::ApplicationBase &app, bool gsi_coverage, const std::vector &class_names_vector) { std::set class_names; class_names.insert (class_names_vector.begin (), class_names_vector.end ()); @@ -129,7 +143,7 @@ run_tests (const std::vector &selected_tests, bool editable, boo tl::Timer timer; timer.start(); - if (! (*t)->do_test (e != 0, slow)) { + if (! run_test (*t, e != 0, slow, repeat)) { ut::ctrl << ""; @@ -414,6 +428,7 @@ main_cont (int &argc, char **argv) bool verbose = false; bool debug_mode = false; bool continue_flag = false; + int repeat = 1; tl::CommandLineOptions cmd; cmd << tl::arg ("-a", &xml_format, "Provide XML output format (JUnit format)") @@ -428,11 +443,12 @@ main_cont (int &argc, char **argv) << tl::arg ("-s", &slow, "Includes slow (long runner) tests") << tl::arg ("-v", &verbose, "Provides verbose output") << tl::arg ("-g", &gsi_coverage, "Produces a GSI test coverage statistics") - << tl::arg ("*-gg=class", &class_names, "Produces a specific GDS coverage statistics" + << tl::arg ("-r=n", &repeat, "Repeat the tests n times each") + << tl::arg ("*-gg=class", &class_names, "Produces a specific GDS coverage statistics", "With this specification, coverage will be printed for this specific class. " "This option can be used multiple times to add more classes." ) - << tl::arg ("-x=test", &exclude_test_list, "Exclude the following tests" + << tl::arg ("-x=test", &exclude_test_list, "Exclude the following tests", "This option can be given multiple times or with a comma-separated list " "of pattern. Test tests matching one of the exclude pattern " "are not executed." @@ -509,7 +525,7 @@ main_cont (int &argc, char **argv) selected_tests = &tl::TestRegistrar::instance()->tests (); } - result = run_tests (*selected_tests, editable, non_editable, slow, app, gsi_coverage, class_names); + result = run_tests (*selected_tests, editable, non_editable, slow, repeat, app, gsi_coverage, class_names); ut::ctrl << ""; From 8691ab8e5a48c185242b56e547a21c1bd37df8d9 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 24 Feb 2018 18:43:21 +0100 Subject: [PATCH 2/8] Some small changes to changelog (typos, formatting) --- Changelog | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Changelog b/Changelog index 21f41d8f0..4fbcf8093 100644 --- a/Changelog +++ b/Changelog @@ -8,39 +8,39 @@ * Enhancement: 64 bit coordinate support enabled on Windows builds * Further bugfixes: See links - https://github.com/klayoutmatthias/klayout/issues/21 (Autorun(-early) doesn't seem to run when lym files are inside a package) - - https://github.com/klayoutmatthias/klayout/issues/24 (Text insert dialog possible) + - https://github.com/klayoutmatthias/klayout/issues/24 (Text insert dialog bug - Ok button isn't working) - https://github.com/klayoutmatthias/klayout/issues/26 (Exceptions are reported every time they propagate up in the call chain in the ruby debugger) - https://github.com/klayoutmatthias/klayout/issues/28 (CIF format detection failed) - https://github.com/klayoutmatthias/klayout/issues/30 (Writer options dialog non-functional on a fresh configuration) - - https://github.com/klayoutmatthias/klayout/issues/32 (rounding issue with instance properties) + - https://github.com/klayoutmatthias/klayout/issues/32 (Rounding issue with instance properties) - https://github.com/klayoutmatthias/klayout/issues/33 (Plugin factory not working when using with Python) - - https://github.com/klayoutmatthias/klayout/issues/36 (hardening against destruction of object inside event handler) + - https://github.com/klayoutmatthias/klayout/issues/36 (Hardening against destruction of object inside event handler) - https://github.com/klayoutmatthias/klayout/issues/39 (Action cannot be reassigned) - https://github.com/klayoutmatthias/klayout/issues/40 (Crash in Python binding) - https://github.com/klayoutmatthias/klayout/issues/41 (Polygon#touches? issue) - - https://github.com/klayoutmatthias/klayout/issues/42 (headless mode support with Qt5/-zz) - - https://github.com/klayoutmatthias/klayout/issues/43 (crash when using Qt specific command line options) + - https://github.com/klayoutmatthias/klayout/issues/42 (Headless mode support with Qt5/-zz) + - https://github.com/klayoutmatthias/klayout/issues/43 (Crash when using Qt specific command line options) - https://github.com/klayoutmatthias/klayout/issues/44 (Transformation constructor with x,y not working) - https://github.com/klayoutmatthias/klayout/issues/45 (Partial selection does not capture instance) - https://github.com/klayoutmatthias/klayout/issues/48 (Cancel does not reset current tool) - https://github.com/klayoutmatthias/klayout/issues/51 (Segmentation fault on return to main window and other opportunities) - - https://github.com/klayoutmatthias/klayout/issues/53 (unreadable 'about' text) - - https://github.com/klayoutmatthias/klayout/issues/59 (async download of package index and details) + - https://github.com/klayoutmatthias/klayout/issues/53 (Unreadable 'about' text) - https://github.com/klayoutmatthias/klayout/issues/62 (QXmlSimpleReader#parse cannot be called) - - https://github.com/klayoutmatthias/klayout/issues/63 (wrong output on DRC non_interacting with empty second input) - - https://github.com/klayoutmatthias/klayout/issues/64 (crash on exit) + - https://github.com/klayoutmatthias/klayout/issues/63 (Wrong output on DRC non_interacting with empty second input) + - https://github.com/klayoutmatthias/klayout/issues/64 (Crash on exit) - https://github.com/klayoutmatthias/klayout/issues/68 (OASIS reader issue with degenerated shapes) - https://github.com/klayoutmatthias/klayout/issues/69 (DRC: 'inside' does not merge shapes of second input) - - https://github.com/klayoutmatthias/klayout/issues/71 (target cell argument is required) + - https://github.com/klayoutmatthias/klayout/issues/71 (Target cell argument is required) - https://github.com/klayoutmatthias/klayout/issues/72 (Edges/Region NOT issue) - - https://github.com/klayoutmatthias/klayout/issues/73 (allow 'change layers' on PCells which support a single layer parameter) - - https://github.com/klayoutmatthias/klayout/issues/74 (small-corner boolean issue) + - https://github.com/klayoutmatthias/klayout/issues/73 (Allow 'change layers' on PCells which support a single layer parameter) + - https://github.com/klayoutmatthias/klayout/issues/74 (Small-corner boolean issue) - https://github.com/klayoutmatthias/klayout/issues/75 (Python PCell issue when parameters are called 'layer') - https://github.com/klayoutmatthias/klayout/issues/79 (Replace function enabled also for read-only macros) * Further enhancements: see links - - https://github.com/klayoutmatthias/klayout/issues/29 (permissive mode for OASIS writer on odd-width paths) + - https://github.com/klayoutmatthias/klayout/issues/29 (Permissive mode for OASIS writer on odd-width paths) + - https://github.com/klayoutmatthias/klayout/issues/59 (Async download of package index and details) - https://github.com/klayoutmatthias/klayout/issues/66 (Authentication dialog indicates retry) - - https://github.com/klayoutmatthias/klayout/issues/77 (copy_tree works in non-editable mode too) + - https://github.com/klayoutmatthias/klayout/issues/77 (Layout#copy_tree now works in non-editable mode too) 0.25 (2017-11-04): * Enhancement: Menu customization From 093bd526f77414a3a3431cc3d9745a06c520fa95 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 24 Feb 2018 18:47:46 +0100 Subject: [PATCH 3/8] Updated changelog. --- Changelog | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index 4fbcf8093..f3e2c84b0 100644 --- a/Changelog +++ b/Changelog @@ -1,8 +1,8 @@ 0.25.1 (2018-02-23): -* Enhancements: build compatibility with MacOS, Qt 5.9. - Qt 4.6+4.7 supported as well with restrictions: +* Enhancements: build compatibility with MacOS and Qt 5.9. + Qt 4.6 supported now as well with one restriction: the package installation feature is not working. -* Bugfix: Package manager +* Bugfixs: Package manager - Remove button wasn't enabled if multiple packages were selected - A potential crash ob removing packages was fixed * Enhancement: 64 bit coordinate support enabled on Windows builds From 2ffdbb4d91c65d03c2b2ed6740138b7c789b83bb Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 27 Feb 2018 00:02:57 +0100 Subject: [PATCH 4/8] Suppress repeated message in unit tests if not required. --- src/unit_tests/unit_test_main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unit_tests/unit_test_main.cc b/src/unit_tests/unit_test_main.cc index e64406a91..3047d7b66 100644 --- a/src/unit_tests/unit_test_main.cc +++ b/src/unit_tests/unit_test_main.cc @@ -74,7 +74,7 @@ static bool run_test (tl::TestBase *t, bool editable, bool slow, int repeat) { for (int i = 0; i < repeat; ++i) { - if (repeat > 0) { + if (repeat > 1) { ut::noctrl << "Repeat iteration " << i + 1 << " of " << repeat; } if (! t->do_test (editable, slow)) { From 6f0ecd3d9ce76df62a9bfa650c7ff42fbfa0a017 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 27 Feb 2018 21:59:52 +0100 Subject: [PATCH 5/8] Show tip window once for non-standard background combination mode. --- src/lay/lay/layMainWindow.cc | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 37be91928..01d08facd 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -1318,19 +1318,6 @@ MainWindow::about_to_exec () return; } } - - edt::combine_mode_type cm = edt::CM_Add; - config_get (edt::cfg_edit_combine_mode, cm, edt::CMConverter ()); - if (lay::ApplicationBase::instance ()->is_editable () && cm != edt::CM_Add) { - lay::TipDialog td (QApplication::activeWindow (), - tl::to_string (QObject::tr ("The background combination mode of the shape editor is set to some other mode than 'Add'.\n" - "This can be confusing, because a shape may not be drawn as expected.\n\nTo switch back to normal mode, choose 'Add' for the background combination mode in the toolbar.")), - "has-non-add-edit-combine-mode"); - if (td.exec_dialog ()) { - // Don't bother the user with more dialogs. - return; - } - } } void From 7da3b0206ada905e1618916888ca679d8ab7f630 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 3 Mar 2018 00:21:23 +0100 Subject: [PATCH 6/8] DRC as early autorun This will finally enable DRC runsets started from an autorun macro. --- src/drc/drc/built-in-macros/drc.lym | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drc/drc/built-in-macros/drc.lym b/src/drc/drc/built-in-macros/drc.lym index 514b59a4d..012250912 100644 --- a/src/drc/drc/built-in-macros/drc.lym +++ b/src/drc/drc/built-in-macros/drc.lym @@ -7,7 +7,7 @@ true - false + true false From 5fbc20702e839c6721ca90bc3633d070371f28bd Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 11 Mar 2018 21:58:59 +0100 Subject: [PATCH 7/8] Macro editor enhancements (stop on exceptions) This commit tries to address #85 and provide these features: - dynamic configuration of the macro IDE behaviour - side effect: a new entry in the setup dialog for the IDE settings - "stop on exceptions" can be taught to ignore certain files --- ...SetupDialog.ui => MacroEditorSetupPage.ui} | 118 ++++--- src/lay/lay/lay.pro | 12 +- src/lay/lay/layMacroEditorDialog.cc | 290 +++++++++++------- src/lay/lay/layMacroEditorDialog.h | 34 +- ...upDialog.cc => layMacroEditorSetupPage.cc} | 216 ++++++++++--- ...etupDialog.h => layMacroEditorSetupPage.h} | 43 +-- 6 files changed, 473 insertions(+), 240 deletions(-) rename src/lay/lay/{MacroEditorSetupDialog.ui => MacroEditorSetupPage.ui} (85%) rename src/lay/lay/{layMacroEditorSetupDialog.cc => layMacroEditorSetupPage.cc} (58%) rename src/lay/lay/{layMacroEditorSetupDialog.h => layMacroEditorSetupPage.h} (57%) diff --git a/src/lay/lay/MacroEditorSetupDialog.ui b/src/lay/lay/MacroEditorSetupPage.ui similarity index 85% rename from src/lay/lay/MacroEditorSetupDialog.ui rename to src/lay/lay/MacroEditorSetupPage.ui index 2479c3fbe..21947b9c5 100644 --- a/src/lay/lay/MacroEditorSetupDialog.ui +++ b/src/lay/lay/MacroEditorSetupPage.ui @@ -1,7 +1,7 @@ - MacroEditorSetupDialog - + MacroEditorSetupPage + 0 @@ -32,7 +32,7 @@ - 0 + 3 @@ -452,10 +452,71 @@ - - - Ask whether to stop in debugger on exception + + + As&k whether to stop in debugger on exception + + true + + + false + + + + + + Don't stop inside these files: + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + Clear List + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 32 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QAbstractItemView::NoSelection + + + + @@ -475,16 +536,6 @@ - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - @@ -495,38 +546,5 @@ - - - buttonBox - accepted() - MacroEditorSetupDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - MacroEditorSetupDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - + diff --git a/src/lay/lay/lay.pro b/src/lay/lay/lay.pro index 45371f44c..b17a5fe2b 100644 --- a/src/lay/lay/lay.pro +++ b/src/lay/lay/lay.pro @@ -20,7 +20,6 @@ HEADERS = \ layLogViewerDialog.h \ layMacroEditorDialog.h \ layMacroEditorPage.h \ - layMacroEditorSetupDialog.h \ layMacroEditorTree.h \ layMacroPropertiesDialog.h \ layMacroVariableView.h \ @@ -57,7 +56,8 @@ HEADERS = \ layLibraryController.h \ layFontController.h \ layNativePlugin.h \ - laySystemPaths.h + laySystemPaths.h \ + layMacroEditorSetupPage.h FORMS = \ ClipDialog.ui \ @@ -69,7 +69,6 @@ FORMS = \ LayoutStatistics.ui \ LogViewerDialog.ui \ MacroEditorDialog.ui \ - MacroEditorSetupDialog.ui \ MacroPropertiesDialog.ui \ MacroTemplateSelectionDialog.ui \ MainConfigPage.ui \ @@ -106,7 +105,8 @@ FORMS = \ SaltGrainPropertiesDialog.ui \ SaltGrainTemplateSelectionDialog.ui \ SaltManagerInstallConfirmationDialog.ui \ - CustomizeMenuConfigPage.ui + CustomizeMenuConfigPage.ui \ + MacroEditorSetupPage.ui SOURCES = \ gsiDeclLayApplication.cc \ @@ -125,7 +125,6 @@ SOURCES = \ layLogViewerDialog.cc \ layMacroEditorDialog.cc \ layMacroEditorPage.cc \ - layMacroEditorSetupDialog.cc \ layMacroEditorTree.cc \ layMacroPropertiesDialog.cc \ layMacroVariableView.cc \ @@ -161,7 +160,8 @@ SOURCES = \ layLibraryController.cc \ layFontController.cc \ layNativePlugin.cc \ - laySystemPaths.cc + laySystemPaths.cc \ + layMacroEditorSetupPage.cc RESOURCES = layBuildInMacros.qrc \ layHelpResources.qrc \ diff --git a/src/lay/lay/layMacroEditorDialog.cc b/src/lay/lay/layMacroEditorDialog.cc index a866660f0..81c8c6290 100644 --- a/src/lay/lay/layMacroEditorDialog.cc +++ b/src/lay/lay/layMacroEditorDialog.cc @@ -22,10 +22,11 @@ #include "ui_MacroTemplateSelectionDialog.h" +#include "layConfigurationDialog.h" #include "layMacroController.h" #include "layMacroEditorTree.h" #include "layMacroEditorDialog.h" -#include "layMacroEditorSetupDialog.h" +#include "layMacroEditorSetupPage.h" #include "layMacroPropertiesDialog.h" #include "layFileDialog.h" #include "layMainWindow.h" @@ -58,6 +59,9 @@ #include #include +namespace lay +{ + const std::string cfg_macro_editor_styles ("macro-editor-styles"); const std::string cfg_macro_editor_save_all_on_run ("macro-editor-save-all-on-run"); const std::string cfg_macro_editor_stop_on_exception ("macro-editor-stop-on-exception"); @@ -74,9 +78,7 @@ const std::string cfg_macro_editor_current_macro ("macro-editor-current-macro"); const std::string cfg_macro_editor_active_macro ("macro-editor-active-macro"); const std::string cfg_macro_editor_watch_expressions ("macro-editor-watch-expressions"); const std::string cfg_macro_editor_debugging_enabled ("macro-editor-debugging-enabled"); - -namespace lay -{ +const std::string cfg_macro_editor_ignore_exception_list ("macro-editor-ignore-exception-list"); // ----------------------------------------------------------------------------------------- // Implementation of the macro template selection dialog @@ -225,8 +227,10 @@ public: static lay::MacroEditorDialog *s_macro_editor_instance = 0; -MacroEditorDialog::MacroEditorDialog (QWidget * /*parent*/, lym::MacroCollection *root) +MacroEditorDialog::MacroEditorDialog (lay::MainWindow *mw, lym::MacroCollection *root) : QDialog (0 /*show as individual top widget*/, Qt::Window), + lay::Plugin (mw, true), + mp_plugin_root (mw), mp_root (root), m_first_show (true), m_in_processing (false), m_debugging_on (true), mp_run_macro (0), @@ -245,6 +249,7 @@ MacroEditorDialog::MacroEditorDialog (QWidget * /*parent*/, lym::MacroCollection m_eval_context (-1), m_process_events_interval (0.0), m_window_closed (true), + m_needs_update (true), m_ntab (8), m_nindent (2), m_save_all_on_run (false), @@ -598,6 +603,8 @@ MacroEditorDialog::MacroEditorDialog (QWidget * /*parent*/, lym::MacroCollection if (! s_macro_editor_instance) { s_macro_editor_instance = this; } + + config_setup (); } MacroEditorDialog::~MacroEditorDialog () @@ -716,6 +723,113 @@ MacroEditorDialog::current_macro_tree () return t; } +void +MacroEditorDialog::config_finalize () +{ + if (m_needs_update) { + + for (int i = 0; i < tabWidget->count (); ++i) { + MacroEditorPage *page = dynamic_cast (tabWidget->widget (i)); + if (page) { + page->set_ntab (m_ntab); + page->set_nindent (m_nindent); + page->apply_attributes (); + page->set_font (m_font_family, m_font_size); + } + } + + refresh_file_watcher (); + + m_needs_update = false; + + } +} + +bool +MacroEditorDialog::configure (const std::string &name, const std::string &value) +{ + // Reads the dynamic configuration + + if (name == cfg_macro_editor_styles) { + + if (m_styles != value) { + m_styles = value; + m_needs_update = true; + } + m_highlighters.load (value); + return true; + + } else if (name == cfg_macro_editor_save_all_on_run) { + tl::from_string (value, m_save_all_on_run); + return true; + } else if (name == cfg_macro_editor_stop_on_exception) { + tl::from_string (value, m_stop_on_exception); + return true; + } else if (name == cfg_macro_editor_file_watcher_enabled) { + + bool en = m_file_watcher_enabled; + tl::from_string (value, en); + if (en != m_file_watcher_enabled) { + m_file_watcher_enabled = en; + m_needs_update = true; + } + return true; + + } else if (name == cfg_macro_editor_font_family) { + + if (m_font_family != value) { + m_font_family = value; + m_needs_update = true; + } + return true; + + } else if (name == cfg_macro_editor_font_size) { + + int v = m_font_size; + tl::from_string (value, v); + if (v != m_font_size) { + m_font_size = v; + m_needs_update = true; + } + return true; + + } else if (name == cfg_macro_editor_tab_width) { + + int v = m_ntab; + tl::from_string (value, v); + if (v != m_ntab) { + m_ntab = v; + m_needs_update = true; + } + return true; + + } else if (name == cfg_macro_editor_indent) { + + int v = m_nindent; + tl::from_string (value, v); + if (v != m_nindent) { + m_nindent = v; + m_needs_update = true; + } + return true; + + } else if (name == cfg_macro_editor_ignore_exception_list) { + + m_ignore_exception_list.clear (); + tl::Extractor ex (value.c_str ()); + while (! ex.at_end ()) { + std::string f; + ex.read_word_or_quoted (f); + ex.test (";"); + m_ignore_exception_list.insert (f); + } + return true; + + } else { + return lay::Plugin::configure (name, value); + } +} + void MacroEditorDialog::showEvent (QShowEvent *) { @@ -726,29 +840,19 @@ MacroEditorDialog::showEvent (QShowEvent *) m_window_closed = false; - // read configuration - std::string styles; - if (MainWindow::instance ()->config_get (cfg_macro_editor_styles, styles)) { - m_highlighters.load (styles); - } - MainWindow::instance ()->config_get (cfg_macro_editor_save_all_on_run, m_save_all_on_run); - MainWindow::instance ()->config_get (cfg_macro_editor_stop_on_exception, m_stop_on_exception); - MainWindow::instance ()->config_get (cfg_macro_editor_file_watcher_enabled, m_file_watcher_enabled); - MainWindow::instance ()->config_get (cfg_macro_editor_font_family, m_font_family); - MainWindow::instance ()->config_get (cfg_macro_editor_font_size, m_font_size); - MainWindow::instance ()->config_get (cfg_macro_editor_tab_width, m_ntab); - MainWindow::instance ()->config_get (cfg_macro_editor_indent, m_nindent); - MainWindow::instance ()->config_get (cfg_macro_editor_debugging_enabled, m_debugging_on); + // read debugger environment from configuration + + mp_plugin_root->config_get (cfg_macro_editor_debugging_enabled, m_debugging_on); std::string ws; - MainWindow::instance ()->config_get (cfg_macro_editor_window_state, ws); + mp_plugin_root->config_get (cfg_macro_editor_window_state, ws); lay::restore_dialog_state (this, ws); input_field->clear (); try { std::string hi; - MainWindow::instance ()->config_get (cfg_macro_editor_console_mru, hi); + mp_plugin_root->config_get (cfg_macro_editor_console_mru, hi); tl::Extractor ex (hi.c_str ()); while (! ex.at_end ()) { std::string h; @@ -770,7 +874,7 @@ MacroEditorDialog::showEvent (QShowEvent *) } std::string ci; - MainWindow::instance ()->config_get (cfg_macro_editor_console_interpreter, ci); + mp_plugin_root->config_get (cfg_macro_editor_console_interpreter, ci); if (ci == "ruby") { pythonLangSel->setChecked (false); rubyLangSel->setChecked (true); @@ -784,7 +888,7 @@ MacroEditorDialog::showEvent (QShowEvent *) m_watch_expressions.clear (); std::string we; - MainWindow::instance ()->config_get (cfg_macro_editor_watch_expressions, we); + mp_plugin_root->config_get (cfg_macro_editor_watch_expressions, we); tl::Extractor ex (we.c_str ()); while (! ex.at_end ()) { @@ -806,7 +910,7 @@ MacroEditorDialog::showEvent (QShowEvent *) try { std::string om; - MainWindow::instance ()->config_get (cfg_macro_editor_open_macros, om); + mp_plugin_root->config_get (cfg_macro_editor_open_macros, om); tl::Extractor ex (om.c_str ()); while (! ex.at_end ()) { std::string h; @@ -818,7 +922,7 @@ MacroEditorDialog::showEvent (QShowEvent *) } catch (...) { } std::string am; - MainWindow::instance ()->config_get (cfg_macro_editor_active_macro, am); + mp_plugin_root->config_get (cfg_macro_editor_active_macro, am); if (! am.empty ()) { lym::Macro *macro = mp_root->find_macro (am); if (macro) { @@ -829,7 +933,7 @@ MacroEditorDialog::showEvent (QShowEvent *) dbgOn->setChecked (m_debugging_on); std::string cm; - MainWindow::instance ()->config_get (cfg_macro_editor_current_macro, cm); + mp_plugin_root->config_get (cfg_macro_editor_current_macro, cm); if (! cm.empty ()) { // this will make that macro the current one editor_for_file (cm); @@ -866,10 +970,10 @@ void MacroEditorDialog::closeEvent (QCloseEvent *) { // save the debugging enabled state - MainWindow::instance ()->config_set (cfg_macro_editor_debugging_enabled, m_debugging_on); + mp_plugin_root->config_set (cfg_macro_editor_debugging_enabled, m_debugging_on); // save the window state - MainWindow::instance ()->config_set (cfg_macro_editor_window_state, lay::save_dialog_state (this)); + mp_plugin_root->config_set (cfg_macro_editor_window_state, lay::save_dialog_state (this)); // save the console history (at maximum the last 200 entries) std::string hi; @@ -879,7 +983,7 @@ MacroEditorDialog::closeEvent (QCloseEvent *) } hi += tl::to_quoted_string (tl::to_string (input_field->itemText (i))); } - MainWindow::instance ()->config_set (cfg_macro_editor_console_mru, hi); + mp_plugin_root->config_set (cfg_macro_editor_console_mru, hi); // save the open macro list std::string om; @@ -892,7 +996,7 @@ MacroEditorDialog::closeEvent (QCloseEvent *) om += tl::to_quoted_string (page->macro ()->path ()); } } - MainWindow::instance ()->config_set (cfg_macro_editor_open_macros, om); + mp_plugin_root->config_set (cfg_macro_editor_open_macros, om); // save the watch expressions std::string we; @@ -908,15 +1012,15 @@ MacroEditorDialog::closeEvent (QCloseEvent *) we += ":"; we += tl::to_quoted_string (i->second); } - MainWindow::instance ()->config_set (cfg_macro_editor_watch_expressions, we); + mp_plugin_root->config_set (cfg_macro_editor_watch_expressions, we); // save the active (run) macro - MainWindow::instance ()->config_set (cfg_macro_editor_active_macro, mp_run_macro ? mp_run_macro->path () : std::string ()); + mp_plugin_root->config_set (cfg_macro_editor_active_macro, mp_run_macro ? mp_run_macro->path () : std::string ()); // save the current macro MacroEditorPage *page = dynamic_cast (tabWidget->currentWidget ()); std::string cm = page && page->macro () ? page->macro ()->path () : std::string (); - MainWindow::instance ()->config_set (cfg_macro_editor_current_macro, cm); + mp_plugin_root->config_set (cfg_macro_editor_current_macro, cm); // save the current interpreter in the console std::string ci; @@ -925,7 +1029,7 @@ MacroEditorDialog::closeEvent (QCloseEvent *) } else if (pythonLangSel->isChecked ()) { ci = "python"; } - MainWindow::instance ()->config_set (cfg_macro_editor_console_interpreter, ci); + mp_plugin_root->config_set (cfg_macro_editor_console_interpreter, ci); // stop execution when the window is closed m_in_exec = false; @@ -1914,73 +2018,9 @@ MacroEditorDialog::setup_button_clicked () return; } - // fill data - - lay::MacroEditorSetupDialogData data; - data.tab_width = m_ntab; - data.indent = m_nindent; - data.save_all_on_run = m_save_all_on_run; - data.stop_on_exception = m_stop_on_exception; - data.file_watcher_enabled = m_file_watcher_enabled; - data.font_family = m_font_family; - data.font_size = m_font_size; - - if (m_highlighters.basic_attributes ()) { - data.basic_attributes.assign (*m_highlighters.basic_attributes ()); - } - for (MacroEditorHighlighters::const_iterator a = m_highlighters.begin (); a != m_highlighters.end (); ++a) { - data.specific_attributes.push_back (std::make_pair (a->first, GenericSyntaxHighlighterAttributes (& data.basic_attributes))); - data.specific_attributes.back ().second.assign (a->second); - } - - lay::MacroEditorSetupDialog dialog (this); - if (dialog.exec_dialog (data)) { - - m_ntab = data.tab_width; - m_nindent = data.indent; - m_stop_on_exception = data.stop_on_exception; - m_file_watcher_enabled = data.file_watcher_enabled; - m_font_family = data.font_family; - m_font_size = data.font_size; - - if (m_highlighters.basic_attributes ()) { - m_highlighters.basic_attributes ()->assign (data.basic_attributes); - } - - for (MacroEditorHighlighters::iterator a = m_highlighters.begin (); a != m_highlighters.end (); ++a) { - for (std::vector< std::pair >::const_iterator i = data.specific_attributes.begin (); i != data.specific_attributes.end (); ++i) { - if (i->first == a->first) { - a->second.assign (i->second); - break; - } - } - } - - m_save_all_on_run = data.save_all_on_run; - - for (int i = 0; i < tabWidget->count (); ++i) { - MacroEditorPage *page = dynamic_cast (tabWidget->widget (i)); - if (page) { - page->set_ntab (m_ntab); - page->set_nindent (m_nindent); - page->apply_attributes (); - page->set_font (m_font_family, m_font_size); - } - } - - // write configuration - MainWindow::instance ()->config_set (cfg_macro_editor_styles, m_highlighters.to_string ()); - MainWindow::instance ()->config_set (cfg_macro_editor_save_all_on_run, m_save_all_on_run); - MainWindow::instance ()->config_set (cfg_macro_editor_file_watcher_enabled, m_file_watcher_enabled); - MainWindow::instance ()->config_set (cfg_macro_editor_stop_on_exception, m_stop_on_exception); - MainWindow::instance ()->config_set (cfg_macro_editor_tab_width, m_ntab); - MainWindow::instance ()->config_set (cfg_macro_editor_indent, m_nindent); - MainWindow::instance ()->config_set (cfg_macro_editor_font_family, m_font_family); - MainWindow::instance ()->config_set (cfg_macro_editor_font_size, m_font_size); - MainWindow::instance ()->config_end (); - + lay::ConfigurationDialog config_dialog (this, mp_plugin_root, "MacroEditor"); + if (config_dialog.exec ()) { refresh_file_watcher (); - } } @@ -2253,12 +2293,12 @@ MacroEditorDialog::ensure_writeable_collection_selected () } static std::vector > -get_custom_paths () +get_custom_paths (lay::PluginRoot *root) { std::vector > paths; std::string mp; - MainWindow::instance ()->config_get (cfg_custom_macro_paths, mp); + root->config_get (cfg_custom_macro_paths, mp); try { @@ -2281,7 +2321,7 @@ get_custom_paths () } static void -set_custom_paths (const std::vector > &paths) +set_custom_paths (lay::PluginRoot *root, const std::vector > &paths) { std::string mp; @@ -2295,7 +2335,7 @@ set_custom_paths (const std::vector > &paths mp += p->second; } - MainWindow::instance ()->config_set (cfg_custom_macro_paths, mp); + root->config_set (cfg_custom_macro_paths, mp); } void @@ -2494,7 +2534,7 @@ BEGIN_PROTECTED std::string cat = current_macro_tree ()->category (); - std::vector > paths = get_custom_paths (); + std::vector > paths = get_custom_paths (mp_plugin_root); std::string new_path = tl::to_string (QFileInfo (new_dir).absoluteFilePath ()); paths.push_back (std::make_pair (new_path, cat)); @@ -2503,7 +2543,7 @@ BEGIN_PROTECTED throw tl::Exception (tl::to_string (QObject::tr ("The selected directory is already installed as custom location"))); } - set_custom_paths (paths); + set_custom_paths (mp_plugin_root, paths); if (c->has_autorun ()) { if (QMessageBox::question (this, QObject::tr ("Run Macros"), QObject::tr ("The selected folder has macros configured to run automatically.\n\nChoose 'Yes' to run these macros now. Choose 'No' to not run them."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { @@ -2538,7 +2578,7 @@ BEGIN_PROTECTED throw tl::Exception (tl::to_string (QObject::tr ("Select tree location to remove"))); } - std::vector > paths = get_custom_paths (); + std::vector > paths = get_custom_paths (mp_plugin_root); bool found = false; @@ -2560,7 +2600,7 @@ BEGIN_PROTECTED mp_root->erase (collection); // save the new paths - set_custom_paths (paths); + set_custom_paths (mp_plugin_root, paths); END_PROTECTED } @@ -2809,10 +2849,34 @@ MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_ return; } - if (QMessageBox::critical (this, QObject::tr ("Exception Caught"), - tl::to_qstring (tl::to_string (QObject::tr ("Caught the following exception:\n")) + emsg + " (Class " + eclass + ")\n\n" + tl::to_string (QObject::tr ("Press 'Ok' to continue and 'Cancel' to stop in the debugger"))), - QMessageBox::Cancel, QMessageBox::Ok) == QMessageBox::Ok) { + std::string p; + if (file_id > 0 && file_id <= m_file_to_widget.size () && m_file_to_widget [file_id - 1].first) { + p = m_file_to_widget [file_id - 1].first->path (); + if (m_ignore_exception_list.find (p) != m_ignore_exception_list.end ()) { + return; + } + } + + int res = QMessageBox::critical (this, QObject::tr ("Exception Caught"), + tl::to_qstring (tl::to_string (QObject::tr ("Caught the following exception:\n")) + emsg + " (Class " + eclass + ")\n\n" + tl::to_string (QObject::tr ("Press 'Ok' to continue.\nPress 'Ignore' to ignore this and future exceptions from this file.\nPress 'Cancel' to stop in the debugger"))), + QMessageBox::Cancel | QMessageBox::Ok | QMessageBox::Ignore, + QMessageBox::Ok); + + if (res == QMessageBox::Ok) { + return; + + } else if (res == QMessageBox::Ignore) { + + std::string il; + il += tl::to_quoted_string (p); + for (std::set::const_iterator i = m_ignore_exception_list.begin (); i != m_ignore_exception_list.end (); ++i) { + il += ";"; + il += tl::to_quoted_string (*i); + } + mp_plugin_root->config_set (cfg_macro_editor_ignore_exception_list, il); + return; + } write_str (emsg.c_str (), OS_stderr); @@ -3399,6 +3463,12 @@ class MacroEditorPluginDeclaration : public lay::PluginDeclaration { public: + virtual lay::ConfigPage *config_page (QWidget *parent, std::string &title) const + { + title = tl::to_string (QObject::tr ("Application|Macro Development IDE")); + return new MacroEditorSetupPage (parent); + } + virtual void get_options (std::vector < std::pair > &options) const { options.push_back (std::pair (cfg_macro_editor_styles, "")); diff --git a/src/lay/lay/layMacroEditorDialog.h b/src/lay/lay/layMacroEditorDialog.h index 6e92402e1..bb492c71e 100644 --- a/src/lay/lay/layMacroEditorDialog.h +++ b/src/lay/lay/layMacroEditorDialog.h @@ -29,6 +29,7 @@ #include "ui_MacroEditorDialog.h" #include "layMacroEditorPage.h" #include "layMacroController.h" +#include "layPlugin.h" #include "tlDeferredExecution.h" #include "tlTimer.h" #include "tlFileSystemWatcher.h" @@ -50,11 +51,34 @@ class QTreeWidgetItem; namespace lay { +extern const std::string cfg_macro_editor_styles; +extern const std::string cfg_macro_editor_save_all_on_run; +extern const std::string cfg_macro_editor_stop_on_exception; +extern const std::string cfg_macro_editor_file_watcher_enabled; +extern const std::string cfg_macro_editor_font_family; +extern const std::string cfg_macro_editor_font_size; +extern const std::string cfg_macro_editor_tab_width; +extern const std::string cfg_macro_editor_indent; +extern const std::string cfg_macro_editor_window_state; +extern const std::string cfg_macro_editor_console_mru; +extern const std::string cfg_macro_editor_console_interpreter; +extern const std::string cfg_macro_editor_open_macros; +extern const std::string cfg_macro_editor_current_macro; +extern const std::string cfg_macro_editor_active_macro; +extern const std::string cfg_macro_editor_watch_expressions; +extern const std::string cfg_macro_editor_debugging_enabled; +extern const std::string cfg_macro_editor_ignore_exception_list; + class MacroEditorTree; class BrowserPanel; +class MainWindow; class MacroEditorDialog - : public QDialog, public gsi::Console, private Ui::MacroEditorDialog, public gsi::ExecutionHandler + : public QDialog, + public lay::Plugin, + public gsi::Console, + public gsi::ExecutionHandler, + private Ui::MacroEditorDialog { Q_OBJECT @@ -74,7 +98,7 @@ public: /** * @brief Constructor */ - MacroEditorDialog (QWidget *parent, lym::MacroCollection *root); + MacroEditorDialog (lay::MainWindow *parent, lym::MacroCollection *root); /** * @brief Destructor @@ -262,7 +286,10 @@ private: lym::Macro *new_macro (); void do_search_edited (); void select_trace (size_t index); + bool configure (const std::string &name, const std::string &value); + void config_finalize (); + lay::PluginRoot *mp_plugin_root; lym::MacroCollection *mp_root; bool m_first_show; bool m_in_processing; @@ -294,10 +321,13 @@ private: double m_process_events_interval; tl::Clock m_last_process_events; bool m_window_closed; + bool m_needs_update; + std::string m_styles; int m_ntab; int m_nindent; bool m_save_all_on_run; bool m_stop_on_exception; + std::set m_ignore_exception_list; bool m_file_watcher_enabled; std::string m_font_family; int m_font_size; diff --git a/src/lay/lay/layMacroEditorSetupDialog.cc b/src/lay/lay/layMacroEditorSetupPage.cc similarity index 58% rename from src/lay/lay/layMacroEditorSetupDialog.cc rename to src/lay/lay/layMacroEditorSetupPage.cc index 339f47ec5..9dc60c5ae 100644 --- a/src/lay/lay/layMacroEditorSetupDialog.cc +++ b/src/lay/lay/layMacroEditorSetupPage.cc @@ -21,15 +21,114 @@ */ -#include "layMacroEditorSetupDialog.h" +#include "layMacroEditorSetupPage.h" +#include "layMacroEditorPage.h" +#include "layMacroEditorDialog.h" +#include "layGenericSyntaxHighlighter.h" + +#include "lymMacro.h" #include "tlString.h" +#include #include namespace lay { +struct MacroEditorSetupDialogData +{ + MacroEditorSetupDialogData () + : basic_attributes (0), tab_width (8), indent (2), save_all_on_run (true), stop_on_exception (true), file_watcher_enabled (true), font_size (0) + { + } + + GenericSyntaxHighlighterAttributes basic_attributes; + std::vector > specific_attributes; + int tab_width; + int indent; + bool save_all_on_run; + bool stop_on_exception; + bool file_watcher_enabled; + std::string font_family; + int font_size; + std::set ignore_exceptions_list; + + void setup (lay::PluginRoot *root) + { + lay::MacroEditorHighlighters highlighters (0); + std::string styles; + root->config_get (cfg_macro_editor_styles, styles); + highlighters.load (styles); + + if (highlighters.basic_attributes ()) { + basic_attributes.assign (*highlighters.basic_attributes ()); + } + for (lay::MacroEditorHighlighters::const_iterator a = highlighters.begin (); a != highlighters.end (); ++a) { + specific_attributes.push_back (std::make_pair (a->first, GenericSyntaxHighlighterAttributes (& basic_attributes))); + specific_attributes.back ().second.assign (a->second); + } + + root->config_get (cfg_macro_editor_save_all_on_run, save_all_on_run); + root->config_get (cfg_macro_editor_file_watcher_enabled, file_watcher_enabled); + root->config_get (cfg_macro_editor_stop_on_exception, stop_on_exception); + root->config_get (cfg_macro_editor_tab_width, tab_width); + root->config_get (cfg_macro_editor_indent, indent); + root->config_get (cfg_macro_editor_font_family, font_family); + root->config_get (cfg_macro_editor_font_size, font_size); + + std::string il; + root->config_get (cfg_macro_editor_ignore_exception_list, il); + ignore_exceptions_list.clear (); + tl::Extractor ex (il.c_str ()); + while (! ex.at_end ()) { + std::string f; + ex.read_word_or_quoted (f); + ex.test (";"); + ignore_exceptions_list.insert (f); + } + } + + void commit (lay::PluginRoot *root) + { + lay::MacroEditorHighlighters highlighters (0); + + if (highlighters.basic_attributes ()) { + highlighters.basic_attributes ()->assign (basic_attributes); + } + + for (MacroEditorHighlighters::iterator a = highlighters.begin (); a != highlighters.end (); ++a) { + for (std::vector< std::pair >::const_iterator i = specific_attributes.begin (); i != specific_attributes.end (); ++i) { + if (i->first == a->first) { + a->second.assign (i->second); + break; + } + } + } + + // write configuration + + root->config_set (cfg_macro_editor_styles, highlighters.to_string ()); + root->config_set (cfg_macro_editor_save_all_on_run, save_all_on_run); + root->config_set (cfg_macro_editor_file_watcher_enabled, file_watcher_enabled); + root->config_set (cfg_macro_editor_stop_on_exception, stop_on_exception); + root->config_set (cfg_macro_editor_tab_width, tab_width); + root->config_set (cfg_macro_editor_indent, indent); + root->config_set (cfg_macro_editor_font_family, font_family); + root->config_set (cfg_macro_editor_font_size, font_size); + + std::string il; + for (std::set::const_iterator i = ignore_exceptions_list.begin (); i != ignore_exceptions_list.end (); ++i) { + if (! il.empty ()) { + il += ";"; + } + il += tl::to_quoted_string (*i); + } + root->config_set (cfg_macro_editor_ignore_exception_list, il); + + } +}; + static void update_item (QListWidgetItem *item, QTextCharFormat format) { @@ -38,8 +137,8 @@ update_item (QListWidgetItem *item, QTextCharFormat format) item->setData (Qt::BackgroundRole, format.background ()); } -MacroEditorSetupDialog::MacroEditorSetupDialog (QWidget *parent) - : QDialog (parent), mp_data (0) +MacroEditorSetupPage::MacroEditorSetupPage (QWidget *parent) + : lay::ConfigPage (parent), mp_data (0) { setupUi (this); @@ -52,22 +151,49 @@ MacroEditorSetupDialog::MacroEditorSetupDialog (QWidget *parent) connect (background_color_button, SIGNAL (color_changed (QColor)), this, SLOT (color_changed (QColor))); connect (font_sel, SIGNAL (currentFontChanged (const QFont &)), this, SLOT (update_font ())); connect (font_size, SIGNAL (valueChanged (int)), this, SLOT (update_font ())); + connect (clear_el, SIGNAL (clicked ()), this, SLOT (clear_exception_list ())); +} + +MacroEditorSetupPage::~MacroEditorSetupPage () +{ + delete mp_data; + mp_data = 0; } void -MacroEditorSetupDialog::color_changed (QColor) +MacroEditorSetupPage::color_changed (QColor) { commit_attributes (styles_list->currentItem ()); } void -MacroEditorSetupDialog::cb_changed (int) +MacroEditorSetupPage::cb_changed (int) { commit_attributes (styles_list->currentItem ()); } +void +MacroEditorSetupPage::clear_exception_list () +{ + if (mp_data) { + mp_data->ignore_exceptions_list.clear (); + update_ignore_exception_list (); + } +} + +void +MacroEditorSetupPage::update_ignore_exception_list () +{ + if (mp_data) { + exception_list->clear (); + for (std::set::const_iterator i = mp_data->ignore_exceptions_list.begin (); i != mp_data->ignore_exceptions_list.end (); ++i) { + exception_list->addItem (tl::to_qstring (*i)); + } + } +} + void -MacroEditorSetupDialog::update_font () +MacroEditorSetupPage::update_font () { QFont f; f.setFamily (font_sel->currentFont().family ()); @@ -76,26 +202,30 @@ MacroEditorSetupDialog::update_font () styles_list->setFont (f); } -int -MacroEditorSetupDialog::exec_dialog (MacroEditorSetupDialogData &data) +void +MacroEditorSetupPage::setup (PluginRoot *root) { - mp_data = &data; + delete mp_data; + mp_data = new MacroEditorSetupDialogData (); + mp_data->setup (root); - tab_width->setValue (data.tab_width); - indent->setValue (data.indent); - save_all_cb->setChecked (data.save_all_on_run); - stop_on_exception->setChecked (data.stop_on_exception); - watch_files->setChecked (data.file_watcher_enabled); + update_ignore_exception_list (); - if (data.font_size <= 0) { - data.font_size = font ().pointSize (); - data.font_family = "Monospace"; + tab_width->setValue (mp_data->tab_width); + indent->setValue (mp_data->indent); + save_all_cb->setChecked (mp_data->save_all_on_run); + stop_on_exception->setChecked (mp_data->stop_on_exception); + watch_files->setChecked (mp_data->file_watcher_enabled); + + if (mp_data->font_size <= 0) { + mp_data->font_size = font ().pointSize (); + mp_data->font_family = "Monospace"; } QFont f; - f.setFamily (tl::to_qstring (data.font_family)); + f.setFamily (tl::to_qstring (mp_data->font_family)); font_sel->setCurrentFont (f); - font_size->setValue (data.font_size); + font_size->setValue (mp_data->font_size); styles_list->blockSignals (true); @@ -103,18 +233,18 @@ MacroEditorSetupDialog::exec_dialog (MacroEditorSetupDialogData &data) std::map basic_names; - for (GenericSyntaxHighlighterAttributes::const_iterator a = data.basic_attributes.begin (); a != data.basic_attributes.end (); ++a) { + for (GenericSyntaxHighlighterAttributes::const_iterator a = mp_data->basic_attributes.begin (); a != mp_data->basic_attributes.end (); ++a) { QListWidgetItem *item = new QListWidgetItem (styles_list); QString n = tl::to_qstring (tl::to_string (QObject::tr ("(basic)")) + " ") + a->first; item->setText (n); item->setData (Qt::UserRole, -1); item->setData (Qt::UserRole + 1, a->second); basic_names.insert (std::make_pair (a->second, n)); - update_item (item, data.basic_attributes.format_for (a->second)); + update_item (item, mp_data->basic_attributes.format_for (a->second)); } int na = 0; - for (std::vector >::const_iterator sa = data.specific_attributes.begin (); sa != data.specific_attributes.end (); ++sa, ++na) { + for (std::vector >::const_iterator sa = mp_data->specific_attributes.begin (); sa != mp_data->specific_attributes.end (); ++sa, ++na) { QString l = tl::to_qstring ("(" + sa->first + ") "); @@ -137,30 +267,32 @@ MacroEditorSetupDialog::exec_dialog (MacroEditorSetupDialogData &data) update_attributes (styles_list->currentItem ()); update_font (); +} - int r = QDialog::exec (); - if (r) { - - if (styles_list->currentItem ()) { - commit_attributes (styles_list->currentItem ()); - } - - data.tab_width = tab_width->value (); - data.indent = indent->value (); - data.save_all_on_run = save_all_cb->isChecked (); - data.stop_on_exception = stop_on_exception->isChecked (); - data.file_watcher_enabled = watch_files->isChecked (); - - data.font_family = tl::to_string (font_sel->currentFont ().family ()); - data.font_size = font_size->value (); - +void +MacroEditorSetupPage::commit (PluginRoot *root) +{ + if (styles_list->currentItem ()) { + commit_attributes (styles_list->currentItem ()); } - return r; + if (mp_data) { + + mp_data->tab_width = tab_width->value (); + mp_data->indent = indent->value (); + mp_data->save_all_on_run = save_all_cb->isChecked (); + mp_data->stop_on_exception = stop_on_exception->isChecked (); + mp_data->file_watcher_enabled = watch_files->isChecked (); + + mp_data->font_family = tl::to_string (font_sel->currentFont ().family ()); + mp_data->font_size = font_size->value (); + + mp_data->commit (root); + } } void -MacroEditorSetupDialog::current_attribute_changed (QListWidgetItem *current, QListWidgetItem *previous) +MacroEditorSetupPage::current_attribute_changed (QListWidgetItem *current, QListWidgetItem *previous) { if (previous) { commit_attributes (previous); @@ -170,7 +302,7 @@ MacroEditorSetupDialog::current_attribute_changed (QListWidgetItem *current, QLi } void -MacroEditorSetupDialog::commit_attributes (QListWidgetItem *to_item) +MacroEditorSetupPage::commit_attributes (QListWidgetItem *to_item) { if (! to_item) { return; @@ -252,7 +384,7 @@ MacroEditorSetupDialog::commit_attributes (QListWidgetItem *to_item) } void -MacroEditorSetupDialog::update_attributes (QListWidgetItem *from_item) +MacroEditorSetupPage::update_attributes (QListWidgetItem *from_item) { if (from_item) { diff --git a/src/lay/lay/layMacroEditorSetupDialog.h b/src/lay/lay/layMacroEditorSetupPage.h similarity index 57% rename from src/lay/lay/layMacroEditorSetupDialog.h rename to src/lay/lay/layMacroEditorSetupPage.h index 0f7d8b444..85f763ef8 100644 --- a/src/lay/lay/layMacroEditorSetupDialog.h +++ b/src/lay/lay/layMacroEditorSetupPage.h @@ -21,60 +21,43 @@ */ -#ifndef HDR_layMacroEditorSetupDialog -#define HDR_layMacroEditorSetupDialog +#ifndef HDR_layMacroEditorSetupPage +#define HDR_layMacroEditorSetupPage -#include "layGenericSyntaxHighlighter.h" -#include "lymMacro.h" -#include "ui_MacroEditorSetupDialog.h" - -#include - -#include +#include "layPlugin.h" +#include "ui_MacroEditorSetupPage.h" namespace lay { -struct MacroEditorSetupDialogData -{ - MacroEditorSetupDialogData () - : basic_attributes (0), tab_width (8), indent (2), save_all_on_run (true), stop_on_exception (true), file_watcher_enabled (true), font_size (0) - { - } - - GenericSyntaxHighlighterAttributes basic_attributes; - std::vector > specific_attributes; - int tab_width; - int indent; - bool save_all_on_run; - bool stop_on_exception; - bool file_watcher_enabled; - std::string font_family; - int font_size; -}; +struct MacroEditorSetupDialogData; /** * @brief The dialog for editing the properties of the debugger/editor */ -class MacroEditorSetupDialog - : public QDialog, private Ui::MacroEditorSetupDialog +class MacroEditorSetupPage + : public lay::ConfigPage, private Ui::MacroEditorSetupPage { Q_OBJECT public: - MacroEditorSetupDialog (QWidget *parent); + MacroEditorSetupPage (QWidget *parent); + ~MacroEditorSetupPage (); - int exec_dialog (MacroEditorSetupDialogData &data); + virtual void setup (PluginRoot *root); + virtual void commit (PluginRoot *root); protected slots: void current_attribute_changed (QListWidgetItem *current, QListWidgetItem *previous); void cb_changed (int n); void color_changed (QColor c); void update_font (); + void clear_exception_list (); private: void commit_attributes (QListWidgetItem *to_item); void update_attributes (QListWidgetItem *from_item); + void update_ignore_exception_list (); MacroEditorSetupDialogData *mp_data; }; From 802237141b2c5cbbcad7386c712530181634c9f8 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 12 Mar 2018 00:47:04 +0100 Subject: [PATCH 8/8] Fixed #90 (DRC issue with 'extended' and joined = true) --- src/db/db/dbEdges.cc | 35 ++++++++++++++++++++++++++++------- src/db/unit_tests/dbEdges.cc | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/db/db/dbEdges.cc b/src/db/db/dbEdges.cc index 3890d4fbd..00f7b7542 100644 --- a/src/db/db/dbEdges.cc +++ b/src/db/db/dbEdges.cc @@ -883,20 +883,31 @@ struct JoinEdgesCluster void finish () { std::multimap objects_by_p1; - std::multiset p2; + std::multimap objects_by_p2; for (iterator o = begin (); o != end (); ++o) { if (o->first->p1 () != o->first->p2 ()) { objects_by_p1.insert (std::make_pair (o->first->p1 (), o)); - p2.insert (o->first->p2 ()); + objects_by_p2.insert (std::make_pair (o->first->p2 (), o)); } } - while (! p2.empty ()) { + while (! objects_by_p2.empty ()) { tl_assert (! objects_by_p1.empty ()); // Find the beginning of a new sequence - std::multimap::iterator j = objects_by_p1.begin (); + std::multimap::iterator j0 = objects_by_p1.begin (); + std::multimap::iterator j = j0; + do { + std::multimap::iterator jj = objects_by_p2.find (j->first); + if (jj == objects_by_p2.end ()) { + break; + } else { + j = objects_by_p1.find (jj->second->first->p1 ()); + tl_assert (j != objects_by_p1.end ()); + } + } while (j != j0); + iterator i = j->second; // determine a sequence @@ -906,12 +917,22 @@ struct JoinEdgesCluster do { + // record the next point pts.push_back (i->first->p2 ()); - std::multiset::iterator ip2 = p2.find (i->first->p2 ()); - tl_assert (ip2 != p2.end ()); - p2.erase (ip2); + + // remove the edge as it's taken + std::multimap::iterator jj; + for (jj = objects_by_p2.find (i->first->p2 ()); jj != objects_by_p2.end () && jj->first == i->first->p2 (); ++jj) { + if (jj->second == i) { + break; + } + } + tl_assert (jj != objects_by_p2.end () && jj->second == i); + objects_by_p2.erase (jj); objects_by_p1.erase (j); + // process along the edge to the next one + // TODO: this chooses any solution in case of forks. Choose a specific one? j = objects_by_p1.find (i->first->p2 ()); if (j != objects_by_p1.end ()) { i = j->second; diff --git a/src/db/unit_tests/dbEdges.cc b/src/db/unit_tests/dbEdges.cc index cf6d78a15..6a5a3c7b1 100644 --- a/src/db/unit_tests/dbEdges.cc +++ b/src/db/unit_tests/dbEdges.cc @@ -311,7 +311,40 @@ TEST(6) EXPECT_EQ (r.to_string (), "(-20,-20;-20,220;120,220;120,-20/-10,-10;110,-10;110,210;-10,210)"); } -TEST(7) +TEST(6b) +{ + // Ticket #90: order of edges as input to the edge collector should not matter + + db::Edges e; + e.insert (db::Edge (db::Point (0, -200), db::Point (100, -200))); + e.insert (db::Edge (db::Point (250, -200), db::Point (300, 0))); + e.insert (db::Edge (db::Point (0, 0), db::Point (0, -200))); + e.insert (db::Edge (db::Point (200, 0), db::Point (250, -200))); + + db::Region r; + e.extended (r, 0, 0, 20, 0, true); + EXPECT_EQ (r.to_string (), "(0,-200;0,0;20,0;20,-180;100,-180;100,-200);(250,-200;200,0;219,5;250,-118;281,5;300,0)"); +} + +TEST(6c) +{ + // A more complex scenario with forks + + db::Edges e; + e.insert (db::Edge (db::Point (0, -200), db::Point (100, -200))); + e.insert (db::Edge (db::Point (250, -200), db::Point (300, 0))); + e.insert (db::Edge (db::Point (0, 0), db::Point (0, -200))); + e.insert (db::Edge (db::Point (0, -100), db::Point (0, -200))); + e.insert (db::Edge (db::Point (200, 0), db::Point (250, -200))); + e.insert (db::Edge (db::Point (0, -200), db::Point (200, -200))); + e.insert (db::Edge (db::Point (250, -200), db::Point (350, 0))); + + db::Region r; + e.extended (r, 0, 0, 20, 0, true); + EXPECT_EQ (r.to_string (), "(0,-200;0,0;20,0;20,-180;100,-180;100,-200);(0,-200;0,-100;20,-100;20,-180;200,-180;200,-200);(250,-200;200,0;219,5;250,-118;281,5;300,0);(250,-200;232,-191;332,9;350,0)"); +} + +TEST(7) { db::Edges e; e.insert (db::Edge (db::Point (0, 0), db::Point (0, 200)));