diff --git a/src/klayout.pro b/src/klayout.pro
index 60855e611..196fd9638 100644
--- a/src/klayout.pro
+++ b/src/klayout.pro
@@ -98,3 +98,7 @@ plugins.depends += lib rdb db
}
unit_tests.depends += plugins $$MAIN_DEPENDS
+
+RESOURCES += \
+ laybasic/laybasic/layResources.qrc \
+ laybasic/laybasic/layResources.qrc
diff --git a/src/laybasic/laybasic/MarkerBrowserConfigPage2.ui b/src/laybasic/laybasic/MarkerBrowserConfigPage2.ui
index 27e576e68..94b14426c 100644
--- a/src/laybasic/laybasic/MarkerBrowserConfigPage2.ui
+++ b/src/laybasic/laybasic/MarkerBrowserConfigPage2.ui
@@ -115,7 +115,7 @@
-
- The color in which the rulers are drawn
+ The color in which the markers are drawn
diff --git a/src/laybasic/laybasic/MarkerBrowserPage.ui b/src/laybasic/laybasic/MarkerBrowserPage.ui
index 8d6c61387..682d9ae9c 100644
--- a/src/laybasic/laybasic/MarkerBrowserPage.ui
+++ b/src/laybasic/laybasic/MarkerBrowserPage.ui
@@ -17,7 +17,16 @@
6
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
-
@@ -39,7 +48,16 @@
QFrame::Raised
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
@@ -51,7 +69,7 @@
...
-
+
:/down.png:/down.png
@@ -62,7 +80,7 @@
...
-
+
:/up.png:/up.png
@@ -129,7 +147,16 @@
QFrame::Raised
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
-
@@ -157,7 +184,7 @@
- :/find.png
+ :/find.png
@@ -230,7 +257,16 @@
QFrame::Raised
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
@@ -252,7 +288,7 @@
...
-
+
:/up.png:/up.png
@@ -270,7 +306,7 @@
...
-
+
:/down.png:/down.png
@@ -363,7 +399,16 @@
QFrame::Raised
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
@@ -385,7 +430,7 @@
Photo
-
+
:/photo.png:/photo.png
@@ -399,7 +444,7 @@
W
-
+
:/waived.png:/waived.png
@@ -433,7 +478,7 @@
Imp
-
+
:/important.png:/important.png
@@ -450,7 +495,7 @@ p, li { white-space: pre-wrap; }
...
-
+
:/nophoto.png:/nophoto.png
@@ -473,7 +518,16 @@ p, li { white-space: pre-wrap; }
0
-
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
0
-
@@ -523,7 +577,7 @@ p, li { white-space: pre-wrap; }
photo_pb
-
+
diff --git a/src/laybasic/laybasic/NetlistBrowserConfigPage.ui b/src/laybasic/laybasic/NetlistBrowserConfigPage.ui
new file mode 100644
index 000000000..857fe8996
--- /dev/null
+++ b/src/laybasic/laybasic/NetlistBrowserConfigPage.ui
@@ -0,0 +1,155 @@
+
+
+ NetlistBrowserConfigPage
+
+
+
+ 0
+ 0
+ 571
+ 162
+
+
+
+ Netlist Database Browser
+
+
+
+ 6
+
+
+ 9
+
+
-
+
+
+ Netlist Browser
+
+
+
+ 9
+
+
+ 6
+
+
-
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Minimum
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+ Window
+
+
+
+ -
+
+
-
+
+ Don't change
+
+
+ -
+
+ Fit context cell
+
+
+ -
+
+ Fit marker with margin ..
+
+
+ -
+
+ Center marker
+
+
+ -
+
+ Center marker with size ..
+
+
+
+
+ -
+
+
-
+
+ Any Cell
+
+
+ -
+
+ Netlist Top Circuit
+
+
+ -
+
+ Current Cell
+
+
+ -
+
+ Current or Any Cell
+
+
+ -
+
+ Net's Circuit
+
+
+
+
+ -
+
+
+ false
+
+
+
+ -
+
+
+ Maximum number of shapes to show for net
+
+
+
+ -
+
+
+ Context
+
+
+
+ -
+
+
+ µm
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui b/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui
new file mode 100644
index 000000000..c0ac46fd7
--- /dev/null
+++ b/src/laybasic/laybasic/NetlistBrowserConfigPage2.ui
@@ -0,0 +1,166 @@
+
+ NetlistBrowserConfigPage2
+
+
+
+ 0
+ 0
+ 571
+ 174
+
+
+
+ Netlist Browser
+
+
+
+ 9
+
+
+ 6
+
+ -
+
+
+ Net Appearance
+
+
+
+ 9
+
+
+ 6
+
+
-
+
+
+ With halo
+
+
+ true
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ pixel
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 71
+ 31
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+ 0
+ 0
+
+
+
+ pixel
+
+
+
+ -
+
+
+ Line width
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 41
+ 31
+
+
+
+
+ -
+
+
+ Vertex size
+
+
+
+ -
+
+
+ The color in which the nets are drawn
+
+
+
+
+
+
+ -
+
+
+ Net color
+
+
+
+ -
+
+
+ Stipple
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ lay::DitherPatternSelectionButton
+ QPushButton
+
+
+
+ lay::ColorButton
+ QPushButton
+
+
+
+
+
+
diff --git a/src/laybasic/laybasic/NetlistBrowserDialog.ui b/src/laybasic/laybasic/NetlistBrowserDialog.ui
new file mode 100644
index 000000000..c8be982eb
--- /dev/null
+++ b/src/laybasic/laybasic/NetlistBrowserDialog.ui
@@ -0,0 +1,347 @@
+
+
+ NetlistBrowserDialog
+
+
+
+ 0
+ 0
+ 515
+ 553
+
+
+
+ Netlist Database Browser
+
+
+
+ 6
+
+
+ 9
+
+
+ 9
+
+
+ 9
+
+
+ 9
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 6
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 20
+
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+ QComboBox::AdjustToContentsOnFirstShow
+
+
+
+ -
+
+
+ Netlist
+
+
+
+ -
+
+
+ ... on layout
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+ QComboBox::AdjustToContentsOnFirstShow
+
+
+
+ -
+
+
+ File ...
+
+
+ QToolButton::InstantPopup
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 10
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 6
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ 1
+
+
+
+
+ 6
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+
+
+
+
+
+ 6
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Choose "Open" from the "File ..." menu
+to load a netlist, a net database
+or a LVS cross-reference
+
+
+ Qt::AlignCenter
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 6
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Configure
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Close
+
+
+
+
+
+
+
+
+
+
+ lay::NetlistBrowserPage
+ QFrame
+
+ 1
+
+
+
+ l2ndb_cb
+ layout_cb
+ configure_pb
+ pushButton_2
+
+
+
+
+ pushButton_2
+ clicked()
+ NetlistBrowserDialog
+ accept()
+
+
+ 837
+ 441
+
+
+ 881
+ 387
+
+
+
+
+
diff --git a/src/laybasic/laybasic/NetlistBrowserPage.ui b/src/laybasic/laybasic/NetlistBrowserPage.ui
new file mode 100644
index 000000000..6d4dff2ca
--- /dev/null
+++ b/src/laybasic/laybasic/NetlistBrowserPage.ui
@@ -0,0 +1,226 @@
+
+
+ NetlistBrowserPage
+
+
+
+ 0
+ 0
+ 650
+ 570
+
+
+
+ Form
+
+
+
+ 6
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 1
+ 0
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 6
+
+
-
+
+
+ ...
+
+
+
+ :/down.png:/down.png
+
+
+
+ -
+
+
+ ...
+
+
+
+ :/up.png:/up.png
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 4
+
+
+
+ Qt::ActionsContextMenu
+
+
+ QAbstractItemView::ExtendedSelection
+
+
+ QAbstractItemView::SelectRows
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ Netlist
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+ Configure filters
+
+
+
+
+
+ :/find.png
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ directory_tree
+ dir_up_pb
+ dir_down_pb
+ filter
+
+
+
+
+
+
diff --git a/src/laybasic/laybasic/layNetlistBrowser.cc b/src/laybasic/laybasic/layNetlistBrowser.cc
new file mode 100644
index 000000000..1afa98b86
--- /dev/null
+++ b/src/laybasic/laybasic/layNetlistBrowser.cc
@@ -0,0 +1,309 @@
+
+/*
+
+ KLayout Layout Viewer
+ Copyright (C) 2006-2019 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 "layNetlistBrowserDialog.h"
+
+#include "layConverters.h"
+
+#include
+
+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");
+
+// ------------------------------------------------------------
+
+static struct {
+ lay::NetlistBrowserConfig::net_context_mode_type mode;
+ const char *string;
+} context_modes [] = {
+ { lay::NetlistBrowserConfig::AnyCell, "any-cell" },
+ { lay::NetlistBrowserConfig::NetlistTop, "netlist-top" },
+ { lay::NetlistBrowserConfig::Current, "current-cell" },
+ { lay::NetlistBrowserConfig::CurrentOrAny, "current-or-any-cell" },
+ { lay::NetlistBrowserConfig::Local, "local-cell" },
+};
+
+void
+NetlistBrowserContextModeConverter::from_string (const std::string &value, lay::NetlistBrowserConfig::net_context_mode_type &mode)
+{
+ for (unsigned int i = 0; i < sizeof (context_modes) / sizeof (context_modes [0]); ++i) {
+ if (value == context_modes [i].string) {
+ mode = context_modes [i].mode;
+ return;
+ }
+ }
+ throw tl::Exception (tl::to_string (QObject::tr ("Invalid marker database browser context mode: ")) + value);
+}
+
+std::string
+NetlistBrowserContextModeConverter::to_string (lay::NetlistBrowserConfig::net_context_mode_type mode)
+{
+ for (unsigned int i = 0; i < sizeof (context_modes) / sizeof (context_modes [0]); ++i) {
+ if (mode == context_modes [i].mode) {
+ return context_modes [i].string;
+ }
+ }
+ return "";
+}
+
+
+// ------------------------------------------------------------
+
+static struct {
+ lay::NetlistBrowserConfig::net_window_type mode;
+ const char *string;
+} window_modes [] = {
+ { lay::NetlistBrowserConfig::DontChange, "dont-change" },
+ { lay::NetlistBrowserConfig::FitCell, "fit-cell" },
+ { lay::NetlistBrowserConfig::FitNet, "fit-net" },
+ { lay::NetlistBrowserConfig::Center, "center" },
+ { lay::NetlistBrowserConfig::CenterSize, "center-size" }
+};
+
+void
+NetlistBrowserWindowModeConverter::from_string (const std::string &value, lay::NetlistBrowserConfig::net_window_type &mode)
+{
+ for (unsigned int i = 0; i < sizeof (window_modes) / sizeof (window_modes [0]); ++i) {
+ if (value == window_modes [i].string) {
+ mode = window_modes [i].mode;
+ return;
+ }
+ }
+ throw tl::Exception (tl::to_string (QObject::tr ("Invalid marker database browser window mode: ")) + value);
+}
+
+std::string
+NetlistBrowserWindowModeConverter::to_string (lay::NetlistBrowserConfig::net_window_type mode)
+{
+ for (unsigned int i = 0; i < sizeof (window_modes) / sizeof (window_modes [0]); ++i) {
+ if (mode == window_modes [i].mode) {
+ return window_modes [i].string;
+ }
+ }
+ return "";
+}
+
+
+// ------------------------------------------------------------
+// Implementation of NetlistBrowserConfigPage
+
+NetlistBrowserConfigPage::NetlistBrowserConfigPage (QWidget *parent)
+ : lay::ConfigPage (parent)
+{
+ Ui::NetlistBrowserConfigPage::setupUi (this);
+
+ connect (cbx_window, SIGNAL (currentIndexChanged (int)), this, SLOT (window_changed (int)));
+}
+
+void
+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 ());
+ 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 ());
+ cbx_window->setCurrentIndex (int (wmode));
+
+ // window dimension
+ double wdim = 1.0;
+ root->config_get (cfg_l2n_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);
+ le_max_markers->setText (tl::to_qstring (tl::to_string (max_marker_count)));
+
+ // enable controls
+ window_changed (int (wmode));
+}
+
+void
+NetlistBrowserConfigPage::window_changed (int m)
+{
+ le_window->setEnabled (m == int (lay::NetlistBrowserConfig::FitNet) || m == int (lay::NetlistBrowserConfig::CenterSize));
+}
+
+void
+NetlistBrowserConfigPage::commit (lay::PluginRoot *root)
+{
+ double dim = 1.0;
+ tl::from_string (tl::to_string (le_window->text ()), dim);
+
+ 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);
+}
+
+// ------------------------------------------------------------
+// Implementation of NetlistBrowserConfigPage2
+
+NetlistBrowserConfigPage2::NetlistBrowserConfigPage2 (QWidget *parent)
+ : lay::ConfigPage (parent)
+{
+ Ui::NetlistBrowserConfigPage2::setupUi (this);
+}
+
+void
+NetlistBrowserConfigPage2::setup (lay::PluginRoot *root)
+{
+ // marker color
+ QColor color;
+ root->config_get (cfg_l2n_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);
+ if (lw < 0) {
+ lw_le->setText (QString ());
+ } else {
+ lw_le->setText (tl::to_qstring (tl::to_string (lw)));
+ }
+
+ // marker vertex size
+ int vs = 0;
+ root->config_get (cfg_l2n_highlight_vertex_size, vs);
+ if (vs < 0) {
+ vs_le->setText (QString ());
+ } else {
+ vs_le->setText (tl::to_qstring (tl::to_string (vs)));
+ }
+
+ // stipple pattern
+ int dp = 0;
+ root->config_get (cfg_l2n_highlight_dither_pattern, dp);
+ stipple_pb->set_dither_pattern (dp);
+
+ // halo
+ int halo = 0;
+ root->config_get (cfg_l2n_highlight_halo, halo);
+ halo_cb->setCheckState (halo < 0 ? Qt::PartiallyChecked : (halo ? Qt::Checked : Qt::Unchecked));
+}
+
+void
+NetlistBrowserConfigPage2::commit (lay::PluginRoot *root)
+{
+ QColor color (color_pb->get_color ());
+ root->config_set (cfg_l2n_highlight_color, color, lay::ColorConverter ());
+
+ if (lw_le->text ().isEmpty ()) {
+ root->config_set (cfg_l2n_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);
+ } catch (...) { }
+ }
+
+ if (vs_le->text ().isEmpty ()) {
+ root->config_set (cfg_l2n_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);
+ } catch (...) { }
+ }
+
+ root->config_set (cfg_l2n_highlight_dither_pattern, stipple_pb->dither_pattern ());
+
+ if (halo_cb->checkState () == Qt::PartiallyChecked) {
+ root->config_set (cfg_l2n_highlight_halo, -1);
+ } else if (halo_cb->checkState () == Qt::Unchecked) {
+ root->config_set (cfg_l2n_highlight_halo, 0);
+ } else if (halo_cb->checkState () == Qt::Checked) {
+ root->config_set (cfg_l2n_highlight_halo, 1);
+ }
+}
+
+// ------------------------------------------------------------
+// Declaration and implementation of the browser plugin declaration object
+
+class NetlistBrowserPluginDeclaration
+ : public lay::PluginDeclaration
+{
+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"));
+ }
+
+ virtual std::vector > config_pages (QWidget *parent) const
+ {
+ std::vector > pages;
+ pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Netlist Browser|Setup")), new NetlistBrowserConfigPage (parent)));
+ pages.push_back (std::make_pair (tl::to_string (QObject::tr ("Netlist Browser|Net Appearance")), new NetlistBrowserConfigPage2 (parent)));
+ return pages;
+ }
+
+ virtual void get_menu_entries (std::vector &menu_entries) const
+ {
+ lay::PluginDeclaration::get_menu_entries (menu_entries);
+ menu_entries.push_back (lay::MenuEntry ("netlist_browser::show", "browse_netlists", "tools_menu.end", tl::to_string (QObject::tr ("Netlist Browser"))));
+ }
+
+ virtual lay::Plugin *create_plugin (db::Manager *, lay::PluginRoot *root, lay::LayoutView *view) const
+ {
+ return new lay::NetlistBrowserDialog (root, view);
+ }
+};
+
+static tl::RegisteredClass config_decl (new NetlistBrowserPluginDeclaration (), 12100, "NetlistBrowserPlugin");
+
+}
+
diff --git a/src/laybasic/laybasic/layNetlistBrowser.h b/src/laybasic/laybasic/layNetlistBrowser.h
new file mode 100644
index 000000000..10b1372fe
--- /dev/null
+++ b/src/laybasic/laybasic/layNetlistBrowser.h
@@ -0,0 +1,90 @@
+
+/*
+
+ KLayout Layout Viewer
+ Copyright (C) 2006-2019 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
+
+*/
+
+
+#ifndef HDR_layNetlistBrowser
+#define HDR_layNetlistBrowser
+
+#include "layPlugin.h"
+#include "ui_NetlistBrowserConfigPage.h"
+#include "ui_NetlistBrowserConfigPage2.h"
+
+#include "dbTrans.h"
+
+#include
+
+namespace lay
+{
+
+struct NetlistBrowserConfig
+{
+ enum net_context_mode_type { AnyCell = 0, NetlistTop, Current, CurrentOrAny, Local };
+ enum net_window_type { DontChange = 0, FitCell, FitNet, Center, CenterSize };
+};
+
+class NetlistBrowserConfigPage
+ : public lay::ConfigPage,
+ private Ui::NetlistBrowserConfigPage
+{
+ Q_OBJECT
+
+public:
+ NetlistBrowserConfigPage (QWidget *parent);
+
+ virtual void setup (lay::PluginRoot *root);
+ virtual void commit (lay::PluginRoot *root);
+
+public slots:
+ void window_changed (int);
+};
+
+class NetlistBrowserConfigPage2
+ : public lay::ConfigPage,
+ private Ui::NetlistBrowserConfigPage2
+{
+ Q_OBJECT
+
+public:
+ NetlistBrowserConfigPage2 (QWidget *parent);
+
+ virtual void setup (lay::PluginRoot *root);
+ virtual void commit (lay::PluginRoot *root);
+};
+
+class NetlistBrowserContextModeConverter
+{
+public:
+ void from_string (const std::string &value, lay::NetlistBrowserConfig::net_context_mode_type &mode);
+ std::string to_string (lay::NetlistBrowserConfig::net_context_mode_type mode);
+};
+
+class NetlistBrowserWindowModeConverter
+{
+public:
+ void from_string (const std::string &value, lay::NetlistBrowserConfig::net_window_type &mode);
+ std::string to_string (lay::NetlistBrowserConfig::net_window_type mode);
+};
+
+}
+
+#endif
+
diff --git a/src/laybasic/laybasic/layNetlistBrowserDialog.cc b/src/laybasic/laybasic/layNetlistBrowserDialog.cc
new file mode 100644
index 000000000..177d40b6f
--- /dev/null
+++ b/src/laybasic/laybasic/layNetlistBrowserDialog.cc
@@ -0,0 +1,628 @@
+
+/*
+
+ KLayout Layout Viewer
+ Copyright (C) 2006-2019 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 "layNetlistBrowserDialog.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
+#include
+
+#include
+
+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;
+
+NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutView *vw)
+ : lay::Browser (root, vw),
+ Ui::NetlistBrowserDialog (),
+ m_context (lay::NetlistBrowserConfig::AnyCell),
+ m_window (lay::NetlistBrowserConfig::FitNet),
+ m_window_dim (0.0),
+ m_max_shape_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_l2n_index (-1)
+{
+ Ui::NetlistBrowserDialog::setupUi (this);
+
+ browser_frame->set_plugin_root (root);
+
+ 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);
+ }
+
+ 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 (l2ndb_cb, SIGNAL (activated (int)), this, SLOT (l2ndb_index_changed (int)));
+ connect (configure_pb, SIGNAL (clicked ()), this, SLOT (configure_clicked ()));
+
+ cellviews_changed ();
+}
+
+NetlistBrowserDialog::~NetlistBrowserDialog ()
+{
+ tl::Object::detach_from_all_events ();
+}
+
+void
+NetlistBrowserDialog::configure_clicked ()
+{
+ lay::ConfigurationDialog config_dialog (this, lay::PluginRoot::instance (), "NetlistBrowserPlugin");
+ config_dialog.exec ();
+}
+
+void
+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);
+ }
+
+ l2ndb_index_changed (-1);
+#endif
+
+END_PROTECTED
+}
+
+void
+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;
+ }
+
+ }
+
+ int new_l2n_index = m_l2n_index;
+
+ view ()->remove_rdb (m_l2n_index);
+
+ // try to use another rbd ...
+ if (new_l2n_index >= int (view ()->num_rdbs ())) {
+ --new_l2n_index;
+ }
+ if (new_l2n_index < int (view ()->num_rdbs ()) && new_l2n_index >= 0) {
+ l2ndb_index_changed (new_l2n_index);
+ }
+
+ }
+#endif
+
+END_PROTECTED
+}
+
+void
+NetlistBrowserDialog::export_clicked ()
+{
+BEGIN_PROTECTED
+
+#if 0 // @@@
+ if (m_l2n_index >= int (view ()->num_rdbs ()) || m_l2n_index < 0) {
+ return;
+ }
+
+ const rdb::Database *rdb = view ()->get_rdb (m_l2n_index);
+ if (! rdb) {
+ return;
+ }
+
+ const lay::CellView &cv = view ()->cellview (m_cv_index);
+ if (! cv.is_valid ()) {
+ return;
+ }
+
+ try {
+
+ view ()->manager ()->transaction (tl::to_string (QObject::tr ("Export Net")));
+
+ // ....
+
+ view ()->manager ()->commit ();
+ view ()->update_content ();
+
+ } catch (...) {
+ view ()->manager ()->commit ();
+ view ()->update_content ();
+ throw;
+ }
+#endif
+
+END_PROTECTED
+}
+
+void
+NetlistBrowserDialog::saveas_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) {
+
+ // 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 ());
+ if (save_dialog.get_save (fn)) {
+
+ rdb->save (fn);
+ rdb->reset_modified ();
+
+ }
+
+ }
+
+ }
+#endif
+
+END_PROTECTED
+}
+
+void
+NetlistBrowserDialog::reload_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->filename ().empty ()) {
+
+ browser_frame->set_rdb (0);
+ rdb->load (rdb->filename ());
+ browser_frame->set_rdb (rdb);
+
+ }
+
+ }
+#endif
+
+END_PROTECTED
+}
+
+void
+NetlistBrowserDialog::open_clicked ()
+{
+BEGIN_PROTECTED
+
+#if 0 // @@@
+ // collect the formats available ...
+ std::string fmts = tl::to_string (QObject::tr ("All files (*)"));
+ for (tl::Registrar::iterator rdr = tl::Registrar::begin (); rdr != tl::Registrar::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 db (new rdb::Database ());
+ db->load (m_open_filename);
+
+ int l2n_index = view ()->add_rdb (db.release ());
+ l2n_cb->setCurrentIndex (l2n_index);
+ // it looks like the setCurrentIndex does not issue this signal:
+ l2ndb_index_changed (l2n_index);
+
+ }
+#endif
+
+END_PROTECTED
+}
+
+bool
+NetlistBrowserDialog::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_l2n_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) {
+
+ tl::from_string (value, show_all);
+
+ } else if (name == cfg_l2n_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) {
+
+ 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_l2n_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) {
+
+ 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_l2n_highlight_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_l2n_highlight_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_l2n_highlight_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_l2n_highlight_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_shape_count (m_max_shape_count);
+ browser_frame->set_window (m_window, m_window_dim, m_context);
+ 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->show_all (show_all);
+
+ return taken;
+}
+
+void
+NetlistBrowserDialog::load (int l2n_index, int cv_index)
+{
+#if 0 // @@@ TODO: implement
+ if (! view ()->get_rdb (l2n_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_l2n_name = view ()->get_rdb (l2n_index)->name ();
+
+ // force an update
+ rdbs_changed ();
+ cellviews_changed ();
+
+ activate ();
+#endif
+}
+
+void
+NetlistBrowserDialog::l2ndbs_changed ()
+{
+#if 0 // @@@ TODO: implement
+ int l2n_index = -1;
+
+ l2n_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) {
+ l2n_index = i;
+ }
+ }
+
+ // force an update
+ m_l2n_index = l2n_index;
+ l2n_cb->setCurrentIndex (l2n_index);
+ if (active ()) {
+ update_content ();
+ }
+#endif
+}
+
+void
+NetlistBrowserDialog::cellview_changed (int)
+{
+ browser_frame->update_highlights ();
+}
+
+void
+NetlistBrowserDialog::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
+NetlistBrowserDialog::l2ndb_index_changed (int index)
+{
+ if (m_l2n_index != index) {
+ m_l2n_index = index;
+ if (active ()) {
+ update_content ();
+ }
+ }
+}
+
+void
+NetlistBrowserDialog::cv_index_changed (int index)
+{
+ if (m_cv_index != index) {
+ m_cv_index = index;
+ if (active ()) {
+ update_content ();
+ }
+ }
+}
+
+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::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_l2n_index < 0 && view ()->get_rdb (0) != 0) {
+
+ m_l2n_name = view ()->get_rdb (0)->name ();
+ rdbs_changed ();
+
+ } else {
+ update_content ();
+ }
+#endif
+}
+
+void
+NetlistBrowserDialog::update_content ()
+{
+#if 0 // @@@ TODO: implement
+ rdb::Database *rdb = view ()->get_rdb (m_l2n_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 (l2n_cb->currentIndex () != m_l2n_index) {
+ l2n_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 ());
+ }
+
+ // @@@ browser_frame->set_rdb (0);
+ browser_frame->set_view (0, 0);
+}
+
+void
+NetlistBrowserDialog::menu_activated (const std::string &symbol)
+{
+ if (symbol == "marker_browser::show") {
+ view ()->deactivate_all_browsers ();
+ activate ();
+ } else {
+ lay::Browser::menu_activated (symbol);
+ }
+}
+
+}
+
diff --git a/src/laybasic/laybasic/layNetlistBrowserDialog.h b/src/laybasic/laybasic/layNetlistBrowserDialog.h
new file mode 100644
index 000000000..cd46df0b6
--- /dev/null
+++ b/src/laybasic/laybasic/layNetlistBrowserDialog.h
@@ -0,0 +1,101 @@
+
+/*
+
+ KLayout Layout Viewer
+ Copyright (C) 2006-2019 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
+
+*/
+
+
+#ifndef HDR_layNetlistBrowserDialog
+#define HDR_layNetlistBrowserDialog
+
+#include "ui_NetlistBrowserDialog.h"
+#include "layBrowser.h"
+#include "layNetlistBrowser.h"
+
+namespace lay
+{
+
+class NetlistBrowserDialog
+ : public lay::Browser,
+ private Ui::NetlistBrowserDialog
+{
+ Q_OBJECT
+
+public:
+ NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutView *view);
+ ~NetlistBrowserDialog ();
+
+ void load (int lay_index, int cv_index);
+
+private:
+ // implementation of the lay::Browser interface
+ virtual void activated ();
+ virtual void deactivated ();
+
+ bool configure (const std::string &name, const std::string &value);
+
+ // implementation of the lay::Plugin interface
+ virtual void menu_activated (const std::string &symbol);
+
+ void cellviews_changed ();
+ void cellview_changed (int index);
+ void l2ndbs_changed ();
+
+public slots:
+ void cv_index_changed (int);
+ void l2ndb_index_changed (int);
+ void saveas_clicked ();
+ void export_clicked ();
+ void reload_clicked ();
+ void open_clicked ();
+ void unload_clicked ();
+ void unload_all_clicked ();
+ void configure_clicked ();
+
+private:
+ lay::NetlistBrowserConfig::net_context_mode_type m_context;
+ lay::NetlistBrowserConfig::net_window_type m_window;
+ double m_window_dim;
+ unsigned int m_max_shape_count;
+ QColor m_marker_color;
+ int m_marker_line_width;
+ int m_marker_vertex_size;
+ int m_marker_halo;
+ int m_marker_dither_pattern;
+ std::string m_layout_name;
+ int m_cv_index;
+ std::string m_lay_name;
+ int m_l2n_index;
+ std::string m_open_filename;
+ QAction *m_open_action;
+ QAction *m_saveas_action;
+ QAction *m_export_action;
+ QAction *m_unload_action;
+ QAction *m_unload_all_action;
+ QAction *m_reload_action;
+
+ void update_content ();
+ void scan_layer ();
+ void scan_layer_flat ();
+};
+
+}
+
+#endif
+
diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.cc b/src/laybasic/laybasic/layNetlistBrowserPage.cc
new file mode 100644
index 000000000..c1dab5d06
--- /dev/null
+++ b/src/laybasic/laybasic/layNetlistBrowserPage.cc
@@ -0,0 +1,172 @@
+
+/*
+
+ KLayout Layout Viewer
+ Copyright (C) 2006-2019 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 "layNetlistBrowserPage.h"
+
+namespace lay
+{
+
+extern std::string cfg_l2n_show_all;
+
+// ----------------------------------------------------------------------------------
+// NetlistBrowserPage implementation
+
+NetlistBrowserPage::NetlistBrowserPage (QWidget * /*parent*/)
+ : m_show_all (true),
+ m_context (lay::NetlistBrowserConfig::NetlistTop),
+ m_window (lay::NetlistBrowserConfig::FitNet),
+ m_window_dim (0.0),
+ m_max_shape_count (1000),
+ m_marker_line_width (-1),
+ m_marker_vertex_size (-1),
+ m_marker_halo (-1),
+ m_marker_dither_pattern (-1),
+ mp_view (0),
+ m_cv_index (0),
+ mp_plugin_root (0)
+{
+ Ui::NetlistBrowserPage::setupUi (this);
+
+ m_show_all_action = new QAction (QObject::tr ("Show All"), this);
+ m_show_all_action->setCheckable (true);
+ m_show_all_action->setChecked (m_show_all);
+
+ connect (m_show_all_action, SIGNAL (triggered ()), this, SLOT (show_all_clicked ()));
+ connect (filter, SIGNAL (textEdited (const QString &)), this, SLOT (filter_changed ()));
+}
+
+NetlistBrowserPage::~NetlistBrowserPage ()
+{
+ // @@@
+}
+
+void
+NetlistBrowserPage::set_plugin_root (lay::PluginRoot *pr)
+{
+ mp_plugin_root = pr;
+}
+
+void
+NetlistBrowserPage::set_highlight_style (QColor color, int line_width, int vertex_size, int halo, int dither_pattern)
+{
+ m_marker_color = color;
+ m_marker_line_width = line_width;
+ m_marker_vertex_size = vertex_size;
+ m_marker_halo = halo;
+ m_marker_dither_pattern = dither_pattern;
+ update_highlights ();
+}
+
+void
+NetlistBrowserPage::set_view (lay::LayoutView *view, unsigned int cv_index)
+{
+ mp_view = view;
+ m_cv_index = cv_index;
+ update_highlights ();
+}
+
+void
+NetlistBrowserPage::set_window (lay::NetlistBrowserConfig::net_window_type window, double window_dim, lay::NetlistBrowserConfig::net_context_mode_type context)
+{
+ if (window != m_window || window_dim != m_window_dim || context != m_context) {
+ m_window = window;
+ m_window_dim = window_dim;
+ m_context = context;
+ }
+}
+
+void
+NetlistBrowserPage::set_max_shape_count (size_t max_shape_count)
+{
+ if (m_max_shape_count != max_shape_count) {
+ m_max_shape_count = max_shape_count;
+#if 0 // @@@
+ update_marker_list (1 /*select first*/);
+#endif
+ }
+}
+
+void
+NetlistBrowserPage::filter_changed ()
+{
+#if 0 // @@@
+ MarkerBrowserTreeViewModel *tree_model = dynamic_cast (directory_tree->model ());
+ if (tree_model) {
+ set_hidden_rec (tree_model, directory_tree, QModelIndex (), m_show_all, cat_filter->text (), cell_filter->text ());
+ }
+ update_highlights (2 /*select all*/);
+#endif
+}
+
+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 ()));
+ }
+}
+
+void
+NetlistBrowserPage::show_all (bool f)
+{
+ if (f != m_show_all) {
+
+ m_show_all = f;
+ m_show_all_action->setChecked (f);
+
+#if 0 // @@@
+ MarkerBrowserTreeViewModel *tree_model = dynamic_cast (directory_tree->model ());
+ if (tree_model) {
+ set_hidden_rec (tree_model, directory_tree, QModelIndex (), m_show_all, cat_filter->text (), cell_filter->text ());
+ }
+#endif
+
+ }
+}
+
+void
+NetlistBrowserPage::update_highlights ()
+{
+#if 0
+ if (! m_enable_updates) {
+ m_update_needed = true;
+ return;
+ }
+
+ if (m_recursion_sentinel) {
+ return;
+ }
+
+ m_recursion_sentinel = true;
+ try {
+ do_update_markers ();
+ } catch (...) {
+ m_recursion_sentinel = false;
+ throw;
+ }
+ m_recursion_sentinel = false;
+#endif
+}
+
+}
+
diff --git a/src/laybasic/laybasic/layNetlistBrowserPage.h b/src/laybasic/laybasic/layNetlistBrowserPage.h
new file mode 100644
index 000000000..4bf02c324
--- /dev/null
+++ b/src/laybasic/laybasic/layNetlistBrowserPage.h
@@ -0,0 +1,149 @@
+
+/*
+
+ KLayout Layout Viewer
+ Copyright (C) 2006-2019 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
+
+*/
+
+
+#ifndef HDR_layNetlistBrowserPage
+#define HDR_layNetlistBrowserPage
+
+#include "ui_NetlistBrowserPage.h"
+#include "layNetlistBrowser.h"
+#include "dbBox.h"
+
+#include
+
+class QAction;
+
+namespace lay
+{
+ class LayoutView;
+ class DMarker;
+ class PluginRoot;
+}
+
+namespace lay
+{
+
+class Database;
+
+/**
+ * @brief A marker browser page
+ */
+class NetlistBrowserPage
+ : public QFrame,
+ public Ui::NetlistBrowserPage
+{
+Q_OBJECT
+
+public:
+ /**
+ * @brief Constructor
+ */
+ NetlistBrowserPage (QWidget *parent);
+
+ /**
+ * @brief Destructor
+ */
+ ~NetlistBrowserPage ();
+
+ /**
+ * @brief Sets the plugin root object for this object
+ */
+ void set_plugin_root (lay::PluginRoot *pr);
+
+ /**
+ * @brief Attaches the page to a view
+ *
+ * This method can be given a layout view object.
+ * If that pointer is non-null, the browser will attach itself to
+ * the view and provide highlights for the selected markers inside the given cellview.
+ */
+ void set_view (lay::LayoutView *view, unsigned int cv_index);
+
+ /**
+ * @brief Set the window type and window dimensions
+ */
+ void set_window (lay::NetlistBrowserConfig::net_window_type window_type, double window_dim, lay::NetlistBrowserConfig::net_context_mode_type context);
+
+ /**
+ * @brief Update the net highlights
+ *
+ * This method should be called if the cellview has changed so the highlights can
+ * be recomputed and shown in the new cell context.
+ */
+ void update_highlights ();
+
+ /**
+ * @brief Set the maximum number of shapes highlighted for a net
+ */
+ void set_max_shape_count (size_t max_shape_count);
+
+ /**
+ * @brief Set the highlight style
+ *
+ * @param color The color or an invalid color to take the default color for selection
+ * @param line_width The line width or negative for the default line width
+ * @param vertex_size The vertex size or negative for the default vertex size
+ * @param halo The halo flag or -1 for default
+ * @param dither_pattern The dither pattern index of -1 to take the default
+ */
+ void set_highlight_style (QColor color, int line_width, int vertex_size, int halo, int dither_pattern);
+
+ /**
+ * @brief Gets a value indicating whether all items in the netlist tree are shown (specifically for cross-reference DBs)
+ */
+ bool show_all () const
+ {
+ return m_show_all;
+ }
+
+ /**
+ * @brief Sets a value indicating whether all items in the netlist tree are shown (specifically for cross-reference DBs)
+ *
+ * If this property is set to false, only cross-reference entries with error are shown.
+ */
+ void show_all (bool f);
+
+private slots:
+ void show_all_clicked ();
+ void filter_changed ();
+
+private:
+ bool m_show_all;
+ QAction *m_show_all_action;
+ NetlistBrowserConfig::net_context_mode_type m_context;
+ NetlistBrowserConfig::net_window_type m_window;
+ double m_window_dim;
+ size_t m_max_shape_count;
+ QColor m_marker_color;
+ int m_marker_line_width;
+ int m_marker_vertex_size;
+ int m_marker_halo;
+ int m_marker_dither_pattern;
+ lay::LayoutView *mp_view;
+ unsigned int m_cv_index;
+ lay::PluginRoot *mp_plugin_root;
+};
+
+} // namespace lay
+
+#endif
+
diff --git a/src/laybasic/laybasic/laybasic.pro b/src/laybasic/laybasic/laybasic.pro
index 316d434e8..a76210d9a 100644
--- a/src/laybasic/laybasic/laybasic.pro
+++ b/src/laybasic/laybasic/laybasic.pro
@@ -65,7 +65,11 @@ FORMS = \
SpecificLoadLayoutOptionsDialog.ui \
SelectLineStyleForm.ui \
LayoutViewConfigPage6a.ui \
- EditLineStylesForm.ui
+ EditLineStylesForm.ui \
+ NetlistBrowserPage.ui \
+ NetlistBrowserConfigPage.ui \
+ NetlistBrowserConfigPage2.ui \
+ NetlistBrowserDialog.ui
RESOURCES = \
@@ -159,6 +163,9 @@ SOURCES = \
layEditLineStylesForm.cc \
layEditLineStyleWidget.cc \
layBackgroundAwareTreeStyle.cc \
+ layNetlistBrowser.cc \
+ layNetlistBrowserDialog.cc \
+ layNetlistBrowserPage.cc
HEADERS = \
gtf.h \
@@ -244,7 +251,10 @@ HEADERS = \
layEditLineStyleWidget.h \
laybasicCommon.h \
laybasicConfig.h \
- layBackgroundAwareTreeStyle.h
+ layBackgroundAwareTreeStyle.h \
+ layNetlistBrowser.h \
+ layNetlistBrowserDialog.h \
+ layNetlistBrowserPage.h
INCLUDEPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC
DEPENDPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC
diff --git a/src/laybasic/laybasic/rdbMarkerBrowserPage.h b/src/laybasic/laybasic/rdbMarkerBrowserPage.h
index 982395720..66cd279a9 100644
--- a/src/laybasic/laybasic/rdbMarkerBrowserPage.h
+++ b/src/laybasic/laybasic/rdbMarkerBrowserPage.h
@@ -69,7 +69,7 @@ public:
*/
void set_plugin_root (lay::PluginRoot *pr);
- /*
+ /**
* @brief Attach the page to a view
*
* This method can be given a layout view object.