diff --git a/src/edt/edt/PCellParametersDialog.ui b/src/edt/edt/PCellParametersDialog.ui deleted file mode 100644 index be3b83cde..000000000 --- a/src/edt/edt/PCellParametersDialog.ui +++ /dev/null @@ -1,73 +0,0 @@ - - - PCellParametersDialog - - - - 0 - 0 - 469 - 429 - - - - PCell Parameters - - - - - - - - - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - edt::PCellParametersPage - QWidget -
edtPCellParametersPage.h
- 1 -
-
- - - - buttons - rejected() - PCellParametersDialog - reject() - - - 321 - 405 - - - 337 - 423 - - - - - buttons - accepted() - PCellParametersDialog - accept() - - - 427 - 405 - - - 443 - 425 - - - - -
diff --git a/src/edt/edt/edt.pro b/src/edt/edt/edt.pro index 613c92dc3..a10d63c9e 100644 --- a/src/edt/edt/edt.pro +++ b/src/edt/edt/edt.pro @@ -41,7 +41,6 @@ FORMS = \ PolygonPropertiesPage.ui \ RoundCornerOptionsDialog.ui \ TextPropertiesPage.ui \ - PCellParametersDialog.ui \ DistributeOptionsDialog.ui \ EditorOptionsInstPCellParam.ui diff --git a/src/edt/edt/edtMainService.cc b/src/edt/edt/edtMainService.cc index 304bcb738..b2b522623 100644 --- a/src/edt/edt/edtMainService.cc +++ b/src/edt/edt/edtMainService.cc @@ -59,6 +59,7 @@ MainService::MainService (db::Manager *manager, lay::LayoutView *view, lay::Disp : lay::Plugin (view), lay::Editable (view), db::Object (manager), + dm_setup_pages (this, &MainService::do_setup_pages), mp_view (view), mp_root (root), m_needs_update (false), @@ -2358,6 +2359,14 @@ private: void MainService::config_finalize () +{ + // It's important that the editor option pages are updated last - because the + // configuration change may trigger other configuration changes + dm_setup_pages (); +} + +void +MainService::do_setup_pages () { setup_pages (view ()); } diff --git a/src/edt/edt/edtMainService.h b/src/edt/edt/edtMainService.h index 1ae28fc79..2b22cefee 100644 --- a/src/edt/edt/edtMainService.h +++ b/src/edt/edt/edtMainService.h @@ -201,6 +201,9 @@ public: virtual void config_finalize (); private: + // The deferred execution handler for the config_finalize event + tl::DeferredMethod dm_setup_pages; + // The layout view that this service is attached to lay::LayoutView *mp_view; lay::Dispatcher *mp_root; @@ -242,6 +245,7 @@ private: lay::FlattenInstOptionsDialog *flatten_inst_options_dialog (); edt::MakeCellOptionsDialog *make_cell_options_dialog (); edt::MakeArrayOptionsDialog *make_array_options_dialog (); + void do_setup_pages (); }; } diff --git a/src/edt/edt/edtPCellParametersPage.cc b/src/edt/edt/edtPCellParametersPage.cc index 87ab6d3e4..08ad31c71 100644 --- a/src/edt/edt/edtPCellParametersPage.cc +++ b/src/edt/edt/edtPCellParametersPage.cc @@ -165,6 +165,8 @@ PCellParametersPage::init () mp_parameters_area = 0; QGridLayout *frame_layout = new QGridLayout (this); + // spacing and margin for tool windows + frame_layout->setMargin (0); setLayout (frame_layout); mp_error_icon = new QLabel (this); @@ -200,6 +202,7 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int m_widgets.clear (); mp_parameters_area = new QScrollArea (this); + mp_parameters_area->setFrameShape (QFrame::NoFrame); QGridLayout *frame_layout = dynamic_cast (QFrame::layout ()); frame_layout->addWidget (mp_parameters_area, 0, 0, 1, 2); frame_layout->setRowStretch (0, 1); @@ -211,6 +214,9 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int QGridLayout *inner_grid = new QGridLayout (inner_frame); inner_frame->setLayout (inner_grid); + inner_grid->setMargin (4); + inner_grid->setHorizontalSpacing (6); + inner_grid->setVerticalSpacing (2); QWidget *main_frame = inner_frame; QGridLayout *main_grid = inner_grid; @@ -247,6 +253,9 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int main_grid->addWidget (gb, main_row, 0, 1, 2); inner_grid = new QGridLayout (gb); + inner_grid->setMargin (4); + inner_grid->setHorizontalSpacing (6); + inner_grid->setVerticalSpacing (2); gb->setLayout (inner_grid); inner_frame = gb; @@ -286,6 +295,7 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int QHBoxLayout *hb = new QHBoxLayout (f); hb->setMargin (0); f->setLayout (hb); + f->setFrameShape (QFrame::NoFrame); QLineEdit *le = new QLineEdit (f); le->setEnabled (! p->is_readonly ()); diff --git a/src/edt/edt/edtService.cc b/src/edt/edt/edtService.cc index c244213ad..f479b1c56 100644 --- a/src/edt/edt/edtService.cc +++ b/src/edt/edt/edtService.cc @@ -231,6 +231,12 @@ Service::snap2 (const db::DPoint &p, const db::DPoint &plast, bool connect) cons return lay::obj_snap (m_snap_to_objects ? view () : 0, plast, p, m_edit_grid == db::DVector () ? m_global_grid : m_edit_grid, connect ? connect_ac () : move_ac (), snap_range).second; } +void +Service::service_configuration_changed () +{ + // The base class implementation does nothing +} + bool Service::configure (const std::string &name, const std::string &value) { @@ -238,27 +244,58 @@ Service::configure (const std::string &name, const std::string &value) edt::ACConverter acc; if (name == cfg_edit_global_grid) { + egc.from_string (value, m_global_grid); + service_configuration_changed (); + } else if (name == cfg_edit_show_shapes_of_instances) { + tl::from_string (value, m_show_shapes_of_instances); + service_configuration_changed (); + } else if (name == cfg_edit_max_shapes_of_instances) { + tl::from_string (value, m_max_shapes_of_instances); + service_configuration_changed (); + } else if (name == cfg_edit_grid) { + egc.from_string (value, m_edit_grid); + service_configuration_changed (); + return true; // taken + } else if (name == cfg_edit_snap_to_objects) { + tl::from_string (value, m_snap_to_objects); + service_configuration_changed (); + return true; // taken + } else if (name == cfg_edit_move_angle_mode) { + acc.from_string (value, m_move_ac); + service_configuration_changed (); + return true; // taken + } else if (name == cfg_edit_connect_angle_mode) { + acc.from_string (value, m_connect_ac); + service_configuration_changed (); + return true; // taken + } else if (name == cfg_edit_top_level_selection) { + tl::from_string (value, m_top_level_sel); + service_configuration_changed (); + } else if (name == cfg_edit_hier_copy_mode) { + tl::from_string (value, m_hier_copy_mode); + service_configuration_changed (); + } return false; // not taken diff --git a/src/edt/edt/edtService.h b/src/edt/edt/edtService.h index 6e93219cb..997d7e102 100644 --- a/src/edt/edt/edtService.h +++ b/src/edt/edt/edtService.h @@ -455,6 +455,11 @@ protected: */ virtual void do_cancel_edit () { } + /** + * @brief Called when a configuration parameter provided by the service base class has changed + */ + virtual void service_configuration_changed (); + /** * @brief Install a marker for representing the edited object * diff --git a/src/edt/edt/edtServiceImpl.cc b/src/edt/edt/edtServiceImpl.cc index c3779c76e..63e5235f6 100644 --- a/src/edt/edt/edtServiceImpl.cc +++ b/src/edt/edt/edtServiceImpl.cc @@ -1288,10 +1288,6 @@ InstService::do_begin_edit (const db::DPoint &p) m_trans = db::VCplxTrans (1.0 / cv->layout ().dbu ()) * tv [0] * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans (); } - lay::Marker *marker = new lay::Marker (view (), m_cv_index, ! show_shapes_of_instances (), show_shapes_of_instances () ? max_shapes_of_instances () : 0); - marker->set_vertex_shape (lay::ViewOp::Cross); - marker->set_vertex_size (9 /*cross vertex size*/); - set_edit_marker (marker); update_marker (); } @@ -1505,18 +1501,33 @@ InstService::do_cancel_edit () } } +void +InstService::service_configuration_changed () +{ + m_needs_update = true; +} + bool InstService::configure (const std::string &name, const std::string &value) { if (name == cfg_edit_inst_cell_name) { - m_cell_or_pcell_name = value; - m_needs_update = true; + + if (value != m_cell_or_pcell_name) { + m_cell_or_pcell_name = value; + m_needs_update = true; + } + return true; // taken } if (name == cfg_edit_inst_lib_name) { - m_lib_name = value; - m_needs_update = true; + + if (value != m_lib_name) { + m_lib_name_previous = m_lib_name; + m_lib_name = value; + m_needs_update = true; + } + return true; // taken } @@ -1603,9 +1614,58 @@ void InstService::config_finalize () { if (m_needs_update) { + + // if the library or cell name has changed, store the current pcell parameters and try to reuse + // an existing parameter set + if (! m_cell_or_pcell_name_previous.empty () && (m_cell_or_pcell_name_previous != m_cell_or_pcell_name || m_lib_name_previous != m_lib_name)) { + + 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 (); + } + + m_is_pcell = false; + + const lay::CellView &cv = view ()->cellview (m_cv_index); + if (cv.is_valid ()) { + + db::Library *lib = db::LibraryManager::instance ().lib_ptr_by_name (m_lib_name); + + // find the layout the cell has to be looked up: that is either the layout of the current instance or + // the library selected + const db::Layout *layout; + if (lib) { + layout = &lib->layout (); + } else { + layout = &cv->layout (); + } + + m_is_pcell = layout->pcell_by_name (m_cell_or_pcell_name.c_str ()).first; + + } + + } + m_has_valid_cell = false; - update_marker (); + update_marker (); // NOTE: sets m_is_pcell m_needs_update = false; + + // remember the current cell or library name + m_cell_or_pcell_name_previous = m_cell_or_pcell_name; + m_lib_name_previous = m_lib_name; + + // 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 ()); + } + } edt::Service::config_finalize (); @@ -1614,13 +1674,16 @@ InstService::config_finalize () void InstService::update_marker () { - lay::Marker *marker = dynamic_cast (edit_marker ()); - if (marker) { + lay::Marker *marker = new lay::Marker (view (), m_cv_index, ! show_shapes_of_instances (), show_shapes_of_instances () ? max_shapes_of_instances () : 0); + marker->set_vertex_shape (lay::ViewOp::Cross); + marker->set_vertex_size (9 /*cross vertex size*/); + set_edit_marker (marker); + + db::CellInstArray inst; + if (get_inst (inst)) { + marker->set (inst, m_trans); + } else { marker->set (); - db::CellInstArray inst; - if (get_inst (inst)) { - marker->set (inst, m_trans); - } } } diff --git a/src/edt/edt/edtServiceImpl.h b/src/edt/edt/edtServiceImpl.h index 048b117a1..3720a9f52 100644 --- a/src/edt/edt/edtServiceImpl.h +++ b/src/edt/edt/edtServiceImpl.h @@ -220,6 +220,8 @@ public: protected: bool configure (const std::string &name, const std::string &value); + void service_configuration_changed (); + void config_finalize (); private: @@ -228,7 +230,9 @@ private: bool m_mirror; db::DPoint m_disp; std::string m_cell_or_pcell_name, m_lib_name; + std::string m_cell_or_pcell_name_previous, m_lib_name_previous; std::map m_pcell_parameters; + std::map, std::map > m_stored_pcell_parameters; bool m_is_pcell; bool m_array; unsigned int m_rows, m_columns;