mirror of https://github.com/KLayout/klayout.git
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:
parent
1c6ffb4086
commit
ca1ec353fb
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ¶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<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> ¶meters)
|
|||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue