diff --git a/src/lay/layApplication.cc b/src/lay/layApplication.cc index bf4b65abf..d53df08fb 100644 --- a/src/lay/layApplication.cc +++ b/src/lay/layApplication.cc @@ -929,37 +929,10 @@ Application::Application (int &argc, char **argv, bool non_ui_mode) lay::MacroController *mc = lay::MacroController::instance (); - if (mc && ! m_no_macros) { - - // Add the global ruby modules as the first ones. - m_load_macros.insert (m_load_macros.begin (), global_modules.begin (), global_modules.end ()); - - for (std::vector ::const_iterator p = m_klayout_path.begin (); p != m_klayout_path.end (); ++p) { - if (p == m_klayout_path.begin ()) { - mc->add_path (*p, tl::to_string (QObject::tr ("Local")), std::string (), false); - } else if (m_klayout_path.size () == 2) { - mc->add_path (*p, tl::to_string (QObject::tr ("Global")), std::string (), true); - } else { - mc->add_path (*p, tl::to_string (QObject::tr ("Global")) + " - " + *p, std::string (), true); - } - } - - // Install the custom folders - for (std::vector >::const_iterator p = custom_macro_paths.begin (); p != custom_macro_paths.end (); ++p) { - mc->add_path (p->first, tl::to_string (QObject::tr ("Project")) + " - " + p->first, p->second, false); - } - - // Actually load the macros - mc->load (); - - } - lay::TechnologyController *tc = lay::TechnologyController::instance (); if (tc) { - tc->enable_macros (! m_no_macros); - // auto-import technologies for (std::vector ::const_iterator p = m_klayout_path.begin (); p != m_klayout_path.end (); ++p) { std::string tp = tl::to_string (QDir (tl::to_qstring (*p)).filePath (QString::fromUtf8 ("tech"))); @@ -987,7 +960,38 @@ Application::Application (int &argc, char **argv, bool non_ui_mode) } - tc->refresh (); + tc->load (); + + } + + if (mc) { + + mc->enable_implicit_macros (! m_no_macros); + + if (! m_no_macros) { + + // Add the global ruby modules as the first ones. + m_load_macros.insert (m_load_macros.begin (), global_modules.begin (), global_modules.end ()); + + for (std::vector ::const_iterator p = m_klayout_path.begin (); p != m_klayout_path.end (); ++p) { + if (p == m_klayout_path.begin ()) { + mc->add_path (*p, tl::to_string (QObject::tr ("Local")), std::string (), false); + } else if (m_klayout_path.size () == 2) { + mc->add_path (*p, tl::to_string (QObject::tr ("Global")), std::string (), true); + } else { + mc->add_path (*p, tl::to_string (QObject::tr ("Global")) + " - " + *p, std::string (), true); + } + } + + // Install the custom folders + for (std::vector >::const_iterator p = custom_macro_paths.begin (); p != custom_macro_paths.end (); ++p) { + mc->add_path (p->first, tl::to_string (QObject::tr ("Project")) + " - " + p->first, p->second, false); + } + + } + + // Actually load the macros + mc->load (); } diff --git a/src/lay/layMacro.cc b/src/lay/layMacro.cc index 848fea380..2a062b540 100644 --- a/src/lay/layMacro.cc +++ b/src/lay/layMacro.cc @@ -1083,7 +1083,7 @@ void MacroCollection::on_macro_changed (Macro *macro) } } -void MacroCollection::collect_used_nodes(std::set ¯os, std::set ¯o_collections) +void MacroCollection::collect_used_nodes (std::set ¯os, std::set ¯o_collections) { for (MacroCollection::child_iterator c = begin_children (); c != end_children (); ++c) { macro_collections.insert (c->second); diff --git a/src/lay/layMacroController.cc b/src/lay/layMacroController.cc index fe220ca71..ddc68d15e 100644 --- a/src/lay/layMacroController.cc +++ b/src/lay/layMacroController.cc @@ -37,7 +37,7 @@ namespace lay { MacroController::MacroController () - : mp_macro_editor (0), mp_mw (0), + : mp_macro_editor (0), mp_mw (0), m_no_implicit_macros (false), dm_do_update_menu_with_macros (this, &MacroController::do_update_menu_with_macros) { connect (&m_temp_macros, SIGNAL (menu_needs_update ()), this, SLOT (update_menu_with_macros ())); @@ -74,6 +74,8 @@ MacroController::load () } } + + sync_implicit_macros (false); } void @@ -89,7 +91,7 @@ MacroController::initialized (lay::PluginRoot *root) connect (&lay::MacroCollection::root (), SIGNAL (macro_collection_changed (MacroCollection *)), this, SLOT (update_menu_with_macros ())); if (lay::TechnologyController::instance ()) { connect (lay::TechnologyController::instance (), SIGNAL (active_technology_changed ()), this, SLOT (update_menu_with_macros ())); - connect (lay::TechnologyController::instance (), SIGNAL (technologies_edited ()), this, SLOT (update_menu_with_macros ())); + connect (lay::TechnologyController::instance (), SIGNAL (technologies_edited ()), this, SLOT (technologies_edited ())); } // update the menus with the macro menu bindings as late as possible (now we @@ -104,7 +106,7 @@ MacroController::uninitialize (lay::PluginRoot * /*root*/) disconnect (&lay::MacroCollection::root (), SIGNAL (macro_collection_changed (MacroCollection *)), this, SLOT (update_menu_with_macros ())); if (lay::TechnologyController::instance ()) { disconnect (lay::TechnologyController::instance (), SIGNAL (active_technology_changed ()), this, SLOT (update_menu_with_macros ())); - disconnect (lay::TechnologyController::instance (), SIGNAL (technologies_edited ()), this, SLOT (update_menu_with_macros ())); + disconnect (lay::TechnologyController::instance (), SIGNAL (technologies_edited ()), this, SLOT (technologies_edited ())); } delete mp_macro_editor; @@ -264,6 +266,136 @@ MacroController::show_editor (const std::string &cat, bool force_add) } } +void +MacroController::enable_implicit_macros (bool enable) +{ + m_no_implicit_macros = !enable; +} + +void +MacroController::sync_implicit_macros (bool check_autorun) +{ + if (m_no_implicit_macros) { + return; + } + + std::set > tech_macro_paths; + std::map, std::string> tech_names_by_path; + + // Add additional places where the technologies define some macros + for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) { + + if (t->base_path ().empty ()) { + continue; + } + + for (size_t c = 0; c < macro_categories ().size (); ++c) { + + QDir base_dir (tl::to_qstring (t->base_path ())); + if (base_dir.exists ()) { + + QDir macro_dir (base_dir.filePath (tl::to_qstring (macro_categories () [c].first))); + if (macro_dir.exists ()) { + + std::string mp = tl::to_string (macro_dir.path ()); + std::pair cp (macro_categories () [c].first, mp); + tech_macro_paths.insert (cp); + std::string &tn = tech_names_by_path [cp]; + if (! tn.empty ()) { + tn += ","; + } + tn += t->name (); + + } + + } + + } + + } + + // delete macro collections which are no longer required or update description + std::vector folders_to_delete; + std::string desc_prefix = tl::to_string (QObject::tr ("Technology")) + " - "; + + lay::MacroCollection *root = &lay::MacroCollection::root (); + + for (lay::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) { + + std::pair cp (m->second->category (), m->second->path ()); + if (m->second->virtual_mode () == lay::MacroCollection::TechFolder && m_tech_macro_paths.find (cp) != m_tech_macro_paths.end ()) { + + if (tech_macro_paths.find (cp) == tech_macro_paths.end ()) { + // no longer used + folders_to_delete.push_back (m->second); + } else { + // used: update description if required + std::string desc = desc_prefix + tech_names_by_path [cp]; + m->second->set_description (desc); + } + + } + + } + + 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); + } + + // store new paths + m_tech_macro_paths = tech_macro_paths; + + // add new folders + for (lay::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) { + if (m->second->virtual_mode () == lay::MacroCollection::TechFolder) { + std::pair cp (m->second->category (), m->second->path ()); + tech_macro_paths.erase (cp); + } + } + + std::vector new_folders; + + for (std::set >::const_iterator p = tech_macro_paths.begin (); p != tech_macro_paths.end (); ++p) { + + const std::string &tn = tech_names_by_path [*p]; + + // TODO: is it wise to make it writeable? + if (tl::verbosity () >= 20) { + tl::info << "Adding macro folder " << p->second << ", category '" << p->first << "' for technologies " << tn; + } + + // 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. + lay::MacroCollection *mc = lay::MacroCollection::root ().add_folder (desc_prefix + tn, p->second, p->first, false); + if (mc) { + + mc->set_virtual_mode (lay::MacroCollection::TechFolder); + new_folders.push_back (mc); + + } + + } + + if (check_autorun) { + + 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 && 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::refresh () { @@ -369,6 +501,14 @@ MacroController::add_macro_items_to_menu (lay::MacroCollection &collection, int } } +void +MacroController::technologies_edited () +{ + sync_implicit_macros (true); + refresh (); + update_menu_with_macros (); +} + void MacroController::update_menu_with_macros () { diff --git a/src/lay/layMacroController.h b/src/lay/layMacroController.h index 90b683358..5d6e53697 100644 --- a/src/lay/layMacroController.h +++ b/src/lay/layMacroController.h @@ -103,6 +103,14 @@ public: */ virtual void drop_url (const std::string &path_or_url); + /** + * @brief Enables or disables implicit macros + * If implicit macros are enabled, the macro tree contains the macros defined within the technologies + * and other implicit sources. + * This flag needs to be set initially and before the technology tree is updated. + */ + void enable_implicit_macros (bool enable); + /** * @brief Shows the macro editor * @@ -159,16 +167,24 @@ public slots: */ void update_menu_with_macros (); + /** + * @brief Called when the technologies got changed + */ + void technologies_edited (); + private: lay::MacroEditorDialog *mp_macro_editor; lay::MainWindow *mp_mw; + bool m_no_implicit_macros; tl::DeferredMethod dm_do_update_menu_with_macros; std::vector m_macro_actions; std::map m_action_to_macro; lay::MacroCollection m_temp_macros; std::vector< std::pair > > > m_paths; std::vector< std::pair > m_macro_categories; + std::set > m_tech_macro_paths; + void sync_implicit_macros (bool check_autorun); void add_macro_items_to_menu (lay::MacroCollection &collection, int &n, std::set &groups, const lay::Technology *tech, std::vector > *key_bindings); void do_update_menu_with_macros (); }; diff --git a/src/lay/layMacroEditorDialog.cc b/src/lay/layMacroEditorDialog.cc index d1c67e288..58edc972f 100644 --- a/src/lay/layMacroEditorDialog.cc +++ b/src/lay/layMacroEditorDialog.cc @@ -263,6 +263,7 @@ MacroEditorDialog::MacroEditorDialog (QWidget * /*parent*/, lay::MacroCollection connect (mp_root, SIGNAL (macro_changed (Macro *)), this, SLOT (macro_changed (Macro *))); connect (mp_root, SIGNAL (macro_deleted (Macro *)), this, SLOT (macro_deleted (Macro *))); + connect (mp_root, SIGNAL (macro_collection_deleted (MacroCollection *)), this, SLOT (macro_collection_deleted (MacroCollection *))); m_categories = lay::MacroController::instance ()->macro_categories (); @@ -1534,6 +1535,35 @@ MacroEditorDialog::commit () } } +void +MacroEditorDialog::macro_collection_deleted (lay::MacroCollection *collection) +{ + // close the tab pages related to the collection we want to delete + std::set used_macros; + std::set used_collections; + collection->collect_used_nodes (used_macros, used_collections); + + for (std::set ::iterator mc = used_macros.begin (); mc != used_macros.end (); ++mc) { + + if (mp_run_macro == *mc) { + mp_run_macro = 0; + } + + std::map ::iterator p = m_tab_widgets.find (*mc); + if (p != m_tab_widgets.end ()) { + p->second->connect_macro (0); + tabWidget->blockSignals (true); // blockSignals prevents a reentrant call into set_current of the tree + tabWidget->removeTab (tabWidget->indexOf (p->second)); + tabWidget->blockSignals (false); + delete p->second; + m_tab_widgets.erase (p); + } + + } + + refresh_file_watcher (); +} + void MacroEditorDialog::macro_deleted (lay::Macro *macro) { @@ -2594,30 +2624,13 @@ BEGIN_PROTECTED throw tl::Exception (tl::to_string (QObject::tr ("Unable to remove that location"))); } - // close the tab pages related to the collection we want to delete - std::set used_macros; - std::set used_collections; - collection->collect_used_nodes (used_macros, used_collections); - - for (std::set ::iterator mc = used_macros.begin (); mc != used_macros.end (); ++mc) { - - std::map ::iterator p = m_tab_widgets.find (*mc); - if (p != m_tab_widgets.end ()) { - p->second->connect_macro (0); - delete p->second; - m_tab_widgets.erase (p); - } - - } - - // actually remove the collection + // actually remove the collection (update is done through the + // macro_collection_deleted signal handler). mp_root->erase (collection); // save the new paths set_custom_paths (paths); - refresh_file_watcher (); - END_PROTECTED } diff --git a/src/lay/layMacroEditorDialog.h b/src/lay/layMacroEditorDialog.h index 476baa492..2fc328e10 100644 --- a/src/lay/layMacroEditorDialog.h +++ b/src/lay/layMacroEditorDialog.h @@ -192,6 +192,7 @@ private slots: void help_requested (const QString &s); void macro_changed (Macro *macro); void macro_deleted (Macro *macro); + void macro_collection_deleted (MacroCollection *collection); void add_watch (); void edit_watch (); void del_watches (); diff --git a/src/lay/layTechSetupDialog.cc b/src/lay/layTechSetupDialog.cc index 3f94132bf..c143043ef 100644 --- a/src/lay/layTechSetupDialog.cc +++ b/src/lay/layTechSetupDialog.cc @@ -542,7 +542,7 @@ TechSetupDialog::refresh_clicked () { BEGIN_PROTECTED - lay::TechnologyController::instance ()->refresh (m_technologies); + lay::TechnologyController::instance ()->rescan (m_technologies); update (); END_PROTECTED diff --git a/src/lay/layTechnologyController.cc b/src/lay/layTechnologyController.cc index 6f0b26c4f..d10aa2340 100644 --- a/src/lay/layTechnologyController.cc +++ b/src/lay/layTechnologyController.cc @@ -24,7 +24,6 @@ #include "layTechnologyController.h" #include "layTechSetupDialog.h" #include "layMainWindow.h" -#include "layMacroController.h" #include "layApplication.h" #include "layConfig.h" #include "laybasicConfig.h" @@ -47,18 +46,12 @@ std::string tech_string_from_name (const std::string &tn) } TechnologyController::TechnologyController () - : PluginDeclaration (), mp_editor (0), mp_mw (0), m_no_macros (false), mp_active_technology (0) + : PluginDeclaration (), mp_editor (0), mp_mw (0), mp_active_technology (0) { m_current_technology_updated = false; m_technologies_configured = false; } -void -TechnologyController::enable_macros (bool enable) -{ - m_no_macros = !enable; -} - TechnologyController * TechnologyController::instance () { @@ -80,8 +73,6 @@ TechnologyController::initialize (lay::PluginRoot * /*root*/) void TechnologyController::initialized (lay::PluginRoot *root) { - sync_tech_macro_locations (); - mp_mw = dynamic_cast (root); if (mp_mw) { mp_editor = new lay::TechSetupDialog (mp_mw); @@ -223,16 +214,13 @@ TechnologyController::configure (const std::string &name, const std::string &val if (! value.empty ()) { - // sync the non-persisted technologies with the configuration - lay::Technologies::instance ()->begin_updates (); try { - lay::Technologies::instance ()->load_from_xml (value); + lay::Technologies new_tech = *lay::Technologies::instance (); + new_tech.load_from_xml (value); + replace_technologies (new_tech); + m_technologies_configured = true; } catch (...) { } - lay::Technologies::instance ()->end_updates_no_event (); - - // explicitly handle changes -> no recursion - m_technologies_configured = true; } @@ -351,6 +339,24 @@ TechnologyController::update_menu () update_active_technology (); } +void +TechnologyController::replace_technologies (const lay::Technologies &technologies) +{ + bool has_active_tech = (mp_active_technology != 0); + std::string active_tech_name; + if (mp_active_technology) { + active_tech_name = mp_active_technology->name (); + } + + lay::Technologies ().instance ()->begin_updates (); + *lay::Technologies ().instance () = technologies; + lay::Technologies ().instance ()->end_updates_no_event (); + + if (has_active_tech) { + mp_active_technology = lay::Technologies::instance ()->technology_by_name (active_tech_name); + } +} + void TechnologyController::show_editor () { @@ -374,9 +380,7 @@ TechnologyController::show_editor () } } - lay::Technologies ().instance ()->begin_updates (); - *lay::Technologies ().instance () = new_tech; - lay::Technologies ().instance ()->end_updates_no_event (); + replace_technologies (new_tech); // save the technologies that need to be saved // TODO: save only the ones that really need saving @@ -424,19 +428,6 @@ TechnologyController::show_editor () QMessageBox::Ok); } - std::vector nm = sync_tech_macro_locations (); - - bool has_autorun = false; - for (std::vector::const_iterator m = nm.begin (); m != nm.end () && ! has_autorun; ++m) { - has_autorun = (*m)->has_autorun (); - } - - if (has_autorun && QMessageBox::question (mp_mw, QObject::tr ("Run Macros"), QObject::tr ("Some macros associated with technologies now 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 = nm.begin (); m != nm.end (); ++m) { - (*m)->autorun (); - } - } - update_menu (); emit technologies_edited (); @@ -451,25 +442,13 @@ TechnologyController::default_root () } void -TechnologyController::refresh () +TechnologyController::load () { - try { - - lay::Technologies::instance ()->begin_updates (); - refresh (*lay::Technologies::instance ()); - lay::Technologies::instance ()->end_updates_no_event (); - - update_menu (); - emit technologies_edited (); - - } catch (...) { - lay::Technologies::instance ()->end_updates_no_event (); - throw; - } + rescan (*lay::Technologies::instance ()); } void -TechnologyController::refresh (lay::Technologies &technologies) +TechnologyController::rescan (lay::Technologies &technologies) { lay::Technologies current = technologies; @@ -545,119 +524,6 @@ TechnologyController::add_path (const std::string &p) m_paths.push_back (p); } -std::vector -TechnologyController::sync_tech_macro_locations () -{ - lay::MacroController *mc = lay::MacroController::instance (); - - if (! mc || m_no_macros) { - return std::vector (); - } - - std::set > tech_macro_paths; - std::map, std::string> tech_names_by_path; - - // Add additional places where the technologies define some macros - for (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::Technologies::instance ()->end (); ++t) { - - if (t->base_path ().empty ()) { - continue; - } - - for (size_t c = 0; c < mc->macro_categories ().size (); ++c) { - - QDir base_dir (tl::to_qstring (t->base_path ())); - if (base_dir.exists ()) { - - QDir macro_dir (base_dir.filePath (tl::to_qstring (mc->macro_categories () [c].first))); - if (macro_dir.exists ()) { - - std::string mp = tl::to_string (macro_dir.path ()); - std::pair cp (mc->macro_categories () [c].first, mp); - tech_macro_paths.insert (cp); - std::string &tn = tech_names_by_path [cp]; - if (! tn.empty ()) { - tn += ","; - } - tn += t->name (); - - } - - } - - } - - } - - // delete macro collections which are no longer required or update description - std::vector folders_to_delete; - std::string desc_prefix = tl::to_string (QObject::tr ("Technology")) + " - "; - - lay::MacroCollection *root = &lay::MacroCollection::root (); - - for (lay::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) { - - std::pair cp (m->second->category (), m->second->path ()); - if (m->second->virtual_mode () == lay::MacroCollection::TechFolder && m_tech_macro_paths.find (cp) != m_tech_macro_paths.end ()) { - - if (tech_macro_paths.find (cp) == tech_macro_paths.end ()) { - // no longer used - folders_to_delete.push_back (m->second); - } else { - // used: update description if required - std::string desc = desc_prefix + tech_names_by_path [cp]; - m->second->set_description (desc); - } - - } - - } - - 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); - } - - // store new paths - m_tech_macro_paths = tech_macro_paths; - - // add new folders - for (lay::MacroCollection::child_iterator m = root->begin_children (); m != root->end_children (); ++m) { - if (m->second->virtual_mode () == lay::MacroCollection::TechFolder) { - std::pair cp (m->second->category (), m->second->path ()); - tech_macro_paths.erase (cp); - } - } - - std::vector new_folders; - - for (std::set >::const_iterator p = tech_macro_paths.begin (); p != tech_macro_paths.end (); ++p) { - - const std::string &tn = tech_names_by_path [*p]; - - // TODO: is it wise to make it writeable? - if (tl::verbosity () >= 20) { - tl::info << "Adding macro folder " << p->second << ", category '" << p->first << "' for technologies " << tn; - } - - // 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. - lay::MacroCollection *mc = lay::MacroCollection::root ().add_folder (desc_prefix + tn, p->second, p->first, false); - if (mc) { - - mc->set_virtual_mode (lay::MacroCollection::TechFolder); - new_folders.push_back (mc); - - } - - } - - return new_folders; -} - static tl::RegisteredClass config_decl (new TechnologyController (), 110, "TechnologyController"); } diff --git a/src/lay/layTechnologyController.h b/src/lay/layTechnologyController.h index ea5d7f00f..69fd5da90 100644 --- a/src/lay/layTechnologyController.h +++ b/src/lay/layTechnologyController.h @@ -70,16 +70,9 @@ public: */ lay::Technology *active_technology () const; - /** - * @brief Enables or disables macros - * If macros are enabled, the macro tree contains the macros defined within the technologies. - * This flag needs to be set initially and before the technology tree is updated. - */ - void enable_macros (bool enable); - /** * @brief Adds a path as a search path for technologies - * "refresh" needs to be called after search paths have been added. + * "load" needs to be called after search paths have been added. */ void add_path (const std::string &path); @@ -87,19 +80,19 @@ public: * @brief Adds a temporary technology * Temporary technologies are additional technologies which are added to the list of technologies * but are not persisted or editable. - * "refresh" needs to be called after temp technologies have been added. + * "load" needs to be called after temp technologies have been added. */ void add_temp_tech (const lay::Technology &t); /** - * @brief Updates the given technology collection with the technologies from the search path and teh temp technologies + * @brief Updates the given technology collection with the technologies from the search path and the temp technologies */ - void refresh (lay::Technologies &technologies); + void rescan (lay::Technologies &technologies); /** - * @brief Refreshes the global list of technologies + * @brief Loads the global list of technologies */ - void refresh (); + void load (); /** * @brief Gets the default root folder @@ -133,10 +126,8 @@ private: bool m_technologies_configured; lay::TechSetupDialog *mp_editor; lay::MainWindow *mp_mw; - bool m_no_macros; std::vector m_paths; std::vector m_temp_tech; - std::set > m_tech_macro_paths; lay::Technology *mp_active_technology; void update_active_technology (); @@ -148,7 +139,7 @@ private: bool menu_activated (const std::string &symbol) const; void update_current_technology (); void update_menu (); - std::vector sync_tech_macro_locations (); + void replace_technologies (const lay::Technologies &technologies); }; }