mirror of https://github.com/KLayout/klayout.git
WIP: netlist browser
This commit is contained in:
parent
5500ca45d8
commit
9ee58b161f
|
|
@ -26,6 +26,7 @@
|
||||||
#include "laySaltDownloadManager.h"
|
#include "laySaltDownloadManager.h"
|
||||||
#include "laySalt.h"
|
#include "laySalt.h"
|
||||||
#include "layVersion.h"
|
#include "layVersion.h"
|
||||||
|
#include "layItemDelegates.h"
|
||||||
#include "ui_SaltGrainTemplateSelectionDialog.h"
|
#include "ui_SaltGrainTemplateSelectionDialog.h"
|
||||||
#include "tlString.h"
|
#include "tlString.h"
|
||||||
#include "tlExceptions.h"
|
#include "tlExceptions.h"
|
||||||
|
|
@ -59,7 +60,7 @@ public:
|
||||||
|
|
||||||
m_salt_templates.add_location (":/salt_templates");
|
m_salt_templates.add_location (":/salt_templates");
|
||||||
salt_view->setModel (new SaltModel (this, &m_salt_templates));
|
salt_view->setModel (new SaltModel (this, &m_salt_templates));
|
||||||
salt_view->setItemDelegate (new SaltItemDelegate (this));
|
salt_view->setItemDelegate (new lay::HTMLItemDelegate (this));
|
||||||
salt_view->setCurrentIndex (salt_view->model ()->index (0, 0, QModelIndex ()));
|
salt_view->setCurrentIndex (salt_view->model ()->index (0, 0, QModelIndex ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +131,7 @@ SaltManagerDialog::SaltManagerDialog (QWidget *parent, lay::Salt *salt, const st
|
||||||
SaltModel *model = new SaltModel (this, mp_salt);
|
SaltModel *model = new SaltModel (this, mp_salt);
|
||||||
model->set_empty_explanation (tr ("No packages are present on this system"));
|
model->set_empty_explanation (tr ("No packages are present on this system"));
|
||||||
salt_view->setModel (model);
|
salt_view->setModel (model);
|
||||||
salt_view->setItemDelegate (new SaltItemDelegate (this));
|
salt_view->setItemDelegate (new lay::HTMLItemDelegate (this));
|
||||||
|
|
||||||
SaltModel *mine_model;
|
SaltModel *mine_model;
|
||||||
|
|
||||||
|
|
@ -138,13 +139,13 @@ SaltManagerDialog::SaltManagerDialog (QWidget *parent, lay::Salt *salt, const st
|
||||||
mine_model = new SaltModel (this, &m_salt_mine, mp_salt, true);
|
mine_model = new SaltModel (this, &m_salt_mine, mp_salt, true);
|
||||||
mine_model->set_empty_explanation (tr ("All available packages are installed"));
|
mine_model->set_empty_explanation (tr ("All available packages are installed"));
|
||||||
salt_mine_view_new->setModel (mine_model);
|
salt_mine_view_new->setModel (mine_model);
|
||||||
salt_mine_view_new->setItemDelegate (new SaltItemDelegate (this));
|
salt_mine_view_new->setItemDelegate (new lay::HTMLItemDelegate (this));
|
||||||
|
|
||||||
// This model will show only the grains of mp_salt_mine which are present in mp_salt already.
|
// This model will show only the grains of mp_salt_mine which are present in mp_salt already.
|
||||||
mine_model = new SaltModel (this, &m_salt_mine, mp_salt, false);
|
mine_model = new SaltModel (this, &m_salt_mine, mp_salt, false);
|
||||||
mine_model->set_empty_explanation (tr ("No packages are installed"));
|
mine_model->set_empty_explanation (tr ("No packages are installed"));
|
||||||
salt_mine_view_update->setModel (mine_model);
|
salt_mine_view_update->setModel (mine_model);
|
||||||
salt_mine_view_update->setItemDelegate (new SaltItemDelegate (this));
|
salt_mine_view_update->setItemDelegate (new lay::HTMLItemDelegate (this));
|
||||||
|
|
||||||
mode_tab->setCurrentIndex (0);
|
mode_tab->setCurrentIndex (0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,84 +25,13 @@
|
||||||
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QAbstractTextDocumentLayout>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QListView>
|
|
||||||
|
|
||||||
namespace lay
|
namespace lay
|
||||||
{
|
{
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
SaltItemDelegate::SaltItemDelegate (QObject *parent)
|
|
||||||
: QStyledItemDelegate (parent)
|
|
||||||
{
|
|
||||||
// .. nothing yet ..
|
|
||||||
}
|
|
||||||
|
|
||||||
const int textWidth = 500;
|
|
||||||
|
|
||||||
void
|
|
||||||
SaltItemDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
QStyleOptionViewItemV4 optionV4 = option;
|
|
||||||
initStyleOption (&optionV4, index);
|
|
||||||
// let the text take all the available space (fixes #144)
|
|
||||||
optionV4.showDecorationSelected = true;
|
|
||||||
|
|
||||||
bool is_enabled = (optionV4.state & QStyle::State_Enabled);
|
|
||||||
if ((index.flags () & 0x10000) != 0) {
|
|
||||||
// the item wants to be drawn "disabled"
|
|
||||||
is_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
optionV4.state |= QStyle::State_Enabled;
|
|
||||||
|
|
||||||
QStyle *style = optionV4.widget ? optionV4.widget->style () : QApplication::style ();
|
|
||||||
|
|
||||||
QTextDocument doc;
|
|
||||||
doc.setHtml (optionV4.text);
|
|
||||||
|
|
||||||
optionV4.text = QString ();
|
|
||||||
style->drawControl (QStyle::CE_ItemViewItem, &optionV4, painter);
|
|
||||||
|
|
||||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
|
||||||
|
|
||||||
if (optionV4.state & QStyle::State_Selected) {
|
|
||||||
ctx.palette.setColor (QPalette::Text, optionV4.palette.color (QPalette::Active, QPalette::HighlightedText));
|
|
||||||
} else if (! is_enabled) {
|
|
||||||
ctx.palette.setColor (QPalette::Text, optionV4.palette.color (QPalette::Disabled, QPalette::Text));
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect textRect = style->subElementRect (QStyle::SE_ItemViewItemText, &optionV4);
|
|
||||||
painter->save ();
|
|
||||||
painter->translate (textRect.topLeft ());
|
|
||||||
painter->setClipRect (textRect.translated (-textRect.topLeft ()));
|
|
||||||
doc.setTextWidth (textWidth);
|
|
||||||
doc.documentLayout ()->draw (painter, ctx);
|
|
||||||
painter->restore ();
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize
|
|
||||||
SaltItemDelegate::sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
QStyleOptionViewItemV4 optionV4 = option;
|
|
||||||
initStyleOption (&optionV4, index);
|
|
||||||
|
|
||||||
const QListView *view = dynamic_cast<const QListView *> (optionV4.widget);
|
|
||||||
QSize icon_size (0, 0);
|
|
||||||
if (view) {
|
|
||||||
icon_size = view->iconSize ();
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextDocument doc;
|
|
||||||
doc.setHtml (optionV4.text);
|
|
||||||
doc.setTextWidth (textWidth);
|
|
||||||
return QSize (textWidth + icon_size.width () + 6, std::max (icon_size.height () + 12, int (doc.size ().height ())));
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
SaltModel::SaltModel (QObject *parent, lay::Salt *salt, lay::Salt *salt_filtered, bool salt_exclude)
|
SaltModel::SaltModel (QObject *parent, lay::Salt *salt, lay::Salt *salt_filtered, bool salt_exclude)
|
||||||
: QAbstractItemModel (parent), mp_salt (salt),
|
: QAbstractItemModel (parent), mp_salt (salt),
|
||||||
mp_salt_filtered (salt_filtered), m_salt_exclude (salt_exclude),
|
mp_salt_filtered (salt_filtered), m_salt_exclude (salt_exclude),
|
||||||
|
|
|
||||||
|
|
@ -196,21 +196,6 @@ public:
|
||||||
void create_ordered_list ();
|
void create_ordered_list ();
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A delegate displaying the summary of a grain
|
|
||||||
*/
|
|
||||||
class SaltItemDelegate
|
|
||||||
: public QStyledItemDelegate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SaltItemDelegate (QObject *parent);
|
|
||||||
|
|
||||||
void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
|
||||||
QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -63,93 +63,15 @@
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="2" column="1">
|
<item row="3" column="0" colspan="9">
|
||||||
<widget class="QToolButton" name="dir_down_pb">
|
<widget class="QFrame" name="frame_3">
|
||||||
<property name="text">
|
|
||||||
<string>...</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../lay/lay/layResources.qrc">
|
|
||||||
<normaloff>:/down.png</normaloff>:/down.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QToolButton" name="dir_up_pb">
|
|
||||||
<property name="text">
|
|
||||||
<string>...</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../lay/lay/layResources.qrc">
|
|
||||||
<normaloff>:/up.png</normaloff>:/up.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="4">
|
|
||||||
<widget class="QTreeView" name="directory_tree">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="baseSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>4</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="contextMenuPolicy">
|
|
||||||
<enum>Qt::ActionsContextMenu</enum>
|
|
||||||
</property>
|
|
||||||
<property name="selectionMode">
|
|
||||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
|
||||||
</property>
|
|
||||||
<property name="selectionBehavior">
|
|
||||||
<enum>QAbstractItemView::SelectRows</enum>
|
|
||||||
</property>
|
|
||||||
<property name="uniformRowHeights">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="sortingEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="allColumnsShowFocus">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="headerVisible">
|
|
||||||
<bool>true</bool>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0" colspan="4">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Netlist</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="2" colspan="2">
|
|
||||||
<widget class="QFrame" name="frame_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -162,6 +84,28 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="dir_down_pb">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/down.png</normaloff>:/down.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="dir_up_pb">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/up.png</normaloff>:/up.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
@ -210,6 +154,138 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0" colspan="9">
|
||||||
|
<widget class="QTreeView" name="directory_tree">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>4</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::ActionsContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="uniformRowHeights">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="allColumnsShowFocus">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="headerVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="5" colspan="4">
|
||||||
|
<widget class="QFrame" name="frame_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="9">
|
||||||
|
<widget class="QFrame" name="frame_4">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="backward">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/back_16.png</normaloff>:/back_16.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="forward">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../lay/lay/layResources.qrc">
|
||||||
|
<normaloff>:/forward_16.png</normaloff>:/forward_16.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Netlist</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
@ -218,9 +294,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>directory_tree</tabstop>
|
<tabstop>directory_tree</tabstop>
|
||||||
<tabstop>dir_up_pb</tabstop>
|
|
||||||
<tabstop>dir_down_pb</tabstop>
|
|
||||||
<tabstop>filter</tabstop>
|
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../../lay/lay/layResources.qrc"/>
|
<include location="../../lay/lay/layResources.qrc"/>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,193 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
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 "layItemDelegates.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QTextDocument>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
#include <QAbstractItemView>
|
||||||
|
|
||||||
|
namespace lay
|
||||||
|
{
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HTMLItemDelegate::HTMLItemDelegate (QObject *parent)
|
||||||
|
: QStyledItemDelegate (parent)
|
||||||
|
{
|
||||||
|
m_icon_margin = 6;
|
||||||
|
m_icon_spacing = 6;
|
||||||
|
m_text_margin = 4;
|
||||||
|
m_text_height = -1;
|
||||||
|
m_text_width = 500;
|
||||||
|
m_plain_text = false;
|
||||||
|
m_anchors_clickable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLItemDelegate::set_anchors_clickable (bool a)
|
||||||
|
{
|
||||||
|
m_anchors_clickable = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLItemDelegate::set_plain_text (bool pt)
|
||||||
|
{
|
||||||
|
m_plain_text = pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLItemDelegate::set_icon_margin (int m)
|
||||||
|
{
|
||||||
|
m_icon_margin = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLItemDelegate::set_icon_spacing (int s)
|
||||||
|
{
|
||||||
|
m_icon_spacing = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLItemDelegate::set_text_margin (int m)
|
||||||
|
{
|
||||||
|
m_text_margin = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLItemDelegate::set_text_height (int h)
|
||||||
|
{
|
||||||
|
m_text_height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLItemDelegate::set_text_width (int w)
|
||||||
|
{
|
||||||
|
m_text_width = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HTMLItemDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QStyleOptionViewItemV4 option_v4 = option;
|
||||||
|
initStyleOption (&option_v4, index);
|
||||||
|
// let the text take all the available space (fixes #144)
|
||||||
|
option_v4.showDecorationSelected = true;
|
||||||
|
|
||||||
|
bool is_enabled = (option_v4.state & QStyle::State_Enabled);
|
||||||
|
if ((index.flags () & 0x10000) != 0) {
|
||||||
|
// the item wants to be drawn "disabled"
|
||||||
|
is_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
option_v4.state |= QStyle::State_Enabled;
|
||||||
|
|
||||||
|
QStyle *style = option_v4.widget ? option_v4.widget->style () : QApplication::style ();
|
||||||
|
|
||||||
|
QTextDocument doc;
|
||||||
|
if (m_plain_text) {
|
||||||
|
doc.setPlainText (option_v4.text);
|
||||||
|
} else {
|
||||||
|
doc.setHtml (option_v4.text);
|
||||||
|
}
|
||||||
|
doc.setTextWidth (m_text_width);
|
||||||
|
doc.setDocumentMargin (m_text_margin);
|
||||||
|
|
||||||
|
option_v4.text = QString ();
|
||||||
|
style->drawControl (QStyle::CE_ItemViewItem, &option_v4, painter);
|
||||||
|
|
||||||
|
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||||
|
|
||||||
|
if (option_v4.state & QStyle::State_Selected) {
|
||||||
|
ctx.palette.setColor (QPalette::Text, option_v4.palette.color (QPalette::Active, QPalette::HighlightedText));
|
||||||
|
} else if (! is_enabled) {
|
||||||
|
ctx.palette.setColor (QPalette::Text, option_v4.palette.color (QPalette::Disabled, QPalette::Text));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect text_rect = style->subElementRect (QStyle::SE_ItemViewItemText, &option_v4);
|
||||||
|
painter->save ();
|
||||||
|
QPoint tr = text_rect.topLeft ();
|
||||||
|
painter->translate (tr);
|
||||||
|
painter->setClipRect (text_rect.translated (-tr));
|
||||||
|
doc.documentLayout ()->draw (painter, ctx);
|
||||||
|
painter->restore ();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize
|
||||||
|
HTMLItemDelegate::sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QStyleOptionViewItemV4 option_v4 = option;
|
||||||
|
initStyleOption (&option_v4, index);
|
||||||
|
|
||||||
|
const QAbstractItemView *view = dynamic_cast<const QAbstractItemView *> (option_v4.widget);
|
||||||
|
QSize icon_size (0, 0);
|
||||||
|
if (view) {
|
||||||
|
icon_size = view->iconSize ();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextDocument doc;
|
||||||
|
if (m_plain_text) {
|
||||||
|
doc.setPlainText (option_v4.text);
|
||||||
|
} else {
|
||||||
|
doc.setHtml (option_v4.text);
|
||||||
|
}
|
||||||
|
doc.setTextWidth (m_text_width);
|
||||||
|
doc.setDocumentMargin (m_text_margin);
|
||||||
|
bool has_icon = ! option_v4.icon.isNull ();
|
||||||
|
int th = m_text_height < 0 ? int (doc.size ().height ()) : m_text_height;
|
||||||
|
return QSize (m_text_width + (has_icon ? icon_size.width () + m_icon_spacing : 0), std::max (has_icon ? icon_size.height () + 2 * m_icon_margin : 0, th));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HTMLItemDelegate::editorEvent (QEvent *event, QAbstractItemModel * /*model*/, const QStyleOptionViewItem &option, const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if ((event->type () == QEvent::MouseButtonRelease || event->type () == QEvent::MouseButtonPress) && ! m_plain_text && m_anchors_clickable) {
|
||||||
|
|
||||||
|
QMouseEvent *mouse_event = static_cast<QMouseEvent *> (event);
|
||||||
|
|
||||||
|
QStyleOptionViewItemV4 option_v4 = option;
|
||||||
|
initStyleOption (&option_v4, index);
|
||||||
|
|
||||||
|
QTextDocument doc;
|
||||||
|
doc.setHtml (option_v4.text);
|
||||||
|
doc.setTextWidth (m_text_width);
|
||||||
|
doc.setDocumentMargin (m_text_margin);
|
||||||
|
|
||||||
|
QStyle *style = option_v4.widget ? option_v4.widget->style () : QApplication::style ();
|
||||||
|
QRect text_rect = style->subElementRect (QStyle::SE_ItemViewItemText, &option_v4);
|
||||||
|
|
||||||
|
QString a = doc.documentLayout ()->anchorAt (mouse_event->pos () - text_rect.topLeft ());
|
||||||
|
if (! a.isNull ()) {
|
||||||
|
if (event->type () == QEvent::MouseButtonRelease) {
|
||||||
|
emit anchor_clicked (a);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
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_layItemDelegates
|
||||||
|
#define HDR_layItemDelegates
|
||||||
|
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
|
||||||
|
namespace lay
|
||||||
|
{
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A delegate displaying the display text as HTML formatted text
|
||||||
|
*/
|
||||||
|
class HTMLItemDelegate
|
||||||
|
: public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
HTMLItemDelegate (QObject *parent);
|
||||||
|
|
||||||
|
virtual void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
virtual QSize sizeHint (const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
virtual bool editorEvent (QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
|
||||||
|
|
||||||
|
void set_anchors_clickable (bool a);
|
||||||
|
bool anchors_clickable () const
|
||||||
|
{
|
||||||
|
return m_anchors_clickable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_icon_margin (int m);
|
||||||
|
int icon_margin () const
|
||||||
|
{
|
||||||
|
return m_icon_margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_icon_spacing (int s);
|
||||||
|
int icon_spacing () const
|
||||||
|
{
|
||||||
|
return m_icon_spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_text_margin (int m);
|
||||||
|
int text_margin () const
|
||||||
|
{
|
||||||
|
return m_text_margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_text_height (int h);
|
||||||
|
int text_height () const
|
||||||
|
{
|
||||||
|
return m_text_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_text_width (int w);
|
||||||
|
int text_width () const
|
||||||
|
{
|
||||||
|
return m_text_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_plain_text (bool pt);
|
||||||
|
bool plain_text () const
|
||||||
|
{
|
||||||
|
return m_plain_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void anchor_clicked (const QString &url);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_icon_margin, m_icon_spacing, m_text_margin;
|
||||||
|
int m_text_width, m_text_height;
|
||||||
|
bool m_plain_text;
|
||||||
|
bool m_anchors_clickable;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -22,9 +22,12 @@
|
||||||
|
|
||||||
|
|
||||||
#include "layNetlistBrowserPage.h"
|
#include "layNetlistBrowserPage.h"
|
||||||
|
#include "layItemDelegates.h"
|
||||||
#include "dbLayoutToNetlist.h"
|
#include "dbLayoutToNetlist.h"
|
||||||
#include "dbNetlistDeviceClasses.h"
|
#include "dbNetlistDeviceClasses.h"
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
namespace lay
|
namespace lay
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -429,6 +432,45 @@ NetlistBrowserModel::data (const QModelIndex &index, int role) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
NetlistBrowserModel::make_link_to (const db::Net *net) const
|
||||||
|
{
|
||||||
|
if (! net) {
|
||||||
|
return QString ();
|
||||||
|
} else {
|
||||||
|
void *id = make_id_circuit_net (circuit_index (net->circuit ()), net_index (net));
|
||||||
|
return tl::to_qstring (tl::sprintf ("<a href='int:net?id=%s'>%s</a>", tl::to_string (reinterpret_cast<size_t> (id)), net->expanded_name ()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
std::string device_string (const db::Device *device)
|
||||||
|
{
|
||||||
|
if (! device || ! device->device_class ()) {
|
||||||
|
return std::string ();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string s = device->device_class ()->name ();
|
||||||
|
bool first = true;
|
||||||
|
const std::vector<db::DeviceParameterDefinition> &pd = device->device_class ()->parameter_definitions ();
|
||||||
|
for (std::vector<db::DeviceParameterDefinition>::const_iterator p = pd.begin (); p != pd.end (); ++p) {
|
||||||
|
if (p->is_primary ()) {
|
||||||
|
if (first) {
|
||||||
|
s += " [";
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
s += ", ";
|
||||||
|
}
|
||||||
|
s += p->name ();
|
||||||
|
s += "=";
|
||||||
|
double v = device->parameter_value (p->id ());
|
||||||
|
s += tl::to_string (v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s += "]";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
NetlistBrowserModel::text (const QModelIndex &index) const
|
NetlistBrowserModel::text (const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
|
|
@ -436,99 +478,152 @@ NetlistBrowserModel::text (const QModelIndex &index) const
|
||||||
|
|
||||||
if (is_id_circuit (id)) {
|
if (is_id_circuit (id)) {
|
||||||
|
|
||||||
db::Circuit *circuit = circuit_from_id (id);
|
// circuit: header column = name, other columns empty
|
||||||
if (circuit) {
|
if (index.column () == 0) {
|
||||||
return tl::to_qstring (circuit->name ());
|
db::Circuit *circuit = circuit_from_id (id);
|
||||||
|
if (circuit) {
|
||||||
|
return tl::to_qstring (circuit->name ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_pin (id) || is_id_circuit_subcircuit_pin (id)) {
|
} else if (is_id_circuit_pin (id) || is_id_circuit_subcircuit_pin (id)) {
|
||||||
|
|
||||||
db::Pin *pin = pin_from_id (id);
|
// circuit/pin: header column = name, other columns empty
|
||||||
if (pin) {
|
if (index.column () == 0) {
|
||||||
return tl::to_qstring (pin->expanded_name ());
|
db::Pin *pin = pin_from_id (id);
|
||||||
|
if (pin) {
|
||||||
|
return tl::to_qstring (pin->expanded_name ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_pin_net (id)) {
|
} else if (is_id_circuit_pin_net (id)) {
|
||||||
|
|
||||||
|
// circuit/pin/net: header column = name, second column link to net
|
||||||
db::Circuit *circuit = circuit_from_id (id);
|
db::Circuit *circuit = circuit_from_id (id);
|
||||||
db::Pin *pin = pin_from_id (id);
|
db::Pin *pin = pin_from_id (id);
|
||||||
if (pin) {
|
if (pin) {
|
||||||
db::Net *net = circuit->net_for_pin (pin->id ());
|
db::Net *net = circuit->net_for_pin (pin->id ());
|
||||||
if (net) {
|
if (net) {
|
||||||
return tl::to_qstring (net->expanded_name ());
|
if (index.column () == 0) {
|
||||||
|
return tl::to_qstring (net->expanded_name ());
|
||||||
|
} else {
|
||||||
|
return make_link_to (net);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_device (id)) {
|
} else if (is_id_circuit_device (id)) {
|
||||||
|
|
||||||
|
// circuit/device: header column = class + parameters, second column device name
|
||||||
db::Device *device = device_from_id (id);
|
db::Device *device = device_from_id (id);
|
||||||
if (device) {
|
if (device && device->device_class ()) {
|
||||||
return tl::to_qstring (device->expanded_name ());
|
|
||||||
|
if (index.column () == 0) {
|
||||||
|
return tl::to_qstring (device_string (device));
|
||||||
|
} else {
|
||||||
|
return tl::to_qstring (device->expanded_name ());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_device_terminal (id)) {
|
} else if (is_id_circuit_device_terminal (id)) {
|
||||||
|
|
||||||
|
// circuit/device/terminal: header column = terminal name, second column link to net
|
||||||
db::Device *device = device_from_id (id);
|
db::Device *device = device_from_id (id);
|
||||||
if (device && device->device_class ()) {
|
if (device && device->device_class ()) {
|
||||||
size_t terminal = circuit_device_terminal_index_from_id (id);
|
size_t terminal = circuit_device_terminal_index_from_id (id);
|
||||||
if (device->device_class ()->terminal_definitions ().size () > terminal) {
|
if (device->device_class ()->terminal_definitions ().size () > terminal) {
|
||||||
return tl::to_qstring (device->device_class ()->terminal_definitions () [terminal].name ());
|
const db::DeviceTerminalDefinition &td = device->device_class ()->terminal_definitions () [terminal];
|
||||||
|
if (index.column () == 0) {
|
||||||
|
return tl::to_qstring (td.name ());
|
||||||
|
} else {
|
||||||
|
return make_link_to (device->net_for_terminal (td.id ()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_subcircuit (id)) {
|
} else if (is_id_circuit_subcircuit (id)) {
|
||||||
|
|
||||||
|
// circuit/subcircuit: header column = circuit name, second column subcircuit name
|
||||||
db::SubCircuit *subcircuit = subcircuit_from_id (id);
|
db::SubCircuit *subcircuit = subcircuit_from_id (id);
|
||||||
if (subcircuit) {
|
if (subcircuit) {
|
||||||
return tl::to_qstring (subcircuit->expanded_name ());
|
if (index.column () == 0) {
|
||||||
|
return tl::to_qstring (subcircuit->circuit_ref ()->name ());
|
||||||
|
} else {
|
||||||
|
return tl::to_qstring (subcircuit->expanded_name ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_net (id)) {
|
} else if (is_id_circuit_net (id)) {
|
||||||
|
|
||||||
|
// circuit/net: header column = node count, second column net name
|
||||||
db::Net *net = net_from_id (id);
|
db::Net *net = net_from_id (id);
|
||||||
if (net) {
|
if (net) {
|
||||||
return tl::to_qstring (net->expanded_name ());
|
if (index.column () == 0) {
|
||||||
|
return tl::to_qstring ("(" + tl::to_string (net->pin_count () + net->terminal_count () + net->subcircuit_pin_count ()) + ")");
|
||||||
|
} else {
|
||||||
|
return tl::to_qstring (net->expanded_name ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_net_pin (id)) {
|
} else if (is_id_circuit_net_pin (id)) {
|
||||||
|
|
||||||
|
// circuit/net/pin: header column = pin name, second column empty (for now)
|
||||||
const db::NetPinRef *ref = net_pinref_from_id (id);
|
const db::NetPinRef *ref = net_pinref_from_id (id);
|
||||||
if (ref && ref->pin ()) {
|
if (ref && ref->pin ()) {
|
||||||
return tl::to_qstring (ref->pin ()->expanded_name ());
|
if (index.column () == 0) {
|
||||||
|
// TODO: make link to pin
|
||||||
|
return tl::to_qstring (ref->pin ()->expanded_name ());
|
||||||
|
}
|
||||||
|
// TODO: in case of compare use second and third column
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_net_subcircuit_pin (id)) {
|
} else if (is_id_circuit_net_subcircuit_pin (id)) {
|
||||||
|
|
||||||
|
// TODO: enhance
|
||||||
const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id);
|
const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id);
|
||||||
if (ref && ref->pin ()) {
|
if (ref && ref->pin ()) {
|
||||||
|
// TODO: make link to circuit
|
||||||
return tl::to_qstring (ref->pin ()->expanded_name ());
|
return tl::to_qstring (ref->pin ()->expanded_name ());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_net_subcircuit_pin_others (id)) {
|
} else if (is_id_circuit_net_subcircuit_pin_others (id)) {
|
||||||
|
|
||||||
|
// TODO: enhance
|
||||||
const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id);
|
const db::NetSubcircuitPinRef *ref = net_subcircuit_pinref_from_id (id);
|
||||||
size_t other_index = circuit_net_subcircuit_pin_other_index_from_id (id);
|
size_t other_index = circuit_net_subcircuit_pin_other_index_from_id (id);
|
||||||
|
|
||||||
if (ref && ref->pin () && ref->subcircuit () && ref->subcircuit ()->circuit_ref () && ref->subcircuit ()->circuit_ref ()->pin_by_id (other_index)) {
|
if (ref && ref->pin () && ref->subcircuit () && ref->subcircuit ()->circuit_ref () && ref->subcircuit ()->circuit_ref ()->pin_by_id (other_index)) {
|
||||||
const db::Pin *pin = ref->subcircuit ()->circuit_ref ()->pin_by_id (other_index);
|
const db::Pin *pin = ref->subcircuit ()->circuit_ref ()->pin_by_id (other_index);
|
||||||
|
// TODO: make link to pin inside circuit
|
||||||
return tl::to_qstring (pin->expanded_name ());
|
return tl::to_qstring (pin->expanded_name ());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_net_device_terminal (id)) {
|
} else if (is_id_circuit_net_device_terminal (id)) {
|
||||||
|
|
||||||
|
// circuit/net/device terminal: header column = terminal and device string, second column = device name
|
||||||
const db::NetTerminalRef *ref = net_terminalref_from_id (id);
|
const db::NetTerminalRef *ref = net_terminalref_from_id (id);
|
||||||
if (ref && ref->terminal_def ()) {
|
if (ref && ref->terminal_def ()) {
|
||||||
return tl::to_qstring (ref->terminal_def ()->name ());
|
if (index.column () == 0) {
|
||||||
|
return tl::to_qstring (ref->terminal_def ()->name () + " - " + device_string (ref->device ()));
|
||||||
|
} else {
|
||||||
|
return tl::to_qstring (ref->device ()->expanded_name ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is_id_circuit_net_device_terminal_others (id)) {
|
} else if (is_id_circuit_net_device_terminal_others (id)) {
|
||||||
|
|
||||||
|
// circuit/net/device terminal/more: header column = terminal name, second column = net link
|
||||||
const db::NetTerminalRef *ref = net_terminalref_from_id (id);
|
const db::NetTerminalRef *ref = net_terminalref_from_id (id);
|
||||||
size_t other_index = circuit_net_device_terminal_other_index_from_id (id);
|
size_t other_index = circuit_net_device_terminal_other_index_from_id (id);
|
||||||
|
|
||||||
if (ref && ref->device_class () && ref->device_class ()->terminal_definitions ().size () > other_index) {
|
if (ref && ref->device_class () && ref->device_class ()->terminal_definitions ().size () > other_index) {
|
||||||
const db::DeviceTerminalDefinition &def = ref->device_class ()->terminal_definitions ()[other_index];
|
const db::DeviceTerminalDefinition &def = ref->device_class ()->terminal_definitions ()[other_index];
|
||||||
return tl::to_qstring (def.name ());
|
if (index.column () == 0) {
|
||||||
|
return tl::to_qstring (def.name ());
|
||||||
|
} else {
|
||||||
|
return make_link_to (ref->device ()->net_for_terminal (def.id ()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -762,6 +857,20 @@ NetlistBrowserModel::index (int row, int column, const QModelIndex &parent) cons
|
||||||
return createIndex (row, column, new_id);
|
return createIndex (row, column, new_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QModelIndex
|
||||||
|
NetlistBrowserModel::index_from_id (void *id, int column) const
|
||||||
|
{
|
||||||
|
if (is_id_circuit_net (id)) {
|
||||||
|
db::Circuit *circuit = circuit_from_id (id);
|
||||||
|
return createIndex (int (circuit->pin_count () + circuit_net_index_from_id (id)), column, make_id_circuit_net (circuit_index_from_id (id), circuit_net_index_from_id (id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: more ...
|
||||||
|
|
||||||
|
return QModelIndex ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QModelIndex
|
QModelIndex
|
||||||
NetlistBrowserModel::parent (const QModelIndex &index) const
|
NetlistBrowserModel::parent (const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
|
|
@ -979,6 +1088,38 @@ NetlistBrowserModel::subcircuit_from_id (void *id) const
|
||||||
return attr_by_object_and_index (circuit, index, circuit->begin_subcircuits (), circuit->end_subcircuits (), m_subcircuit_by_circuit_and_index);
|
return attr_by_object_and_index (circuit, index, circuit->begin_subcircuits (), circuit->end_subcircuits (), m_subcircuit_by_circuit_and_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class Attr, class Iter>
|
||||||
|
static size_t index_from_attr (const Attr *attr, const Iter &begin, const Iter &end, std::map<const Attr *, size_t> &cache)
|
||||||
|
{
|
||||||
|
typename std::map<const Attr *, size_t>::iterator cc = cache.find (attr);
|
||||||
|
if (cc != cache.end ()) {
|
||||||
|
return cc->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t index = 0;
|
||||||
|
for (Iter i = begin; i != end; ++i, ++index) {
|
||||||
|
if (i.operator-> () == attr) {
|
||||||
|
cache.insert (std::make_pair (i.operator-> (), index));
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tl_assert (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
NetlistBrowserModel::circuit_index (const db::Circuit *circuit) const
|
||||||
|
{
|
||||||
|
return index_from_attr (circuit, netlist ()->begin_circuits (), netlist ()->end_circuits (), m_circuit_index_by_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
NetlistBrowserModel::net_index (const db::Net *net) const
|
||||||
|
{
|
||||||
|
const db::Circuit *circuit = net->circuit ();
|
||||||
|
return index_from_attr (net, circuit->begin_nets (), circuit->end_nets (), m_net_index_by_object);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// NetlistBrowserPage implementation
|
// NetlistBrowserPage implementation
|
||||||
|
|
||||||
|
|
@ -994,7 +1135,8 @@ NetlistBrowserPage::NetlistBrowserPage (QWidget * /*parent*/)
|
||||||
m_marker_dither_pattern (-1),
|
m_marker_dither_pattern (-1),
|
||||||
mp_view (0),
|
mp_view (0),
|
||||||
m_cv_index (0),
|
m_cv_index (0),
|
||||||
mp_plugin_root (0)
|
mp_plugin_root (0),
|
||||||
|
m_history_ptr (0)
|
||||||
{
|
{
|
||||||
Ui::NetlistBrowserPage::setupUi (this);
|
Ui::NetlistBrowserPage::setupUi (this);
|
||||||
|
|
||||||
|
|
@ -1002,8 +1144,26 @@ NetlistBrowserPage::NetlistBrowserPage (QWidget * /*parent*/)
|
||||||
m_show_all_action->setCheckable (true);
|
m_show_all_action->setCheckable (true);
|
||||||
m_show_all_action->setChecked (m_show_all);
|
m_show_all_action->setChecked (m_show_all);
|
||||||
|
|
||||||
|
lay::HTMLItemDelegate *delegate;
|
||||||
|
|
||||||
|
delegate = new lay::HTMLItemDelegate (this);
|
||||||
|
delegate->set_text_margin (2);
|
||||||
|
delegate->set_anchors_clickable (true);
|
||||||
|
connect (delegate, SIGNAL (anchor_clicked (const QString &)), this, SLOT (anchor_clicked (const QString &)));
|
||||||
|
directory_tree->setItemDelegateForColumn (1, delegate);
|
||||||
|
|
||||||
|
delegate = new lay::HTMLItemDelegate (this);
|
||||||
|
delegate->set_text_margin (2);
|
||||||
|
delegate->set_plain_text (true);
|
||||||
|
directory_tree->setItemDelegateForColumn (0, delegate);
|
||||||
|
|
||||||
connect (m_show_all_action, SIGNAL (triggered ()), this, SLOT (show_all_clicked ()));
|
connect (m_show_all_action, SIGNAL (triggered ()), this, SLOT (show_all_clicked ()));
|
||||||
connect (filter, SIGNAL (textEdited (const QString &)), this, SLOT (filter_changed ()));
|
connect (filter, SIGNAL (textEdited (const QString &)), this, SLOT (filter_changed ()));
|
||||||
|
connect (forward, SIGNAL (clicked ()), this, SLOT (navigate_forward ()));
|
||||||
|
connect (backward, SIGNAL (clicked ()), this, SLOT (navigate_back ()));
|
||||||
|
|
||||||
|
forward->setEnabled (false);
|
||||||
|
backward->setEnabled (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
NetlistBrowserPage::~NetlistBrowserPage ()
|
NetlistBrowserPage::~NetlistBrowserPage ()
|
||||||
|
|
@ -1057,6 +1217,85 @@ NetlistBrowserPage::set_max_shape_count (size_t max_shape_count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserPage::anchor_clicked (const QString &a)
|
||||||
|
{
|
||||||
|
QUrl url (a);
|
||||||
|
QString ids = url.queryItemValue (QString::fromUtf8 ("id"));
|
||||||
|
if (ids.isEmpty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *id = reinterpret_cast<void *> (ids.toULongLong ());
|
||||||
|
navigate_to (id, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserPage::navigate_to (void *id, bool fwd)
|
||||||
|
{
|
||||||
|
NetlistBrowserModel *model = dynamic_cast<NetlistBrowserModel *> (directory_tree->model ());
|
||||||
|
if (! model) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex index = model->index_from_id (id, 0);
|
||||||
|
if (! index.isValid ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
directory_tree->setCurrentIndex (index);
|
||||||
|
|
||||||
|
add_to_history (id, fwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserPage::current_index_changed (const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if (index.isValid ()) {
|
||||||
|
printf("@@@1\n"); fflush(stdout);
|
||||||
|
add_to_history (index.internalPointer (), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserPage::add_to_history (void *id, bool fwd)
|
||||||
|
{
|
||||||
|
if (! fwd) {
|
||||||
|
if (m_history_ptr > 1) {
|
||||||
|
--m_history_ptr;
|
||||||
|
m_history [m_history_ptr - 1] = id;
|
||||||
|
}
|
||||||
|
} else if (m_history_ptr >= m_history.size ()) {
|
||||||
|
m_history.push_back (id);
|
||||||
|
m_history_ptr = m_history.size ();
|
||||||
|
} else {
|
||||||
|
if (m_history [m_history_ptr] != id) {
|
||||||
|
m_history.erase (m_history.begin () + m_history_ptr + 1, m_history.end ());
|
||||||
|
}
|
||||||
|
m_history [m_history_ptr] = id;
|
||||||
|
++m_history_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
backward->setEnabled (m_history_ptr > 1);
|
||||||
|
forward->setEnabled (m_history_ptr < m_history.size ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserPage::navigate_back ()
|
||||||
|
{
|
||||||
|
if (m_history_ptr > 1) {
|
||||||
|
navigate_to (m_history [m_history_ptr - 2], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetlistBrowserPage::navigate_forward ()
|
||||||
|
{
|
||||||
|
if (m_history_ptr < m_history.size ()) {
|
||||||
|
navigate_to (m_history [m_history_ptr]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NetlistBrowserPage::filter_changed ()
|
NetlistBrowserPage::filter_changed ()
|
||||||
{
|
{
|
||||||
|
|
@ -1137,6 +1376,7 @@ NetlistBrowserPage::set_l2ndb (db::LayoutToNetlist *database)
|
||||||
NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database);
|
NetlistBrowserModel *new_model = new NetlistBrowserModel (directory_tree, database);
|
||||||
|
|
||||||
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 (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (directory_selection_changed (const QItemSelection &, const QItemSelection &)));
|
// @@@ connect (directory_tree->selectionModel (), SIGNAL (selectionChanged (const QItemSelection &, const QItemSelection &)), this, SLOT (directory_selection_changed (const QItemSelection &, const QItemSelection &)));
|
||||||
|
|
||||||
directory_tree->header ()->setSortIndicatorShown (true);
|
directory_tree->header ()->setSortIndicatorShown (true);
|
||||||
|
|
|
||||||
|
|
@ -78,8 +78,9 @@ public:
|
||||||
virtual QModelIndex parent (const QModelIndex &index) const;
|
virtual QModelIndex parent (const QModelIndex &index) const;
|
||||||
virtual int rowCount (const QModelIndex &parent) const;
|
virtual int rowCount (const QModelIndex &parent) const;
|
||||||
|
|
||||||
private:
|
QModelIndex index_from_id (void *id, int column) const;
|
||||||
|
|
||||||
|
private:
|
||||||
void *make_id_circuit (size_t circuit_index) const;
|
void *make_id_circuit (size_t circuit_index) const;
|
||||||
void *make_id_circuit_pin (size_t circuit_index, size_t pin_index) const;
|
void *make_id_circuit_pin (size_t circuit_index, size_t pin_index) const;
|
||||||
void *make_id_circuit_pin_net (size_t circuit_index, size_t pin_index, size_t net_index) const;
|
void *make_id_circuit_pin_net (size_t circuit_index, size_t pin_index, size_t net_index) const;
|
||||||
|
|
@ -128,6 +129,9 @@ private:
|
||||||
db::SubCircuit *subcircuit_from_id (void *id) const;
|
db::SubCircuit *subcircuit_from_id (void *id) const;
|
||||||
QString text (const QModelIndex &index) const;
|
QString text (const QModelIndex &index) const;
|
||||||
QIcon icon (const QModelIndex &index) const;
|
QIcon icon (const QModelIndex &index) const;
|
||||||
|
size_t circuit_index (const db::Circuit *attr) const;
|
||||||
|
size_t net_index (const db::Net *attr) const;
|
||||||
|
QString make_link_to (const db::Net *net) const;
|
||||||
|
|
||||||
db::Netlist *netlist () const
|
db::Netlist *netlist () const
|
||||||
{
|
{
|
||||||
|
|
@ -143,6 +147,8 @@ private:
|
||||||
mutable std::map<db::Circuit *, std::map<size_t, db::Device *> > m_device_by_circuit_and_index;
|
mutable std::map<db::Circuit *, std::map<size_t, db::Device *> > m_device_by_circuit_and_index;
|
||||||
mutable std::map<db::Circuit *, std::map<size_t, db::Pin *> > m_pin_by_circuit_and_index;
|
mutable std::map<db::Circuit *, std::map<size_t, db::Pin *> > m_pin_by_circuit_and_index;
|
||||||
mutable std::map<db::Circuit *, std::map<size_t, db::SubCircuit *> > m_subcircuit_by_circuit_and_index;
|
mutable std::map<db::Circuit *, std::map<size_t, db::SubCircuit *> > m_subcircuit_by_circuit_and_index;
|
||||||
|
mutable std::map<const db::Circuit *, size_t> m_circuit_index_by_object;
|
||||||
|
mutable std::map<const db::Net *, size_t> m_net_index_by_object;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -239,6 +245,10 @@ public:
|
||||||
private slots:
|
private slots:
|
||||||
void show_all_clicked ();
|
void show_all_clicked ();
|
||||||
void filter_changed ();
|
void filter_changed ();
|
||||||
|
void anchor_clicked (const QString &url);
|
||||||
|
void navigate_back ();
|
||||||
|
void navigate_forward ();
|
||||||
|
void current_index_changed (const QModelIndex &index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_show_all;
|
bool m_show_all;
|
||||||
|
|
@ -256,6 +266,11 @@ private:
|
||||||
unsigned int m_cv_index;
|
unsigned int m_cv_index;
|
||||||
lay::PluginRoot *mp_plugin_root;
|
lay::PluginRoot *mp_plugin_root;
|
||||||
tl::weak_ptr<db::LayoutToNetlist> mp_database;
|
tl::weak_ptr<db::LayoutToNetlist> mp_database;
|
||||||
|
std::vector<void *> m_history;
|
||||||
|
size_t m_history_ptr;
|
||||||
|
|
||||||
|
void add_to_history (void *id, bool fwd);
|
||||||
|
void navigate_to (void *id, bool forward = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lay
|
} // namespace lay
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,8 @@ SOURCES = \
|
||||||
layBackgroundAwareTreeStyle.cc \
|
layBackgroundAwareTreeStyle.cc \
|
||||||
layNetlistBrowser.cc \
|
layNetlistBrowser.cc \
|
||||||
layNetlistBrowserDialog.cc \
|
layNetlistBrowserDialog.cc \
|
||||||
layNetlistBrowserPage.cc
|
layNetlistBrowserPage.cc \
|
||||||
|
layItemDelegates.cc
|
||||||
|
|
||||||
HEADERS = \
|
HEADERS = \
|
||||||
gtf.h \
|
gtf.h \
|
||||||
|
|
@ -255,7 +256,8 @@ HEADERS = \
|
||||||
layBackgroundAwareTreeStyle.h \
|
layBackgroundAwareTreeStyle.h \
|
||||||
layNetlistBrowser.h \
|
layNetlistBrowser.h \
|
||||||
layNetlistBrowserDialog.h \
|
layNetlistBrowserDialog.h \
|
||||||
layNetlistBrowserPage.h
|
layNetlistBrowserPage.h \
|
||||||
|
layItemDelegates.h
|
||||||
|
|
||||||
INCLUDEPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC
|
INCLUDEPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC
|
||||||
DEPENDPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC
|
DEPENDPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue