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
-
- 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;