From ca1ec353fbc62954b3e402ae19472f0d29a2a840 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 20 Dec 2020 23:49:29 +0100 Subject: [PATCH] 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 --- src/edt/edt/edtEditorOptionsPages.cc | 2 +- src/edt/edt/edtInstPropertiesPage.cc | 2 +- src/edt/edt/edtPCellParametersPage.cc | 15 +++--- src/edt/edt/edtPCellParametersPage.h | 3 +- src/lay/lay/layTechnologyController.cc | 4 -- src/laybasic/laybasic/layLayoutView.cc | 25 +++++++-- src/laybasic/laybasic/layLayoutView.h | 9 +++- src/laybasic/laybasic/layWidgets.cc | 73 ++++++++++++++++---------- 8 files changed, 82 insertions(+), 51 deletions(-) diff --git a/src/edt/edt/edtEditorOptionsPages.cc b/src/edt/edt/edtEditorOptionsPages.cc index 779398f97..df2f67f69 100644 --- a/src/edt/edt/edtEditorOptionsPages.cc +++ b/src/edt/edt/edtEditorOptionsPages.cc @@ -872,7 +872,7 @@ EditorOptionsInstPCellParam::update_pcell_parameters (const std::vector 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); diff --git a/src/edt/edt/edtInstPropertiesPage.cc b/src/edt/edt/edtInstPropertiesPage.cc index 08a4c27fa..40f805210 100644 --- a/src/edt/edt/edtInstPropertiesPage.cc +++ b/src/edt/edt/edtInstPropertiesPage.cc @@ -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); } diff --git a/src/edt/edt/edtPCellParametersPage.cc b/src/edt/edt/edtPCellParametersPage.cc index 5908c8d36..150f0f76d 100644 --- a/src/edt/edt/edtPCellParametersPage.cc +++ b/src/edt/edt/edtPCellParametersPage.cc @@ -25,6 +25,7 @@ #include "edtPropertiesPageUtils.h" #include "layWidgets.h" #include "layQtTools.h" +#include "layLayoutView.h" #include "tlScriptError.h" #include @@ -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 ¶meters) +PCellParametersPage::setup (lay::LayoutView *view, int cv_index, const db::PCellDeclaration *pcell_decl, const db::pcell_parameters_type ¶meters) { mp_pcell_decl.reset (const_cast (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 ¶meters) const std::vector &pcp = mp_pcell_decl->parameter_declarations (); for (std::vector::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]); } } } diff --git a/src/edt/edt/edtPCellParametersPage.h b/src/edt/edt/edtPCellParametersPage.h index 158a3cb07..a180d4f9c 100644 --- a/src/edt/edt/edtPCellParametersPage.h +++ b/src/edt/edt/edtPCellParametersPage.h @@ -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 ¶meters); + void setup (lay::LayoutView *view, int cv_index, const db::PCellDeclaration *pcell_decl, const db::pcell_parameters_type ¶meters); /** * @brief Gets the pages current state @@ -124,7 +124,6 @@ private: QLabel *mp_error_icon; tl::weak_ptr mp_pcell_decl; std::vector m_widgets; - const db::Layout *mp_layout; lay::LayoutView *mp_view; int m_cv_index; db::pcell_parameters_type m_parameters; diff --git a/src/lay/lay/layTechnologyController.cc b/src/lay/lay/layTechnologyController.cc index 53f85f05a..eec75c495 100644 --- a/src/lay/lay/layTechnologyController.cc +++ b/src/lay/lay/layTechnologyController.cc @@ -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 { diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index fe3c642b7..18f1c6ddc 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -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 &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 &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 (); diff --git a/src/laybasic/laybasic/layLayoutView.h b/src/laybasic/laybasic/layLayoutView.h index 66469b163..a54e731fb 100644 --- a/src/laybasic/laybasic/layLayoutView.h +++ b/src/laybasic/laybasic/layLayoutView.h @@ -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 (); diff --git a/src/laybasic/laybasic/layWidgets.cc b/src/laybasic/laybasic/layWidgets.cc index a84b96601..c40d666b4 100644 --- a/src/laybasic/laybasic/layWidgets.cc +++ b/src/laybasic/laybasic/layWidgets.cc @@ -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::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 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 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::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 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 >::iterator ll = mp_private->layers.begin (); ll != mp_private->layers.end (); ++ll) { - std::map, 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 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 >::iterator ll = mp_private->layers.begin (); ll != mp_private->layers.end (); ++ll) { + std::map, 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) {