From 1bb662b9edc590cc4826c62f6369725aef4b83e8 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 2 Dec 2017 18:48:28 +0100 Subject: [PATCH] Fixed #21 (Autorun(-early) doesn't seem to run when lym files are inside a package) --- src/lay/lay/layApplication.cc | 2 +- src/lay/lay/layMacroController.cc | 211 +++++++++++++++++------------- src/lay/lay/layMacroController.h | 5 +- src/lym/lym/lymMacro.cc | 5 + src/lym/lym/lymMacro.h | 5 + 5 files changed, 131 insertions(+), 97 deletions(-) diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index aa886d70a..27727cf60 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -773,7 +773,7 @@ Application::Application (int &argc, char **argv, bool non_ui_mode) } // Actually load the macros and/or establish the search path - mc->finish (! m_no_macros); + mc->finish (); } diff --git a/src/lay/lay/layMacroController.cc b/src/lay/lay/layMacroController.cc index 9b5e86fc0..d8db9cc91 100644 --- a/src/lay/lay/layMacroController.cc +++ b/src/lay/lay/layMacroController.cc @@ -80,7 +80,7 @@ static lay::MacroController::MacroCategory drc_cat () } void -MacroController::finish (bool load) +MacroController::finish () { // Scan built-in macros // These macros are always taken, even if there are no macros requested (they are required to @@ -96,10 +96,14 @@ MacroController::finish (bool load) m_macro_categories.push_back (python_cat ()); m_macro_categories.push_back (drc_cat ()); + // scans the macros from techs and packages (this will allow autorun-early on them) + // and updates m_external_paths + sync_macro_sources (); + // Scan for macros and set interpreter path for (std::vector ::const_iterator p = m_internal_paths.begin (); p != m_internal_paths.end (); ++p) { - if (load) { + if (! m_no_implicit_macros) { for (size_t c = 0; c < m_macro_categories.size (); ++c) { @@ -137,6 +141,19 @@ MacroController::finish (bool load) } } + + + // Scan for macros in packages and techs + + if (! m_no_implicit_macros) { + for (std::vector ::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) { + lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly); + } + } + + // Set the interpreter path to packages too + + sync_package_paths (); } void @@ -377,10 +394,106 @@ void MacroController::sync_implicit_macros (bool ask_before_autorun) { if (m_no_implicit_macros) { - sync_package_paths (); - return; - } + sync_macro_sources (); + sync_package_paths (); + + } else { + + // determine the paths currently in use + std::map prev_folders_by_path; + for (std::vector::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) { + prev_folders_by_path.insert (std::make_pair (p->path, p.operator-> ())); + } + + // gets the external paths (tech, packages) into m_external_paths + sync_macro_sources (); + + // delete macro collections which are no longer required or update description + + std::vector folders_to_delete; + + // determine the paths that will be in use + std::map new_folders_by_path; + for (std::vector::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) { + new_folders_by_path.insert (std::make_pair (p->path, p.operator-> ())); + } + + lym::MacroCollection *root = &lym::MacroCollection::root (); + + for (lym::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) { + if (m->second->virtual_mode () == lym::MacroCollection::TechFolder || + m->second->virtual_mode () == lym::MacroCollection::SaltFolder) { + std::map::const_iterator u = new_folders_by_path.find (m->second->path ()); + if (u == new_folders_by_path.end ()) { + // no longer used + folders_to_delete.push_back (m->second); + } else { + m->second->set_description (u->second->description); + } + } + } + + for (std::vector::iterator m = folders_to_delete.begin (); m != folders_to_delete.end (); ++m) { + if (tl::verbosity () >= 20) { + tl::info << "Removing macro folder " << (*m)->path () << ", category '" << (*m)->category () << "' because no longer in use"; + } + root->erase (*m); + } + + // sync the search paths with the packages + sync_package_paths (); + + // add new folders + std::vector new_folders; + + for (std::vector::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) { + + if (prev_folders_by_path.find (p->path) != prev_folders_by_path.end ()) { + continue; + } + + if (tl::verbosity () >= 20) { + tl::info << "Adding macro folder " << p->path << ", category '" << p->cat << "' for '" << p->description << "'"; + } + + // Add the folder. Note: it may happen that a macro folder for the tech specific macros already exists in + // a non-tech context. + // In that case, the add_folder method will return 0. + + // TODO: is it wise to make this writeable? + lym::MacroCollection *mc = lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly); + if (mc) { + mc->set_virtual_mode (p->type); + new_folders.push_back (mc); + } + + } + + { + // This prevents the message dialog below to issue deferred methods + tl::NoDeferredMethods silent; + + bool has_autorun = false; + for (std::vector::const_iterator m = new_folders.begin (); m != new_folders.end () && ! has_autorun; ++m) { + has_autorun = (*m)->has_autorun (); + } + + if (has_autorun) { + if (! ask_before_autorun || QMessageBox::question (mp_mw, QObject::tr ("Run Macros"), QObject::tr ("Some macros associated with new items are configured to run automatically.\n\nChoose 'Yes' to run these macros now. Choose 'No' to not run them."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + for (std::vector::const_iterator m = new_folders.begin (); m != new_folders.end (); ++m) { + (*m)->autorun (); + } + } + } + } + + } +} + +void +MacroController::sync_macro_sources () +{ std::vector external_paths; // Add additional places where the technologies define some macros @@ -480,96 +593,8 @@ MacroController::sync_implicit_macros (bool ask_before_autorun) } - // delete macro collections which are no longer required or update description - - std::vector folders_to_delete; - - // determine the paths that will be in use - std::map new_folders_by_path; - for (std::vector::const_iterator p = external_paths.begin (); p != external_paths.end (); ++p) { - new_folders_by_path.insert (std::make_pair (p->path, p.operator-> ())); - } - - // determine the paths currently in use - std::map prev_folders_by_path; - for (std::vector::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) { - prev_folders_by_path.insert (std::make_pair (p->path, p.operator-> ())); - } - - lym::MacroCollection *root = &lym::MacroCollection::root (); - - for (lym::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) { - if (m->second->virtual_mode () == lym::MacroCollection::TechFolder || - m->second->virtual_mode () == lym::MacroCollection::SaltFolder) { - std::map::const_iterator u = new_folders_by_path.find (m->second->path ()); - if (u == new_folders_by_path.end ()) { - // no longer used - folders_to_delete.push_back (m->second); - } else { - m->second->set_description (u->second->description); - } - } - } - - for (std::vector::iterator m = folders_to_delete.begin (); m != folders_to_delete.end (); ++m) { - if (tl::verbosity () >= 20) { - tl::info << "Removing macro folder " << (*m)->path () << ", category '" << (*m)->category () << "' because no longer in use"; - } - root->erase (*m); - } - - // sync the search paths with the packages - sync_package_paths (); - // store new paths m_external_paths = external_paths; - - // add new folders - - std::vector new_folders; - - for (std::vector::const_iterator p = m_external_paths.begin (); p != m_external_paths.end (); ++p) { - - if (prev_folders_by_path.find (p->path) != prev_folders_by_path.end ()) { - continue; - } - - if (tl::verbosity () >= 20) { - tl::info << "Adding macro folder " << p->path << ", category '" << p->cat << "' for '" << p->description << "'"; - } - - // Add the folder. Note: it may happen that a macro folder for the tech specific macros already exists in - // a non-tech context. - // In that case, the add_folder method will return 0. - - // TODO: is it wise to make this writeable? - lym::MacroCollection *mc = lym::MacroCollection::root ().add_folder (p->description, p->path, p->cat, p->readonly); - if (mc) { - mc->set_virtual_mode (p->type); - new_folders.push_back (mc); - } - - } - - { - - // This prevents the message dialog below to issue deferred methods - tl::NoDeferredMethods silent; - - bool has_autorun = false; - for (std::vector::const_iterator m = new_folders.begin (); m != new_folders.end () && ! has_autorun; ++m) { - has_autorun = (*m)->has_autorun (); - } - - if (has_autorun) { - if (! ask_before_autorun || QMessageBox::question (mp_mw, QObject::tr ("Run Macros"), QObject::tr ("Some macros associated with new items are configured to run automatically.\n\nChoose 'Yes' to run these macros now. Choose 'No' to not run them."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - for (std::vector::const_iterator m = new_folders.begin (); m != new_folders.end (); ++m) { - (*m)->autorun (); - } - } - } - - } } void diff --git a/src/lay/lay/layMacroController.h b/src/lay/lay/layMacroController.h index cd6716f38..5e7e5faef 100644 --- a/src/lay/lay/layMacroController.h +++ b/src/lay/lay/layMacroController.h @@ -144,10 +144,8 @@ public: /** * @brief Loads the macros from the predefined paths and establishes the search paths * This method will also establish the macro categories. - * If "load" is false, only the search path will be set. The macros themselves are not - * loaded into memory. */ - void finish (bool load); + void finish (); /** * @brief Adds a temporary macro @@ -256,6 +254,7 @@ private: void sync_file_watcher (); void sync_files (); void sync_package_paths (); + void sync_macro_sources (); }; } diff --git a/src/lym/lym/lymMacro.cc b/src/lym/lym/lymMacro.cc index bd253a8db..7c4ab1bb2 100644 --- a/src/lym/lym/lymMacro.cc +++ b/src/lym/lym/lymMacro.cc @@ -1789,6 +1789,11 @@ bool MacroCollection::has_autorun () const return has_autorun_for (*this, false); } +bool MacroCollection::has_autorun_early () const +{ + return has_autorun_for (*this, true); +} + static void autorun_for (lym::MacroCollection &collection, bool early) { for (lym::MacroCollection::child_iterator c = collection.begin_children (); c != collection.end_children (); ++c) { diff --git a/src/lym/lym/lymMacro.h b/src/lym/lym/lymMacro.h index 9d7e65474..e93376049 100644 --- a/src/lym/lym/lymMacro.h +++ b/src/lym/lym/lymMacro.h @@ -989,6 +989,11 @@ public: */ void autorun (); + /** + * @brief Returns true, if the collection has an early autorun macro + */ + bool has_autorun_early () const; + /** * @brief Runs all macros marked with early auto-run */