diff --git a/src/edt/edt/edtPlugin.cc b/src/edt/edt/edtPlugin.cc index ec50d70c6..926325850 100644 --- a/src/edt/edt/edtPlugin.cc +++ b/src/edt/edt/edtPlugin.cc @@ -88,20 +88,19 @@ void get_inst_options (std::vector < std::pair > &opti edt::RecentConfigurationPage::ConfigurationDescriptor inst_cfg_descriptors[] = { - 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_lib_name, tl::to_string (tr ("Library")), edt::RecentConfigurationPage::CellLibraryName), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_cell_name, tl::to_string (tr ("Cell")), edt::RecentConfigurationPage::CellDisplayName), 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), - edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_array, tl::to_string (tr ("Array")), edt::RecentConfigurationPage::Bool), - edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_rows, tl::to_string (tr ("Rows")), edt::RecentConfigurationPage::Double), - edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_row_x, tl::to_string (tr ("Row step (x)")), edt::RecentConfigurationPage::Double), - edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_row_y, tl::to_string (tr ("Row step (y)")), edt::RecentConfigurationPage::Double), - edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_columns, tl::to_string (tr ("Columns")), edt::RecentConfigurationPage::Double), - edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_column_x, tl::to_string (tr ("Column step (x)")), edt::RecentConfigurationPage::Double), - edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_column_y, tl::to_string (tr ("Column step (y)")), edt::RecentConfigurationPage::Double) + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_array, tl::to_string (tr ("Array")), edt::RecentConfigurationPage::ArrayFlag), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_rows, tl::to_string (tr ("Rows")), edt::RecentConfigurationPage::IntIfArray), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_row_x, tl::to_string (tr ("Row step (x)")), edt::RecentConfigurationPage::DoubleIfArray), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_row_y, tl::to_string (tr ("Row step (y)")), edt::RecentConfigurationPage::DoubleIfArray), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_columns, tl::to_string (tr ("Columns")), edt::RecentConfigurationPage::IntIfArray), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_column_x, tl::to_string (tr ("Column step (x)")), edt::RecentConfigurationPage::DoubleIfArray), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_column_y, tl::to_string (tr ("Column step (y)")), edt::RecentConfigurationPage::DoubleIfArray), + edt::RecentConfigurationPage::ConfigurationDescriptor (cfg_edit_inst_pcell_parameters, tl::to_string (tr ("PCell parameters")), edt::RecentConfigurationPage::PCellParameters) }; static diff --git a/src/edt/edt/edtRecentConfigurationPage.cc b/src/edt/edt/edtRecentConfigurationPage.cc index 0d86a5ce5..1d9bcec56 100644 --- a/src/edt/edt/edtRecentConfigurationPage.cc +++ b/src/edt/edt/edtRecentConfigurationPage.cc @@ -21,10 +21,14 @@ */ #include "edtRecentConfigurationPage.h" +#include "edtUtils.h" #include "layDispatcher.h" +#include "dbLibraryManager.h" +#include "dbLibrary.h" #include #include +#include namespace edt { @@ -37,11 +41,19 @@ RecentConfigurationPage::init () QVBoxLayout *ly = new QVBoxLayout (this); ly->setMargin (0); + QLabel *label = new QLabel (this); + label->setText (tr ("Click to select a recent configuration")); + ly->addWidget (label); + mp_tree_widget = new QTreeWidget (this); mp_tree_widget->setRootIsDecorated (false); mp_tree_widget->setUniformRowHeights (true); + mp_tree_widget->setSelectionMode (QAbstractItemView::NoSelection); + mp_tree_widget->setAllColumnsShowFocus (true); ly->addWidget (mp_tree_widget); + connect (mp_tree_widget, SIGNAL (itemClicked (QTreeWidgetItem *, int)), this, SLOT (item_clicked (QTreeWidgetItem *))); + mp_tree_widget->setColumnCount (int (m_cfg.size ())); QStringList column_labels; @@ -107,13 +119,112 @@ RecentConfigurationPage::set_stored_values (const std::list &values, RecentConfigurationPage::ConfigurationRendering rendering) { // store original value - item->setData (column, Qt::UserRole, tl::to_qstring (v)); + item->setData (column, Qt::UserRole, tl::to_qstring (values [column])); - // @@@ rendering - item->setText (column, tl::to_qstring (v)); + switch (rendering) { + + case RecentConfigurationPage::ArrayFlag: + case RecentConfigurationPage::Bool: + { + bool f = false; + tl::from_string (values [column], f); + static QString checkmark = QString::fromUtf8 ("\xe2\x9c\x93"); + item->setText (column, f ? checkmark : QString ()); // "checkmark" + } + break; + + case RecentConfigurationPage::Layer: + // @@@ + item->setText (column, tl::to_qstring (values [column])); + break; + + case RecentConfigurationPage::Int: + case RecentConfigurationPage::Double: + case RecentConfigurationPage::Text: + case RecentConfigurationPage::CellLibraryName: + item->setText (column, tl::to_qstring (values [column])); + break; + + case RecentConfigurationPage::IntIfArray: + case RecentConfigurationPage::DoubleIfArray: + { + bool is_array = false; + int flag_column = 0; + for (std::list::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++flag_column) { + if (c->rendering == RecentConfigurationPage::ArrayFlag) { + tl::from_string (values [flag_column], is_array); + break; + } + } + + if (is_array) { + item->setText (column, tl::to_qstring (values [column])); + } else { + item->setText (column, QString ()); + } + } + break; + + case RecentConfigurationPage::CellDisplayName: + { + // search for a libname + int libname_column = 0; + const db::Library *lib = 0; + for (std::list::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++libname_column) { + if (c->rendering == RecentConfigurationPage::CellLibraryName) { + lib = db::LibraryManager::instance ().lib_ptr_by_name (values [libname_column]); + break; + } + } + + if (lib) { + + // search for a PCell parameters + int pcp_column = 0; + std::map pcp; + for (std::list::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++pcp_column) { + if (c->rendering == RecentConfigurationPage::PCellParameters) { + pcp = pcell_parameters_from_string (values [pcp_column]); + break; + } + } + + std::pair pcid = lib->layout ().pcell_by_name (values [column].c_str ()); + if (pcid.first) { + const db::PCellDeclaration *pc_decl = lib->layout ().pcell_declaration (pcid.second); + if (pc_decl) { + item->setText (column, tl::to_qstring (pc_decl->get_display_name (pc_decl->map_parameters (pcp)))); + break; + } + } + + } + + item->setText (column, tl::to_qstring (values [column])); + } + break; + + case RecentConfigurationPage::PCellParameters: + { + std::map pcp; + pcp = pcell_parameters_from_string (values [column]); + std::string r; + for (std::map::const_iterator p = pcp.begin (); p != pcp.end (); ++p) { + if (p != pcp.begin ()) { + r += ","; + } + r += p->first; + r += "="; + r += p->second.to_string (); + } + + item->setText (column, tl::to_qstring (r)); + } + break; + } } @@ -134,7 +245,7 @@ RecentConfigurationPage::update_list (const std::list > int column = 0; for (std::list::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++column) { if (column < int (v->size ())) { - render_to (item, column, (*v) [column], c->rendering); + render_to (item, column, *v, c->rendering); } } @@ -147,6 +258,17 @@ RecentConfigurationPage::update_list (const std::list > mp_tree_widget->header ()->resizeSections (QHeaderView::ResizeToContents); } +void +RecentConfigurationPage::item_clicked (QTreeWidgetItem *item) +{ + int column = 0; + for (std::list::const_iterator c = m_cfg.begin (); c != m_cfg.end (); ++c, ++column) { + std::string v = tl::to_string (item->data (column, Qt::UserRole).toString ()); + dispatcher ()->config_set (c->cfg_name, v); + } + dispatcher ()->config_end (); +} + void RecentConfigurationPage::commit_recent (lay::Dispatcher *root) { diff --git a/src/edt/edt/edtRecentConfigurationPage.h b/src/edt/edt/edtRecentConfigurationPage.h index 37bd35fcb..766a7f77f 100644 --- a/src/edt/edt/edtRecentConfigurationPage.h +++ b/src/edt/edt/edtRecentConfigurationPage.h @@ -52,7 +52,12 @@ public: Double = 2, Int = 3, Layer = 4, - PCellParamters = 5 + PCellParameters = 5, + CellLibraryName = 6, + CellDisplayName = 7, + ArrayFlag = 8, + DoubleIfArray = 9, + IntIfArray = 10 }; struct ConfigurationDescriptor @@ -80,6 +85,9 @@ public: virtual void setup (lay::Dispatcher * /*root*/) { } virtual void commit_recent (lay::Dispatcher *root); +private slots: + void item_clicked (QTreeWidgetItem *item); + private: std::string m_recent_cfg_name; std::list m_cfg; @@ -89,6 +97,7 @@ private: void update_list (const std::list > &stored_values); std::list > get_stored_values () const; void set_stored_values (const std::list > &values) const; + void render_to (QTreeWidgetItem *item, int column, const std::vector &values, RecentConfigurationPage::ConfigurationRendering rendering); }; } diff --git a/src/edt/edt/edtServiceImpl.cc b/src/edt/edt/edtServiceImpl.cc index 637617ef4..b4a339f0c 100644 --- a/src/edt/edt/edtServiceImpl.cc +++ b/src/edt/edt/edtServiceImpl.cc @@ -1093,7 +1093,7 @@ InstService::InstService (db::Manager *manager, lay::LayoutView *view) m_array (false), m_rows (1), m_columns (1), m_row_x (0.0), m_row_y (0.0), m_column_x (0.0), m_column_y (0.0), m_place_origin (false), m_reference_transaction_id (0), - m_needs_update (true), m_has_valid_cell (false), m_in_drag_drop (false), + m_needs_update (true), m_parameters_changed (false), m_has_valid_cell (false), m_in_drag_drop (false), m_current_cell (0), mp_current_layout (0), mp_pcell_decl (0), m_cv_index (-1) { // .. nothing yet .. @@ -1137,6 +1137,8 @@ InstService::drag_enter_event (const db::DPoint &p, const lay::DragDropDataBase view ()->cancel (); set_edit_marker (0); + bool switch_parameters = true; + // configure from the drag/drop data if (cd->library ()) { @@ -1168,6 +1170,7 @@ InstService::drag_enter_event (const db::DPoint &p, const lay::DragDropDataBase if (! cd->pcell_params ().empty ()) { m_pcell_parameters = pcell_decl->named_parameters (cd->pcell_params ()); + switch_parameters = false; } } else if (cd->layout ()->is_valid_cell_index (cd->cell_index ())) { @@ -1178,7 +1181,7 @@ InstService::drag_enter_event (const db::DPoint &p, const lay::DragDropDataBase return false; } - switch_cell_or_pcell (); + switch_cell_or_pcell (switch_parameters); sync_to_config (); m_in_drag_drop = true; @@ -1550,6 +1553,7 @@ InstService::configure (const std::string &name, const std::string &value) m_is_pcell = ! value.empty (); m_needs_update = true; + m_parameters_changed = true; } @@ -1714,7 +1718,7 @@ InstService::configure (const std::string &name, const std::string &value) } void -InstService::switch_cell_or_pcell () +InstService::switch_cell_or_pcell (bool switch_parameters) { // if the library or cell name has changed, store the current pcell parameters and try to reuse // an existing parameter set @@ -1722,11 +1726,15 @@ InstService::switch_cell_or_pcell () m_stored_pcell_parameters[std::make_pair (m_cell_or_pcell_name_previous, m_lib_name_previous)] = m_pcell_parameters; - std::map, std::map >::const_iterator p = m_stored_pcell_parameters.find (std::make_pair (m_cell_or_pcell_name, m_lib_name)); - if (p != m_stored_pcell_parameters.end ()) { - m_pcell_parameters = p->second; - } else { - m_pcell_parameters.clear (); + if (switch_parameters) { + + std::map, std::map >::const_iterator p = m_stored_pcell_parameters.find (std::make_pair (m_cell_or_pcell_name, m_lib_name)); + if (p != m_stored_pcell_parameters.end ()) { + m_pcell_parameters = p->second; + } else { + m_pcell_parameters.clear (); + } + } } @@ -1759,22 +1767,32 @@ InstService::config_finalize () { if (m_needs_update) { - switch_cell_or_pcell (); + // don't switch parameters if they have been updated explicitly + // since the last "config_finalize". This means the sender of the configuration events + // wants the parameters to be set in a specific way. Don't interfere. + bool switch_parameters = ! m_parameters_changed; + + switch_cell_or_pcell (switch_parameters); m_has_valid_cell = false; update_marker (); - m_needs_update = false; - // Reflects any changes in PCell parameters induced by reuse of make_cell (called from update_marker) - // in the configuration - if (m_is_pcell) { - dispatcher ()->config_set (cfg_edit_inst_pcell_parameters, pcell_parameters_to_string (m_pcell_parameters)); - } else { - dispatcher ()->config_set (cfg_edit_inst_pcell_parameters, std::string ()); + if (switch_parameters) { + // Reflects any changes in PCell parameters in the configuration + // TODO: it's somewhat questionable to do this inside "config_finalize" as this method is supposed + // to reflect changes rather than induce some. + if (m_is_pcell) { + dispatcher ()->config_set (cfg_edit_inst_pcell_parameters, pcell_parameters_to_string (m_pcell_parameters)); + } else { + dispatcher ()->config_set (cfg_edit_inst_pcell_parameters, std::string ()); + } } } + m_needs_update = false; + m_parameters_changed = false; + edt::Service::config_finalize (); } diff --git a/src/edt/edt/edtServiceImpl.h b/src/edt/edt/edtServiceImpl.h index f9545694a..d892bae43 100644 --- a/src/edt/edt/edtServiceImpl.h +++ b/src/edt/edt/edtServiceImpl.h @@ -239,7 +239,7 @@ private: double m_row_x, m_row_y, m_column_x, m_column_y; bool m_place_origin; db::Manager::transaction_id_t m_reference_transaction_id; - bool m_needs_update; + bool m_needs_update, m_parameters_changed; bool m_has_valid_cell; bool m_in_drag_drop; db::cell_index_type m_current_cell; @@ -253,7 +253,7 @@ private: std::pair make_cell (const lay::CellView &cv); tl::Variant get_default_layer_for_pcell (); void sync_to_config (); - void switch_cell_or_pcell (); + void switch_cell_or_pcell (bool switch_parameters); }; } diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 0a7bacd70..36b9bb96c 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -2603,6 +2603,8 @@ MainWindow::select_view (int index) try { + cancel (); + tl_assert (index >= 0 && index < int (views ())); mp_tab_bar->setCurrentIndex (index);