mirror of https://github.com/KLayout/klayout.git
Netlist browser: some bug fixes in search, probe net feature.
This commit is contained in:
parent
4e15b3df92
commit
60216ee3f6
|
|
@ -285,6 +285,23 @@ to load a netlist or a netlist/LVS database</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="probe_pb">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Select a new by clicking on a shape</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Probe Net</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="sticky_cbx">
|
||||||
|
<property name="text">
|
||||||
|
<string>Lock</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
|
||||||
|
|
@ -200,13 +200,6 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="probe_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Probe</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -243,7 +236,7 @@
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<attribute name="headerVisible">
|
<attribute name="headerVisible">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,9 @@ void NetInfoDialog::update_info_text ()
|
||||||
info.cdata (tl::to_string (tr ("Net")));
|
info.cdata (tl::to_string (tr ("Net")));
|
||||||
info.end_element ("th");
|
info.end_element ("th");
|
||||||
info.start_element ("th");
|
info.start_element ("th");
|
||||||
|
info.cdata (tl::to_string (tr ("Circuit")));
|
||||||
|
info.end_element ("th");
|
||||||
|
info.start_element ("th");
|
||||||
info.cdata (tl::to_string (tr ("Shapes")));
|
info.cdata (tl::to_string (tr ("Shapes")));
|
||||||
info.end_element ("th");
|
info.end_element ("th");
|
||||||
info.start_element ("th");
|
info.start_element ("th");
|
||||||
|
|
@ -177,6 +180,12 @@ void NetInfoDialog::update_info_text ()
|
||||||
info.cdata (net->expanded_name ());
|
info.cdata (net->expanded_name ());
|
||||||
info.end_element ("td");
|
info.end_element ("td");
|
||||||
|
|
||||||
|
info.start_element ("td");
|
||||||
|
if (net->circuit ()) {
|
||||||
|
info.cdata (net->circuit ()->name ());
|
||||||
|
}
|
||||||
|
info.end_element ("td");
|
||||||
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
info.start_element ("td");
|
info.start_element ("td");
|
||||||
|
|
@ -253,23 +262,6 @@ void NetInfoDialog::update_info_text ()
|
||||||
info.start_element ("hr");
|
info.start_element ("hr");
|
||||||
info.end_element ("hr");
|
info.end_element ("hr");
|
||||||
|
|
||||||
info.start_element ("h3");
|
|
||||||
info.cdata (tl::to_string (QObject::tr ("Details:")));
|
|
||||||
info.end_element ("h3");
|
|
||||||
|
|
||||||
info.start_element ("p");
|
|
||||||
info.start_element ("b");
|
|
||||||
info.cdata (tl::to_string (QObject::tr ("Net name: ")));
|
|
||||||
info.end_element ("b");
|
|
||||||
info.cdata (net->expanded_name ());
|
|
||||||
info.start_element ("br");
|
|
||||||
info.end_element ("br");
|
|
||||||
info.start_element ("b");
|
|
||||||
info.cdata (tl::to_string (QObject::tr ("Circuit: ")));
|
|
||||||
info.end_element ("b");
|
|
||||||
info.cdata (net->circuit () ? net->circuit ()->name () : "(null)");
|
|
||||||
info.end_element ("p");
|
|
||||||
|
|
||||||
std::map<std::string, std::set<std::string> > shapes;
|
std::map<std::string, std::set<std::string> > shapes;
|
||||||
|
|
||||||
// map as (layernumber, group of shapes by layer):
|
// map as (layernumber, group of shapes by layer):
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,9 @@
|
||||||
|
|
||||||
#include "layNetlistBrowserDialog.h"
|
#include "layNetlistBrowserDialog.h"
|
||||||
#include "tlProgress.h"
|
#include "tlProgress.h"
|
||||||
#include "layLayoutView.h"
|
|
||||||
#include "tlExceptions.h"
|
#include "tlExceptions.h"
|
||||||
|
#include "layLayoutView.h"
|
||||||
|
#include "layFinder.h"
|
||||||
#include "layFileDialog.h"
|
#include "layFileDialog.h"
|
||||||
#include "layConverters.h"
|
#include "layConverters.h"
|
||||||
#include "layQtTools.h"
|
#include "layQtTools.h"
|
||||||
|
|
@ -56,6 +57,7 @@ extern const std::string cfg_l2ndb_window_state;
|
||||||
|
|
||||||
NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutView *vw)
|
NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutView *vw)
|
||||||
: lay::Browser (root, vw),
|
: lay::Browser (root, vw),
|
||||||
|
lay::ViewService (vw->view_object_widget ()),
|
||||||
Ui::NetlistBrowserDialog (),
|
Ui::NetlistBrowserDialog (),
|
||||||
m_window (lay::NetlistBrowserConfig::FitNet),
|
m_window (lay::NetlistBrowserConfig::FitNet),
|
||||||
m_window_dim (0.0),
|
m_window_dim (0.0),
|
||||||
|
|
@ -67,7 +69,8 @@ NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutVi
|
||||||
m_marker_dither_pattern (-1),
|
m_marker_dither_pattern (-1),
|
||||||
m_marker_intensity (0),
|
m_marker_intensity (0),
|
||||||
m_cv_index (-1),
|
m_cv_index (-1),
|
||||||
m_l2n_index (-1)
|
m_l2n_index (-1),
|
||||||
|
m_mouse_state (0)
|
||||||
{
|
{
|
||||||
Ui::NetlistBrowserDialog::setupUi (this);
|
Ui::NetlistBrowserDialog::setupUi (this);
|
||||||
|
|
||||||
|
|
@ -111,6 +114,8 @@ NetlistBrowserDialog::NetlistBrowserDialog (lay::PluginRoot *root, lay::LayoutVi
|
||||||
connect (layout_cb, SIGNAL (activated (int)), this, SLOT (cv_index_changed (int)));
|
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 (l2ndb_cb, SIGNAL (activated (int)), this, SLOT (l2ndb_index_changed (int)));
|
||||||
connect (configure_pb, SIGNAL (clicked ()), this, SLOT (configure_clicked ()));
|
connect (configure_pb, SIGNAL (clicked ()), this, SLOT (configure_clicked ()));
|
||||||
|
connect (probe_pb, SIGNAL (clicked ()), this, SLOT (probe_button_pressed ()));
|
||||||
|
connect (sticky_cbx, SIGNAL (clicked ()), this, SLOT (sticky_mode_clicked ()));
|
||||||
|
|
||||||
cellviews_changed ();
|
cellviews_changed ();
|
||||||
}
|
}
|
||||||
|
|
@ -123,10 +128,188 @@ NetlistBrowserDialog::~NetlistBrowserDialog ()
|
||||||
void
|
void
|
||||||
NetlistBrowserDialog::configure_clicked ()
|
NetlistBrowserDialog::configure_clicked ()
|
||||||
{
|
{
|
||||||
|
release_mouse ();
|
||||||
|
|
||||||
lay::ConfigurationDialog config_dialog (this, lay::PluginRoot::instance (), "NetlistBrowserPlugin");
|
lay::ConfigurationDialog config_dialog (this, lay::PluginRoot::instance (), "NetlistBrowserPlugin");
|
||||||
config_dialog.exec ();
|
config_dialog.exec ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NetlistBrowserDialog::mouse_move_event (const db::DPoint & /*p*/, unsigned int /*buttons*/, bool prio)
|
||||||
|
{
|
||||||
|
if (prio && m_mouse_state != 0) {
|
||||||
|
set_cursor (lay::Cursor::cross);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserDialog::sticky_mode_clicked ()
|
||||||
|
{
|
||||||
|
BEGIN_PROTECTED
|
||||||
|
if (! sticky_cbx->isChecked ()) {
|
||||||
|
release_mouse ();
|
||||||
|
} else {
|
||||||
|
probe_button_pressed ();
|
||||||
|
}
|
||||||
|
END_PROTECTED
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NetlistBrowserDialog::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
||||||
|
{
|
||||||
|
if (prio && (buttons & lay::LeftButton) != 0 && m_mouse_state != 0) {
|
||||||
|
|
||||||
|
// TODO: not used yet, borrowed from net tracer ... TODO: implement short locator!
|
||||||
|
if (m_mouse_state == 2) {
|
||||||
|
|
||||||
|
m_mouse_first_point = p;
|
||||||
|
m_mouse_state = 3;
|
||||||
|
|
||||||
|
view ()->message (tl::to_string (QObject::tr ("Click on the second point in the net")));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
bool trace_path = (m_mouse_state == 3);
|
||||||
|
|
||||||
|
if (trace_path || ! sticky_cbx->isChecked ()) {
|
||||||
|
release_mouse ();
|
||||||
|
}
|
||||||
|
|
||||||
|
probe_net (p, trace_path);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserDialog::probe_net (const db::DPoint &p, bool trace_path)
|
||||||
|
{
|
||||||
|
// prepare for the net tracing
|
||||||
|
double l = double (lay::search_range) / widget ()->mouse_event_trans ().mag ();
|
||||||
|
|
||||||
|
db::DBox start_search_box = db::DBox (p, p).enlarged (db::DVector (l, l));
|
||||||
|
|
||||||
|
// @@@ not used yet ..
|
||||||
|
db::DBox stop_search_box;
|
||||||
|
if (trace_path) {
|
||||||
|
stop_search_box = db::DBox (m_mouse_first_point, m_mouse_first_point).enlarged (db::DVector (l, l));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int start_layer = 0;
|
||||||
|
db::Point start_point;
|
||||||
|
unsigned int cv_index;
|
||||||
|
|
||||||
|
// locate the seed shape to figure out the cv index and layer
|
||||||
|
{
|
||||||
|
|
||||||
|
lay::ShapeFinder finder (true /*point mode*/, false /*all levels*/, db::ShapeIterator::All);
|
||||||
|
|
||||||
|
// go through all visible layers of all cellviews and find a seed shape
|
||||||
|
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
||||||
|
if (lprop->is_visual ()) {
|
||||||
|
finder.find (view (), *lprop, start_search_box);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return, if no shape was found
|
||||||
|
lay::ShapeFinder::iterator r = finder.begin ();
|
||||||
|
if (r == finder.end ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv_index = r->cv_index ();
|
||||||
|
start_layer = r->layer ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the cv index is not corresponding to the one of the current netlist, ignore this event
|
||||||
|
if (int (cv_index) != m_cv_index) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine the cellview
|
||||||
|
lay::CellView cv = view ()->cellview (cv_index);
|
||||||
|
if (! cv.is_valid ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine the start point
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<db::DCplxTrans> tv = view ()->cv_transform_variants (m_cv_index, start_layer);
|
||||||
|
if (tv.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
db::CplxTrans tt = tv.front () * db::CplxTrans (cv->layout ().dbu ()) * cv.context_trans ();
|
||||||
|
|
||||||
|
start_point = tt.inverted ().trans (start_search_box.center ());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const db::Net *net = 0;
|
||||||
|
|
||||||
|
db::LayoutToNetlist *l2ndb = view ()->get_l2ndb (m_l2n_index);
|
||||||
|
if (l2ndb) {
|
||||||
|
|
||||||
|
// determines the corresponding layer inside the database and probe the net from this region and the
|
||||||
|
// start point.
|
||||||
|
|
||||||
|
db::Region *region = 0;
|
||||||
|
|
||||||
|
const db::Connectivity &conn = l2ndb->connectivity ();
|
||||||
|
for (db::Connectivity::layer_iterator layer = conn.begin_layers (); layer != conn.end_layers (); ++layer) {
|
||||||
|
db::LayerProperties lp = l2ndb->internal_layout ()->get_properties (*layer);
|
||||||
|
if (! lp.is_null () && lp == cv->layout ().get_properties (start_layer)) {
|
||||||
|
region = l2ndb->layer_by_index (*layer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// probe the net
|
||||||
|
|
||||||
|
if (region) {
|
||||||
|
net = l2ndb->probe_net (*region, start_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// select the net if one was found
|
||||||
|
browser_frame->select_net (net);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserDialog::release_mouse ()
|
||||||
|
{
|
||||||
|
m_mouse_state = 0;
|
||||||
|
view ()->message ();
|
||||||
|
widget ()->ungrab_mouse (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
lay::ViewService *
|
||||||
|
NetlistBrowserDialog::view_service_interface ()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserDialog::probe_button_pressed ()
|
||||||
|
{
|
||||||
|
BEGIN_PROTECTED
|
||||||
|
|
||||||
|
m_mouse_state = 1;
|
||||||
|
|
||||||
|
view ()->message (tl::to_string (QObject::tr ("Click on a point in the net")));
|
||||||
|
widget ()->grab_mouse (this, false);
|
||||||
|
|
||||||
|
END_PROTECTED
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NetlistBrowserDialog::unload_all_clicked ()
|
NetlistBrowserDialog::unload_all_clicked ()
|
||||||
{
|
{
|
||||||
|
|
@ -510,8 +693,13 @@ NetlistBrowserDialog::activated ()
|
||||||
void
|
void
|
||||||
NetlistBrowserDialog::update_content ()
|
NetlistBrowserDialog::update_content ()
|
||||||
{
|
{
|
||||||
|
release_mouse ();
|
||||||
|
|
||||||
db::LayoutToNetlist *l2ndb = view ()->get_l2ndb (m_l2n_index);
|
db::LayoutToNetlist *l2ndb = view ()->get_l2ndb (m_l2n_index);
|
||||||
|
|
||||||
|
probe_pb->setEnabled (l2ndb != 0);
|
||||||
|
release_mouse ();
|
||||||
|
|
||||||
if (! l2ndb) {
|
if (! l2ndb) {
|
||||||
central_stack->setCurrentIndex (1);
|
central_stack->setCurrentIndex (1);
|
||||||
}
|
}
|
||||||
|
|
@ -554,6 +742,8 @@ NetlistBrowserDialog::update_content ()
|
||||||
void
|
void
|
||||||
NetlistBrowserDialog::deactivated ()
|
NetlistBrowserDialog::deactivated ()
|
||||||
{
|
{
|
||||||
|
release_mouse ();
|
||||||
|
|
||||||
if (lay::PluginRoot::instance ()) {
|
if (lay::PluginRoot::instance ()) {
|
||||||
lay::PluginRoot::instance ()->config_set (cfg_l2ndb_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 ());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "ui_NetlistBrowserDialog.h"
|
#include "ui_NetlistBrowserDialog.h"
|
||||||
#include "layBrowser.h"
|
#include "layBrowser.h"
|
||||||
#include "layNetlistBrowser.h"
|
#include "layNetlistBrowser.h"
|
||||||
|
#include "layViewObject.h"
|
||||||
#include "layColorPalette.h"
|
#include "layColorPalette.h"
|
||||||
|
|
||||||
namespace lay
|
namespace lay
|
||||||
|
|
@ -34,6 +35,7 @@ namespace lay
|
||||||
|
|
||||||
class NetlistBrowserDialog
|
class NetlistBrowserDialog
|
||||||
: public lay::Browser,
|
: public lay::Browser,
|
||||||
|
public lay::ViewService,
|
||||||
private Ui::NetlistBrowserDialog
|
private Ui::NetlistBrowserDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -49,7 +51,11 @@ private:
|
||||||
virtual void activated ();
|
virtual void activated ();
|
||||||
virtual void deactivated ();
|
virtual void deactivated ();
|
||||||
|
|
||||||
bool configure (const std::string &name, const std::string &value);
|
virtual bool configure (const std::string &name, const std::string &value);
|
||||||
|
|
||||||
|
virtual bool mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||||
|
virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||||
|
virtual lay::ViewService *view_service_interface ();
|
||||||
|
|
||||||
// implementation of the lay::Plugin interface
|
// implementation of the lay::Plugin interface
|
||||||
virtual void menu_activated (const std::string &symbol);
|
virtual void menu_activated (const std::string &symbol);
|
||||||
|
|
@ -68,6 +74,8 @@ public slots:
|
||||||
void unload_clicked ();
|
void unload_clicked ();
|
||||||
void unload_all_clicked ();
|
void unload_all_clicked ();
|
||||||
void configure_clicked ();
|
void configure_clicked ();
|
||||||
|
void probe_button_pressed ();
|
||||||
|
void sticky_mode_clicked ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
lay::NetlistBrowserConfig::net_window_type m_window;
|
lay::NetlistBrowserConfig::net_window_type m_window;
|
||||||
|
|
@ -86,6 +94,8 @@ private:
|
||||||
std::string m_l2ndb_name;
|
std::string m_l2ndb_name;
|
||||||
int m_l2n_index;
|
int m_l2n_index;
|
||||||
std::string m_open_filename;
|
std::string m_open_filename;
|
||||||
|
db::DPoint m_mouse_first_point;
|
||||||
|
int m_mouse_state;
|
||||||
QAction *m_open_action;
|
QAction *m_open_action;
|
||||||
QAction *m_saveas_action;
|
QAction *m_saveas_action;
|
||||||
QAction *m_export_action;
|
QAction *m_export_action;
|
||||||
|
|
@ -94,8 +104,8 @@ private:
|
||||||
QAction *m_reload_action;
|
QAction *m_reload_action;
|
||||||
|
|
||||||
void update_content ();
|
void update_content ();
|
||||||
void scan_layer ();
|
void release_mouse ();
|
||||||
void scan_layer_flat ();
|
void probe_net (const db::DPoint &p, bool trace_path);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "layLayoutView.h"
|
#include "layLayoutView.h"
|
||||||
#include "layMarker.h"
|
#include "layMarker.h"
|
||||||
#include "layNetInfoDialog.h"
|
#include "layNetInfoDialog.h"
|
||||||
|
#include "tlProgress.h"
|
||||||
#include "dbLayoutToNetlist.h"
|
#include "dbLayoutToNetlist.h"
|
||||||
#include "dbNetlistDeviceClasses.h"
|
#include "dbNetlistDeviceClasses.h"
|
||||||
|
|
||||||
|
|
@ -1203,8 +1204,16 @@ NetlistBrowserModel::hasChildren (const QModelIndex &parent) const
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant
|
QVariant
|
||||||
NetlistBrowserModel::headerData (int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const
|
NetlistBrowserModel::headerData (int section, Qt::Orientation /*orientation*/, int role) const
|
||||||
{
|
{
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
if (section == 0) {
|
||||||
|
return tr ("Object");
|
||||||
|
} else if (section == 1) {
|
||||||
|
return tr ("Attribute");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return QVariant ();
|
return QVariant ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1295,6 +1304,13 @@ NetlistBrowserModel::colors_changed ()
|
||||||
emit dataChanged (index (0, 0, QModelIndex ()), index (rowCount (QModelIndex()) - 1, 0, QModelIndex ()));
|
emit dataChanged (index (0, 0, QModelIndex ()), index (rowCount (QModelIndex()) - 1, 0, QModelIndex ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QModelIndex
|
||||||
|
NetlistBrowserModel::index_from_net (const db::Net *net) const
|
||||||
|
{
|
||||||
|
void *id = make_id_circuit_net (circuit_index (net->circuit ()), net_index (net));
|
||||||
|
return index_from_id (id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
const db::Net *
|
const db::Net *
|
||||||
NetlistBrowserModel::net_from_index (const QModelIndex &index) const
|
NetlistBrowserModel::net_from_index (const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
|
|
@ -1818,6 +1834,18 @@ NetlistBrowserPage::current_index_changed (const QModelIndex &index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserPage::select_net (const db::Net *net)
|
||||||
|
{
|
||||||
|
if (! net || ! net->circuit ()) {
|
||||||
|
directory_tree->clearSelection ();
|
||||||
|
} else {
|
||||||
|
NetlistBrowserModel *model = dynamic_cast<NetlistBrowserModel *> (directory_tree->model ());
|
||||||
|
tl_assert (model != 0);
|
||||||
|
directory_tree->setCurrentIndex (model->index_from_net (net));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const db::Net *>
|
std::vector<const db::Net *>
|
||||||
NetlistBrowserPage::selected_nets ()
|
NetlistBrowserPage::selected_nets ()
|
||||||
{
|
{
|
||||||
|
|
@ -1962,15 +1990,21 @@ NetlistBrowserPage::info_button_pressed ()
|
||||||
|
|
||||||
static QModelIndex find_next (QAbstractItemModel *model, const QRegExp &to_find, const QModelIndex &from)
|
static QModelIndex find_next (QAbstractItemModel *model, const QRegExp &to_find, const QModelIndex &from)
|
||||||
{
|
{
|
||||||
if (! from.isValid ()) {
|
QModelIndex index = from;
|
||||||
return from;
|
|
||||||
|
if (! index.isValid () && model->hasChildren (index)) {
|
||||||
|
index = model->index (0, 0, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! index.isValid ()) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex current = index;
|
||||||
|
|
||||||
std::vector<QModelIndex> parent_stack;
|
std::vector<QModelIndex> parent_stack;
|
||||||
std::vector<std::pair<int, int> > rows_stack;
|
std::vector<std::pair<int, int> > rows_stack;
|
||||||
|
|
||||||
QModelIndex index = from;
|
|
||||||
|
|
||||||
while (index.isValid ()) {
|
while (index.isValid ()) {
|
||||||
|
|
||||||
parent_stack.push_back (model->parent (index));
|
parent_stack.push_back (model->parent (index));
|
||||||
|
|
@ -1983,13 +2017,15 @@ static QModelIndex find_next (QAbstractItemModel *model, const QRegExp &to_find,
|
||||||
std::reverse (parent_stack.begin (), parent_stack.end ());
|
std::reverse (parent_stack.begin (), parent_stack.end ());
|
||||||
std::reverse (rows_stack.begin (), rows_stack.end ());
|
std::reverse (rows_stack.begin (), rows_stack.end ());
|
||||||
|
|
||||||
QModelIndex current = from;
|
tl::AbsoluteProgress progress (tl::to_string (tr ("Searching ...")));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
|
++progress;
|
||||||
|
|
||||||
bool has_next = false;
|
bool has_next = false;
|
||||||
|
|
||||||
if (model->hasChildren (current)) {
|
if (model->hasChildren (current) && rows_stack.size () < 2) {
|
||||||
|
|
||||||
int row_count = model->rowCount (current);
|
int row_count = model->rowCount (current);
|
||||||
if (row_count > 0) {
|
if (row_count > 0) {
|
||||||
|
|
@ -2008,7 +2044,7 @@ static QModelIndex find_next (QAbstractItemModel *model, const QRegExp &to_find,
|
||||||
|
|
||||||
++rows_stack.back ().first;
|
++rows_stack.back ().first;
|
||||||
|
|
||||||
if (rows_stack.back ().first == rows_stack.back ().second) {
|
if (rows_stack.back ().first >= rows_stack.back ().second) {
|
||||||
|
|
||||||
// up
|
// up
|
||||||
current = parent_stack.back ();
|
current = parent_stack.back ();
|
||||||
|
|
@ -2033,7 +2069,7 @@ static QModelIndex find_next (QAbstractItemModel *model, const QRegExp &to_find,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (current != from);
|
} while (current.internalPointer () != from.internalPointer () || current.row () != from.row ());
|
||||||
|
|
||||||
return QModelIndex ();
|
return QModelIndex ();
|
||||||
}
|
}
|
||||||
|
|
@ -2098,6 +2134,7 @@ NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
|
||||||
// NOTE: with the tree as the parent, the tree will take over ownership of the model
|
// NOTE: with the tree as the parent, the tree will take over ownership of the model
|
||||||
NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database, &m_colorizer);
|
NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database, &m_colorizer);
|
||||||
|
|
||||||
|
delete directory_tree->model ();
|
||||||
directory_tree->setModel (new_model);
|
directory_tree->setModel (new_model);
|
||||||
connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &)));
|
connect (directory_tree->selectionModel (), SIGNAL (currentChanged (const QModelIndex &, const QModelIndex &)), this, SLOT (current_index_changed (const QModelIndex &)));
|
||||||
connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ()));
|
connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (net_selection_changed ()));
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ public:
|
||||||
QModelIndex index_from_id (void *id, int column) const;
|
QModelIndex index_from_id (void *id, int column) const;
|
||||||
|
|
||||||
const db::Net *net_from_index (const QModelIndex &index) const;
|
const db::Net *net_from_index (const QModelIndex &index) const;
|
||||||
|
QModelIndex index_from_net (const db::Net *net) const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void colors_changed ();
|
void colors_changed ();
|
||||||
|
|
@ -252,6 +253,10 @@ public:
|
||||||
*/
|
*/
|
||||||
void set_l2ndb (db::LayoutToNetlist *database);
|
void set_l2ndb (db::LayoutToNetlist *database);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Selects a net or clears the selection if net == 0
|
||||||
|
*/
|
||||||
|
void select_net (const db::Net *net);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the window type and window dimensions
|
* @brief Set the window type and window dimensions
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue