Some fixes for the technology feature

- Fixed some potential segfaults due to invalid layout object
- More consistent handling of potential technology switch due to
  active cellview change
This commit is contained in:
Matthias Koefferlein 2020-12-20 23:49:29 +01:00
parent 1c6ffb4086
commit ca1ec353fb
8 changed files with 82 additions and 51 deletions

View File

@ -872,7 +872,7 @@ EditorOptionsInstPCellParam::update_pcell_parameters (const std::vector <tl::Var
if (pc.first && layout->pcell_declaration (pc.second) && view ()->cellview (m_cv_index).is_valid ()) {
mp_pcell_parameters = new PCellParametersPage (this, true /*dense*/);
mp_pcell_parameters->setup (&view ()->cellview (m_cv_index)->layout (), view (), m_cv_index, layout->pcell_declaration (pc.second), parameters);
mp_pcell_parameters->setup (view (), m_cv_index, layout->pcell_declaration (pc.second), parameters);
this->layout ()->addWidget (mp_pcell_parameters);
mp_pcell_parameters->set_state (pcp_state);

View File

@ -810,7 +810,7 @@ InstPropertiesPage::update_pcell_parameters ()
mp_pcell_parameters = new PCellParametersPage (pcell_tab);
connect (mp_pcell_parameters, SIGNAL (edited ()), this, SIGNAL (edited ()));
mp_pcell_parameters->setup (&cv->layout (), mp_service->view (), pos->cv_index (), layout->pcell_declaration (pc.second), parameters);
mp_pcell_parameters->setup (mp_service->view (), pos->cv_index (), layout->pcell_declaration (pc.second), parameters);
pcell_tab->layout ()->addWidget (mp_pcell_parameters);
}

View File

@ -25,6 +25,7 @@
#include "edtPropertiesPageUtils.h"
#include "layWidgets.h"
#include "layQtTools.h"
#include "layLayoutView.h"
#include "tlScriptError.h"
#include <QFrame>
@ -40,7 +41,7 @@
namespace edt
{
static void set_value (const db::PCellParameterDeclaration &p, const db::Layout * /*layout*/, QWidget *widget, const tl::Variant &value)
static void set_value (const db::PCellParameterDeclaration &p, QWidget *widget, const tl::Variant &value)
{
if (p.get_choices ().empty ()) {
@ -154,7 +155,6 @@ void
PCellParametersPage::init ()
{
mp_pcell_decl.reset (0);
mp_layout = 0;
mp_view = 0;
m_cv_index = 0;
mp_parameters_area = 0;
@ -183,10 +183,9 @@ PCellParametersPage::init ()
}
void
PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int cv_index, const db::PCellDeclaration *pcell_decl, const db::pcell_parameters_type &parameters)
PCellParametersPage::setup (lay::LayoutView *view, int cv_index, const db::PCellDeclaration *pcell_decl, const db::pcell_parameters_type &parameters)
{
mp_pcell_decl.reset (const_cast<db::PCellDeclaration *> (pcell_decl)); // no const weak_ptr ...
mp_layout = layout;
mp_view = view;
m_cv_index = cv_index;
m_parameters = parameters;
@ -385,7 +384,7 @@ PCellParametersPage::setup (const db::Layout *layout, lay::LayoutView *view, int
}
set_value (*p, mp_layout, m_widgets.back (), value);
set_value (*p, m_widgets.back (), value);
++row;
if (inner_frame == main_frame) {
@ -592,7 +591,9 @@ PCellParametersPage::get_parameters (bool *ok)
}
// coerce the parameters
mp_pcell_decl->coerce_parameters (*mp_layout, parameters);
if (mp_view->cellview (m_cv_index).is_valid ()) {
mp_pcell_decl->coerce_parameters (mp_view->cellview (m_cv_index)->layout (), parameters);
}
set_parameters (parameters);
mp_error_label->hide ();
@ -642,7 +643,7 @@ PCellParametersPage::set_parameters (const std::vector<tl::Variant> &parameters)
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
if (r < parameters.size () && m_widgets [r]) {
set_value (*p, mp_layout, m_widgets [r], parameters [r]);
set_value (*p, m_widgets [r], parameters [r]);
}
}
}

View File

@ -78,7 +78,7 @@ public:
* @param pcell_decl The PCell declaration
* @param parameters The parameter values to show (if empty, the default values are used)
*/
void setup (const db::Layout *layout, lay::LayoutView *view, int cv_index, const db::PCellDeclaration *pcell_decl, const db::pcell_parameters_type &parameters);
void setup (lay::LayoutView *view, int cv_index, const db::PCellDeclaration *pcell_decl, const db::pcell_parameters_type &parameters);
/**
* @brief Gets the pages current state
@ -124,7 +124,6 @@ private:
QLabel *mp_error_icon;
tl::weak_ptr<db::PCellDeclaration> mp_pcell_decl;
std::vector<QWidget *> m_widgets;
const db::Layout *mp_layout;
lay::LayoutView *mp_view;
int m_cv_index;
db::pcell_parameters_type m_parameters;

View File

@ -290,10 +290,6 @@ TechnologyController::menu_activated (const std::string &symbol) const
if (mp_mw) {
// Cancels the current modes - changing the technology may make libraries unavailable
// for example.
mp_mw->cancel ();
// apply technology with undo
mp_mw->manager ().transaction (tl::sprintf (tl::to_string (tr ("Apply technology '%s'")), m_current_technology));
try {

View File

@ -2538,7 +2538,7 @@ LayoutView::erase_cellview (unsigned int index)
return;
}
cancel ();
cancel_esc ();
// issue to event that signals a change in the cellviews
cellviews_about_to_change_event ();
@ -2704,6 +2704,8 @@ LayoutView::signal_apply_technology (lay::LayoutHandle *layout_handle)
if (cellview (i).handle () == layout_handle) {
cancel_esc ();
std::string lyp_file;
const db::Technology *tech = db::Technologies::instance ()->technology_by_name (cellview (i)->tech_name ());
if (tech && ! tech->eff_layer_properties_file ().empty ()) {
@ -3056,7 +3058,7 @@ void
LayoutView::reload_layout (unsigned int cv_index)
{
stop ();
cancel ();
cancel_esc ();
// save the current view state
lay::DisplayState state;
@ -3948,6 +3950,13 @@ LayoutView::cancel ()
clear_selection ();
}
void
LayoutView::cancel_esc ()
{
cancel ();
switch_mode (default_mode ());
}
void
LayoutView::bookmark_current_view ()
{
@ -4751,7 +4760,7 @@ LayoutView::select_cellviews_fit (const std::list <CellView> &cvs)
cellviews_about_to_change_event ();
set_min_hier_levels (0);
cancel ();
cancel_esc ();
m_cellviews = cvs;
zoom_fit ();
finish_cellviews_changed ();
@ -4772,6 +4781,12 @@ LayoutView::active_cellview_changed (int index)
{
if (m_active_cellview_changed_event_enabled) {
// we need to cancel pending drawing or dragging operations to reflect the new cellview (different target, may have different technology etc.)
cancel_esc ();
// we need to setup the editor option pages because the technology may have changed
dm_setup_editor_option_pages ();
active_cellview_changed_event ();
active_cellview_changed_with_index_event (index);
@ -4889,7 +4904,7 @@ LayoutView::select_cellviews (const std::list <CellView> &cvs)
cellviews_about_to_change_event ();
set_min_hier_levels (0);
cancel ();
cancel_esc ();
m_cellviews = cvs;
redraw ();
@ -4914,7 +4929,7 @@ LayoutView::select_cellview (int index, const CellView &cv)
cellview_about_to_change_event (index);
cancel ();
cancel_esc ();
*cellview_iter (index) = cv;
redraw ();

View File

@ -2576,12 +2576,17 @@ public slots:
void store_state ();
/**
* @brief Cancel all edit operations and clear the selection
* @brief Cancels all edit operations, clears the selection and resets the mode to "Select"
*/
void cancel_esc ();
/**
* @brief Cancels all edit operations and clears the selection
*/
void cancel ();
/**
* @brief Cancel all edit operations but leave selection
* @brief Cancels all edit operations but maintains selection
*/
void cancel_edits ();

View File

@ -420,7 +420,7 @@ LayerSelectionComboBox::set_view (lay::LayoutView *view, int cv_index, bool all_
return;
}
mp_private->layout = &view->cellview (cv_index)->layout ();
mp_private->layout = 0;
mp_private->view = view;
mp_private->cv_index = cv_index;
mp_private->all_layers = all_layers;
@ -465,45 +465,60 @@ LayerSelectionComboBox::update_layer_list ()
if (mp_private->view) {
LPIPairCompareOp cmp_op;
std::map<std::pair <db::LayerProperties, int>, std::string, LPIPairCompareOp> name_for_layer (cmp_op);
LayerPropertiesConstIterator lp = mp_private->view->begin_layers ();
while (! lp.at_end ()) {
if (lp->cellview_index () == mp_private->cv_index && ! lp->has_children () && (mp_private->all_layers || lp->layer_index () >= 0) && lp->source (true).layer_props () != db::LayerProperties ()) {
std::pair <db::LayerProperties, int> k (lp->source (true).layer_props (), lp->layer_index ());
name_for_layer.insert (std::make_pair (k, lp->display_string (mp_private->view, true, true /*always show source*/)));
mp_private->layers.push_back (k);
}
++lp;
const db::Layout *layout = 0;
const CellView &cv = mp_private->view->cellview (mp_private->cv_index);
if (cv.is_valid ()) {
layout = & cv->layout ();
}
size_t nk = mp_private->layers.size ();
if (! layout) {
for (unsigned int l = 0; l < mp_private->layout->layers (); ++l) {
if (mp_private->layout->is_valid_layer (l)) {
std::pair <db::LayerProperties, int> k (mp_private->layout->get_properties (l), int (l));
if (name_for_layer.find (k) == name_for_layer.end ()) {
set_current_layer (-1);
} else {
LPIPairCompareOp cmp_op;
std::map<std::pair <db::LayerProperties, int>, std::string, LPIPairCompareOp> name_for_layer (cmp_op);
LayerPropertiesConstIterator lp = mp_private->view->begin_layers ();
while (! lp.at_end ()) {
if (lp->cellview_index () == mp_private->cv_index && ! lp->has_children () && (mp_private->all_layers || lp->layer_index () >= 0) && lp->source (true).layer_props () != db::LayerProperties ()) {
std::pair <db::LayerProperties, int> k (lp->source (true).layer_props (), lp->layer_index ());
name_for_layer.insert (std::make_pair (k, lp->display_string (mp_private->view, true, true /*always show source*/)));
mp_private->layers.push_back (k);
}
++lp;
}
}
std::sort (mp_private->layers.begin () + nk, mp_private->layers.end ());
size_t nk = mp_private->layers.size ();
for (std::vector <std::pair <db::LayerProperties, int> >::iterator ll = mp_private->layers.begin (); ll != mp_private->layers.end (); ++ll) {
std::map<std::pair <db::LayerProperties, int>, std::string, LPIPairCompareOp>::const_iterator ln = name_for_layer.find (*ll);
if (ln != name_for_layer.end ()) {
addItem (tl::to_qstring (ln->second));
} else {
addItem (tl::to_qstring (ll->first.to_string ()));
for (unsigned int l = 0; l < layout->layers (); ++l) {
if (layout->is_valid_layer (l)) {
std::pair <db::LayerProperties, int> k (layout->get_properties (l), int (l));
if (name_for_layer.find (k) == name_for_layer.end ()) {
mp_private->layers.push_back (k);
}
}
}
}
if (mp_private->new_layer_enabled) {
addItem (QObject::tr ("New Layer .."));
}
std::sort (mp_private->layers.begin () + nk, mp_private->layers.end ());
set_current_layer (props);
for (std::vector <std::pair <db::LayerProperties, int> >::iterator ll = mp_private->layers.begin (); ll != mp_private->layers.end (); ++ll) {
std::map<std::pair <db::LayerProperties, int>, std::string, LPIPairCompareOp>::const_iterator ln = name_for_layer.find (*ll);
if (ln != name_for_layer.end ()) {
addItem (tl::to_qstring (ln->second));
} else {
addItem (tl::to_qstring (ll->first.to_string ()));
}
}
if (mp_private->new_layer_enabled) {
addItem (QObject::tr ("New Layer .."));
}
set_current_layer (props);
}
} else if (mp_private->layout) {