2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
KLayout Layout Viewer
|
2017-02-12 15:28:14 +01:00
|
|
|
Copyright (C) 2006-2017 Matthias Koefferlein
|
2017-02-12 13:21:08 +01:00
|
|
|
|
|
|
|
|
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 "rdbMarkerBrowserDialog.h"
|
|
|
|
|
#include "rdb.h"
|
|
|
|
|
#include "rdbReader.h"
|
|
|
|
|
#include "tlProgress.h"
|
|
|
|
|
#include "layLayoutView.h"
|
|
|
|
|
#include "tlExceptions.h"
|
|
|
|
|
#include "layFileDialog.h"
|
|
|
|
|
#include "layConverters.h"
|
|
|
|
|
#include "layQtTools.h"
|
|
|
|
|
#include "layConfigurationDialog.h"
|
|
|
|
|
#include "dbLayoutUtils.h"
|
|
|
|
|
#include "dbRecursiveShapeIterator.h"
|
|
|
|
|
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include <QInputDialog>
|
|
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
namespace rdb
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
extern std::string cfg_rdb_context_mode;
|
|
|
|
|
extern std::string cfg_rdb_show_all;
|
|
|
|
|
extern std::string cfg_rdb_window_state;
|
|
|
|
|
extern std::string cfg_rdb_window_mode;
|
|
|
|
|
extern std::string cfg_rdb_window_dim;
|
|
|
|
|
extern std::string cfg_rdb_max_marker_count;
|
|
|
|
|
extern std::string cfg_rdb_marker_color;
|
|
|
|
|
extern std::string cfg_rdb_marker_line_width;
|
|
|
|
|
extern std::string cfg_rdb_marker_vertex_size;
|
|
|
|
|
extern std::string cfg_rdb_marker_halo;
|
|
|
|
|
extern std::string cfg_rdb_marker_dither_pattern;
|
|
|
|
|
|
|
|
|
|
MarkerBrowserDialog::MarkerBrowserDialog (lay::PluginRoot *root, lay::LayoutView *vw)
|
|
|
|
|
: lay::Browser (root, vw),
|
|
|
|
|
Ui::MarkerBrowserDialog (),
|
|
|
|
|
m_context (rdb::AnyCell),
|
|
|
|
|
m_window (rdb::FitMarker),
|
|
|
|
|
m_window_dim (0.0),
|
|
|
|
|
m_max_marker_count (0),
|
|
|
|
|
m_marker_line_width (-1),
|
|
|
|
|
m_marker_vertex_size (-1),
|
|
|
|
|
m_marker_halo (-1),
|
|
|
|
|
m_marker_dither_pattern (-1),
|
|
|
|
|
m_cv_index (-1),
|
|
|
|
|
m_rdb_index (-1)
|
|
|
|
|
{
|
|
|
|
|
Ui::MarkerBrowserDialog::setupUi (this);
|
|
|
|
|
|
|
|
|
|
browser_frame->set_plugin_root (root);
|
|
|
|
|
|
|
|
|
|
if (view ()) {
|
|
|
|
|
view ()->cellviews_changed_event.add (this, &MarkerBrowserDialog::cellviews_changed);
|
|
|
|
|
view ()->cellview_changed_event.add (this, &MarkerBrowserDialog::cellview_changed);
|
|
|
|
|
view ()->rdb_list_changed_event.add (this, &MarkerBrowserDialog::rdbs_changed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_open_action = new QAction (QObject::tr ("Open"), file_menu);
|
|
|
|
|
m_saveas_action = new QAction (QObject::tr ("Save As"), file_menu);
|
|
|
|
|
m_export_action = new QAction (QObject::tr ("Export To Layout"), file_menu);
|
|
|
|
|
m_reload_action = new QAction (QObject::tr ("Reload"), file_menu);
|
|
|
|
|
m_unload_action = new QAction (QObject::tr ("Unload"), file_menu);
|
|
|
|
|
m_unload_all_action = new QAction (QObject::tr ("Unload All"), file_menu);
|
|
|
|
|
|
|
|
|
|
connect (m_open_action, SIGNAL (triggered ()), this, SLOT (open_clicked ()));
|
|
|
|
|
connect (m_saveas_action, SIGNAL (triggered ()), this, SLOT (saveas_clicked ()));
|
|
|
|
|
connect (m_export_action, SIGNAL (triggered ()), this, SLOT (export_clicked ()));
|
|
|
|
|
connect (m_reload_action, SIGNAL (triggered ()), this, SLOT (reload_clicked ()));
|
|
|
|
|
connect (m_unload_action, SIGNAL (triggered ()), this, SLOT (unload_clicked ()));
|
|
|
|
|
connect (m_unload_all_action, SIGNAL (triggered ()), this, SLOT (unload_all_clicked ()));
|
|
|
|
|
|
|
|
|
|
file_menu->addAction (m_open_action);
|
|
|
|
|
file_menu->addAction (m_saveas_action);
|
|
|
|
|
QAction *sep0 = new QAction (file_menu);
|
|
|
|
|
sep0->setSeparator (true);
|
|
|
|
|
file_menu->addAction (m_export_action);
|
|
|
|
|
QAction *sep1 = new QAction (file_menu);
|
|
|
|
|
sep1->setSeparator (true);
|
|
|
|
|
file_menu->addAction (sep1);
|
|
|
|
|
file_menu->addAction (m_reload_action);
|
|
|
|
|
QAction *sep2 = new QAction (file_menu);
|
|
|
|
|
sep2->setSeparator (true);
|
|
|
|
|
file_menu->addAction (sep2);
|
|
|
|
|
file_menu->addAction (m_unload_action);
|
|
|
|
|
file_menu->addAction (m_unload_all_action);
|
|
|
|
|
|
|
|
|
|
connect (layout_cb, SIGNAL (activated (int)), this, SLOT (cv_index_changed (int)));
|
|
|
|
|
connect (rdb_cb, SIGNAL (activated (int)), this, SLOT (rdb_index_changed (int)));
|
|
|
|
|
connect (configure_pb, SIGNAL (clicked ()), this, SLOT (configure_clicked ()));
|
|
|
|
|
|
|
|
|
|
cellviews_changed ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MarkerBrowserDialog::~MarkerBrowserDialog ()
|
|
|
|
|
{
|
|
|
|
|
tl::Object::detach_from_all_events ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::configure_clicked ()
|
|
|
|
|
{
|
|
|
|
|
lay::ConfigurationDialog config_dialog (this, lay::PluginRoot::instance (), "MarkerBrowserPlugin");
|
|
|
|
|
config_dialog.exec ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::unload_all_clicked ()
|
|
|
|
|
{
|
|
|
|
|
BEGIN_PROTECTED
|
|
|
|
|
|
|
|
|
|
bool modified = false;
|
|
|
|
|
for (int i = 0; i < int (view ()->num_rdbs ()); ++i) {
|
|
|
|
|
rdb::Database *rdb = view ()->get_rdb (i);
|
|
|
|
|
if (rdb && rdb->is_modified ()) {
|
|
|
|
|
modified = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (modified) {
|
|
|
|
|
|
|
|
|
|
QMessageBox msgbox (QMessageBox::Question, QObject::tr ("Unload Without Saving"),
|
|
|
|
|
QObject::tr ("At least one database was not saved.\nPress 'Continue' to continue anyway or 'Cancel' for not unloading the database."));
|
|
|
|
|
QPushButton *ok = msgbox.addButton (QObject::tr ("Continue"), QMessageBox::AcceptRole);
|
|
|
|
|
msgbox.setDefaultButton (msgbox.addButton (QMessageBox::Cancel));
|
|
|
|
|
|
|
|
|
|
msgbox.exec ();
|
|
|
|
|
|
|
|
|
|
if (msgbox.clickedButton () != ok) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (view ()->num_rdbs () > 0) {
|
|
|
|
|
view ()->remove_rdb (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rdb_index_changed (-1);
|
|
|
|
|
|
|
|
|
|
END_PROTECTED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::unload_clicked ()
|
|
|
|
|
{
|
|
|
|
|
BEGIN_PROTECTED
|
|
|
|
|
|
|
|
|
|
if (m_rdb_index < int (view ()->num_rdbs ()) && m_rdb_index >= 0) {
|
|
|
|
|
|
|
|
|
|
rdb::Database *rdb = view ()->get_rdb (m_rdb_index);
|
|
|
|
|
if (rdb && rdb->is_modified ()) {
|
|
|
|
|
|
|
|
|
|
QMessageBox msgbox (QMessageBox::Question, QObject::tr ("Unload Without Saving"),
|
|
|
|
|
QObject::tr ("The database was not saved.\nPress 'Continue' to continue anyway or 'Cancel' for not unloading the database."));
|
|
|
|
|
QPushButton *ok = msgbox.addButton (QObject::tr ("Continue"), QMessageBox::AcceptRole);
|
|
|
|
|
msgbox.setDefaultButton (msgbox.addButton (QMessageBox::Cancel));
|
|
|
|
|
|
|
|
|
|
msgbox.exec ();
|
|
|
|
|
|
|
|
|
|
if (msgbox.clickedButton () != ok) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int new_rdb_index = m_rdb_index;
|
|
|
|
|
|
|
|
|
|
view ()->remove_rdb (m_rdb_index);
|
|
|
|
|
|
|
|
|
|
// try to use another rbd ...
|
|
|
|
|
if (new_rdb_index >= int (view ()->num_rdbs ())) {
|
|
|
|
|
--new_rdb_index;
|
|
|
|
|
}
|
|
|
|
|
if (new_rdb_index < int (view ()->num_rdbs ()) && new_rdb_index >= 0) {
|
|
|
|
|
rdb_index_changed (new_rdb_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
END_PROTECTED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
collect_categories (const Category *cat, std::vector <const Category *> &categories)
|
|
|
|
|
{
|
|
|
|
|
if (cat->sub_categories ().begin () == cat->sub_categories ().end ()) {
|
|
|
|
|
if (cat->num_items () > 0) {
|
|
|
|
|
categories.push_back (cat);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for (Categories::const_iterator subcat = cat->sub_categories ().begin (); subcat != cat->sub_categories ().end (); ++subcat) {
|
|
|
|
|
collect_categories (&*subcat, categories);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::export_clicked ()
|
|
|
|
|
{
|
|
|
|
|
BEGIN_PROTECTED
|
|
|
|
|
|
|
|
|
|
if (m_rdb_index >= int (view ()->num_rdbs ()) || m_rdb_index < 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const rdb::Database *rdb = view ()->get_rdb (m_rdb_index);
|
|
|
|
|
if (! rdb) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const lay::CellView &cv = view ()->cellview (m_cv_index);
|
|
|
|
|
if (! cv.is_valid ()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
|
QString text = QInputDialog::getText(this, QObject::tr ("Layer Offset"),
|
|
|
|
|
QObject::tr ("Enter the first GDS layer that is produced.\nLeave empty for not producing GDS layer numbers at all:"),
|
|
|
|
|
QLineEdit::Normal,
|
|
|
|
|
QString (), &ok);
|
|
|
|
|
if (! ok) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
text = text.simplified ();
|
|
|
|
|
|
|
|
|
|
int lnum = -1;
|
|
|
|
|
ok = false;
|
|
|
|
|
if (! text.isEmpty ()) {
|
|
|
|
|
lnum = text.toInt (&ok);
|
|
|
|
|
if (! ok) {
|
|
|
|
|
throw tl::Exception (tl::to_string (QObject::tr ("Invalid layer number: ")) + tl::to_string (text));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
view ()->manager ()->transaction (tl::to_string (QObject::tr ("Export Markers")));
|
|
|
|
|
|
|
|
|
|
std::vector <const Category *> categories;
|
|
|
|
|
for (rdb::Categories::const_iterator cat = rdb->categories ().begin (); cat != rdb->categories ().end (); ++cat) {
|
|
|
|
|
collect_categories (&*cat, categories);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (std::vector <const Category *>::const_iterator cat = categories.begin (); cat != categories.end (); ++cat) {
|
|
|
|
|
|
|
|
|
|
db::LayerProperties lp;
|
|
|
|
|
if (lnum >= 0) {
|
|
|
|
|
lp.layer = lnum++;
|
|
|
|
|
lp.datatype = 0;
|
|
|
|
|
}
|
|
|
|
|
lp.name = (*cat)->name ();
|
|
|
|
|
|
|
|
|
|
unsigned int layer = cv->layout ().insert_layer (lp);
|
|
|
|
|
|
|
|
|
|
lay::LayerProperties props;
|
|
|
|
|
props.set_source (lay::ParsedLayerSource (lp, m_cv_index));
|
|
|
|
|
|
|
|
|
|
view ()->init_layer_properties (props);
|
|
|
|
|
view ()->insert_layer (view ()->end_layers (), props);
|
|
|
|
|
|
|
|
|
|
for (Cells::const_iterator cell = rdb->cells ().begin (); cell != rdb->cells ().end (); ++cell) {
|
|
|
|
|
|
|
|
|
|
std::pair<Database::const_item_ref_iterator, Database::const_item_ref_iterator> be = rdb->items_by_cell_and_category (cell->id (), (*cat)->id ());
|
|
|
|
|
if (be.first == be.second) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
db::cell_index_type target_cell = cv.cell_index ();
|
|
|
|
|
db::DCplxTrans trans;
|
|
|
|
|
|
|
|
|
|
// TODO: be more verbose if that fails:
|
|
|
|
|
std::pair<bool, db::cell_index_type> cc = cv->layout ().cell_by_name (cell->name ().c_str ());
|
|
|
|
|
if (cc.first) {
|
|
|
|
|
target_cell = cc.second;
|
|
|
|
|
} else {
|
|
|
|
|
const rdb::Cell *top_cell = rdb->cell_by_qname (rdb->top_cell_name ());
|
|
|
|
|
if (top_cell) {
|
|
|
|
|
std::pair <bool, db::DCplxTrans> context = cell->path_to (top_cell->id (), rdb);
|
|
|
|
|
if (context.first) {
|
|
|
|
|
trans = context.second;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (Database::const_item_ref_iterator item = be.first; item != be.second; ++item) {
|
|
|
|
|
|
|
|
|
|
// Produce the shapes ...
|
|
|
|
|
for (rdb::Values::const_iterator v = (*item)->values ().begin (); v != (*item)->values ().end (); ++v) {
|
|
|
|
|
|
|
|
|
|
const rdb::Value<db::DPolygon> *polygon_value = dynamic_cast <const rdb::Value<db::DPolygon> *> (v->get ());
|
|
|
|
|
const rdb::Value<db::DBox> *box_value = dynamic_cast <const rdb::Value<db::DBox> *> (v->get ());
|
|
|
|
|
const rdb::Value<db::DEdge> *edge_value = dynamic_cast <const rdb::Value<db::DEdge> *> (v->get ());
|
|
|
|
|
const rdb::Value<db::DEdgePair> *edge_pair_value = dynamic_cast <const rdb::Value<db::DEdgePair> *> (v->get ());
|
|
|
|
|
|
|
|
|
|
if (polygon_value) {
|
|
|
|
|
|
|
|
|
|
db::Polygon polygon = db::Polygon (db::DCplxTrans (1.0 / cv->layout ().dbu ()) * trans * polygon_value->value ());
|
|
|
|
|
cv->layout ().cell (target_cell).shapes (layer).insert (polygon);
|
|
|
|
|
|
|
|
|
|
} else if (edge_value) {
|
|
|
|
|
|
|
|
|
|
db::Edge edge = db::Edge (db::DCplxTrans (1.0 / cv->layout ().dbu ()) * trans * edge_value->value ());
|
|
|
|
|
cv->layout ().cell (target_cell).shapes (layer).insert (edge);
|
|
|
|
|
|
|
|
|
|
} else if (edge_pair_value) {
|
|
|
|
|
|
|
|
|
|
// Note: there is no edge pair inside the database currently. Hence we convert it to a polygon
|
|
|
|
|
db::EdgePair edge_pair = db::EdgePair (db::DCplxTrans (1.0 / cv->layout ().dbu ()) * trans * edge_pair_value->value ());
|
|
|
|
|
cv->layout ().cell (target_cell).shapes (layer).insert (edge_pair.to_polygon (1));
|
|
|
|
|
|
|
|
|
|
} else if (box_value) {
|
|
|
|
|
|
|
|
|
|
db::Polygon polygon = db::Polygon (db::DCplxTrans (1.0 / cv->layout ().dbu ()) * trans * db::DPolygon (box_value->value ()));
|
|
|
|
|
cv->layout ().cell (target_cell).shapes (layer).insert (polygon);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
view ()->manager ()->commit ();
|
|
|
|
|
view ()->update_content ();
|
|
|
|
|
|
|
|
|
|
} catch (...) {
|
|
|
|
|
view ()->manager ()->commit ();
|
|
|
|
|
view ()->update_content ();
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
END_PROTECTED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::saveas_clicked ()
|
|
|
|
|
{
|
|
|
|
|
BEGIN_PROTECTED
|
|
|
|
|
|
|
|
|
|
if (m_rdb_index < int (view ()->num_rdbs ()) && m_rdb_index >= 0) {
|
|
|
|
|
|
|
|
|
|
rdb::Database *rdb = view ()->get_rdb (m_rdb_index);
|
|
|
|
|
if (rdb) {
|
|
|
|
|
|
|
|
|
|
// prepare and open the file dialog
|
|
|
|
|
lay::FileDialog save_dialog (this, tl::to_string (QObject::tr ("Marker Database File")), "KLayout RDB files (*.lyrdb)");
|
|
|
|
|
std::string fn (rdb->filename ());
|
|
|
|
|
if (save_dialog.get_save (fn)) {
|
|
|
|
|
|
|
|
|
|
rdb->save (fn);
|
|
|
|
|
rdb->reset_modified ();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
END_PROTECTED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::reload_clicked ()
|
|
|
|
|
{
|
|
|
|
|
BEGIN_PROTECTED
|
|
|
|
|
if (m_rdb_index < int (view ()->num_rdbs ()) && m_rdb_index >= 0) {
|
|
|
|
|
|
|
|
|
|
rdb::Database *rdb = view ()->get_rdb (m_rdb_index);
|
|
|
|
|
if (rdb && ! rdb->filename ().empty ()) {
|
|
|
|
|
|
|
|
|
|
browser_frame->set_rdb (0);
|
|
|
|
|
rdb->load (rdb->filename ());
|
|
|
|
|
browser_frame->set_rdb (rdb);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
END_PROTECTED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::open_clicked ()
|
|
|
|
|
{
|
|
|
|
|
BEGIN_PROTECTED
|
|
|
|
|
|
|
|
|
|
// collect the formats available ...
|
|
|
|
|
std::string fmts = tl::to_string (QObject::tr ("All files (*)"));
|
|
|
|
|
for (tl::Registrar<rdb::FormatDeclaration>::iterator rdr = tl::Registrar<rdb::FormatDeclaration>::begin (); rdr != tl::Registrar<rdb::FormatDeclaration>::end (); ++rdr) {
|
|
|
|
|
fmts += ";;" + rdr->file_format ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// prepare and open the file dialog
|
|
|
|
|
lay::FileDialog open_dialog (this, tl::to_string (QObject::tr ("Marker Database File")), fmts);
|
|
|
|
|
if (open_dialog.get_open (m_open_filename)) {
|
|
|
|
|
|
|
|
|
|
std::auto_ptr <rdb::Database> db (new rdb::Database ());
|
|
|
|
|
db->load (m_open_filename);
|
|
|
|
|
|
|
|
|
|
int rdb_index = view ()->add_rdb (db.release ());
|
|
|
|
|
rdb_cb->setCurrentIndex (rdb_index);
|
|
|
|
|
// it looks like the setCurrentIndex does not issue this signal:
|
|
|
|
|
rdb_index_changed (rdb_index);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
END_PROTECTED
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
MarkerBrowserDialog::configure (const std::string &name, const std::string &value)
|
|
|
|
|
{
|
|
|
|
|
bool need_update = false;
|
|
|
|
|
bool taken = true;
|
|
|
|
|
bool show_all = browser_frame->show_all ();
|
|
|
|
|
|
|
|
|
|
if (name == cfg_rdb_context_mode) {
|
|
|
|
|
|
|
|
|
|
context_mode_type context = m_context;
|
|
|
|
|
MarkerBrowserContextModeConverter ().from_string (value, context);
|
|
|
|
|
need_update = lay::test_and_set (m_context, context);
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_show_all) {
|
|
|
|
|
|
|
|
|
|
tl::from_string (value, show_all);
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_window_mode) {
|
|
|
|
|
|
|
|
|
|
window_type window = m_window;
|
|
|
|
|
MarkerBrowserWindowModeConverter ().from_string (value, window);
|
|
|
|
|
need_update = lay::test_and_set (m_window, window);
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_window_dim) {
|
|
|
|
|
|
|
|
|
|
double wdim = m_window_dim;
|
|
|
|
|
tl::from_string (value, wdim);
|
|
|
|
|
if (fabs (wdim - m_window_dim) > 1e-6) {
|
|
|
|
|
m_window_dim = wdim;
|
|
|
|
|
need_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_max_marker_count) {
|
|
|
|
|
|
|
|
|
|
unsigned int mc = 0;
|
|
|
|
|
tl::from_string (value, mc);
|
|
|
|
|
need_update = lay::test_and_set (m_max_marker_count, mc);
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_marker_color) {
|
|
|
|
|
|
|
|
|
|
QColor color;
|
|
|
|
|
if (! value.empty ()) {
|
|
|
|
|
lay::ColorConverter ().from_string (value, color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (color != m_marker_color) {
|
|
|
|
|
m_marker_color = color;
|
|
|
|
|
need_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_marker_line_width) {
|
|
|
|
|
|
|
|
|
|
int lw = 0;
|
|
|
|
|
tl::from_string (value, lw);
|
|
|
|
|
|
|
|
|
|
if (lw != m_marker_line_width) {
|
|
|
|
|
m_marker_line_width = lw;
|
|
|
|
|
need_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_marker_vertex_size) {
|
|
|
|
|
|
|
|
|
|
int vs = 0;
|
|
|
|
|
tl::from_string (value, vs);
|
|
|
|
|
|
|
|
|
|
if (vs != m_marker_vertex_size) {
|
|
|
|
|
m_marker_vertex_size = vs;
|
|
|
|
|
need_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_marker_halo) {
|
|
|
|
|
|
|
|
|
|
int halo = 0;
|
|
|
|
|
tl::from_string (value, halo);
|
|
|
|
|
|
|
|
|
|
if (halo != m_marker_halo) {
|
|
|
|
|
m_marker_halo = halo;
|
|
|
|
|
need_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if (name == cfg_rdb_marker_dither_pattern) {
|
|
|
|
|
|
|
|
|
|
int dp = 0;
|
|
|
|
|
tl::from_string (value, dp);
|
|
|
|
|
|
|
|
|
|
if (dp != m_marker_dither_pattern) {
|
|
|
|
|
m_marker_dither_pattern = dp;
|
|
|
|
|
need_update = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
taken = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (active () && need_update) {
|
|
|
|
|
browser_frame->set_max_marker_count (m_max_marker_count);
|
|
|
|
|
browser_frame->set_window (m_window, m_window_dim, m_context);
|
|
|
|
|
browser_frame->set_marker_style (m_marker_color, m_marker_line_width, m_marker_vertex_size, m_marker_halo, m_marker_dither_pattern);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
browser_frame->show_all (show_all);
|
|
|
|
|
|
|
|
|
|
return taken;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::load (int rdb_index, int cv_index)
|
|
|
|
|
{
|
|
|
|
|
if (! view ()->get_rdb (rdb_index)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! view ()->cellview (cv_index).is_valid ()) {
|
|
|
|
|
m_layout_name = std::string ();
|
|
|
|
|
} else {
|
|
|
|
|
m_layout_name = view ()->cellview (cv_index)->name ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set the new references (by name)
|
|
|
|
|
m_rdb_name = view ()->get_rdb (rdb_index)->name ();
|
|
|
|
|
|
|
|
|
|
// force an update
|
|
|
|
|
rdbs_changed ();
|
|
|
|
|
cellviews_changed ();
|
|
|
|
|
|
|
|
|
|
activate ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::rdbs_changed ()
|
|
|
|
|
{
|
|
|
|
|
int rdb_index = -1;
|
|
|
|
|
|
|
|
|
|
rdb_cb->clear ();
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < view ()->num_rdbs (); ++i) {
|
|
|
|
|
const rdb::Database *rdb = view ()->get_rdb (i);
|
|
|
|
|
rdb_cb->addItem (tl::to_qstring (rdb->name ()));
|
|
|
|
|
if (rdb->name () == m_rdb_name) {
|
|
|
|
|
rdb_index = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// force an update
|
|
|
|
|
m_rdb_index = rdb_index;
|
|
|
|
|
rdb_cb->setCurrentIndex (rdb_index);
|
|
|
|
|
if (active ()) {
|
|
|
|
|
update_content ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::cellview_changed (int)
|
|
|
|
|
{
|
|
|
|
|
browser_frame->update_markers ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::cellviews_changed ()
|
|
|
|
|
{
|
|
|
|
|
int cv_index = -1;
|
|
|
|
|
|
|
|
|
|
layout_cb->clear ();
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < view ()->cellviews (); ++i) {
|
|
|
|
|
const lay::CellView &cv = view ()->cellview (i);
|
|
|
|
|
layout_cb->addItem (tl::to_qstring (cv->name ()));
|
|
|
|
|
if (cv.is_valid () && cv->name () == m_layout_name) {
|
|
|
|
|
cv_index = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
layout_cb->setCurrentIndex (cv_index);
|
|
|
|
|
cv_index_changed (cv_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::rdb_index_changed (int index)
|
|
|
|
|
{
|
|
|
|
|
if (m_rdb_index != index) {
|
|
|
|
|
m_rdb_index = index;
|
|
|
|
|
if (active ()) {
|
|
|
|
|
update_content ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::cv_index_changed (int index)
|
|
|
|
|
{
|
|
|
|
|
if (m_cv_index != index) {
|
|
|
|
|
m_cv_index = index;
|
|
|
|
|
if (active ()) {
|
|
|
|
|
update_content ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::activated ()
|
|
|
|
|
{
|
|
|
|
|
std::string state;
|
|
|
|
|
if (lay::PluginRoot::instance ()) {
|
|
|
|
|
lay::PluginRoot::instance ()->config_get (cfg_rdb_window_state, state);
|
|
|
|
|
}
|
|
|
|
|
lay::restore_dialog_state (this, state);
|
|
|
|
|
|
|
|
|
|
// Switch to the active cellview index when no valid one is set.
|
|
|
|
|
lay::CellView cv = view ()->cellview (m_cv_index);
|
|
|
|
|
if (! cv.is_valid ()) {
|
|
|
|
|
m_cv_index = view ()->active_cellview_index ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_rdb_index < 0 && view ()->get_rdb (0) != 0) {
|
|
|
|
|
|
|
|
|
|
m_rdb_name = view ()->get_rdb (0)->name ();
|
|
|
|
|
rdbs_changed ();
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
update_content ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::update_content ()
|
|
|
|
|
{
|
|
|
|
|
rdb::Database *rdb = view ()->get_rdb (m_rdb_index);
|
|
|
|
|
|
|
|
|
|
if (!rdb ) {
|
|
|
|
|
central_stack->setCurrentIndex (1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_saveas_action->setEnabled (rdb != 0);
|
|
|
|
|
m_export_action->setEnabled (rdb != 0);
|
|
|
|
|
m_unload_action->setEnabled (rdb != 0);
|
|
|
|
|
m_unload_all_action->setEnabled (rdb != 0);
|
|
|
|
|
m_reload_action->setEnabled (rdb != 0);
|
|
|
|
|
|
|
|
|
|
browser_frame->enable_updates (false); // Avoid building the internal lists several times ...
|
|
|
|
|
browser_frame->set_rdb (rdb);
|
|
|
|
|
browser_frame->set_max_marker_count (m_max_marker_count);
|
|
|
|
|
browser_frame->set_marker_style (m_marker_color, m_marker_line_width, m_marker_vertex_size, m_marker_halo, m_marker_dither_pattern);
|
|
|
|
|
browser_frame->set_window (m_window, m_window_dim, m_context);
|
|
|
|
|
browser_frame->set_view (view (), m_cv_index);
|
|
|
|
|
browser_frame->enable_updates (true);
|
|
|
|
|
|
|
|
|
|
if (rdb) {
|
|
|
|
|
// Note: it appears to be required to show the browser page after it has been configured.
|
|
|
|
|
// Otherwise the header gets messed up and the configuration is reset.
|
|
|
|
|
central_stack->setCurrentIndex (0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lay::CellView cv = view ()->cellview (m_cv_index);
|
|
|
|
|
m_layout_name = std::string ();
|
|
|
|
|
if (cv.is_valid ()) {
|
|
|
|
|
m_layout_name = cv->name ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (layout_cb->currentIndex () != m_cv_index) {
|
|
|
|
|
layout_cb->setCurrentIndex (m_cv_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rdb_cb->currentIndex () != m_rdb_index) {
|
|
|
|
|
rdb_cb->setCurrentIndex (m_rdb_index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::deactivated ()
|
|
|
|
|
{
|
|
|
|
|
if (lay::PluginRoot::instance ()) {
|
|
|
|
|
lay::PluginRoot::instance ()->config_set (cfg_rdb_window_state, lay::save_dialog_state (this).c_str ());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
browser_frame->set_rdb (0);
|
|
|
|
|
browser_frame->set_view (0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::scan_layer ()
|
|
|
|
|
{
|
|
|
|
|
std::vector<lay::LayerPropertiesConstIterator> layers = view ()->selected_layers ();
|
|
|
|
|
if (layers.empty ()) {
|
|
|
|
|
throw tl::Exception (tl::to_string (QObject::tr ("No layer selected to get shapes from")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cv_index = -1;
|
|
|
|
|
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
|
|
|
|
if (!(*l)->has_children ()) {
|
|
|
|
|
if (cv_index < 0) {
|
|
|
|
|
cv_index = (*l)->cellview_index ();
|
|
|
|
|
} else if ((*l)->cellview_index () >= 0) {
|
|
|
|
|
if (cv_index != (*l)->cellview_index ()) {
|
|
|
|
|
throw tl::Exception (tl::to_string (QObject::tr ("All layers must originate from the same layout")));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cv_index < 0) {
|
|
|
|
|
throw tl::Exception (tl::to_string (QObject::tr ("No valid layer selected")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Shapes To Markers")), 10000);
|
|
|
|
|
progress.set_format (tl::to_string (QObject::tr ("%.0f0000 markers")));
|
|
|
|
|
progress.set_unit (10000);
|
|
|
|
|
|
|
|
|
|
const lay::CellView &cv = view ()->cellview (cv_index);
|
|
|
|
|
const db::Layout &layout = cv->layout ();
|
|
|
|
|
|
|
|
|
|
std::auto_ptr<rdb::Database> rdb (new rdb::Database ());
|
|
|
|
|
rdb->set_name ("Shapes");
|
|
|
|
|
rdb->set_top_cell_name (layout.cell_name (cv.cell_index ()));
|
|
|
|
|
rdb::Cell *rdb_top_cell = rdb->create_cell (rdb->top_cell_name ());
|
|
|
|
|
|
|
|
|
|
std::string desc;
|
|
|
|
|
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
|
|
|
|
if (!(*l)->has_children () && (*l)->cellview_index () >= 0 && layout.is_valid_layer ((*l)->layer_index ())) {
|
|
|
|
|
if (! desc.empty ()) {
|
|
|
|
|
desc += ", ";
|
|
|
|
|
}
|
|
|
|
|
desc += layout.get_properties ((*l)->layer_index ()).to_string ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rdb->set_description ("Shapes of layer(s) " + desc);
|
|
|
|
|
|
|
|
|
|
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
|
|
|
|
|
|
|
|
|
if (!(*l)->has_children () && (*l)->cellview_index () >= 0 && layout.is_valid_layer ((*l)->layer_index ())) {
|
|
|
|
|
|
|
|
|
|
rdb::Category *cat = rdb->create_category (layout.get_properties ((*l)->layer_index ()).to_string ());
|
|
|
|
|
|
|
|
|
|
for (db::Layout::const_iterator cid = layout.begin (); cid != layout.end (); ++cid) {
|
|
|
|
|
|
|
|
|
|
const db::Cell &cell = *cid;
|
|
|
|
|
if (cell.shapes ((*l)->layer_index ()).size () > 0) {
|
|
|
|
|
|
|
|
|
|
std::string cn = layout.cell_name (cell.cell_index ());
|
|
|
|
|
const rdb::Cell *rdb_cell = rdb->cell_by_qname (cn);
|
|
|
|
|
if (! rdb_cell) {
|
|
|
|
|
|
|
|
|
|
rdb::Cell *rdb_cell_nc = rdb->create_cell (cn);
|
|
|
|
|
rdb_cell = rdb_cell_nc;
|
|
|
|
|
|
|
|
|
|
std::pair<bool, db::ICplxTrans> ctx = db::find_layout_context (layout, cell.cell_index (), cv.cell_index ());
|
|
|
|
|
if (ctx.first) {
|
|
|
|
|
db::DCplxTrans t = db::DCplxTrans (layout.dbu ()) * db::DCplxTrans (ctx.second) * db::DCplxTrans (1.0 / layout.dbu ());
|
|
|
|
|
rdb_cell_nc->references ().insert (Reference (t, rdb_top_cell->id ()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (db::ShapeIterator shape = cell.shapes ((*l)->layer_index ()).begin (db::ShapeIterator::All); ! shape.at_end (); ++shape) {
|
|
|
|
|
|
|
|
|
|
std::auto_ptr<rdb::ValueBase> value;
|
|
|
|
|
|
|
|
|
|
if (shape->is_polygon () || shape->is_box ()) {
|
|
|
|
|
|
|
|
|
|
db::Polygon poly;
|
|
|
|
|
shape->polygon (poly);
|
|
|
|
|
value.reset (new rdb::Value <db::DPolygon> (poly.transformed (db::CplxTrans (layout.dbu ()))));
|
|
|
|
|
|
|
|
|
|
} else if (shape->is_path ()) {
|
|
|
|
|
|
|
|
|
|
db::Path path;
|
|
|
|
|
shape->path (path);
|
|
|
|
|
value.reset (new rdb::Value <db::DPath> (path.transformed (db::CplxTrans (layout.dbu ()))));
|
|
|
|
|
|
|
|
|
|
} else if (shape->is_text ()) {
|
|
|
|
|
|
|
|
|
|
db::Text text;
|
|
|
|
|
shape->text (text);
|
|
|
|
|
value.reset (new rdb::Value <db::DText> (text.transformed (db::CplxTrans (layout.dbu ()))));
|
|
|
|
|
|
|
|
|
|
} else if (shape->is_edge ()) {
|
|
|
|
|
|
|
|
|
|
db::Edge edge;
|
|
|
|
|
shape->edge (edge);
|
|
|
|
|
value.reset (new rdb::Value <db::DEdge> (edge.transformed (db::CplxTrans (layout.dbu ()))));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rdb::Item *item = rdb->create_item (rdb_cell->id (), cat->id ());
|
|
|
|
|
item->values ().add (value.release ());
|
|
|
|
|
++progress;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int rdb_index = view ()->add_rdb (rdb.release ());
|
|
|
|
|
view ()->open_rdb_browser (rdb_index, cv_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::scan_layer_flat ()
|
|
|
|
|
{
|
|
|
|
|
std::vector<lay::LayerPropertiesConstIterator> layers = view ()->selected_layers ();
|
|
|
|
|
if (layers.empty ()) {
|
|
|
|
|
throw tl::Exception (tl::to_string (QObject::tr ("No layer selected to get shapes from")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int cv_index = -1;
|
|
|
|
|
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
|
|
|
|
if (!(*l)->has_children ()) {
|
|
|
|
|
if (cv_index < 0) {
|
|
|
|
|
cv_index = (*l)->cellview_index ();
|
|
|
|
|
} else if ((*l)->cellview_index () >= 0) {
|
|
|
|
|
if (cv_index != (*l)->cellview_index ()) {
|
|
|
|
|
throw tl::Exception (tl::to_string (QObject::tr ("All layers must originate from the same layout")));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cv_index < 0) {
|
|
|
|
|
throw tl::Exception (tl::to_string (QObject::tr ("No valid layer selected")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tl::AbsoluteProgress progress (tl::to_string (QObject::tr ("Shapes To Markers")), 10000);
|
|
|
|
|
progress.set_format (tl::to_string (QObject::tr ("%.0f0000 markers")));
|
|
|
|
|
progress.set_unit (10000);
|
|
|
|
|
|
|
|
|
|
const lay::CellView &cv = view ()->cellview (cv_index);
|
|
|
|
|
const db::Layout &layout = cv->layout ();
|
|
|
|
|
|
|
|
|
|
std::auto_ptr<rdb::Database> rdb (new rdb::Database ());
|
|
|
|
|
rdb->set_name ("Shapes");
|
|
|
|
|
rdb->set_top_cell_name (layout.cell_name (cv.cell_index ()));
|
|
|
|
|
rdb::Cell *rdb_top_cell = rdb->create_cell (rdb->top_cell_name ());
|
|
|
|
|
|
|
|
|
|
std::string desc;
|
|
|
|
|
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
|
|
|
|
if (!(*l)->has_children () && (*l)->cellview_index () >= 0 && layout.is_valid_layer ((*l)->layer_index ())) {
|
|
|
|
|
if (! desc.empty ()) {
|
|
|
|
|
desc += ", ";
|
|
|
|
|
}
|
|
|
|
|
desc += layout.get_properties ((*l)->layer_index ()).to_string ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rdb->set_description ("Shapes of layer(s) " + desc);
|
|
|
|
|
|
|
|
|
|
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator l = layers.begin (); l != layers.end (); ++l) {
|
|
|
|
|
|
|
|
|
|
if (!(*l)->has_children () && (*l)->cellview_index () >= 0 && layout.is_valid_layer ((*l)->layer_index ())) {
|
|
|
|
|
|
|
|
|
|
rdb::Category *cat = rdb->create_category (layout.get_properties ((*l)->layer_index ()).to_string ());
|
|
|
|
|
|
|
|
|
|
db::RecursiveShapeIterator shape (layout, *cv.cell (), (*l)->layer_index ());
|
|
|
|
|
while (! shape.at_end ()) {
|
|
|
|
|
|
|
|
|
|
std::auto_ptr<rdb::ValueBase> value;
|
|
|
|
|
|
|
|
|
|
if (shape->is_polygon () || shape->is_box ()) {
|
|
|
|
|
|
|
|
|
|
db::Polygon poly;
|
|
|
|
|
shape->polygon (poly);
|
|
|
|
|
value.reset (new rdb::Value <db::DPolygon> (poly.transformed (db::CplxTrans (layout.dbu ()) * shape.trans ())));
|
|
|
|
|
|
|
|
|
|
} else if (shape->is_path ()) {
|
|
|
|
|
|
|
|
|
|
db::Path path;
|
|
|
|
|
shape->path (path);
|
|
|
|
|
value.reset (new rdb::Value <db::DPath> (path.transformed (db::CplxTrans (layout.dbu ()) * shape.trans ())));
|
|
|
|
|
|
|
|
|
|
} else if (shape->is_text ()) {
|
|
|
|
|
|
|
|
|
|
db::Text text;
|
|
|
|
|
shape->text (text);
|
|
|
|
|
value.reset (new rdb::Value <db::DText> (text.transformed (db::CplxTrans (layout.dbu ()) * shape.trans ())));
|
|
|
|
|
|
|
|
|
|
} else if (shape->is_edge ()) {
|
|
|
|
|
|
|
|
|
|
db::Edge edge;
|
|
|
|
|
shape->edge (edge);
|
|
|
|
|
value.reset (new rdb::Value <db::DEdge> (edge.transformed (db::CplxTrans (layout.dbu ()) * shape.trans ())));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rdb::Item *item = rdb->create_item (rdb_top_cell->id (), cat->id ());
|
|
|
|
|
item->values ().add (value.release ());
|
|
|
|
|
|
|
|
|
|
++progress;
|
|
|
|
|
++shape;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int rdb_index = view ()->add_rdb (rdb.release ());
|
|
|
|
|
view ()->open_rdb_browser (rdb_index, cv_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
MarkerBrowserDialog::menu_activated (const std::string &symbol)
|
|
|
|
|
{
|
|
|
|
|
if (symbol == "marker_browser::show") {
|
|
|
|
|
view ()->deactivate_all_browsers ();
|
|
|
|
|
activate ();
|
|
|
|
|
} else if (symbol == "marker_browser::scan_layers") {
|
|
|
|
|
scan_layer ();
|
|
|
|
|
} else if (symbol == "marker_browser::scan_layers_flat") {
|
|
|
|
|
scan_layer_flat ();
|
|
|
|
|
} else {
|
|
|
|
|
lay::Browser::menu_activated (symbol);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|