mirror of https://github.com/KLayout/klayout.git
WIP: netlist browser log viewer
This commit is contained in:
parent
83946620d9
commit
b1cbafbac0
|
|
@ -38,10 +38,10 @@ LayoutVsSchematicStandardReader::LayoutVsSchematicStandardReader (tl::InputStrea
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void LayoutVsSchematicStandardReader::do_read_lvs (db::LayoutVsSchematic *l2n)
|
||||
void LayoutVsSchematicStandardReader::do_read_lvs (db::LayoutVsSchematic *lvs)
|
||||
{
|
||||
try {
|
||||
read_netlist (l2n);
|
||||
read_netlist (lvs);
|
||||
} catch (tl::Exception &ex) {
|
||||
throw tl::Exception (tl::sprintf (tl::to_string (tr ("%s in line: %d of %s")), ex.msg (), stream ().line_number (), path ()));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -572,7 +572,14 @@
|
|||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeView" name="log_view"/>
|
||||
<widget class="QTreeView" name="log_view">
|
||||
<property name="headerHidden">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "layNetlistBrowserPage.h"
|
||||
#include "layNetlistBrowserModel.h"
|
||||
#include "layNetlistBrowserTreeModel.h"
|
||||
#include "layNetlistLogModel.h"
|
||||
#include "layItemDelegates.h"
|
||||
#include "layCellView.h"
|
||||
#include "layLayoutViewBase.h"
|
||||
|
|
@ -1090,6 +1091,7 @@ void
|
|||
NetlistBrowserPage::setup_trees ()
|
||||
{
|
||||
if (! mp_database.get ()) {
|
||||
|
||||
delete nl_directory_tree->model ();
|
||||
nl_directory_tree->setModel (0);
|
||||
delete sch_directory_tree->model ();
|
||||
|
|
@ -1102,12 +1104,29 @@ NetlistBrowserPage::setup_trees ()
|
|||
sch_hierarchy_tree->setModel (0);
|
||||
delete xref_hierarchy_tree->model ();
|
||||
xref_hierarchy_tree->setModel (0);
|
||||
delete log_view->model ();
|
||||
log_view->setModel (0);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
db::LayoutToNetlist *l2ndb = mp_database.get ();
|
||||
db::LayoutVsSchematic *lvsdb = dynamic_cast<db::LayoutVsSchematic *> (l2ndb);
|
||||
|
||||
if (lvsdb && lvsdb->cross_ref ()) {
|
||||
|
||||
NetlistLogModel *new_model = new NetlistLogModel (log_view, lvsdb->cross_ref ());
|
||||
delete log_view->model ();
|
||||
log_view->setModel (new_model);
|
||||
|
||||
} else {
|
||||
|
||||
delete log_view->model ();
|
||||
log_view->setModel (0);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
// NOTE: with the tree as the parent, the tree will take over ownership of the model
|
||||
NetlistBrowserModel *new_model = new NetlistBrowserModel (nl_directory_tree, l2ndb, &m_colorizer);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <QIcon>
|
||||
#include <QFont>
|
||||
#include <QColor>
|
||||
#include <QWidget>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -70,7 +71,8 @@ namespace {
|
|||
|
||||
const std::string var_sep (" \u21D4 ");
|
||||
|
||||
NetlistLogModel::NetlistLogModel (const db::NetlistCrossReference *cross_ref)
|
||||
NetlistLogModel::NetlistLogModel (QWidget *parent, const db::NetlistCrossReference *cross_ref)
|
||||
: QAbstractItemModel (parent)
|
||||
{
|
||||
tl_assert (cross_ref->netlist_a () != 0);
|
||||
tl_assert (cross_ref->netlist_b () != 0);
|
||||
|
|
@ -88,7 +90,11 @@ NetlistLogModel::NetlistLogModel (const db::NetlistCrossReference *cross_ref)
|
|||
bool
|
||||
NetlistLogModel::hasChildren (const QModelIndex &parent) const
|
||||
{
|
||||
return (parent.isValid () || ! m_circuits.empty ());
|
||||
if (! parent.isValid ()) {
|
||||
return ! m_circuits.empty ();
|
||||
} else {
|
||||
return ! parent.parent ().isValid ();
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
|
|
@ -97,7 +103,18 @@ NetlistLogModel::index (int row, int column, const QModelIndex &parent) const
|
|||
if (! parent.isValid ()) {
|
||||
return createIndex (row, column, quintptr (0));
|
||||
} else {
|
||||
return createIndex (row, column, quintptr (& m_circuits [parent.row ()].second->log_entries [row]));
|
||||
return createIndex (row, column, quintptr (& m_circuits [parent.row ()]));
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
NetlistLogModel::parent (const QModelIndex &child) const
|
||||
{
|
||||
if (child.internalPointer () == (void *) 0) {
|
||||
return QModelIndex ();
|
||||
} else {
|
||||
const circuit_entry *ce = (const circuit_entry *) child.internalPointer ();
|
||||
return createIndex (int (ce - & m_circuits.front ()), child.column (), quintptr (0));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,6 +123,8 @@ NetlistLogModel::rowCount (const QModelIndex &parent) const
|
|||
{
|
||||
if (! parent.isValid ()) {
|
||||
return int (m_circuits.size ());
|
||||
} else if (parent.parent ().isValid ()) {
|
||||
return 0;
|
||||
} else if (parent.row () >= 0 && parent.row () < int (m_circuits.size ())) {
|
||||
return int (m_circuits [parent.row ()].second->log_entries.size ());
|
||||
} else {
|
||||
|
|
@ -116,49 +135,50 @@ NetlistLogModel::rowCount (const QModelIndex &parent) const
|
|||
int
|
||||
NetlistLogModel::columnCount (const QModelIndex & /*parent*/) const
|
||||
{
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant
|
||||
NetlistLogModel::data (const QModelIndex &index, int role) const
|
||||
{
|
||||
const db::NetlistCrossReference::LogEntryData *le = 0;
|
||||
if (index.parent ().isValid ()) {
|
||||
const circuit_entry *ce = (const circuit_entry *) index.internalPointer ();
|
||||
if (ce) {
|
||||
le = &ce->second->log_entries [index.row ()];
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Qt::DecorationRole) {
|
||||
|
||||
if (index.parent ().isValid ()) {
|
||||
auto *le = (const db::NetlistCrossReference::LogEntryData *) index.internalPointer ();
|
||||
if (! le) {
|
||||
// ignore
|
||||
} else if (le->severity == db::NetlistCrossReference::Error) {
|
||||
return QIcon (QString::fromUtf8 (":/error_16.png"));
|
||||
} else if (le->severity == db::NetlistCrossReference::Warning) {
|
||||
return QIcon (QString::fromUtf8 (":/warn_16.png"));
|
||||
} else if (le->severity == db::NetlistCrossReference::Info) {
|
||||
return QIcon (QString::fromUtf8 (":/info_16.png"));
|
||||
} else {
|
||||
return QIcon (QString::fromUtf8 (":/empty_16.png"));
|
||||
}
|
||||
if (! le) {
|
||||
// ignore
|
||||
} else if (le->severity == db::NetlistCrossReference::Error) {
|
||||
return QIcon (QString::fromUtf8 (":/error_16.png"));
|
||||
} else if (le->severity == db::NetlistCrossReference::Warning) {
|
||||
return QIcon (QString::fromUtf8 (":/warn_16.png"));
|
||||
} else if (le->severity == db::NetlistCrossReference::Info) {
|
||||
return QIcon (QString::fromUtf8 (":/info_16.png"));
|
||||
}
|
||||
|
||||
} else if (role == Qt::DisplayRole) {
|
||||
|
||||
if (index.parent ().isValid ()) {
|
||||
auto *le = (const db::NetlistCrossReference::LogEntryData *) index.internalPointer ();
|
||||
if (le) {
|
||||
return QVariant (tl::to_qstring (le->msg));
|
||||
}
|
||||
} else if (index.row () >= 0 && index.row () < int (m_circuits.size ())) {
|
||||
const std::pair<const db::Circuit *, const db::Circuit *> &cp = m_circuits [index.row ()].first;
|
||||
if (cp.first->name () != cp.second->name ()) {
|
||||
return QVariant (tl::to_qstring (cp.first->name () + var_sep + cp.second->name ()));
|
||||
return QVariant (tr ("Circuit ") + tl::to_qstring (cp.first->name () + var_sep + cp.second->name ()));
|
||||
} else {
|
||||
return QVariant (tl::to_qstring (cp.first->name ()));
|
||||
return QVariant (tr ("Circuit ") + tl::to_qstring (cp.first->name ()));
|
||||
}
|
||||
}
|
||||
|
||||
} else if (role == Qt::FontRole) {
|
||||
|
||||
if (index.parent ().isValid ()) {
|
||||
auto *le = (const db::NetlistCrossReference::LogEntryData *) index.internalPointer ();
|
||||
if (le && le->severity == db::NetlistCrossReference::Error) {
|
||||
QFont f;
|
||||
f.setBold (true);
|
||||
|
|
@ -169,7 +189,6 @@ NetlistLogModel::data (const QModelIndex &index, int role) const
|
|||
} else if (role == Qt::ForegroundRole) {
|
||||
|
||||
if (index.parent ().isValid ()) {
|
||||
auto *le = (const db::NetlistCrossReference::LogEntryData *) index.internalPointer ();
|
||||
if (!le) {
|
||||
// ignore
|
||||
} else if (le->severity == db::NetlistCrossReference::Error) {
|
||||
|
|
@ -187,7 +206,7 @@ NetlistLogModel::data (const QModelIndex &index, int role) const
|
|||
QVariant
|
||||
NetlistLogModel::headerData (int section, Qt::Orientation /*orientation*/, int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole && section == 1) {
|
||||
if (role == Qt::DisplayRole && section == 0) {
|
||||
return QVariant (tr ("Message"));
|
||||
} else {
|
||||
return QVariant ();
|
||||
|
|
|
|||
|
|
@ -40,17 +40,19 @@ class LAYUI_PUBLIC NetlistLogModel
|
|||
: public QAbstractItemModel
|
||||
{
|
||||
public:
|
||||
NetlistLogModel (const db::NetlistCrossReference *cross_ref);
|
||||
NetlistLogModel (QWidget *parent, const db::NetlistCrossReference *cross_ref);
|
||||
|
||||
virtual bool hasChildren (const QModelIndex &parent) const;
|
||||
virtual QModelIndex index (int row, int column, const QModelIndex &parent) const;
|
||||
virtual QModelIndex parent (const QModelIndex &child) const;
|
||||
virtual int rowCount (const QModelIndex &parent) const;
|
||||
virtual int columnCount (const QModelIndex &parent) const;
|
||||
virtual QVariant data (const QModelIndex &index, int role) const;
|
||||
virtual QVariant headerData (int section, Qt::Orientation orientation, int role) const;
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::pair<const db::Circuit *, const db::Circuit *>, const db::NetlistCrossReference::PerCircuitData *> > m_circuits;
|
||||
typedef std::pair<std::pair<const db::Circuit *, const db::Circuit *>, const db::NetlistCrossReference::PerCircuitData *> circuit_entry;
|
||||
std::vector<circuit_entry> m_circuits;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue