/* KLayout Layout Viewer Copyright (C) 2006-2018 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "layLayoutPropertiesForm.h" #include "layLayoutView.h" #include "tlExceptions.h" #include "layDialogs.h" #include "tlInternational.h" #include "tlString.h" #include "tlExpression.h" #include #include #include namespace lay { // ------------------------------------------------------------ LayoutPropertiesForm::LayoutPropertiesForm (QWidget *parent, lay::LayoutView *view, const char *name) : QDialog (parent), Ui::LayoutPropertiesForm () { m_editable = view->is_editable (); mp_view = view; setObjectName (QString::fromUtf8 (name)); Ui::LayoutPropertiesForm::setupUi (this); // collect the distinct layout handles std::set handles; for (unsigned int n = 0; n < view->cellviews (); ++n) { handles.insert (view->cellview (n).operator-> ()); } m_handles.reserve (handles.size ()); for (unsigned int n = 0; n < view->cellviews (); ++n) { lay::LayoutHandle *h = view->cellview (n).operator-> (); if (handles.find (h) != handles.end ()) { m_handles.push_back (h); handles.erase (h); layout_cbx->addItem (tl::to_qstring (h->name ())); } } m_index = -1; layout_cbx->setCurrentIndex (view->active_cellview_index ()); connect (layout_cbx, SIGNAL (activated (int)), this, SLOT (layout_selected (int))); connect (prop_pb, SIGNAL (clicked ()), this, SLOT (prop_pb_clicked ())); dbu_le->setEnabled (m_editable); layout_selected (layout_cbx->currentIndex ()); } void LayoutPropertiesForm::accept () { BEGIN_PROTECTED commit (); QDialog::accept (); END_PROTECTED } void LayoutPropertiesForm::commit () { if (m_index >= int (m_handles.size ()) || m_index < 0) { return; } db::Layout &layout = m_handles [m_index]->layout (); // get the database unit double dbu = 0.001; tl::from_string (tl::to_string (dbu_le->text ()), dbu); if (dbu < 1e-6 || dbu > 1e3) { throw tl::Exception (tl::to_string (QObject::tr ("Invalid database unit"))); } if (fabs (dbu - layout.dbu ()) > 1e-6) { mp_view->manager ()->transaction (tl::to_string (QObject::tr ("Change layout's database unit"))); layout.dbu (dbu); mp_view->manager ()->commit (); } // get the selected technology name std::string technology; int technology_index = tech_cbx->currentIndex (); const db::Technology *tech = 0; if (technology_index >= 0 && technology_index < (int) db::Technologies::instance ()->technologies ()) { tech = &(db::Technologies::instance ()->begin () [technology_index]); technology = tech->name (); } if (tech) { bool tech_has_changed = (technology != m_handles [m_index]->tech_name ()); m_handles [m_index]->set_tech_name (technology); std::string lyp_file = tech->eff_layer_properties_file (); if (tech_has_changed && ! lyp_file.empty ()) { // if the new technology has a layer properties file attached, ask whether to load it if (QMessageBox::question (this, QObject::tr ("Load Layer Properties File"), tl::to_qstring (tl::to_string (QObject::tr ("The new technology specifies a layer properties file (")) + lyp_file + tl::to_string (QObject::tr (").\nLoad the new layer properties file?"))), QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes) { // Interpolate the layer properties file name and load the file tl::Eval expr; expr.set_var ("layoutfile", m_handles [m_index]->filename ()); lyp_file = expr.interpolate (lyp_file); mp_view->load_layer_props (lyp_file); } } } } void LayoutPropertiesForm::prop_pb_clicked () { if (m_index >= int (m_handles.size ()) || m_index < 0) { return; } db::Layout &layout = m_handles [m_index]->layout (); db::properties_id_type prop_id = layout.prop_id (); lay::UserPropertiesForm props_form (this); if (props_form.show (mp_view, m_index, prop_id)) { mp_view->manager ()->transaction (tl::to_string (QObject::tr ("Edit layout's user propertes"))); layout.prop_id (prop_id); mp_view->manager ()->commit (); } } void LayoutPropertiesForm::layout_selected (int index) { BEGIN_PROTECTED if (index == m_index) { return; } if (m_index >= 0) { try { commit (); } catch (...) { layout_cbx->setCurrentIndex (m_index); throw; } m_index = -1; } if (index >= int (m_handles.size ()) || index < 0) { return; } m_index = index; const db::Layout &layout = m_handles [index]->layout (); tech_cbx->clear (); unsigned int technology_index = 0; for (db::Technologies::const_iterator t = db::Technologies::instance ()->begin (); t != db::Technologies::instance ()->end (); ++t, ++technology_index) { std::string d = t->name (); if (! d.empty () && ! t->description ().empty ()) { d += " - "; } d += t->description (); tech_cbx->addItem (tl::to_qstring (d)); if (t->name () == m_handles [index]->tech_name ()) { tech_cbx->setCurrentIndex (technology_index); } } dbu_le->setText (tl::to_qstring (tl::to_string (layout.dbu ()))); END_PROTECTED } }