diff --git a/src/edt/edt/edtPlugin.cc b/src/edt/edt/edtPlugin.cc index 5493273b5..ec50d70c6 100644 --- a/src/edt/edt/edtPlugin.cc +++ b/src/edt/edt/edtPlugin.cc @@ -88,7 +88,10 @@ void get_inst_options (std::vector < std::pair > &opti edt::RecentConfigurationPage::ConfigurationDescriptor inst_cfg_descriptors[] = { - edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_cell_name, tl::to_string (tr ("Cell name")), edt::RecentConfigurationPage::Text), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_lib_name, tl::to_string (tr ("Library")), edt::RecentConfigurationPage::Text), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_cell_name, tl::to_string (tr ("Cell")), edt::RecentConfigurationPage::Text), + // encode this into the cell? + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_pcell_parameters, tl::to_string (tr ("PCell parameters")), edt::RecentConfigurationPage::PCellParamters), edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_angle, tl::to_string (tr ("Angle")), edt::RecentConfigurationPage::Double), edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_mirror, tl::to_string (tr ("Mirror")), edt::RecentConfigurationPage::Bool), edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_scale, tl::to_string (tr ("Scale")), edt::RecentConfigurationPage::Double), @@ -104,7 +107,7 @@ edt::RecentConfigurationPage::ConfigurationDescriptor inst_cfg_descriptors[] = static void get_inst_editor_options_pages (std::vector &ret, lay::Dispatcher *dispatcher) { - ret.push_back (new RecentConfigurationPage (dispatcher, 22, tl::to_string (tr ("Recent")), + ret.push_back (new RecentConfigurationPage (dispatcher, "edit-recent-inst-param", &inst_cfg_descriptors[0], &inst_cfg_descriptors[sizeof (inst_cfg_descriptors) / sizeof (inst_cfg_descriptors[0])])); ret.push_back (new EditorOptionsInstPCellParam (dispatcher)); ret.push_back (new EditorOptionsInst (dispatcher)); diff --git a/src/edt/edt/edtRecentConfigurationPage.cc b/src/edt/edt/edtRecentConfigurationPage.cc index 52d06d484..0d86a5ce5 100644 --- a/src/edt/edt/edtRecentConfigurationPage.cc +++ b/src/edt/edt/edtRecentConfigurationPage.cc @@ -29,6 +29,8 @@ namespace edt { +static const size_t max_entries = 100; + void RecentConfigurationPage::init () { @@ -36,6 +38,8 @@ RecentConfigurationPage::init () ly->setMargin (0); mp_tree_widget = new QTreeWidget (this); + mp_tree_widget->setRootIsDecorated (false); + mp_tree_widget->setUniformRowHeights (true); ly->addWidget (mp_tree_widget); mp_tree_widget->setColumnCount (int (m_cfg.size ())); @@ -46,7 +50,7 @@ RecentConfigurationPage::init () } mp_tree_widget->setHeaderLabels (column_labels); - update_list (); + update_list (get_stored_values ()); } RecentConfigurationPage::~RecentConfigurationPage () @@ -54,9 +58,59 @@ RecentConfigurationPage::~RecentConfigurationPage () // .. nothing yet .. } +std::string RecentConfigurationPage::title () const +{ + return tl::to_string (tr ("Recent")); +} + +int RecentConfigurationPage::order () const +{ + return 100; +} + +std::list > +RecentConfigurationPage::get_stored_values () const +{ + std::string serialized_list = dispatcher ()->config_get (m_recent_cfg_name); + + std::list > values; + tl::Extractor ex (serialized_list.c_str ()); + while (! ex.at_end ()) { + + values.push_back (std::vector ()); + while (! ex.at_end () && ! ex.test (";")) { + values.back ().push_back (std::string ()); + ex.read_word_or_quoted (values.back ().back ()); + ex.test (","); + } + + } + + return values; +} + +void +RecentConfigurationPage::set_stored_values (const std::list > &values) const +{ + std::string serialized_list; + for (std::list >::const_iterator v = values.begin (); v != values.end (); ++v) { + if (v != values.begin ()) { + serialized_list += ";"; + } + for (std::vector::const_iterator s = v->begin (); s != v->end (); ++s) { + serialized_list += tl::to_word_or_quoted_string (*s); + serialized_list += ","; + } + } + + dispatcher ()->config_set (m_recent_cfg_name, serialized_list); +} + void render_to (QTreeWidgetItem *item, int column, const std::string &v, RecentConfigurationPage::ConfigurationRendering rendering) { + // store original value + item->setData (column, Qt::UserRole, tl::to_qstring (v)); // @@@ rendering item->setText (column, tl::to_qstring (v)); @@ -64,10 +118,10 @@ render_to (QTreeWidgetItem *item, int column, const std::string &v, RecentConfig } void -RecentConfigurationPage::update_list () +RecentConfigurationPage::update_list (const std::list > &stored_values) { int row = 0; - for (std::list >::const_iterator v = m_stored_values.begin (); v != m_stored_values.end (); ++v, ++row) { + for (std::list >::const_iterator v = stored_values.begin (); v != stored_values.end (); ++v, ++row) { QTreeWidgetItem *item = 0; if (row < mp_tree_widget->topLevelItemCount ()) { @@ -102,16 +156,24 @@ RecentConfigurationPage::commit_recent (lay::Dispatcher *root) values.push_back (root->config_get (c->cfg_name)); } - for (std::list >::iterator v = m_stored_values.begin (); v != m_stored_values.end (); ++v) { + std::list > stored_values = get_stored_values (); + + for (std::list >::iterator v = stored_values.begin (); v != stored_values.end (); ++v) { if (*v == values) { - m_stored_values.erase (v); + stored_values.erase (v); break; } } - m_stored_values.push_front (values); + stored_values.push_front (values); - update_list (); + while (stored_values.size () > max_entries) { + stored_values.erase (--stored_values.end ()); + } + + set_stored_values (stored_values); + + update_list (stored_values); } } diff --git a/src/edt/edt/edtRecentConfigurationPage.h b/src/edt/edt/edtRecentConfigurationPage.h index 3cb290401..37bd35fcb 100644 --- a/src/edt/edt/edtRecentConfigurationPage.h +++ b/src/edt/edt/edtRecentConfigurationPage.h @@ -66,29 +66,29 @@ public: }; template - RecentConfigurationPage (lay::Dispatcher *dispatcher, int order, const std::string &title, Iter begin_cfg, Iter end_cfg) - : EditorOptionsPage (dispatcher), m_title (title), m_order (order), m_cfg (begin_cfg, end_cfg) + RecentConfigurationPage (lay::Dispatcher *dispatcher, const std::string &recent_cfg_name, Iter begin_cfg, Iter end_cfg) + : EditorOptionsPage (dispatcher), m_recent_cfg_name (recent_cfg_name), m_cfg (begin_cfg, end_cfg) { init (); } virtual ~RecentConfigurationPage (); - virtual std::string title () const { return m_title; } - virtual int order () const { return m_order; } + virtual std::string title () const; + virtual int order () const; virtual void apply (lay::Dispatcher * /*root*/) { } virtual void setup (lay::Dispatcher * /*root*/) { } virtual void commit_recent (lay::Dispatcher *root); private: - std::string m_title; - int m_order; + std::string m_recent_cfg_name; std::list m_cfg; QTreeWidget *mp_tree_widget; - std::list > m_stored_values; void init (); - void update_list (); + void update_list (const std::list > &stored_values); + std::list > get_stored_values () const; + void set_stored_values (const std::list > &values) const; }; } diff --git a/src/edt/edt/edtService.cc b/src/edt/edt/edtService.cc index f479b1c56..c035d6698 100644 --- a/src/edt/edt/edtService.cc +++ b/src/edt/edt/edtService.cc @@ -60,45 +60,6 @@ ac_from_buttons (unsigned int buttons) // ------------------------------------------------------------- -std::string pcell_parameters_to_string (const std::map ¶meters) -{ - std::string param; - - param = "!"; // flags PCells - for (std::map::const_iterator p = parameters.begin (); p != parameters.end (); ++p) { - param += tl::to_word_or_quoted_string (p->first); - param += ":"; - param += p->second.to_parsable_string (); - param += ";"; - } - - return param; -} - -std::map pcell_parameters_from_string (const std::string &s) -{ - tl::Extractor ex (s.c_str ()); - std::map pm; - - ex.test ("!"); - - try { - while (! ex.at_end ()) { - std::string n; - ex.read_word_or_quoted (n); - ex.test (":"); - ex.read (pm.insert (std::make_pair (n, tl::Variant ())).first->second); - ex.test (";"); - } - } catch (...) { - // ignore errors - } - - return pm; -} - -// ------------------------------------------------------------- - Service::Service (db::Manager *manager, lay::LayoutView *view, db::ShapeIterator::flags_type flags) : lay::ViewService (view->view_object_widget ()), lay::Editable (view), diff --git a/src/edt/edt/edtServiceImpl.cc b/src/edt/edt/edtServiceImpl.cc index 8f65a7e7a..637617ef4 100644 --- a/src/edt/edt/edtServiceImpl.cc +++ b/src/edt/edt/edtServiceImpl.cc @@ -1417,6 +1417,14 @@ InstService::do_mouse_transform (const db::DPoint &p, db::DFTrans trans) m_column_x = c.x (); m_column_y = c.y (); + dispatcher ()->config_set (cfg_edit_inst_angle, m_angle); + dispatcher ()->config_set (cfg_edit_inst_mirror, m_mirror); + dispatcher ()->config_set (cfg_edit_inst_row_x, m_row_x); + dispatcher ()->config_set (cfg_edit_inst_row_y, m_row_y); + dispatcher ()->config_set (cfg_edit_inst_column_x, m_column_x); + dispatcher ()->config_set (cfg_edit_inst_column_y, m_column_y); + dispatcher ()->config_end (); + // honour the new transformation do_mouse_move (p); } @@ -1535,78 +1543,171 @@ InstService::configure (const std::string &name, const std::string &value) if (name == cfg_edit_inst_pcell_parameters) { - m_pcell_parameters = pcell_parameters_from_string (value); - m_is_pcell = ! value.empty (); + std::map pcp = pcell_parameters_from_string (value); + if (pcp != m_pcell_parameters) { + + m_pcell_parameters = pcp; + m_is_pcell = ! value.empty (); + + m_needs_update = true; + + } - m_needs_update = true; return true; // taken } if (name == cfg_edit_inst_place_origin) { - tl::from_string (value, m_place_origin); - m_needs_update = true; + + bool f; + tl::from_string (value, f); + + if (f != m_place_origin) { + m_place_origin = f; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_scale) { - tl::from_string (value, m_scale); - m_needs_update = true; + + double s; + tl::from_string (value, s); + + if (fabs (s - m_scale) > 1e-10) { + m_scale = s; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_angle) { - tl::from_string (value, m_angle); - m_needs_update = true; + + double a; + tl::from_string (value, a); + + if (fabs (a - m_angle) > 1e-10) { + m_angle = a; + m_needs_update = true; + } + return true; // taken } if (name == cfg_edit_inst_mirror) { - tl::from_string (value, m_mirror); - m_needs_update = true; + + bool f; + tl::from_string (value, f); + + if (f != m_mirror) { + m_mirror = f; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_array) { - tl::from_string (value, m_array); - m_needs_update = true; + + bool f; + tl::from_string (value, f); + + if (f != m_array) { + m_array = f; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_rows) { - tl::from_string (value, m_rows); - m_needs_update = true; + + unsigned int v; + tl::from_string (value, v); + + if (v != m_rows) { + m_rows = v; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_row_x) { - tl::from_string (value, m_row_x); - m_needs_update = true; + + double v; + tl::from_string (value, v); + + if (! db::coord_traits::equal (m_row_x, v)) { + m_row_x = v; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_row_y) { - tl::from_string (value, m_row_y); - m_needs_update = true; + + double v; + tl::from_string (value, v); + + if (! db::coord_traits::equal (m_row_y, v)) { + m_row_y = v; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_columns) { - tl::from_string (value, m_columns); - m_needs_update = true; + + unsigned int v; + tl::from_string (value, v); + + if (v != m_columns) { + m_columns = v; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_column_x) { - tl::from_string (value, m_column_x); - m_needs_update = true; + + double v; + tl::from_string (value, v); + + if (! db::coord_traits::equal (m_column_x, v)) { + m_column_x = v; + m_needs_update = true; + } + return true; // taken + } if (name == cfg_edit_inst_column_y) { - tl::from_string (value, m_column_y); - m_needs_update = true; + + double v; + tl::from_string (value, v); + + if (! db::coord_traits::equal (m_column_y, v)) { + m_column_y = v; + m_needs_update = true; + } + return true; // taken + } return edt::Service::configure (name, value); diff --git a/src/edt/edt/edtUtils.cc b/src/edt/edt/edtUtils.cc index 7cc997bf7..a4833a0a1 100644 --- a/src/edt/edt/edtUtils.cc +++ b/src/edt/edt/edtUtils.cc @@ -35,6 +35,45 @@ namespace edt { +// ------------------------------------------------------------- + +std::string pcell_parameters_to_string (const std::map ¶meters) +{ + std::string param; + + param = "!"; // flags PCells + for (std::map::const_iterator p = parameters.begin (); p != parameters.end (); ++p) { + param += tl::to_word_or_quoted_string (p->first); + param += ":"; + param += p->second.to_parsable_string (); + param += ";"; + } + + return param; +} + +std::map pcell_parameters_from_string (const std::string &s) +{ + tl::Extractor ex (s.c_str ()); + std::map pm; + + ex.test ("!"); + + try { + while (! ex.at_end ()) { + std::string n; + ex.read_word_or_quoted (n); + ex.test (":"); + ex.read (pm.insert (std::make_pair (n, tl::Variant ())).first->second); + ex.test (";"); + } + } catch (...) { + // ignore errors + } + + return pm; +} + // ------------------------------------------------------------- // SelectionIterator implementation diff --git a/src/edt/edt/edtUtils.h b/src/edt/edt/edtUtils.h index a4a512e7a..460f9a12e 100644 --- a/src/edt/edt/edtUtils.h +++ b/src/edt/edt/edtUtils.h @@ -47,6 +47,16 @@ namespace edt { class Service; +/** + * @brief Serializes PCell parameters to a string + */ +std::string pcell_parameters_to_string (const std::map ¶meters); + +/** + * @brief Deerializes PCell parameters from a string + */ +std::map pcell_parameters_from_string (const std::string &s); + /** * @brief Fetch PCell parameters from a cell and merge the guiding shapes into them *