From b95634edf3bdf551c4bff5667fec8996fbdcdb3a Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 30 May 2024 13:58:13 +0200 Subject: [PATCH] Fixing some flaws inside the macro IDE * When deleting a macro, the tab was not closed but became "zombie" * After creating a new folder, macros made there behaved "zombie" too --- src/lay/lay/layMacroEditorDialog.cc | 36 +++++++++++------- src/lay/lay/layMacroEditorDialog.h | 2 + src/lay/lay/layMacroEditorTree.cc | 20 ++++++++++ src/lay/lay/layMacroEditorTree.h | 2 + src/lym/lym/lymMacroCollection.cc | 58 ++++++++++++++++++++++++++++- src/lym/lym/lymMacroCollection.h | 25 +++++++++++++ 6 files changed, 127 insertions(+), 16 deletions(-) diff --git a/src/lay/lay/layMacroEditorDialog.cc b/src/lay/lay/layMacroEditorDialog.cc index bf7e5df7d..ed07e8e17 100644 --- a/src/lay/lay/layMacroEditorDialog.cc +++ b/src/lay/lay/layMacroEditorDialog.cc @@ -278,7 +278,8 @@ MacroEditorDialog::MacroEditorDialog (lay::Dispatcher *pr, lym::MacroCollection m_edit_trace_index (-1), m_add_edit_trace_enabled (true), dm_refresh_file_watcher (this, &MacroEditorDialog::do_refresh_file_watcher), - dm_update_ui_to_run_mode (this, &MacroEditorDialog::do_update_ui_to_run_mode) + dm_update_ui_to_run_mode (this, &MacroEditorDialog::do_update_ui_to_run_mode), + dm_current_tab_changed (this, &MacroEditorDialog::do_current_tab_changed) { // Makes this dialog receive events while progress bars are on - this way we can set breakpoints // during execution of a macro even if anything lengthy is running. @@ -1759,13 +1760,12 @@ MacroEditorDialog::macro_deleted (lym::Macro *macro) std::map ::iterator page = m_tab_widgets.find (macro); if (page != m_tab_widgets.end ()) { - // disable the macro on the page - we'll ask for updates when the file - // watcher becomes active. So long, the macro is "zombie". - page->second->connect_macro (0); - m_tab_widgets.erase (page); + int index = tabWidget->indexOf (page->second); + if (index >= 0) { + tab_close_requested (index); + } } - refresh_file_watcher (); update_ui_to_run_mode (); } @@ -1792,12 +1792,10 @@ MacroEditorDialog::macro_changed (lym::Macro *macro) } } -void -MacroEditorDialog::current_tab_changed (int index) +void +MacroEditorDialog::do_current_tab_changed () { - add_edit_trace (false); - - MacroEditorPage *page = dynamic_cast (tabWidget->widget (index)); + MacroEditorPage *page = dynamic_cast (tabWidget->currentWidget ()); if (page) { int tab_index = 0; for (std::vector::const_iterator mt = m_macro_trees.begin (); mt != m_macro_trees.end (); ++mt, ++tab_index) { @@ -1807,9 +1805,19 @@ MacroEditorDialog::current_tab_changed (int index) } } } +} +void +MacroEditorDialog::current_tab_changed (int index) +{ + // select the current macro - done in a delayed fashion so there is + // no interacting during erase of macros + dm_current_tab_changed (); + + add_edit_trace (false); + + MacroEditorPage *page = dynamic_cast (tabWidget->widget (index)); replaceFrame->setEnabled (page && page->macro () && !page->macro ()->is_readonly ()); - apply_search (); do_update_ui_to_run_mode (); @@ -2500,6 +2508,7 @@ BEGIN_PROTECTED if (m->is_readonly ()) { throw tl::Exception ("Can't delete this macro - it is readonly"); } + if (collection) { if (QMessageBox::question (this, QObject::tr ("Delete Macro File"), @@ -2512,12 +2521,11 @@ BEGIN_PROTECTED throw tl::Exception ("Can't delete this macro"); } + ct->set_current (collection); collection->erase (m); } - ct->set_current (collection); - } refresh_file_watcher (); diff --git a/src/lay/lay/layMacroEditorDialog.h b/src/lay/lay/layMacroEditorDialog.h index 7a0e2e2c5..001829924 100644 --- a/src/lay/lay/layMacroEditorDialog.h +++ b/src/lay/lay/layMacroEditorDialog.h @@ -271,6 +271,7 @@ private: void close_many (int which_relative_to_current); void ensure_writeable_collection_selected (); void update_console_text (); + void do_current_tab_changed (); void start_exec (gsi::Interpreter *interpreter); void end_exec (gsi::Interpreter *interpreter); size_t id_for_path (gsi::Interpreter *interpreter, const std::string &path); @@ -360,6 +361,7 @@ private: std::vector m_changed_files, m_removed_files; tl::DeferredMethod dm_refresh_file_watcher; tl::DeferredMethod dm_update_ui_to_run_mode; + tl::DeferredMethod dm_current_tab_changed; QMenu *mp_tabs_menu; }; diff --git a/src/lay/lay/layMacroEditorTree.cc b/src/lay/lay/layMacroEditorTree.cc index 207d7bdce..cb6507be5 100644 --- a/src/lay/lay/layMacroEditorTree.cc +++ b/src/lay/lay/layMacroEditorTree.cc @@ -123,7 +123,9 @@ MacroTreeModel::MacroTreeModel (QObject *parent, lay::MacroEditorDialog *dialog, : QAbstractItemModel (parent), mp_dialog (dialog), mp_parent (dialog), mp_root (root), m_category (cat) { connect (root, SIGNAL (macro_changed (lym::Macro *)), this, SLOT (macro_changed ())); + connect (root, SIGNAL (macro_about_to_be_deleted (lym::Macro *)), this, SLOT (macro_about_to_be_deleted (lym::Macro *))); connect (root, SIGNAL (macro_deleted (lym::Macro *)), this, SLOT (macro_deleted (lym::Macro *))); + connect (root, SIGNAL (macro_collection_about_to_be_deleted (lym::MacroCollection *)), this, SLOT (macro_collection_about_to_be_deleted (lym::MacroCollection *))); connect (root, SIGNAL (macro_collection_deleted (lym::MacroCollection *)), this, SLOT (macro_collection_deleted (lym::MacroCollection *))); connect (root, SIGNAL (macro_collection_changed (lym::MacroCollection *)), this, SLOT (macro_collection_changed ())); connect (root, SIGNAL (about_to_change ()), this, SLOT (about_to_change ())); @@ -133,7 +135,9 @@ MacroTreeModel::MacroTreeModel (QWidget *parent, lym::MacroCollection *root, con : QAbstractItemModel (parent), mp_dialog (0), mp_parent (parent), mp_root (root), m_category (cat) { connect (root, SIGNAL (macro_changed (lym::Macro *)), this, SLOT (macro_changed ())); + connect (root, SIGNAL (macro_about_to_be_deleted (lym::Macro *)), this, SLOT (macro_about_to_be_deleted (lym::Macro *))); connect (root, SIGNAL (macro_deleted (lym::Macro *)), this, SLOT (macro_deleted (lym::Macro *))); + connect (root, SIGNAL (macro_collection_about_to_be_deleted (lym::MacroCollection *)), this, SLOT (macro_collection_about_to_be_deleted (lym::MacroCollection *))); connect (root, SIGNAL (macro_collection_deleted (lym::MacroCollection *)), this, SLOT (macro_collection_deleted (lym::MacroCollection *))); connect (root, SIGNAL (macro_collection_changed (lym::MacroCollection *)), this, SLOT (macro_collection_changed ())); connect (root, SIGNAL (about_to_change ()), this, SLOT (about_to_change ())); @@ -144,11 +148,27 @@ Qt::DropActions MacroTreeModel::supportedDropActions() const return Qt::MoveAction; } +void MacroTreeModel::macro_about_to_be_deleted (lym::Macro *macro) +{ + QModelIndex index = index_for (macro); + if (index.isValid ()) { + changePersistentIndex (index, QModelIndex ()); + } +} + void MacroTreeModel::macro_deleted (lym::Macro *) { // .. nothing yet .. } +void MacroTreeModel::macro_collection_about_to_be_deleted (lym::MacroCollection *mc) +{ + QModelIndex index = index_for (mc); + if (index.isValid ()) { + changePersistentIndex (index, QModelIndex ()); + } +} + void MacroTreeModel::macro_collection_deleted (lym::MacroCollection *) { // .. nothing yet .. diff --git a/src/lay/lay/layMacroEditorTree.h b/src/lay/lay/layMacroEditorTree.h index 6d7a91606..69d616df6 100644 --- a/src/lay/lay/layMacroEditorTree.h +++ b/src/lay/lay/layMacroEditorTree.h @@ -69,7 +69,9 @@ signals: private slots: void macro_changed (); + void macro_about_to_be_deleted (lym::Macro *macro); void macro_deleted (lym::Macro *macro); + void macro_collection_about_to_be_deleted (lym::MacroCollection *mc); void macro_collection_deleted (lym::MacroCollection *mc); void macro_collection_changed (); void about_to_change (); diff --git a/src/lym/lym/lymMacroCollection.cc b/src/lym/lym/lymMacroCollection.cc index c40645dd8..d91cc481b 100644 --- a/src/lym/lym/lymMacroCollection.cc +++ b/src/lym/lym/lymMacroCollection.cc @@ -124,6 +124,14 @@ void MacroCollection::on_macro_collection_changed (MacroCollection *mc) } } +void MacroCollection::on_child_about_to_be_deleted (MacroCollection *mc) +{ +#if defined(HAVE_QT) + emit child_about_to_be_deleted (mc); +#endif + on_macro_collection_about_to_be_deleted (mc); +} + void MacroCollection::on_child_deleted (MacroCollection *mc) { #if defined(HAVE_QT) @@ -132,6 +140,17 @@ void MacroCollection::on_child_deleted (MacroCollection *mc) on_macro_collection_deleted (mc); } +void MacroCollection::on_macro_collection_about_to_be_deleted (MacroCollection *mc) +{ + if (mp_parent) { + mp_parent->on_macro_collection_about_to_be_deleted (mc); + } else { +#if defined(HAVE_QT) + emit macro_collection_about_to_be_deleted (mc); +#endif + } +} + void MacroCollection::on_macro_collection_deleted (MacroCollection *mc) { if (mp_parent) { @@ -143,6 +162,14 @@ void MacroCollection::on_macro_collection_deleted (MacroCollection *mc) } } +void MacroCollection::on_macro_about_to_be_deleted_here (Macro *macro) +{ +#if defined(HAVE_QT) + emit macro_about_to_be_deleted_here (macro); +#endif + on_macro_about_to_be_deleted (macro); +} + void MacroCollection::on_macro_deleted_here (Macro *macro) { #if defined(HAVE_QT) @@ -151,6 +178,17 @@ void MacroCollection::on_macro_deleted_here (Macro *macro) on_macro_deleted (macro); } +void MacroCollection::on_macro_about_to_be_deleted (Macro *macro) +{ + if (mp_parent) { + mp_parent->on_macro_about_to_be_deleted (macro); + } else { +#if defined(HAVE_QT) + emit macro_about_to_be_deleted (macro); +#endif + } +} + void MacroCollection::on_macro_deleted (Macro *macro) { if (mp_parent) { @@ -539,8 +577,9 @@ void MacroCollection::erase (lym::Macro *mp) for (iterator m = m_macros.begin (); m != m_macros.end (); ++m) { if (m->second == mp) { begin_changes (); - on_macro_deleted_here (mp); + on_macro_about_to_be_deleted_here (mp); m_macros.erase (m); + on_macro_deleted_here (mp); delete mp; on_changed (); return; @@ -553,8 +592,9 @@ void MacroCollection::erase (lym::MacroCollection *mp) for (child_iterator f = m_folders.begin (); f != m_folders.end (); ++f) { if (f->second == mp) { begin_changes (); - on_child_deleted (mp); + on_child_about_to_be_deleted (mp); m_folders.erase (f); + on_child_deleted (mp); delete mp; on_changed (); return; @@ -608,11 +648,25 @@ bool MacroCollection::rename (const std::string &n) return false; } else { m_path = n; + if (parent ()) { + parent ()->folder_renamed (this); + } on_changed (); return true; } } +void MacroCollection::folder_renamed (MacroCollection *mc) +{ + for (auto f = m_folders.begin (); f != m_folders.end (); ++f) { + if (f->second == mc) { + m_folders.erase (f); + m_folders.insert (std::make_pair (mc->name (), mc)); + return; + } + } +} + lym::MacroCollection *MacroCollection::create_folder (const char *prefix, bool mkdir) { std::string name; diff --git a/src/lym/lym/lymMacroCollection.h b/src/lym/lym/lymMacroCollection.h index 31fde7e53..28c851b08 100644 --- a/src/lym/lym/lymMacroCollection.h +++ b/src/lym/lym/lymMacroCollection.h @@ -463,21 +463,41 @@ signals: */ void changed (); + /** + * @brief This signal is sent by collection when a child collection is about to be deleted in this collection + */ + void child_about_to_be_deleted (lym::MacroCollection *); + /** * @brief This signal is sent by collection when a child collection is deleted in this collection */ void child_deleted (lym::MacroCollection *); + /** + * @brief This signal is sent by the root object when a macro collection is about to be deleted + */ + void macro_collection_about_to_be_deleted (lym::MacroCollection *); + /** * @brief This signal is sent by the root object when a macro collection is deleted */ void macro_collection_deleted (lym::MacroCollection *); + /** + * @brief This signal is sent by collection when a macro is about to be deleted in this collection + */ + void macro_about_to_be_deleted_here (lym::Macro *); + /** * @brief This signal is sent by collection when a macro is deleted in this collection */ void macro_deleted_here (lym::Macro *); + /** + * @brief This signal is sent by the root object when a macro is about to be deleted + */ + void macro_about_to_be_deleted (lym::Macro *); + /** * @brief This signal is sent by the root object when a macro is deleted */ @@ -522,9 +542,13 @@ private: int m_virtual_mode; bool m_readonly; + void on_child_about_to_be_deleted (MacroCollection *mc); void on_child_deleted (MacroCollection *mc); + void on_macro_collection_about_to_be_deleted (MacroCollection *mc); void on_macro_collection_deleted (MacroCollection *mc); + void on_macro_about_to_be_deleted_here (Macro *macro); void on_macro_deleted_here (Macro *macro); + void on_macro_about_to_be_deleted (Macro *macro); void on_macro_deleted (Macro *macro); void on_macro_changed (Macro *macro); void on_macro_collection_changed (MacroCollection *mc); @@ -535,6 +559,7 @@ private: void create_entry (const std::string &path); void rename_macro (Macro *macro, const std::string &new_name); + void folder_renamed (MacroCollection *mc); void begin_changes ();