klayout/src/laybasic/layLayoutPropertiesForm.cc

217 lines
5.8 KiB
C++
Raw Normal View History

/*
KLayout Layout Viewer
Copyright (C) 2006-2016 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 <set>
#include <sstream>
#include <QMessageBox>
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 <lay::LayoutHandle *> 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 lay::Technology *tech = 0;
if (technology_index >= 0 && technology_index < (int) lay::Technologies::instance ()->technologies ()) {
tech = &(lay::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 (lay::Technologies::const_iterator t = lay::Technologies::instance ()->begin (); t != lay::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
}
}