From 20b984cc50dc596db98b07c6b5a3a1d07681bda0 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 20 Apr 2019 20:30:12 +0200 Subject: [PATCH] Naming of layers isn't required anymore for connect et al: names are given automatically now. --- src/db/db/dbLayoutToNetlist.cc | 59 ++++- src/db/db/dbLayoutToNetlist.h | 95 +++++++- src/db/db/dbLayoutToNetlistWriter.cc | 22 +- src/db/db/dbLayoutToNetlistWriter.h | 15 +- src/db/db/gsiDeclDbLayoutToNetlist.cc | 52 +++-- src/laybasic/laybasic/gsiDeclLayLayoutView.cc | 50 ++++ src/laybasic/laybasic/layLayoutView.cc | 85 ++++++- src/laybasic/laybasic/layLayoutView.h | 59 ++++- src/laybasic/laybasic/layNetlistBrowser.cc | 86 +++---- .../laybasic/layNetlistBrowserDialog.cc | 214 +++++++----------- .../laybasic/layNetlistBrowserDialog.h | 2 +- .../laybasic/layNetlistBrowserPage.cc | 67 +++++- src/laybasic/laybasic/layNetlistBrowserPage.h | 22 +- 13 files changed, 592 insertions(+), 236 deletions(-) diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index b9bb376ca..34d23c88e 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -26,6 +26,8 @@ #include "dbDeepRegion.h" #include "dbShapeRepository.h" #include "dbCellMapping.h" +#include "dbLayoutToNetlistWriter.h" +#include "dbLayoutToNetlistReader.h" namespace db { @@ -155,7 +157,9 @@ db::Region *LayoutToNetlist::make_text_layer (unsigned int layer_index, const st si.shape_flags (db::ShapeIterator::Texts); std::auto_ptr region (new db::Region (si, dss ())); - register_layer (*region, n); + if (! n.empty ()) { + register_layer (*region, n); + } return region.release (); } @@ -166,7 +170,9 @@ db::Region *LayoutToNetlist::make_polygon_layer (unsigned int layer_index, const si.shape_flags (db::ShapeIterator::Paths | db::ShapeIterator::Polygons | db::ShapeIterator::Boxes); std::auto_ptr region (new db::Region (si, dss ())); - register_layer (*region, n); + if (! n.empty ()) { + register_layer (*region, n); + } return region.release (); } @@ -188,7 +194,7 @@ void LayoutToNetlist::connect (const db::Region &l) } if (! is_persisted (l)) { - throw (tl::Exception (tl::to_string (tr ("Only named layers can be used in intra-layer connectivity for netlist extraction")))); + register_layer (l, make_new_name ()); } // we need to keep a reference, so we can safely delete the region @@ -204,10 +210,10 @@ void LayoutToNetlist::connect (const db::Region &a, const db::Region &b) throw tl::Exception (tl::to_string (tr ("The netlist has already been extracted"))); } if (! is_persisted (a)) { - throw (tl::Exception (tl::to_string (tr ("Only named layers can be used in inter-layer connectivity (first layer) for netlist extraction")))); + register_layer (a, make_new_name ()); } if (! is_persisted (b)) { - throw (tl::Exception (tl::to_string (tr ("Only named layers can be used in inter-layer connectivity (second layer) for netlist extraction")))); + register_layer (b, make_new_name ()); } // we need to keep a reference, so we can safely delete the region @@ -225,7 +231,7 @@ size_t LayoutToNetlist::connect_global (const db::Region &l, const std::string & throw tl::Exception (tl::to_string (tr ("The netlist has already been extracted"))); } if (! is_persisted (l)) { - throw (tl::Exception (tl::to_string (tr ("Only named layers can be used in global connectivity for netlist extraction")))); + register_layer (l, make_new_name ()); } // we need to keep a reference, so we can safely delete the region @@ -343,6 +349,29 @@ void LayoutToNetlist::register_layer (const db::Region ®ion, const std::strin m_name_of_layer [dl.layer ()] = n; } +std::string LayoutToNetlist::make_new_name (const std::string &stem) +{ + int m = std::numeric_limits::max () / 2 + 1; + int n = m; + + std::string name; + while (m > 0) { + + m /= 2; + + name = stem; + name += std::string ("$"); + name += tl::to_string (n - m); + + if (m_named_regions.find (name) == m_named_regions.end ()) { + n -= m; + } + + } + + return name; +} + std::string LayoutToNetlist::name (const db::Region ®ion) const { std::map::const_iterator n = m_name_of_layer.find (layer_of (region)); @@ -939,4 +968,22 @@ db::Region LayoutToNetlist::antenna_check (const db::Region &gate, const db::Reg return db::Region (new db::DeepRegion (dl)); } + +void db::LayoutToNetlist::save (const std::string &path, bool short_format) +{ + tl::OutputStream stream (path); + db::LayoutToNetlistStandardWriter writer (stream, short_format); + set_filename (path); + writer.write (this); +} + +void db::LayoutToNetlist::load (const std::string &path) +{ + tl::InputStream stream (path); + db::LayoutToNetlistStandardReader reader (stream); + set_filename (path); + set_name (stream.filename ()); + reader.read (this); +} + } diff --git a/src/db/db/dbLayoutToNetlist.h b/src/db/db/dbLayoutToNetlist.h index 5003deb03..53c048c15 100644 --- a/src/db/db/dbLayoutToNetlist.h +++ b/src/db/db/dbLayoutToNetlist.h @@ -114,6 +114,73 @@ public: */ ~LayoutToNetlist (); + /** + * @brief Gets the database description + */ + const std::string &description () const + { + return m_description; + } + + /** + * @brief Sets the database description + */ + void set_description (const std::string &description) + { + m_description = description; + } + + /** + * @brief Gets the original file + * + * The original file describes what original file the netlist database + * was derived from. + */ + const std::string &original_file () const + { + return m_original_file; + } + + /** + * @brief Sets the database original file + */ + void set_original_file (const std::string &original_file) + { + m_original_file = original_file; + } + + /** + * @brief Gets the database name + */ + const std::string &name () const + { + return m_name; + } + + /** + * @brief Sets the database name + */ + void set_name (const std::string &name) + { + m_name = name; + } + + /** + * @brief Gets the file name + */ + const std::string &filename () const + { + return m_filename; + } + + /** + * @brief Sets the file name + */ + void set_filename (const std::string &filename) + { + m_filename = filename; + } + /** * @brief Sets the number of threads to use for operations which support multiple threads */ @@ -154,8 +221,7 @@ public: * (see below) enhances readability of backannotated information * if layers are involved. Use this method to attach a name to a region * derived by boolean operations for example. - * Named regions are persisted inside the LayoutToNetlist object. Only - * named regions can be put into "connect". + * Named regions are persisted inside the LayoutToNetlist object. */ void register_layer (const db::Region ®ion, const std::string &name); @@ -264,21 +330,18 @@ public: * a derived layer. Certain limitations apply. It's safe to use * boolean operations for deriving layers. Other operations are applicable as long as they are * capable of delivering hierarchical layers. - * Regions put into "connect" need to be named. */ void connect (const db::Region &l); /** * @brief Defines an inter-layer connection for the given layers. * The conditions mentioned with intra-layer "connect" apply for this method too. - * Regions put into "connect" need to be named. */ void connect (const db::Region &a, const db::Region &b); /** * @brief Connects the given layer with a global net with the given name * Returns the global net ID - * Regions put into "connect" need to be named. */ size_t connect_global (const db::Region &l, const std::string &gn); @@ -531,11 +594,32 @@ public: */ db::Region antenna_check (const db::Region &gate, const db::Region &metal, double ratio, const std::vector > &diodes = std::vector > ()); + /** + * @brief Saves the database to the given path + * + * Currently, the internal format will be used. If "short_format" is true, the short version + * of the format is used. + * + * This is a convenience method. The low-level functionality is the LayoutToNetlistWriter. + */ + void save (const std::string &path, bool short_format); + + /** + * @brief Loads the database from the given path + * + * This is a convenience method. The low-level functionality is the LayoutToNetlistReader. + */ + void load (const std::string &path); + private: // no copying LayoutToNetlist (const db::LayoutToNetlist &other); LayoutToNetlist &operator= (const db::LayoutToNetlist &other); + std::string m_description; + std::string m_name; + std::string m_original_file; + std::string m_filename; db::RecursiveShapeIterator m_iter; std::auto_ptr mp_internal_dss; tl::weak_ptr mp_dss; @@ -556,6 +640,7 @@ private: void build_net_rec (db::cell_index_type ci, size_t cid, db::Layout &target, db::Cell &target_cell, const std::map &lmap, const Net *net, const char *net_cell_name_prefix, const char *cell_name_prefix, const char *device_cell_name_prefix, std::map, db::cell_index_type> &cmap, const ICplxTrans &tr) const; db::DeepLayer deep_layer_of (const db::Region ®ion) const; void ensure_layout () const; + std::string make_new_name (const std::string &stem = std::string ()); }; } diff --git a/src/db/db/dbLayoutToNetlistWriter.cc b/src/db/db/dbLayoutToNetlistWriter.cc index 9508c2fb8..b26a0fa51 100644 --- a/src/db/db/dbLayoutToNetlistWriter.cc +++ b/src/db/db/dbLayoutToNetlistWriter.cc @@ -27,6 +27,26 @@ namespace db { +// ------------------------------------------------------------------------------------------- +// LayoutToNetlistWriterBase implementation + +LayoutToNetlistWriterBase::LayoutToNetlistWriterBase () +{ + // .. nothing yet .. +} + +LayoutToNetlistWriterBase::~LayoutToNetlistWriterBase () +{ + // .. nothing yet .. +} + +void LayoutToNetlistWriterBase::write (const db::LayoutToNetlist *l2n) +{ + do_write (l2n); +} + +// ------------------------------------------------------------------------------------------- + namespace l2n_std_format { @@ -464,7 +484,7 @@ LayoutToNetlistStandardWriter::LayoutToNetlistStandardWriter (tl::OutputStream & // .. nothing yet .. } -void LayoutToNetlistStandardWriter::write (const db::LayoutToNetlist *l2n) +void LayoutToNetlistStandardWriter::do_write (const db::LayoutToNetlist *l2n) { if (m_short_version) { l2n_std_format::std_writer_impl > writer (*mp_stream); diff --git a/src/db/db/dbLayoutToNetlistWriter.h b/src/db/db/dbLayoutToNetlistWriter.h index 117cf62a3..b8f08a844 100644 --- a/src/db/db/dbLayoutToNetlistWriter.h +++ b/src/db/db/dbLayoutToNetlistWriter.h @@ -37,10 +37,16 @@ class LayoutToNetlist; class DB_PUBLIC LayoutToNetlistWriterBase { public: - LayoutToNetlistWriterBase () { } - virtual ~LayoutToNetlistWriterBase () { } + LayoutToNetlistWriterBase (); + virtual ~LayoutToNetlistWriterBase (); - virtual void write (const db::LayoutToNetlist *l2n) = 0; + void write (const db::LayoutToNetlist *l2n); + +protected: + virtual void do_write (const db::LayoutToNetlist *l2n) = 0; + +private: + std::string m_filename; }; /** @@ -52,7 +58,8 @@ class DB_PUBLIC LayoutToNetlistStandardWriter public: LayoutToNetlistStandardWriter (tl::OutputStream &stream, bool short_version); - void write (const db::LayoutToNetlist *l2n); +protected: + void do_write (const db::LayoutToNetlist *l2n); private: tl::OutputStream *mp_stream; diff --git a/src/db/db/gsiDeclDbLayoutToNetlist.cc b/src/db/db/gsiDeclDbLayoutToNetlist.cc index 070980970..4ad93e599 100644 --- a/src/db/db/gsiDeclDbLayoutToNetlist.cc +++ b/src/db/db/gsiDeclDbLayoutToNetlist.cc @@ -22,8 +22,6 @@ #include "gsiDecl.h" #include "dbLayoutToNetlist.h" -#include "dbLayoutToNetlistWriter.h" -#include "dbLayoutToNetlistReader.h" #include "tlStream.h" #include "tlVariant.h" @@ -82,20 +80,6 @@ static void build_all_nets (const db::LayoutToNetlist *l2n, const db::CellMappin l2n->build_all_nets (cmap, target, lmap, net_cell_name_prefix.is_nil () ? 0 : np.c_str (), circuit_cell_name_prefix.is_nil () ? 0 : cp.c_str (), device_cell_name_prefix.is_nil () ? 0 : dp.c_str ()); } -static void write_l2n (const db::LayoutToNetlist *l2n, const std::string &path, bool short_format) -{ - tl::OutputStream stream (path); - db::LayoutToNetlistStandardWriter writer (stream, short_format); - writer.write (l2n); -} - -static void read_l2n (db::LayoutToNetlist *l2n, const std::string &path) -{ - tl::InputStream stream (path); - db::LayoutToNetlistStandardReader reader (stream); - reader.read (l2n); -} - static std::vector l2n_layer_names (const db::LayoutToNetlist *l2n) { std::vector ln; @@ -197,11 +181,34 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", gsi::method ("max_vertex_count", &db::LayoutToNetlist::max_vertex_count, "See \\max_vertex_count= for details about this attribute." ) + + gsi::method ("name", (const std::string &(db::LayoutToNetlist::*) () const) &db::LayoutToNetlist::name, + "@brief Gets the name of the database\n" + ) + + gsi::method ("name=", &db::LayoutToNetlist::set_name, + "@brief Sets the name of the database\n" + ) + + gsi::method ("description", (const std::string &(db::LayoutToNetlist::*) () const) &db::LayoutToNetlist::name, + "@brief Gets the description of the database\n" + ) + + gsi::method ("description=", &db::LayoutToNetlist::set_name, + "@brief Sets the description of the database\n" + ) + + gsi::method ("filename", &db::LayoutToNetlist::filename, + "@brief Gets the file name of the database\n" + "The filename is the name under which the database is stored or empty if it is not associated with a file." + ) + + gsi::method ("original_file", &db::LayoutToNetlist::original_file, + "@brief Gets the original file name of the database\n" + "The original filename is the layout file from which the netlist DB was created." + ) + + gsi::method ("original_file=", &db::LayoutToNetlist::set_original_file, + "@brief Sets the original file name of the database\n" + ) + gsi::method ("name", (std::string (db::LayoutToNetlist::*) (const db::Region ®ion) const) &db::LayoutToNetlist::name, gsi::arg ("l"), - "@brief Get the name of the given layer\n" + "@brief Gets the name of the given layer\n" ) + gsi::method ("name", (std::string (db::LayoutToNetlist::*) (unsigned int) const) &db::LayoutToNetlist::name, gsi::arg ("l"), - "@brief Get the name of the given layer (by index)\n" + "@brief Gets the name of the given layer (by index)\n" ) + gsi::method ("register", (void (db::LayoutToNetlist::*) (const db::Region ®ion, const std::string &)) &db::LayoutToNetlist::register_layer, gsi::arg ("l"), gsi::arg ("n"), "@brief Names the given layer\n" @@ -210,8 +217,9 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "\n" "Naming a layer allows the system to indicate the layer in various contexts, i.e. " "when writing the data to a file. Named layers are also persisted inside the LayoutToNetlist object. " - "They are not discarded when the Region object is destroyed. Only named layers can be put into " - "\\connect.\n" + "They are not discarded when the Region object is destroyed.\n" + "\n" + "If required, the system will assign a name automatically." ) + gsi::method_ext ("layer_names", &l2n_layer_names, "@brief Returns a list of names of the layer kept inside the LayoutToNetlist object." @@ -425,11 +433,11 @@ Class decl_dbLayoutToNetlist ("db", "LayoutToNetlist", "This variant accepts a database-unit location. The location is given in the\n" "coordinate space of the initial cell.\n" ) + - gsi::method_ext ("write", &write_l2n, gsi::arg ("path"), gsi::arg ("short_format", false), + gsi::method ("write", &db::LayoutToNetlist::save, gsi::arg ("path"), gsi::arg ("short_format", false), "@brief Writes the extracted netlist to a file.\n" "This method employs the native format of KLayout.\n" ) + - gsi::method_ext ("read", &read_l2n, gsi::arg ("path"), + gsi::method ("read", &db::LayoutToNetlist::load, gsi::arg ("path"), "@brief Reads the extracted netlist from the file.\n" "This method employs the native format of KLayout.\n" ) + diff --git a/src/laybasic/laybasic/gsiDeclLayLayoutView.cc b/src/laybasic/laybasic/gsiDeclLayLayoutView.cc index 77ae960f4..f4093f94c 100644 --- a/src/laybasic/laybasic/gsiDeclLayLayoutView.cc +++ b/src/laybasic/laybasic/gsiDeclLayLayoutView.cc @@ -28,6 +28,7 @@ #include "layDitherPattern.h" #include "layLineStyles.h" #include "dbSaveLayoutOptions.h" +#include "dbLayoutToNetlist.h" #include "tlStream.h" #if defined(HAVE_QTBINDINGS) @@ -196,6 +197,13 @@ static unsigned int create_rdb (lay::LayoutView *view, const std::string &name) return view->add_rdb (db); } +static unsigned int create_l2ndb (lay::LayoutView *view, const std::string &name) +{ + db::LayoutToNetlist *db = new db::LayoutToNetlist (); + db->set_name (name); + return view->add_l2ndb (db); +} + // this binding returns a const pointer which is not converted into a copy by RBA static lay::LayerPropertiesNodeRef insert_layer1 (lay::LayoutView *view, const lay::LayerPropertiesConstIterator &iter, const lay::LayerProperties &props) { @@ -1427,6 +1435,48 @@ Class decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou "The marker browser is opened showing the report database with the index given by \"rdb_index\".\n" "It will be attached (i.e. navigate to) the layout with the given cellview index in \"cv_index\".\n" ) + + gsi::event ("on_l2ndb_list_changed", &lay::LayoutView::l2ndb_list_changed_event, + "@brief An event that is triggered the list of netlist databases is changed\n" + "\n" + "If a netlist database is added or removed, this event is triggered.\n" + "\n" + "This method has been added in version 0.26." + ) + + gsi::method ("num_l2ndbs", &lay::LayoutView::num_l2ndbs, + "@brief Gets the number of netlist databases loaded into this view\n" + "@return The number of \\LayoutToNetlist objects present in this view\n" + "\n" + "This method has been added in version 0.26." + ) + + gsi::method ("remove_l2ndb", &lay::LayoutView::remove_l2ndb, gsi::arg ("index"), + "@brief Removes a netlist database with the given index\n" + "@param The index of the netlist database to remove from this view" + "\n" + "This method has been added in version 0.26." + ) + + gsi::method ("l2ndb", (db::LayoutToNetlist *(lay::LayoutView::*) (int index)) &lay::LayoutView::get_l2ndb, gsi::arg ("index"), + "@brief Gets the netlist database with the given index\n" + "@return The \\LayoutToNetlist object or nil if the index is not valid" + "\n" + "This method has been added in version 0.26." + ) + + gsi::method_ext ("create_l2ndb", &create_l2ndb, gsi::arg ("name"), + "@brief Creates a new netlist database and returns the index of the new database\n" + "@param name The name of the new netlist database\n" + "@return The index of the new database\n" + "This method returns an index of the new netlist database. Use \\l2ndb to get the actual object. " + "If a netlist database with the given name already exists, a unique name will be created.\n" + "The name will be replaced by the file name when a file is loaded into the netlist database.\n" + "\n" + "This method has been added in version 0.26." + ) + + gsi::method ("show_l2ndb", &lay::LayoutView::open_l2ndb_browser, gsi::arg ("l2ndb_index"), gsi::arg ("cv_index"), + "@brief Shows a netlist database in the marker browser on a certain layout\n" + "The netlist browser is opened showing the netlist database with the index given by \"l2ndb_index\".\n" + "It will be attached (i.e. navigate to) the layout with the given cellview index in \"cv_index\".\n" + "\n" + "This method has been added in version 0.26." + ) + // HINT: the cast is important to direct GSI to the LayoutView method rather than the // Plugin method (in which case we get a segmentation violation ..) // TODO: this method belongs to the Plugin interface and should be located there. diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 9f6b1513a..92b128231 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -66,6 +66,7 @@ #include "layRedrawThreadWorker.h" #include "layParsedLayerSource.h" #include "layBookmarkManagementForm.h" +#include "layNetlistBrowserDialog.h" #include "dbLayout.h" #include "dbLayoutUtils.h" #include "dbRecursiveShapeIterator.h" @@ -73,6 +74,7 @@ #include "dbEdgeProcessor.h" #include "rdb.h" #include "rdbMarkerBrowserDialog.h" +#include "dbLayoutToNetlist.h" #include "tlXMLParser.h" #include "gsi.h" #include "gtf.h" @@ -568,6 +570,7 @@ LayoutView::~LayoutView () cellviews_changed_event.clear (); cellview_changed_event.clear (); rdb_list_changed_event.clear (); + l2ndb_list_changed_event.clear (); file_open_event.clear (); hier_changed_event.clear (); geom_changed_event.clear (); @@ -581,6 +584,11 @@ LayoutView::~LayoutView () remove_rdb (0); } + // remove all L2N DB's + while (num_l2ndbs () > 0) { + remove_l2ndb (0); + } + // delete layer lists std::vector layer_properties_lists; layer_properties_lists.swap (m_layer_properties_lists); @@ -7074,19 +7082,17 @@ LayoutView::cm_clear_layer () } } -unsigned int -LayoutView::add_rdb (rdb::Database *rdb) +template +static void make_unique_name (T *object, Iter from, Iter to) { - // make the name unique - - std::string n (rdb->name ()); + std::string n (object->name ()); int nn = 0; do { bool found = false; - for (unsigned int i = 0; i < num_rdbs () && !found; ++i) { - if (get_rdb (i)->name () == n) { + for (Iter i = from; i != to && !found; ++i) { + if ((*i)->name () == n) { found = true; } } @@ -7095,12 +7101,67 @@ LayoutView::add_rdb (rdb::Database *rdb) break; } - n = rdb->name () + tl::sprintf ("[%d]", ++nn); + n = object->name () + tl::sprintf ("[%d]", ++nn); } while (1); - rdb->set_name (n); + object->set_name (n); +} +unsigned int +LayoutView::add_l2ndb (db::LayoutToNetlist *l2ndb) +{ + make_unique_name (l2ndb, m_l2ndbs.begin (), m_l2ndbs.end ()); + m_l2ndbs.push_back (l2ndb); + + l2ndb_list_changed_event (); + + return (unsigned int)(m_l2ndbs.size () - 1); +} + +db::LayoutToNetlist * +LayoutView::get_l2ndb (int index) +{ + if (index >= 0 && index < int (m_l2ndbs.size ())) { + return m_l2ndbs [index]; + } else { + return 0; + } +} + +void +LayoutView::open_l2ndb_browser (int l2ndb_index, int cv_index) +{ + lay::NetlistBrowserDialog *l2ndb_browser = get_plugin (); + if (l2ndb_browser) { + l2ndb_browser->load (l2ndb_index, cv_index); + } +} + +const db::LayoutToNetlist * +LayoutView::get_l2ndb (int index) const +{ + if (index >= 0 && index < int (m_l2ndbs.size ())) { + return m_l2ndbs [index]; + } else { + return 0; + } +} + +void +LayoutView::remove_l2ndb (unsigned int index) +{ + if (index < (unsigned int) (m_l2ndbs.size ())) { + delete m_l2ndbs [index]; + m_l2ndbs.erase (m_l2ndbs.begin () + index); + l2ndb_list_changed_event (); + } +} + +unsigned int +LayoutView::add_rdb (rdb::Database *rdb) +{ + make_unique_name (rdb, m_l2ndbs.begin (), m_l2ndbs.end ()); m_rdbs.push_back (rdb); rdb_list_changed_event (); @@ -7118,7 +7179,7 @@ LayoutView::get_rdb (int index) } } -void +void LayoutView::open_rdb_browser (int rdb_index, int cv_index) { rdb::MarkerBrowserDialog *rdb_browser = get_plugin (); @@ -7137,7 +7198,7 @@ LayoutView::get_rdb (int index) const } } -void +void LayoutView::remove_rdb (unsigned int index) { if (index < (unsigned int) (m_rdbs.size ())) { @@ -7147,7 +7208,7 @@ LayoutView::remove_rdb (unsigned int index) } } -QSize +QSize LayoutView::sizeHint () const { if ((m_options & LV_Naked) != 0) { diff --git a/src/laybasic/laybasic/layLayoutView.h b/src/laybasic/laybasic/layLayoutView.h index 8802dc72d..c2e3caf0b 100644 --- a/src/laybasic/laybasic/layLayoutView.h +++ b/src/laybasic/laybasic/layLayoutView.h @@ -62,6 +62,7 @@ namespace db { class Layout; class Manager; class SaveLayoutOptions; + class LayoutToNetlist; } namespace lay { @@ -2293,7 +2294,7 @@ public: void remove_rdb (unsigned int index); /** - * @brief Get the number of databases + * @brief Get the number of marker databases */ unsigned int num_rdbs () const { @@ -2307,6 +2308,61 @@ public: */ tl::Event rdb_list_changed_event; + /** + * @brief Add a Netlist database + * + * The layout view will become owner of the database. + * + * @param l2ndb The database to add + * @return The index of the database + */ + unsigned int add_l2ndb (db::LayoutToNetlist *l2ndb); + + /** + * @brief Get the netlist database by index + * + * @param index The index of the database + * @return A pointer to the database or 0 if the index was not valid. + */ + db::LayoutToNetlist *get_l2ndb (int index); + + /** + * @brief Get the netlist database by index (const version) + * + * @param index The index of the database + * @return A pointer to the database or 0 if the index was not valid. + */ + const db::LayoutToNetlist *get_l2ndb (int index) const; + + /** + * @brief Open the L2NDB browser for a given database and associated cv index + */ + void open_l2ndb_browser (int l2ndb_index, int cv_index); + + /** + * @brief Remove the netlist database with the given index + * + * This will release the netlist database at the given index. The list + * will be reduced by that element. This means, that the following elements + * will have different indicies. + */ + void remove_l2ndb (unsigned int index); + + /** + * @brief Get the number of netlist databases + */ + unsigned int num_l2ndbs () const + { + return (unsigned int) m_l2ndbs.size (); + } + + /** + * @brief An event signalling a change in the netlist database list + * + * If netlist databases are added or removed, this event is triggered. + */ + tl::Event l2ndb_list_changed_event; + /** * @brief Deliver a size hint (reimplementation of QWidget) */ @@ -2635,6 +2691,7 @@ private: std::vector > m_hidden_cells; std::string m_title; tl::vector m_rdbs; + tl::vector m_l2ndbs; std::string m_def_lyp_file; bool m_add_other_layers; bool m_always_show_source; diff --git a/src/laybasic/laybasic/layNetlistBrowser.cc b/src/laybasic/laybasic/layNetlistBrowser.cc index 1afa98b86..b9f388fc4 100644 --- a/src/laybasic/laybasic/layNetlistBrowser.cc +++ b/src/laybasic/laybasic/layNetlistBrowser.cc @@ -34,17 +34,17 @@ namespace lay // ------------------------------------------------------------ // Declaration of the configuration options -std::string cfg_l2n_context_mode ("l2n-context-mode"); -std::string cfg_l2n_show_all ("l2n-show-all"); -std::string cfg_l2n_window_state ("l2n-window-state"); -std::string cfg_l2n_window_mode ("l2n-window-mode"); -std::string cfg_l2n_window_dim ("l2n-window-dim"); -std::string cfg_l2n_max_marker_count ("l2n-max-marker-count"); -std::string cfg_l2n_highlight_color ("l2n-highlight-color"); -std::string cfg_l2n_highlight_line_width ("l2n-highlight-line-width"); -std::string cfg_l2n_highlight_vertex_size ("l2n-highlight-vertex-size"); -std::string cfg_l2n_highlight_halo ("l2n-highlight-halo"); -std::string cfg_l2n_highlight_dither_pattern ("l2n-highlight-dither-pattern"); +std::string cfg_l2ndb_context_mode ("l2n-context-mode"); +std::string cfg_l2ndb_show_all ("l2n-show-all"); +std::string cfg_l2ndb_window_state ("l2n-window-state"); +std::string cfg_l2ndb_window_mode ("l2n-window-mode"); +std::string cfg_l2ndb_window_dim ("l2n-window-dim"); +std::string cfg_l2ndb_max_marker_count ("l2n-max-marker-count"); +std::string cfg_l2ndb_highlight_color ("l2n-highlight-color"); +std::string cfg_l2ndb_highlight_line_width ("l2n-highlight-line-width"); +std::string cfg_l2ndb_highlight_vertex_size ("l2n-highlight-vertex-size"); +std::string cfg_l2ndb_highlight_halo ("l2n-highlight-halo"); +std::string cfg_l2ndb_highlight_dither_pattern ("l2n-highlight-dither-pattern"); // ------------------------------------------------------------ @@ -136,22 +136,22 @@ NetlistBrowserConfigPage::setup (lay::PluginRoot *root) { // context mode lay::NetlistBrowserConfig::net_context_mode_type cmode = lay::NetlistBrowserConfig::NetlistTop; - root->config_get (cfg_l2n_context_mode, cmode, NetlistBrowserContextModeConverter ()); + root->config_get (cfg_l2ndb_context_mode, cmode, NetlistBrowserContextModeConverter ()); cbx_context->setCurrentIndex (int (cmode)); // window mode lay::NetlistBrowserConfig::net_window_type wmode = lay::NetlistBrowserConfig::FitNet; - root->config_get (cfg_l2n_window_mode, wmode, NetlistBrowserWindowModeConverter ()); + root->config_get (cfg_l2ndb_window_mode, wmode, NetlistBrowserWindowModeConverter ()); cbx_window->setCurrentIndex (int (wmode)); // window dimension double wdim = 1.0; - root->config_get (cfg_l2n_window_dim, wdim); + root->config_get (cfg_l2ndb_window_dim, wdim); le_window->setText (tl::to_qstring (tl::to_string (wdim))); // max. marker count unsigned int max_marker_count = 1000; - root->config_get (cfg_l2n_max_marker_count, max_marker_count); + root->config_get (cfg_l2ndb_max_marker_count, max_marker_count); le_max_markers->setText (tl::to_qstring (tl::to_string (max_marker_count))); // enable controls @@ -173,10 +173,10 @@ NetlistBrowserConfigPage::commit (lay::PluginRoot *root) unsigned int max_markers_count = 1000; tl::from_string (tl::to_string (le_max_markers->text ()), max_markers_count); - root->config_set (cfg_l2n_context_mode, lay::NetlistBrowserConfig::net_context_mode_type (cbx_context->currentIndex ()), NetlistBrowserContextModeConverter ()); - root->config_set (cfg_l2n_window_mode, lay::NetlistBrowserConfig::net_window_type (cbx_window->currentIndex ()), NetlistBrowserWindowModeConverter ()); - root->config_set (cfg_l2n_window_dim, dim); - root->config_set (cfg_l2n_max_marker_count, max_markers_count); + root->config_set (cfg_l2ndb_context_mode, lay::NetlistBrowserConfig::net_context_mode_type (cbx_context->currentIndex ()), NetlistBrowserContextModeConverter ()); + root->config_set (cfg_l2ndb_window_mode, lay::NetlistBrowserConfig::net_window_type (cbx_window->currentIndex ()), NetlistBrowserWindowModeConverter ()); + root->config_set (cfg_l2ndb_window_dim, dim); + root->config_set (cfg_l2ndb_max_marker_count, max_markers_count); } // ------------------------------------------------------------ @@ -193,12 +193,12 @@ NetlistBrowserConfigPage2::setup (lay::PluginRoot *root) { // marker color QColor color; - root->config_get (cfg_l2n_highlight_color, color, lay::ColorConverter ()); + root->config_get (cfg_l2ndb_highlight_color, color, lay::ColorConverter ()); color_pb->set_color (color); // marker line width int lw = 0; - root->config_get (cfg_l2n_highlight_line_width, lw); + root->config_get (cfg_l2ndb_highlight_line_width, lw); if (lw < 0) { lw_le->setText (QString ()); } else { @@ -207,7 +207,7 @@ NetlistBrowserConfigPage2::setup (lay::PluginRoot *root) // marker vertex size int vs = 0; - root->config_get (cfg_l2n_highlight_vertex_size, vs); + root->config_get (cfg_l2ndb_highlight_vertex_size, vs); if (vs < 0) { vs_le->setText (QString ()); } else { @@ -216,12 +216,12 @@ NetlistBrowserConfigPage2::setup (lay::PluginRoot *root) // stipple pattern int dp = 0; - root->config_get (cfg_l2n_highlight_dither_pattern, dp); + root->config_get (cfg_l2ndb_highlight_dither_pattern, dp); stipple_pb->set_dither_pattern (dp); // halo int halo = 0; - root->config_get (cfg_l2n_highlight_halo, halo); + root->config_get (cfg_l2ndb_highlight_halo, halo); halo_cb->setCheckState (halo < 0 ? Qt::PartiallyChecked : (halo ? Qt::Checked : Qt::Unchecked)); } @@ -229,36 +229,36 @@ void NetlistBrowserConfigPage2::commit (lay::PluginRoot *root) { QColor color (color_pb->get_color ()); - root->config_set (cfg_l2n_highlight_color, color, lay::ColorConverter ()); + root->config_set (cfg_l2ndb_highlight_color, color, lay::ColorConverter ()); if (lw_le->text ().isEmpty ()) { - root->config_set (cfg_l2n_highlight_line_width, -1); + root->config_set (cfg_l2ndb_highlight_line_width, -1); } else { try { int s; tl::from_string (tl::to_string (lw_le->text ()), s); - root->config_set (cfg_l2n_highlight_line_width, s); + root->config_set (cfg_l2ndb_highlight_line_width, s); } catch (...) { } } if (vs_le->text ().isEmpty ()) { - root->config_set (cfg_l2n_highlight_vertex_size, -1); + root->config_set (cfg_l2ndb_highlight_vertex_size, -1); } else { try { int s; tl::from_string (tl::to_string (vs_le->text ()), s); - root->config_set (cfg_l2n_highlight_vertex_size, s); + root->config_set (cfg_l2ndb_highlight_vertex_size, s); } catch (...) { } } - root->config_set (cfg_l2n_highlight_dither_pattern, stipple_pb->dither_pattern ()); + root->config_set (cfg_l2ndb_highlight_dither_pattern, stipple_pb->dither_pattern ()); if (halo_cb->checkState () == Qt::PartiallyChecked) { - root->config_set (cfg_l2n_highlight_halo, -1); + root->config_set (cfg_l2ndb_highlight_halo, -1); } else if (halo_cb->checkState () == Qt::Unchecked) { - root->config_set (cfg_l2n_highlight_halo, 0); + root->config_set (cfg_l2ndb_highlight_halo, 0); } else if (halo_cb->checkState () == Qt::Checked) { - root->config_set (cfg_l2n_highlight_halo, 1); + root->config_set (cfg_l2ndb_highlight_halo, 1); } } @@ -271,16 +271,16 @@ class NetlistBrowserPluginDeclaration public: virtual void get_options (std::vector < std::pair > &options) const { - options.push_back (std::pair (cfg_l2n_context_mode, "netlist-top")); - options.push_back (std::pair (cfg_l2n_window_mode, "fit-net")); - options.push_back (std::pair (cfg_l2n_window_state, "")); - options.push_back (std::pair (cfg_l2n_window_dim, "1.0")); - options.push_back (std::pair (cfg_l2n_max_marker_count, "1000")); - options.push_back (std::pair (cfg_l2n_highlight_color, lay::ColorConverter ().to_string (QColor ()))); - options.push_back (std::pair (cfg_l2n_highlight_line_width, "-1")); - options.push_back (std::pair (cfg_l2n_highlight_vertex_size, "-1")); - options.push_back (std::pair (cfg_l2n_highlight_halo, "-1")); - options.push_back (std::pair (cfg_l2n_highlight_dither_pattern, "-1")); + options.push_back (std::pair (cfg_l2ndb_context_mode, "netlist-top")); + options.push_back (std::pair (cfg_l2ndb_window_mode, "fit-net")); + options.push_back (std::pair (cfg_l2ndb_window_state, "")); + options.push_back (std::pair (cfg_l2ndb_window_dim, "1.0")); + options.push_back (std::pair (cfg_l2ndb_max_marker_count, "1000")); + options.push_back (std::pair (cfg_l2ndb_highlight_color, lay::ColorConverter ().to_string (QColor ()))); + options.push_back (std::pair (cfg_l2ndb_highlight_line_width, "-1")); + options.push_back (std::pair (cfg_l2ndb_highlight_vertex_size, "-1")); + options.push_back (std::pair (cfg_l2ndb_highlight_halo, "-1")); + options.push_back (std::pair (cfg_l2ndb_highlight_dither_pattern, "-1")); } virtual std::vector > config_pages (QWidget *parent) const diff --git a/src/laybasic/laybasic/layNetlistBrowserDialog.cc b/src/laybasic/laybasic/layNetlistBrowserDialog.cc index 177d40b6f..65949b6fc 100644 --- a/src/laybasic/laybasic/layNetlistBrowserDialog.cc +++ b/src/laybasic/laybasic/layNetlistBrowserDialog.cc @@ -29,7 +29,7 @@ #include "layConverters.h" #include "layQtTools.h" #include "layConfigurationDialog.h" -#include "dbLayoutUtils.h" +#include "dbLayoutToNetlist.h" #include "dbRecursiveShapeIterator.h" #include @@ -40,17 +40,17 @@ namespace lay { -extern std::string cfg_l2n_context_mode; -extern std::string cfg_l2n_show_all; -extern std::string cfg_l2n_window_state; -extern std::string cfg_l2n_window_mode; -extern std::string cfg_l2n_window_dim; -extern std::string cfg_l2n_max_marker_count; -extern std::string cfg_l2n_highlight_color; -extern std::string cfg_l2n_highlight_line_width; -extern std::string cfg_l2n_highlight_vertex_size; -extern std::string cfg_l2n_highlight_halo; -extern std::string cfg_l2n_highlight_dither_pattern; +extern std::string cfg_l2ndb_context_mode; +extern std::string cfg_l2ndb_show_all; +extern std::string cfg_l2ndb_window_state; +extern std::string cfg_l2ndb_window_mode; +extern std::string cfg_l2ndb_window_dim; +extern std::string cfg_l2ndb_max_marker_count; +extern std::string cfg_l2ndb_highlight_color; +extern std::string cfg_l2ndb_highlight_line_width; +extern std::string cfg_l2ndb_highlight_vertex_size; +extern std::string cfg_l2ndb_highlight_halo; +extern std::string cfg_l2ndb_highlight_dither_pattern; NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutView *vw) : lay::Browser (root, vw), @@ -73,7 +73,7 @@ NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutVi if (view ()) { view ()->cellviews_changed_event.add (this, &NetlistBrowserDialog::cellviews_changed); view ()->cellview_changed_event.add (this, &NetlistBrowserDialog::cellview_changed); - // @@@view ()->l2n_list_changed_event.add (this, &NetlistBrowserDialog::l2ndbs_changed); + view ()->l2ndb_list_changed_event.add (this, &NetlistBrowserDialog::l2ndbs_changed); } m_open_action = new QAction (QObject::tr ("Open"), file_menu); @@ -129,37 +129,11 @@ NetlistBrowserDialog::unload_all_clicked () { BEGIN_PROTECTED -#if 0 // @@@ - 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); + while (view ()->num_l2ndbs () > 0) { + view ()->remove_l2ndb (0); } l2ndb_index_changed (-1); -#endif END_PROTECTED } @@ -169,39 +143,21 @@ NetlistBrowserDialog::unload_clicked () { BEGIN_PROTECTED -#if 0 // @@@ - if (m_l2n_index < int (view ()->num_rdbs ()) && m_l2n_index >= 0) { - - rdb::Database *rdb = view ()->get_rdb (m_l2n_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; - } - - } + if (m_l2n_index < int (view ()->num_l2ndbs ()) && m_l2n_index >= 0) { int new_l2n_index = m_l2n_index; - view ()->remove_rdb (m_l2n_index); + view ()->remove_l2ndb (m_l2n_index); // try to use another rbd ... - if (new_l2n_index >= int (view ()->num_rdbs ())) { + if (new_l2n_index >= int (view ()->num_l2ndbs ())) { --new_l2n_index; } - if (new_l2n_index < int (view ()->num_rdbs ()) && new_l2n_index >= 0) { + if (new_l2n_index < int (view ()->num_l2ndbs ()) && new_l2n_index >= 0) { l2ndb_index_changed (new_l2n_index); } } -#endif END_PROTECTED } @@ -250,26 +206,23 @@ NetlistBrowserDialog::saveas_clicked () { BEGIN_PROTECTED -#if 0 // @@@ - if (m_l2n_index < int (view ()->num_rdbs ()) && m_l2n_index >= 0) { + if (m_l2n_index < int (view ()->num_l2ndbs ()) && m_l2n_index >= 0) { - rdb::Database *rdb = view ()->get_rdb (m_l2n_index); - if (rdb) { + db::LayoutToNetlist *l2ndb = view ()->get_l2ndb (m_l2n_index); + if (l2ndb) { // prepare and open the file dialog - lay::FileDialog save_dialog (this, tl::to_string (QObject::tr ("Save Net Database")), "KLayout RDB files (*.lyrdb)"); - std::string fn (rdb->filename ()); + lay::FileDialog save_dialog (this, tl::to_string (QObject::tr ("Save Netlist Database")), "KLayout L2N DB files (*.l2n)"); + std::string fn (l2ndb->filename ()); if (save_dialog.get_save (fn)) { - rdb->save (fn); - rdb->reset_modified (); + l2ndb->save (fn, true); } } } -#endif END_PROTECTED } @@ -279,20 +232,18 @@ NetlistBrowserDialog::reload_clicked () { BEGIN_PROTECTED -#if 0 // @@@ - if (m_l2n_index < int (view ()->num_rdbs ()) && m_l2n_index >= 0) { + if (m_l2n_index < int (view ()->num_l2ndbs ()) && m_l2n_index >= 0) { - rdb::Database *rdb = view ()->get_rdb (m_l2n_index); - if (rdb && ! rdb->filename ().empty ()) { + db::LayoutToNetlist *l2ndb = view ()->get_l2ndb (m_l2n_index); + if (l2ndb && ! l2ndb->filename ().empty ()) { - browser_frame->set_rdb (0); - rdb->load (rdb->filename ()); - browser_frame->set_rdb (rdb); + browser_frame->set_l2ndb (0); + l2ndb->load (l2ndb->filename ()); + browser_frame->set_l2ndb (l2ndb); } } -#endif END_PROTECTED } @@ -302,27 +253,30 @@ NetlistBrowserDialog::open_clicked () { BEGIN_PROTECTED -#if 0 // @@@ - // collect the formats available ... std::string fmts = tl::to_string (QObject::tr ("All files (*)")); +#if 0 // @@@ would be good to have this: + // collect the formats available ... for (tl::Registrar::iterator rdr = tl::Registrar::begin (); rdr != tl::Registrar::end (); ++rdr) { fmts += ";;" + rdr->file_format (); } +#else + fmts += ";;L2N DB files (*.l2n)"; + // @@@ TODO: add plain spice +#endif // prepare and open the file dialog - lay::FileDialog open_dialog (this, tl::to_string (QObject::tr ("Marker Database File")), fmts); + lay::FileDialog open_dialog (this, tl::to_string (QObject::tr ("Netlist Database File")), fmts); if (open_dialog.get_open (m_open_filename)) { - std::auto_ptr db (new rdb::Database ()); + std::auto_ptr db (new db::LayoutToNetlist ()); db->load (m_open_filename); - int l2n_index = view ()->add_rdb (db.release ()); - l2n_cb->setCurrentIndex (l2n_index); + int l2n_index = view ()->add_l2ndb (db.release ()); + l2ndb_cb->setCurrentIndex (l2n_index); // it looks like the setCurrentIndex does not issue this signal: l2ndb_index_changed (l2n_index); } -#endif END_PROTECTED } @@ -334,23 +288,23 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val bool taken = true; bool show_all = browser_frame->show_all (); - if (name == cfg_l2n_context_mode) { + if (name == cfg_l2ndb_context_mode) { NetlistBrowserConfig::net_context_mode_type context = m_context; NetlistBrowserContextModeConverter ().from_string (value, context); need_update = lay::test_and_set (m_context, context); - } else if (name == cfg_l2n_show_all) { + } else if (name == cfg_l2ndb_show_all) { tl::from_string (value, show_all); - } else if (name == cfg_l2n_window_mode) { + } else if (name == cfg_l2ndb_window_mode) { NetlistBrowserConfig::net_window_type window = m_window; NetlistBrowserWindowModeConverter ().from_string (value, window); need_update = lay::test_and_set (m_window, window); - } else if (name == cfg_l2n_window_dim) { + } else if (name == cfg_l2ndb_window_dim) { double wdim = m_window_dim; tl::from_string (value, wdim); @@ -359,13 +313,13 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val need_update = true; } - } else if (name == cfg_l2n_max_marker_count) { + } else if (name == cfg_l2ndb_max_marker_count) { unsigned int mc = 0; tl::from_string (value, mc); need_update = lay::test_and_set (m_max_shape_count, mc); - } else if (name == cfg_l2n_highlight_color) { + } else if (name == cfg_l2ndb_highlight_color) { QColor color; if (! value.empty ()) { @@ -377,7 +331,7 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val need_update = true; } - } else if (name == cfg_l2n_highlight_line_width) { + } else if (name == cfg_l2ndb_highlight_line_width) { int lw = 0; tl::from_string (value, lw); @@ -387,7 +341,7 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val need_update = true; } - } else if (name == cfg_l2n_highlight_vertex_size) { + } else if (name == cfg_l2ndb_highlight_vertex_size) { int vs = 0; tl::from_string (value, vs); @@ -397,7 +351,7 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val need_update = true; } - } else if (name == cfg_l2n_highlight_halo) { + } else if (name == cfg_l2ndb_highlight_halo) { int halo = 0; tl::from_string (value, halo); @@ -407,7 +361,7 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val need_update = true; } - } else if (name == cfg_l2n_highlight_dither_pattern) { + } else if (name == cfg_l2ndb_highlight_dither_pattern) { int dp = 0; tl::from_string (value, dp); @@ -433,10 +387,9 @@ NetlistBrowserDialog::configure (const std::string &name, const std::string &val } void -NetlistBrowserDialog::load (int l2n_index, int cv_index) +NetlistBrowserDialog::load (int l2ndb_index, int cv_index) { -#if 0 // @@@ TODO: implement - if (! view ()->get_rdb (l2n_index)) { + if (! view ()->get_l2ndb (l2ndb_index)) { return; } @@ -447,39 +400,36 @@ NetlistBrowserDialog::load (int l2n_index, int cv_index) } // set the new references (by name) - m_l2n_name = view ()->get_rdb (l2n_index)->name (); + m_l2ndb_name = view ()->get_l2ndb (l2ndb_index)->name (); // force an update - rdbs_changed (); + l2ndbs_changed (); cellviews_changed (); activate (); -#endif } void NetlistBrowserDialog::l2ndbs_changed () { -#if 0 // @@@ TODO: implement int l2n_index = -1; - l2n_cb->clear (); + l2ndb_cb->clear (); - for (unsigned int i = 0; i < view ()->num_rdbs (); ++i) { - const rdb::Database *rdb = view ()->get_rdb (i); - l2n_cb->addItem (tl::to_qstring (rdb->name ())); - if (rdb->name () == m_l2n_name) { + for (unsigned int i = 0; i < view ()->num_l2ndbs (); ++i) { + const db::LayoutToNetlist *l2ndb = view ()->get_l2ndb (i); + l2ndb_cb->addItem (tl::to_qstring (l2ndb->name ())); + if (l2ndb->name () == m_l2ndb_name) { l2n_index = i; } } // force an update m_l2n_index = l2n_index; - l2n_cb->setCurrentIndex (l2n_index); + l2ndb_cb->setCurrentIndex (l2n_index); if (active ()) { update_content (); } -#endif } void @@ -532,10 +482,9 @@ NetlistBrowserDialog::cv_index_changed (int index) void NetlistBrowserDialog::activated () { -#if 0 // @@@ TODO: implement std::string state; if (lay::PluginRoot::instance ()) { - lay::PluginRoot::instance ()->config_get (cfg_l2n_window_state, state); + lay::PluginRoot::instance ()->config_get (cfg_l2ndb_window_state, state); } lay::restore_dialog_state (this, state); @@ -545,42 +494,40 @@ NetlistBrowserDialog::activated () m_cv_index = view ()->active_cellview_index (); } - if (m_l2n_index < 0 && view ()->get_rdb (0) != 0) { + if (m_l2n_index < 0 && view ()->get_l2ndb (0) != 0) { - m_l2n_name = view ()->get_rdb (0)->name (); - rdbs_changed (); + m_l2ndb_name = view ()->get_l2ndb (0)->name (); + l2ndbs_changed (); } else { update_content (); } -#endif } void NetlistBrowserDialog::update_content () { -#if 0 // @@@ TODO: implement - rdb::Database *rdb = view ()->get_rdb (m_l2n_index); + db::LayoutToNetlist *l2ndb = view ()->get_l2ndb (m_l2n_index); - if (!rdb ) { + if (! l2ndb) { 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); + m_saveas_action->setEnabled (l2ndb != 0); + m_export_action->setEnabled (l2ndb != 0); + m_unload_action->setEnabled (l2ndb != 0); + m_unload_all_action->setEnabled (l2ndb != 0); + m_reload_action->setEnabled (l2ndb != 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_l2ndb (l2ndb); + browser_frame->set_max_shape_count (m_max_shape_count); + browser_frame->set_highlight_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) { + if (l2ndb) { // 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); @@ -596,20 +543,19 @@ NetlistBrowserDialog::update_content () layout_cb->setCurrentIndex (m_cv_index); } - if (l2n_cb->currentIndex () != m_l2n_index) { - l2n_cb->setCurrentIndex (m_l2n_index); + if (l2ndb_cb->currentIndex () != m_l2n_index) { + l2ndb_cb->setCurrentIndex (m_l2n_index); } -#endif } void NetlistBrowserDialog::deactivated () { if (lay::PluginRoot::instance ()) { - lay::PluginRoot::instance ()->config_set (cfg_l2n_window_state, lay::save_dialog_state (this).c_str ()); + lay::PluginRoot::instance ()->config_set (cfg_l2ndb_window_state, lay::save_dialog_state (this).c_str ()); } - // @@@ browser_frame->set_rdb (0); + browser_frame->set_l2ndb (0); browser_frame->set_view (0, 0); } diff --git a/src/laybasic/laybasic/layNetlistBrowserDialog.h b/src/laybasic/laybasic/layNetlistBrowserDialog.h index cd46df0b6..1f5e12c19 100644 --- a/src/laybasic/laybasic/layNetlistBrowserDialog.h +++ b/src/laybasic/laybasic/layNetlistBrowserDialog.h @@ -80,7 +80,7 @@ private: int m_marker_dither_pattern; std::string m_layout_name; int m_cv_index; - std::string m_lay_name; + std::string m_l2ndb_name; int m_l2n_index; std::string m_open_filename; QAction *m_open_action; diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc index c1dab5d06..9de2c56f4 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.cc +++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc @@ -26,7 +26,7 @@ namespace lay { -extern std::string cfg_l2n_show_all; +extern std::string cfg_l2ndb_show_all; // ---------------------------------------------------------------------------------- // NetlistBrowserPage implementation @@ -122,7 +122,7 @@ void NetlistBrowserPage::show_all_clicked () { if (mp_plugin_root) { - mp_plugin_root->config_set (cfg_l2n_show_all, tl::to_string (m_show_all_action->isChecked ())); + mp_plugin_root->config_set (cfg_l2ndb_show_all, tl::to_string (m_show_all_action->isChecked ())); } } @@ -168,5 +168,68 @@ NetlistBrowserPage::update_highlights () #endif } +void +NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database) +{ +#if 0 // @@@ + if (database != mp_database) { + + release_markers (); + + mp_database = database; + + QAbstractItemModel *tree_model = directory_tree->model (); + + MarkerBrowserTreeViewModel *new_model = new MarkerBrowserTreeViewModel (); + new_model->set_show_empty_ones (true); + new_model->set_database (database); + directory_tree->setModel (new_model); + connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (directory_selection_changed (const QItemSelection &, const QItemSelection &))); + + directory_tree->header ()->setSortIndicatorShown (true); + + cat_filter->setText (QString ()); + cell_filter->setText (QString ()); + set_hidden_rec (new_model, directory_tree, QModelIndex (), m_show_all, QString (), QString ()); + + if (tree_model) { + delete tree_model; + } + + QAbstractItemModel *list_model = markers_list->model (); + + MarkerBrowserListViewModel *new_list_model = new MarkerBrowserListViewModel (); + new_list_model->set_database (database); + markers_list->setModel (new_list_model); + connect (markers_list->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (markers_selection_changed (const QItemSelection &, const QItemSelection &))); + connect (markers_list->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (markers_current_changed (const QModelIndex &, const QModelIndex &))); + + if (list_model) { + delete list_model; + } + + } +#endif +} + +void +NetlistBrowserPage::enable_updates (bool f) +{ +#if 0 // @@@ + if (f != m_enable_updates) { + + m_enable_updates = f; + + if (f && m_update_needed) { + update_markers (); + update_info_text (); + } + + m_update_needed = false; + + } +#endif +} + } diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.h b/src/laybasic/laybasic/layNetlistBrowserPage.h index 4bf02c324..083c20929 100644 --- a/src/laybasic/laybasic/layNetlistBrowserPage.h +++ b/src/laybasic/laybasic/layNetlistBrowserPage.h @@ -32,17 +32,16 @@ class QAction; -namespace lay +namespace db { - class LayoutView; - class DMarker; - class PluginRoot; + class LayoutToNetlist; } namespace lay { -class Database; +class LayoutView; +class PluginRoot; /** * @brief A marker browser page @@ -78,6 +77,14 @@ public: */ void set_view (lay::LayoutView *view, unsigned int cv_index); + /** + * @brief Attach the page to a L2N DB + * + * To detach the page from any L2N DB, pass 0 for the pointer. + */ + void set_l2ndb (db::LayoutToNetlist *database); + + /** * @brief Set the window type and window dimensions */ @@ -122,6 +129,11 @@ public: */ void show_all (bool f); + /** + * @brief Enable or disable updates + */ + void enable_updates (bool f); + private slots: void show_all_clicked (); void filter_changed ();