diff --git a/src/lay/lay/MacroPropertiesDialog.ui b/src/lay/lay/MacroPropertiesDialog.ui index d7a2c29e8..1a281dac4 100644 --- a/src/lay/lay/MacroPropertiesDialog.ui +++ b/src/lay/lay/MacroPropertiesDialog.ui @@ -100,7 +100,6 @@ - 75 true @@ -224,25 +223,56 @@ 6 + + + Priority + + + + Prolog - - - - - - - + Epilog + + + + + 0 + 0 + + + + + + + + for autorun: 0 = first, 1 = second ... + + + + + + + + 1 + 0 + + + + + + + diff --git a/src/lay/lay/layMacroPropertiesDialog.cc b/src/lay/lay/layMacroPropertiesDialog.cc index 58fcf16f5..2c04a77c8 100644 --- a/src/lay/lay/layMacroPropertiesDialog.cc +++ b/src/lay/lay/layMacroPropertiesDialog.cc @@ -75,6 +75,7 @@ MacroPropertiesDialog::update (const lym::Macro *macro) propertiesFrame->setEnabled (! macro->is_readonly ()); description->setText (tl::to_qstring (macro->description ())); version->setText (tl::to_qstring (macro->version ())); + priority->setText (tl::to_qstring (tl::to_string (macro->priority ()))); prolog->setText (tl::to_qstring (macro->prolog ())); epilog->setText (tl::to_qstring (macro->epilog ())); autorun->setChecked (macro->is_autorun ()); @@ -98,6 +99,10 @@ MacroPropertiesDialog::commit (lym::Macro *macro) macro->set_show_in_menu (showmenu->isChecked ()); macro->set_group_name (tl::to_string (groupName->text ())); macro->set_menu_path (tl::to_string (menuPath->text ())); + + int p = 0; + tl::from_string (tl::to_string (priority->text ()), p); + macro->set_priority (p); } } diff --git a/src/lym/lym/lymMacro.cc b/src/lym/lym/lymMacro.cc index f7e34fe36..429a4fbf2 100644 --- a/src/lym/lym/lymMacro.cc +++ b/src/lym/lym/lymMacro.cc @@ -55,7 +55,7 @@ namespace lym // ---------------------------------------------------------------------- Macro::Macro () - : m_modified (true), m_readonly (false), m_autorun (false), m_autorun_default (false), m_autorun_early (false), m_show_in_menu (false), m_is_file (false), mp_parent (0), m_interpreter (None), m_format (Macro::NoFormat) + : m_modified (true), m_readonly (false), m_autorun (false), m_autorun_default (false), m_autorun_early (false), m_priority (0), m_show_in_menu (false), m_is_file (false), mp_parent (0), m_interpreter (None), m_format (Macro::NoFormat) { // .. nothing yet .. } @@ -89,6 +89,7 @@ void Macro::assign (const lym::Macro &other) m_autorun = other.m_autorun; m_autorun_default = other.m_autorun_default; m_autorun_early = other.m_autorun_early; + m_priority = other.m_priority; m_show_in_menu = other.m_show_in_menu; m_shortcut = other.m_shortcut; m_format = other.m_format; @@ -113,6 +114,7 @@ bool Macro::operator== (const Macro &other) const m_text == other.m_text && m_autorun == other.m_autorun && m_autorun_early == other.m_autorun_early && + m_priority == other.m_priority && m_show_in_menu == other.m_show_in_menu && m_shortcut == other.m_shortcut && m_interpreter == other.m_interpreter && @@ -184,6 +186,7 @@ static tl::XMLStruct xml_struct ("klayout-macro", tl::make_member (&Macro::doc, &Macro::set_doc, "doc") + tl::make_member (&Macro::is_autorun, &Macro::set_autorun, "autorun") + tl::make_member (&Macro::is_autorun_early, &Macro::set_autorun_early, "autorun-early") + + tl::make_member (&Macro::priority, &Macro::set_priority, "priority") + tl::make_member (&Macro::shortcut, &Macro::set_shortcut, "shortcut") + tl::make_member (&Macro::show_in_menu, &Macro::set_show_in_menu, "show-in-menu") + tl::make_member (&Macro::group_name, &Macro::set_group_name, "group-name") + @@ -552,19 +555,22 @@ struct PropertyField void (lym::Macro::*string_setter) (const std::string &); bool (lym::Macro::*bool_getter) () const; void (lym::Macro::*bool_setter) (bool); + int (lym::Macro::*int_getter) () const; + void (lym::Macro::*int_setter) (int); }; static PropertyField property_fields[] = { - { "description", &lym::Macro::description, &lym::Macro::set_description, 0, 0 }, - { "prolog", &lym::Macro::prolog, &lym::Macro::set_prolog, 0, 0 }, - { "epilog", &lym::Macro::epilog, &lym::Macro::set_epilog, 0, 0 }, - { "version", &lym::Macro::version, &lym::Macro::set_version, 0, 0 }, - { "autorun", 0, 0, &lym::Macro::is_autorun, &lym::Macro::set_autorun }, - { "autorun-early", 0, 0, &lym::Macro::is_autorun_early, &lym::Macro::set_autorun_early}, - { "show-in-menu", 0, 0, &lym::Macro::show_in_menu, &lym::Macro::set_show_in_menu }, - { "group-name", &lym::Macro::group_name, &lym::Macro::set_group_name, 0, 0 }, - { "menu-path", &lym::Macro::menu_path, &lym::Macro::set_menu_path, 0, 0 }, - { "shortcut", &lym::Macro::shortcut, &lym::Macro::set_shortcut, 0, 0 } + { "description", &lym::Macro::description, &lym::Macro::set_description, 0, 0, 0, 0 }, + { "prolog", &lym::Macro::prolog, &lym::Macro::set_prolog, 0, 0, 0, 0 }, + { "epilog", &lym::Macro::epilog, &lym::Macro::set_epilog, 0, 0, 0, 0 }, + { "version", &lym::Macro::version, &lym::Macro::set_version, 0, 0, 0, 0 }, + { "autorun", 0, 0, &lym::Macro::is_autorun, &lym::Macro::set_autorun, 0, 0 }, + { "autorun-early", 0, 0, &lym::Macro::is_autorun_early, &lym::Macro::set_autorun_early, 0, 0 }, + { "show-in-menu", 0, 0, &lym::Macro::show_in_menu, &lym::Macro::set_show_in_menu, 0, 0 }, + { "group-name", &lym::Macro::group_name, &lym::Macro::set_group_name, 0, 0, 0, 0 }, + { "menu-path", &lym::Macro::menu_path, &lym::Macro::set_menu_path, 0, 0, 0, 0 }, + { "shortcut", &lym::Macro::shortcut, &lym::Macro::set_shortcut, 0, 0, 0, 0 }, + { "priority", 0, 0, 0, 0, &lym::Macro::priority, &lym::Macro::set_priority } }; static std::string escape_pta_string (const char *cp) @@ -625,6 +631,11 @@ void Macro::sync_text_with_properties () if (v) { new_lines.push_back (std::string ("# $") + pf->name); } + } else if (pf->int_getter) { + int v = (this->*(pf->int_getter)) (); + if (v) { + new_lines.push_back (std::string ("# $") + pf->name + ": " + tl::to_string (v)); + } } } @@ -672,6 +683,8 @@ void Macro::sync_properties_with_text () (this->*(pf->string_setter)) (std::string ()); } else if (pf->bool_setter) { (this->*(pf->bool_setter)) (false); + } else if (pf->int_setter) { + (this->*(pf->int_setter)) (0); } } @@ -696,6 +709,10 @@ void Macro::sync_properties_with_text () (this->*(pf->string_setter)) (unescape_pta_string (pex.skip ())); } else if (pf->bool_setter) { (this->*(pf->bool_setter)) (true); + } else if (pf->int_setter) { + int v = 0; + tl::from_string (pex.skip (), v); + (this->*(pf->int_setter)) (v); } break; @@ -767,6 +784,15 @@ void Macro::set_autorun (bool f) } } +void Macro::set_priority (int p) +{ + if (p != m_priority) { + m_modified = true; + m_priority = p; + on_changed (); + } +} + void Macro::set_show_in_menu (bool f) { if (f != m_show_in_menu) { @@ -1875,15 +1901,38 @@ bool MacroCollection::has_autorun_early () const return has_autorun_for (*this, true); } -static void autorun_for (lym::MacroCollection &collection, bool early, std::set *executed_already) +static int collect_priority (lym::MacroCollection &collection, bool early, int from_prio) +{ + int p = -1; + + for (lym::MacroCollection::child_iterator c = collection.begin_children (); c != collection.end_children (); ++c) { + int pp = collect_priority (*c->second, early, from_prio); + if (pp >= from_prio && (p < 0 || pp < p)) { + p = pp; + } + } + + for (lym::MacroCollection::iterator c = collection.begin (); c != collection.end (); ++c) { + if (c->second->can_run () && ((early && c->second->is_autorun_early ()) || (!early && c->second->is_autorun () && !c->second->is_autorun_early ()))) { + int pp = c->second->priority (); + if (pp >= from_prio && (p < 0 || pp < p)) { + p = pp; + } + } + } + + return p; +} + +static void autorun_for_prio (lym::MacroCollection &collection, bool early, std::set *executed_already, int prio) { for (lym::MacroCollection::child_iterator c = collection.begin_children (); c != collection.end_children (); ++c) { - autorun_for (*c->second, early, executed_already); + autorun_for_prio (*c->second, early, executed_already, prio); } for (lym::MacroCollection::iterator c = collection.begin (); c != collection.end (); ++c) { - if (c->second->can_run () && ((early && c->second->is_autorun_early ()) || (!early && c->second->is_autorun () && !c->second->is_autorun_early ()))) { + if (c->second->priority () == prio && c->second->can_run () && ((early && c->second->is_autorun_early ()) || (!early && c->second->is_autorun () && !c->second->is_autorun_early ()))) { if (!executed_already || executed_already->find (c->second->path ()) == executed_already->end ()) { @@ -1903,6 +1952,19 @@ static void autorun_for (lym::MacroCollection &collection, bool early, std::set< } } +static void autorun_for (lym::MacroCollection &collection, bool early, std::set *executed_already) +{ + int prio = 0; + while (true) { + int p = collect_priority (collection, early, prio); + if (p < prio) { + break; + } + autorun_for_prio (collection, early, executed_already, p); + prio = p + 1; + } +} + void MacroCollection::autorun (std::set *already_executed) { autorun_for (*this, false, already_executed); diff --git a/src/lym/lym/lymMacro.h b/src/lym/lym/lymMacro.h index 063901ca4..619be68a6 100644 --- a/src/lym/lym/lymMacro.h +++ b/src/lym/lym/lymMacro.h @@ -430,6 +430,20 @@ public: */ void set_autorun_early (bool f); + /** + * @brief Gets the priority of the macro in autorun and autorun-early mode + * 0 is the first priority, -1 means "never execute". + */ + int priority () const + { + return m_priority; + } + + /** + * @brief Sets the priority + */ + void set_priority (int p); + /** * @brief Gets a value indicating whether the macro shall be shown in the menu */ @@ -596,6 +610,7 @@ private: bool m_autorun; bool m_autorun_default; bool m_autorun_early; + int m_priority; bool m_show_in_menu; std::string m_group_name; std::string m_menu_path;