mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-08 04:08:14 +02:00
WIP: turned ext module into plugins.
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = lay_plugin
|
||||
|
||||
@@ -0,0 +1,843 @@
|
||||
<ui version="4.0" >
|
||||
<class>StreamImportDialog</class>
|
||||
<widget class="QDialog" name="StreamImportDialog" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>754</width>
|
||||
<height>604</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="6" column="1" >
|
||||
<widget class="QPushButton" name="last_pb" >
|
||||
<property name="text" >
|
||||
<string>Back</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="layResources.qrc" >:/back.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>331</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="6" column="3" >
|
||||
<widget class="QPushButton" name="import_pb" >
|
||||
<property name="text" >
|
||||
<string>Import</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2" >
|
||||
<widget class="QPushButton" name="next_pb" >
|
||||
<property name="text" >
|
||||
<string>Next</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="layResources.qrc" >:/forward.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="4" >
|
||||
<widget class="QPushButton" name="cancel_pb" >
|
||||
<property name="text" >
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="5" >
|
||||
<widget class="Line" name="line_4" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="5" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>736</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="5" >
|
||||
<widget class="Line" name="line" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="5" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>736</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="5" >
|
||||
<widget class="QFrame" name="frame_3" >
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="section_header_lbl" >
|
||||
<property name="font" >
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>SectionHeader</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="reset_pb" >
|
||||
<property name="text" >
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="5" >
|
||||
<widget class="QStackedWidget" name="central_stack" >
|
||||
<property name="currentIndex" >
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page" >
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4" >
|
||||
<property name="title" >
|
||||
<string>Input</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="label_7" >
|
||||
<property name="text" >
|
||||
<string>Top cell </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2" >
|
||||
<widget class="QLineEdit" name="file_le" />
|
||||
</item>
|
||||
<item row="0" column="3" >
|
||||
<widget class="QToolButton" name="file_pb" >
|
||||
<property name="text" >
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_6" >
|
||||
<property name="text" >
|
||||
<string>File </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2" >
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>5</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>(leave empty for selecting the top cell automatically)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLineEdit" name="topcell_le" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>7</hsizetype>
|
||||
<vsizetype>0</vsizetype>
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="4" >
|
||||
<widget class="QFrame" name="frame_2" >
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3" >
|
||||
<property name="text" >
|
||||
<string>Stream reader options </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="edit_options_pb" >
|
||||
<property name="text" >
|
||||
<string>Edit ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="reset_options_pb" >
|
||||
<property name="text" >
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox" >
|
||||
<property name="title" >
|
||||
<string>Import Mode</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="import_simple_rb" >
|
||||
<property name="text" >
|
||||
<string>Merge - Merge new cell into current cell and create a new cell hierarchy below</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="import_extra_rb" >
|
||||
<property name="text" >
|
||||
<string>Extra cells - Import as extra cells</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="import_instantiate_rb" >
|
||||
<property name="text" >
|
||||
<string>Instantiate - Instantiate a new cell tree below the current cell</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="import_merge_rb" >
|
||||
<property name="text" >
|
||||
<string>Merge hierarchy - Merge into current cell's hierarchy (attempt to identify corresponding cells)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8" >
|
||||
<property name="text" >
|
||||
<string>Note: All modes except "Extra cells" require a unique top cell for the input file. Either one must be specified or the input file must have a single top cell.</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_2" >
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame" >
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item rowspan="5" row="0" column="0" >
|
||||
<widget class="QGroupBox" name="groupBox_2" >
|
||||
<property name="title" >
|
||||
<string>Layer mapping</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="1" colspan="2" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<string>Use "layer/datatype" notation to specify an offset to be added to layer and/or datatype.</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QLineEdit" name="offset_le" />
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QRadioButton" name="offset_rb" >
|
||||
<property name="text" >
|
||||
<string>On original layers plus offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QRadioButton" name="no_mapping_rb" >
|
||||
<property name="text" >
|
||||
<string>No mapping - use original layers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>211</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_6" >
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_5" >
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="3" column="5" >
|
||||
<widget class="QLineEdit" name="layout_x1_le" />
|
||||
</item>
|
||||
<item row="5" column="2" >
|
||||
<widget class="QLineEdit" name="pcb_y3_le" />
|
||||
</item>
|
||||
<item row="3" column="4" >
|
||||
<widget class="QLabel" name="label_22" >
|
||||
<property name="text" >
|
||||
<string>Point 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="6" >
|
||||
<widget class="QLabel" name="label_24" >
|
||||
<property name="text" >
|
||||
<string>y (micron)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3" >
|
||||
<widget class="QLabel" name="label_17" >
|
||||
<property name="text" >
|
||||
<string>Reference points coordinates on layout to import</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2" >
|
||||
<widget class="QLineEdit" name="pcb_y2_le" />
|
||||
</item>
|
||||
<item row="5" column="4" >
|
||||
<widget class="QLabel" name="Point 3" >
|
||||
<property name="text" >
|
||||
<string>Point 3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="5" >
|
||||
<widget class="QLineEdit" name="layout_x2_le" />
|
||||
</item>
|
||||
<item row="0" column="4" colspan="3" >
|
||||
<widget class="QLabel" name="label_18" >
|
||||
<property name="text" >
|
||||
<string>Reference point coordinates in existing layout</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="5" >
|
||||
<widget class="QLineEdit" name="layout_x3_le" />
|
||||
</item>
|
||||
<item row="5" column="6" >
|
||||
<widget class="QLineEdit" name="layout_y3_le" />
|
||||
</item>
|
||||
<item row="2" column="5" >
|
||||
<widget class="QLabel" name="label_23" >
|
||||
<property name="text" >
|
||||
<string>x (micron)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3" >
|
||||
<widget class="Line" name="line_2" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" >
|
||||
<widget class="QLabel" name="label_25" >
|
||||
<property name="text" >
|
||||
<string>Point 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" >
|
||||
<widget class="QLineEdit" name="pcb_x2_le" />
|
||||
</item>
|
||||
<item row="5" column="0" >
|
||||
<widget class="QLabel" name="label_26" >
|
||||
<property name="text" >
|
||||
<string>Point 3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" >
|
||||
<widget class="QLabel" name="label_21" >
|
||||
<property name="text" >
|
||||
<string>Point 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" >
|
||||
<widget class="QLineEdit" name="pcb_x3_le" />
|
||||
</item>
|
||||
<item row="3" column="2" >
|
||||
<widget class="QLineEdit" name="pcb_y1_le" />
|
||||
</item>
|
||||
<item row="1" column="4" colspan="3" >
|
||||
<widget class="Line" name="line_3" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" >
|
||||
<widget class="QLineEdit" name="pcb_x1_le" />
|
||||
</item>
|
||||
<item row="2" column="2" >
|
||||
<widget class="QLabel" name="label_20" >
|
||||
<property name="text" >
|
||||
<string>y (micron)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" >
|
||||
<widget class="QLabel" name="label_19" >
|
||||
<property name="text" >
|
||||
<string>x (micron)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="4" >
|
||||
<widget class="QLabel" name="label_27" >
|
||||
<property name="text" >
|
||||
<string>Point 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="6" >
|
||||
<widget class="QLineEdit" name="layout_y2_le" />
|
||||
</item>
|
||||
<item row="3" column="6" >
|
||||
<widget class="QLineEdit" name="layout_y1_le" />
|
||||
</item>
|
||||
<item rowspan="6" row="0" column="3" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="7" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>691</width>
|
||||
<height>8</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="7" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>15</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="7" >
|
||||
<widget class="QFrame" name="frame_6" >
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_30" >
|
||||
<property name="text" >
|
||||
<string>Explicit transformation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="explicit_trans_le" >
|
||||
<property name="toolTip" >
|
||||
<string>Examples: "r90", "m45", "r90 (2000,-5000)"</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_31" >
|
||||
<property name="text" >
|
||||
<string>(Reference points have higher priority)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="7" >
|
||||
<widget class="QLabel" name="label_29" >
|
||||
<property name="text" >
|
||||
<string>Leave fields empty to specify less reference points. One point is used to derive the displacement, further points are used to derive the orientation. Currently, no magnification is implied and only simple rotations are derived from the mapping points.
|
||||
|
||||
Alternatively the transformation (imported to existing layout) can be specified using the explicit transformation below. This allows to specify an arbitary transformation. Use the common notation (i.e. "*2 r90 10,-100").</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>file_le</tabstop>
|
||||
<tabstop>file_pb</tabstop>
|
||||
<tabstop>topcell_le</tabstop>
|
||||
<tabstop>edit_options_pb</tabstop>
|
||||
<tabstop>reset_options_pb</tabstop>
|
||||
<tabstop>import_simple_rb</tabstop>
|
||||
<tabstop>import_extra_rb</tabstop>
|
||||
<tabstop>import_instantiate_rb</tabstop>
|
||||
<tabstop>import_merge_rb</tabstop>
|
||||
<tabstop>no_mapping_rb</tabstop>
|
||||
<tabstop>offset_rb</tabstop>
|
||||
<tabstop>offset_le</tabstop>
|
||||
<tabstop>pcb_x1_le</tabstop>
|
||||
<tabstop>pcb_y1_le</tabstop>
|
||||
<tabstop>layout_x1_le</tabstop>
|
||||
<tabstop>layout_y1_le</tabstop>
|
||||
<tabstop>pcb_x2_le</tabstop>
|
||||
<tabstop>pcb_y2_le</tabstop>
|
||||
<tabstop>layout_x2_le</tabstop>
|
||||
<tabstop>layout_y2_le</tabstop>
|
||||
<tabstop>pcb_x3_le</tabstop>
|
||||
<tabstop>pcb_y3_le</tabstop>
|
||||
<tabstop>layout_x3_le</tabstop>
|
||||
<tabstop>layout_y3_le</tabstop>
|
||||
<tabstop>explicit_trans_le</tabstop>
|
||||
<tabstop>last_pb</tabstop>
|
||||
<tabstop>next_pb</tabstop>
|
||||
<tabstop>import_pb</tabstop>
|
||||
<tabstop>cancel_pb</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="layResources.qrc" />
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>import_pb</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>StreamImportDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>572</x>
|
||||
<y>598</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>574</x>
|
||||
<y>614</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>cancel_pb</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>StreamImportDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>679</x>
|
||||
<y>597</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>683</x>
|
||||
<y>613</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,173 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 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 "layStreamImportDialog.h"
|
||||
#include "layStreamImporter.h"
|
||||
|
||||
#include "dbStream.h"
|
||||
|
||||
#include "tlExceptions.h"
|
||||
#include "layPlugin.h"
|
||||
#include "layMainWindow.h"
|
||||
#include "layFileDialog.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
static const std::string cfg_stream_import_spec ("stream-import-spec2");
|
||||
|
||||
class StreamImportPluginDeclaration
|
||||
: public lay::PluginDeclaration
|
||||
{
|
||||
public:
|
||||
StreamImportPluginDeclaration ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void get_options (std::vector < std::pair<std::string, std::string> > &options) const
|
||||
{
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_stream_import_spec, ""));
|
||||
}
|
||||
|
||||
virtual lay::ConfigPage *config_page (QWidget * /*parent*/, std::string & /*title*/) const
|
||||
{
|
||||
// .. nothing yet ..
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
|
||||
{
|
||||
lay::PluginDeclaration::get_menu_entries (menu_entries);
|
||||
menu_entries.push_back (lay::MenuEntry ("lay::import_stream", "import_stream:edit", "file_menu.import_menu.end", tl::to_string (QObject::tr ("Other File Into Current"))));
|
||||
}
|
||||
|
||||
virtual bool configure (const std::string &name, const std::string &value)
|
||||
{
|
||||
if (name == cfg_stream_import_spec) {
|
||||
m_import_spec = value;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void config_finalize ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual bool menu_activated (const std::string &symbol) const
|
||||
{
|
||||
if (symbol == "lay::import_stream") {
|
||||
|
||||
lay::LayoutView *view = lay::LayoutView::current ();
|
||||
if (! view) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("No view open to import files into")));
|
||||
}
|
||||
|
||||
StreamImportData data;
|
||||
try {
|
||||
data.from_string (m_import_spec);
|
||||
} catch (...) {
|
||||
data = StreamImportData ();
|
||||
}
|
||||
|
||||
lay::PluginRoot *config_root = lay::PluginRoot::instance ();
|
||||
|
||||
StreamImportDialog dialog (QApplication::activeWindow (), &data);
|
||||
lay::StreamImporter importer;
|
||||
|
||||
bool ok = false;
|
||||
while (! ok && dialog.exec ()) {
|
||||
|
||||
BEGIN_PROTECTED
|
||||
data.setup_importer (&importer);
|
||||
ok = true;
|
||||
END_PROTECTED
|
||||
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
|
||||
// clear selection
|
||||
lay::MainWindow::instance ()->cancel ();
|
||||
|
||||
config_root->config_set (cfg_stream_import_spec, data.to_string ());
|
||||
config_root->config_end ();
|
||||
|
||||
int cv_index = view->active_cellview_index ();
|
||||
const lay::CellView &cv = view->cellview (cv_index);
|
||||
|
||||
std::vector <unsigned int> new_layer_ids;
|
||||
importer.read (cv->layout (), cv.cell_index (), new_layer_ids);
|
||||
|
||||
// create the initial layer properties
|
||||
std::vector <lay::ParsedLayerSource> new_layers;
|
||||
new_layers.reserve (cv->layout ().layers ());
|
||||
|
||||
for (unsigned int i = 0; i < new_layer_ids.size (); ++i) {
|
||||
if (cv->layout ().is_valid_layer (new_layer_ids [i])) {
|
||||
db::LayerProperties lp (cv->layout ().get_properties (new_layer_ids [i]));
|
||||
new_layers.push_back (lay::ParsedLayerSource (lp, cv_index));
|
||||
}
|
||||
}
|
||||
|
||||
std::sort (new_layers.begin (), new_layers.end ());
|
||||
|
||||
lay::LayerPropertiesList new_props (view->get_properties ());
|
||||
|
||||
// create the layers and do a basic recoloring ..
|
||||
for (std::vector <lay::ParsedLayerSource>::const_iterator l = new_layers.begin (); l != new_layers.end (); ++l) {
|
||||
lay::LayerProperties p;
|
||||
p.set_source (*l);
|
||||
view->init_layer_properties (p);
|
||||
new_props.push_back (p);
|
||||
}
|
||||
|
||||
view->set_properties (new_props);
|
||||
|
||||
view->update_content ();
|
||||
|
||||
config_root->config_set (cfg_stream_import_spec, data.to_string ());
|
||||
config_root->config_end ();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_import_spec;
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new lay::StreamImportPluginDeclaration (), 1300, "lay::StreamImportPlugin");
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,491 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 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 "ui_StreamImportDialog.h"
|
||||
#include "layStreamImporter.h"
|
||||
#include "layStreamImportDialog.h"
|
||||
|
||||
#include "tlExceptions.h"
|
||||
#include "layFileDialog.h"
|
||||
#include "layDialogs.h"
|
||||
#include "layConverters.h"
|
||||
#include "layLoadLayoutOptionsDialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace {
|
||||
|
||||
static struct {
|
||||
const char *string;
|
||||
lay::StreamImportData::mode_type value;
|
||||
} mode_strings [] = {
|
||||
{ "simple", lay::StreamImportData::Simple },
|
||||
{ "instantiate", lay::StreamImportData::Instantiate },
|
||||
{ "extra", lay::StreamImportData::Extra },
|
||||
{ "merge", lay::StreamImportData::Merge }
|
||||
};
|
||||
|
||||
struct ModeConverter
|
||||
{
|
||||
std::string to_string (lay::StreamImportData::mode_type t) const
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof (mode_strings) / sizeof (mode_strings [0]); ++i) {
|
||||
if (mode_strings [i].value == t) {
|
||||
return mode_strings [i].string;
|
||||
}
|
||||
}
|
||||
return std::string ();
|
||||
}
|
||||
|
||||
void from_string (const std::string &s, lay::StreamImportData::mode_type &t) const
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof (mode_strings) / sizeof (mode_strings [0]); ++i) {
|
||||
if (s == mode_strings [i].string) {
|
||||
t = mode_strings [i].value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
t = mode_strings [0].value;
|
||||
}
|
||||
};
|
||||
|
||||
static struct {
|
||||
const char *string;
|
||||
lay::StreamImportData::layer_mode_type value;
|
||||
} layer_mode_strings [] = {
|
||||
{ "original", lay::StreamImportData::Original },
|
||||
{ "offset", lay::StreamImportData::Offset }
|
||||
};
|
||||
|
||||
struct LayerModeConverter
|
||||
{
|
||||
std::string to_string (lay::StreamImportData::layer_mode_type t) const
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof (layer_mode_strings) / sizeof (layer_mode_strings [0]); ++i) {
|
||||
if (layer_mode_strings [i].value == t) {
|
||||
return layer_mode_strings [i].string;
|
||||
}
|
||||
}
|
||||
return std::string ();
|
||||
}
|
||||
|
||||
void from_string (const std::string &s, lay::StreamImportData::layer_mode_type &t) const
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof (layer_mode_strings) / sizeof (layer_mode_strings [0]); ++i) {
|
||||
if (s == layer_mode_strings [i].string) {
|
||||
t = layer_mode_strings [i].value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
t = layer_mode_strings [0].value;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// StreamImportData implementation
|
||||
|
||||
StreamImportData::StreamImportData ()
|
||||
: mode (Simple), layer_mode (Original)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportData::setup_importer (StreamImporter *importer)
|
||||
{
|
||||
importer->set_global_trans (explicit_trans);
|
||||
importer->set_reference_points (reference_points);
|
||||
importer->set_cell_mapping (mode);
|
||||
importer->set_layer_mapping (layer_mode);
|
||||
importer->set_file (file);
|
||||
importer->set_topcell (topcell);
|
||||
importer->set_layer_offset (layer_offset);
|
||||
importer->set_reader_options (options);
|
||||
}
|
||||
|
||||
static tl::XMLElementList xml_elements ()
|
||||
{
|
||||
typedef std::pair <db::DPoint, db::DPoint> ref_point;
|
||||
typedef std::vector<ref_point> ref_point_v;
|
||||
|
||||
return
|
||||
tl::make_member (&StreamImportData::file, "file") +
|
||||
tl::make_member (&StreamImportData::topcell, "cell-name") +
|
||||
tl::make_member (&StreamImportData::layer_offset, "layer-offset") +
|
||||
tl::make_member (&StreamImportData::layer_mode, "layer-mode", LayerModeConverter ()) +
|
||||
tl::make_member (&StreamImportData::mode, "import-mode", ModeConverter ()) +
|
||||
tl::make_element (&StreamImportData::reference_points, "reference-points",
|
||||
tl::make_element<ref_point, ref_point_v::const_iterator, ref_point_v> (&ref_point_v::begin, &ref_point_v::end, &ref_point_v::push_back, "reference-point",
|
||||
tl::make_member (&ref_point::first, "p1") +
|
||||
tl::make_member (&ref_point::second, "p2")
|
||||
)
|
||||
) +
|
||||
tl::make_member (&StreamImportData::explicit_trans, "explicit-trans") +
|
||||
tl::make_element (&StreamImportData::options, "options",
|
||||
db::load_options_xml_element_list ()
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportData::from_string (const std::string &s)
|
||||
{
|
||||
*this = StreamImportData ();
|
||||
|
||||
tl::XMLStringSource source (s);
|
||||
tl::XMLStruct<StreamImportData> xml_struct ("stream-import-data", xml_elements ());
|
||||
xml_struct.parse (source, *this);
|
||||
}
|
||||
|
||||
std::string
|
||||
StreamImportData::to_string () const
|
||||
{
|
||||
tl::OutputStringStream os;
|
||||
tl::XMLStruct<StreamImportData> xml_struct ("stream-import-data", xml_elements ());
|
||||
tl::OutputStream oss (os);
|
||||
xml_struct.write (oss, *this);
|
||||
return os.string ();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// StreamImportDialog implementation
|
||||
|
||||
StreamImportDialog::StreamImportDialog (QWidget *parent, StreamImportData *data)
|
||||
: QDialog (parent), mp_data (data)
|
||||
{
|
||||
mp_ui = new Ui::StreamImportDialog ();
|
||||
mp_ui->setupUi (this);
|
||||
|
||||
connect (mp_ui->last_pb, SIGNAL (clicked ()), this, SLOT (last_page ()));
|
||||
connect (mp_ui->next_pb, SIGNAL (clicked ()), this, SLOT (next_page ()));
|
||||
connect (mp_ui->file_pb, SIGNAL (clicked ()), this, SLOT (browse_filename ()));
|
||||
connect (mp_ui->edit_options_pb, SIGNAL (clicked ()), this, SLOT (edit_options ()));
|
||||
connect (mp_ui->reset_options_pb, SIGNAL (clicked ()), this, SLOT (reset_options ()));
|
||||
connect (mp_ui->reset_pb, SIGNAL (clicked ()), this, SLOT (reset ()));
|
||||
connect (mp_ui->offset_rb, SIGNAL (clicked ()), this, SLOT (mapping_changed ()));
|
||||
connect (mp_ui->no_mapping_rb, SIGNAL (clicked ()), this, SLOT (mapping_changed ()));
|
||||
}
|
||||
|
||||
StreamImportDialog::~StreamImportDialog ()
|
||||
{
|
||||
delete mp_ui;
|
||||
mp_ui = 0;
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::edit_options ()
|
||||
{
|
||||
lay::LoadLayoutOptionsDialog dialog (this, tl::to_string (QObject::tr ("Import Layout Options")));
|
||||
|
||||
dialog.get_options (mp_data->options);
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::reset_options ()
|
||||
{
|
||||
mp_data->options = db::LoadLayoutOptions ();
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::browse_filename ()
|
||||
{
|
||||
QString file = mp_ui->file_le->text ();
|
||||
file = QFileDialog::getOpenFileName (this, QObject::tr ("File To Import"), file, QObject::tr ("All files (*)"));
|
||||
if (! file.isNull ()) {
|
||||
mp_ui->file_le->setText (file);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::reject ()
|
||||
{
|
||||
try {
|
||||
commit_page ();
|
||||
} catch (...) {
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
QDialog::reject ();
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::accept ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
commit_page ();
|
||||
QDialog::accept ();
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
int
|
||||
StreamImportDialog::exec ()
|
||||
{
|
||||
mp_ui->central_stack->setCurrentIndex (0);
|
||||
update ();
|
||||
|
||||
return QDialog::exec ();
|
||||
}
|
||||
|
||||
/*
|
||||
* 0 - General
|
||||
* 1 - Layers
|
||||
* 2 - Reference points
|
||||
*/
|
||||
static int next_pages[] = { 1, 2, -1 };
|
||||
static int prev_pages[] = { -1, 0, 1 };
|
||||
|
||||
void
|
||||
StreamImportDialog::next_page ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
commit_page ();
|
||||
|
||||
int index = mp_ui->central_stack->currentIndex ();
|
||||
if (index >= 0 && index < int (sizeof (next_pages) / sizeof (next_pages [0]))) {
|
||||
index = next_pages [index];
|
||||
if (index >= 0) {
|
||||
mp_ui->central_stack->setCurrentIndex (index);
|
||||
enter_page ();
|
||||
}
|
||||
}
|
||||
|
||||
update ();
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::last_page ()
|
||||
{
|
||||
// "safe" commit
|
||||
try {
|
||||
commit_page ();
|
||||
} catch (...) { }
|
||||
|
||||
BEGIN_PROTECTED
|
||||
|
||||
int index = mp_ui->central_stack->currentIndex ();
|
||||
if (index >= 0 && index < int (sizeof (next_pages) / sizeof (next_pages [0]))) {
|
||||
index = prev_pages [index];
|
||||
if (index >= 0) {
|
||||
mp_ui->central_stack->setCurrentIndex (index);
|
||||
}
|
||||
}
|
||||
|
||||
update ();
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::enter_page ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::commit_page ()
|
||||
{
|
||||
int page = mp_ui->central_stack->currentIndex ();
|
||||
|
||||
if (page == 0) {
|
||||
|
||||
// --- General page
|
||||
mp_data->file = tl::to_string (mp_ui->file_le->text ());
|
||||
mp_data->topcell = tl::to_string (mp_ui->topcell_le->text ());
|
||||
if (mp_ui->import_simple_rb->isChecked ()) {
|
||||
mp_data->mode = StreamImportData::Simple;
|
||||
} else if (mp_ui->import_instantiate_rb->isChecked ()) {
|
||||
mp_data->mode = StreamImportData::Instantiate;
|
||||
} else if (mp_ui->import_extra_rb->isChecked ()) {
|
||||
mp_data->mode = StreamImportData::Extra;
|
||||
} else if (mp_ui->import_merge_rb->isChecked ()) {
|
||||
mp_data->mode = StreamImportData::Merge;
|
||||
}
|
||||
|
||||
} else if (page == 1) {
|
||||
|
||||
// --- Layer mapping
|
||||
if (mp_ui->no_mapping_rb->isChecked ()) {
|
||||
mp_data->layer_mode = StreamImportData::Original;
|
||||
} else if (mp_ui->offset_rb->isChecked ()) {
|
||||
mp_data->layer_mode = StreamImportData::Offset;
|
||||
}
|
||||
|
||||
mp_data->layer_offset = db::LayerOffset ();
|
||||
std::string offset = tl::to_string (mp_ui->offset_le->text ());
|
||||
tl::Extractor ex (offset.c_str ());
|
||||
mp_data->layer_offset.read (ex);
|
||||
|
||||
} else if (page == 2) {
|
||||
|
||||
// --- Coordinate Mapping page
|
||||
QLineEdit *(coord_editors[][4]) = {
|
||||
{ mp_ui->pcb_x1_le, mp_ui->pcb_y1_le, mp_ui->layout_x1_le, mp_ui->layout_y1_le },
|
||||
{ mp_ui->pcb_x2_le, mp_ui->pcb_y2_le, mp_ui->layout_x2_le, mp_ui->layout_y2_le },
|
||||
{ mp_ui->pcb_x3_le, mp_ui->pcb_y3_le, mp_ui->layout_x3_le, mp_ui->layout_y3_le }
|
||||
};
|
||||
|
||||
mp_data->reference_points.clear ();
|
||||
for (unsigned int i = 0; i < sizeof (coord_editors) / sizeof (coord_editors [0]); ++i) {
|
||||
|
||||
std::string t_pcb_x (tl::to_string (coord_editors [i][0]->text ()));
|
||||
tl::Extractor pcb_x (t_pcb_x.c_str ());
|
||||
|
||||
std::string t_pcb_y (tl::to_string (coord_editors [i][1]->text ()));
|
||||
tl::Extractor pcb_y (t_pcb_y.c_str ());
|
||||
|
||||
std::string t_layout_x (tl::to_string (coord_editors [i][2]->text ()));
|
||||
tl::Extractor layout_x (t_layout_x.c_str ());
|
||||
|
||||
std::string t_layout_y (tl::to_string (coord_editors [i][3]->text ()));
|
||||
tl::Extractor layout_y (t_layout_y.c_str ());
|
||||
|
||||
if (pcb_x.at_end () || pcb_y.at_end () || layout_x.at_end () || layout_y.at_end ()) {
|
||||
|
||||
if (! pcb_x.at_end () || ! pcb_y.at_end () || ! layout_x.at_end () || ! layout_y.at_end ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("All coordinates (imported and existing layout) must be specified for a reference point")));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
double x, y;
|
||||
|
||||
pcb_x.read (x);
|
||||
pcb_x.expect_end ();
|
||||
pcb_y.read (y);
|
||||
pcb_y.expect_end ();
|
||||
db::DPoint pcb (x, y);
|
||||
|
||||
layout_x.read (x);
|
||||
layout_x.expect_end ();
|
||||
layout_y.read (y);
|
||||
layout_y.expect_end ();
|
||||
db::DPoint layout (x, y);
|
||||
|
||||
mp_data->reference_points.push_back (std::make_pair (pcb, layout));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::string t (tl::to_string (mp_ui->explicit_trans_le->text ()));
|
||||
tl::Extractor ex (t.c_str ());
|
||||
mp_data->explicit_trans = db::DCplxTrans ();
|
||||
if (! ex.at_end ()) {
|
||||
ex.read (mp_data->explicit_trans);
|
||||
ex.expect_end ();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::update ()
|
||||
{
|
||||
std::string section_headers[] = {
|
||||
tl::to_string (QObject::tr ("General")),
|
||||
tl::to_string (QObject::tr ("Layers")),
|
||||
tl::to_string (QObject::tr ("Coordinate Mapping")),
|
||||
};
|
||||
|
||||
int page = mp_ui->central_stack->currentIndex ();
|
||||
if (page < 0 || page >= int (sizeof (section_headers) / sizeof (section_headers [0]))) {
|
||||
return;
|
||||
}
|
||||
|
||||
mp_ui->last_pb->setEnabled (page > 0);
|
||||
mp_ui->next_pb->setEnabled (page < int (sizeof (section_headers) / sizeof (section_headers [0]) - 1));
|
||||
mp_ui->section_header_lbl->setText (tl::to_qstring (section_headers [page]));
|
||||
|
||||
// --- General page
|
||||
mp_ui->file_le->setText (tl::to_qstring (mp_data->file));
|
||||
mp_ui->topcell_le->setText (tl::to_qstring (mp_data->topcell));
|
||||
mp_ui->import_simple_rb->setChecked (mp_data->mode == StreamImportData::Simple);
|
||||
mp_ui->import_extra_rb->setChecked (mp_data->mode == StreamImportData::Extra);
|
||||
mp_ui->import_instantiate_rb->setChecked (mp_data->mode == StreamImportData::Instantiate);
|
||||
mp_ui->import_merge_rb->setChecked (mp_data->mode == StreamImportData::Merge);
|
||||
|
||||
// --- Layers page
|
||||
mp_ui->no_mapping_rb->setChecked (mp_data->layer_mode == StreamImportData::Original);
|
||||
mp_ui->offset_rb->setChecked (mp_data->layer_mode == StreamImportData::Offset);
|
||||
mp_ui->offset_le->setText (tl::to_qstring (mp_data->layer_offset.to_string ()));
|
||||
mapping_changed ();
|
||||
|
||||
// --- Coordinate Mapping page
|
||||
QLineEdit *(coord_editors[][4]) = {
|
||||
{ mp_ui->pcb_x1_le, mp_ui->pcb_y1_le, mp_ui->layout_x1_le, mp_ui->layout_y1_le },
|
||||
{ mp_ui->pcb_x2_le, mp_ui->pcb_y2_le, mp_ui->layout_x2_le, mp_ui->layout_y2_le },
|
||||
{ mp_ui->pcb_x3_le, mp_ui->pcb_y3_le, mp_ui->layout_x3_le, mp_ui->layout_y3_le }
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof (coord_editors) / sizeof (coord_editors [0]); ++i) {
|
||||
if (mp_data->reference_points.size () > i) {
|
||||
coord_editors[i][0]->setText (tl::to_qstring (tl::to_string (mp_data->reference_points [i].first.x ())));
|
||||
coord_editors[i][1]->setText (tl::to_qstring (tl::to_string (mp_data->reference_points [i].first.y ())));
|
||||
coord_editors[i][2]->setText (tl::to_qstring (tl::to_string (mp_data->reference_points [i].second.x ())));
|
||||
coord_editors[i][3]->setText (tl::to_qstring (tl::to_string (mp_data->reference_points [i].second.y ())));
|
||||
} else {
|
||||
for (unsigned int j = 0; j < 4; ++j) {
|
||||
coord_editors[i][j]->setText (QString ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mp_data->explicit_trans == db::DCplxTrans ()) {
|
||||
mp_ui->explicit_trans_le->setText (QString ());
|
||||
} else {
|
||||
mp_ui->explicit_trans_le->setText (tl::to_qstring (mp_data->explicit_trans.to_string ()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::mapping_changed ()
|
||||
{
|
||||
mp_ui->offset_le->setEnabled (mp_ui->offset_rb->isChecked ());
|
||||
}
|
||||
|
||||
void
|
||||
StreamImportDialog::reset ()
|
||||
{
|
||||
// Commit everything that is not loaded
|
||||
try {
|
||||
commit_page ();
|
||||
} catch (...) {
|
||||
// ..
|
||||
}
|
||||
|
||||
*mp_data = StreamImportData ();
|
||||
mp_ui->central_stack->setCurrentIndex (0);
|
||||
update ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 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_layStreamImportDialog
|
||||
#define HDR_layStreamImportDialog
|
||||
|
||||
#include <QDialog>
|
||||
#include <QAction>
|
||||
#include <QFrame>
|
||||
#include <QComboBox>
|
||||
|
||||
#include "dbLayout.h"
|
||||
#include "dbPoint.h"
|
||||
#include "dbTrans.h"
|
||||
#include "dbLayerProperties.h"
|
||||
#include "dbLoadLayoutOptions.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
class QTreeWidgetItem;
|
||||
class QTreeWidget;
|
||||
class QToolButton;
|
||||
class QLineEdit;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class StreamImportDialog;
|
||||
}
|
||||
|
||||
namespace tl
|
||||
{
|
||||
class InputStream;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
class PluginRoot;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class StreamImporter;
|
||||
|
||||
struct StreamImportData
|
||||
{
|
||||
public:
|
||||
StreamImportData ();
|
||||
|
||||
enum mode_type { Simple = 0, Instantiate = 1, Extra = 2, Merge = 3 };
|
||||
enum layer_mode_type { Original = 0, Offset = 1 };
|
||||
|
||||
mode_type mode;
|
||||
std::string file;
|
||||
std::string topcell;
|
||||
std::vector <std::pair <db::DPoint, db::DPoint> > reference_points;
|
||||
db::DCplxTrans explicit_trans;
|
||||
layer_mode_type layer_mode;
|
||||
db::LayerOffset layer_offset;
|
||||
db::LoadLayoutOptions options;
|
||||
|
||||
void setup_importer (StreamImporter *importer);
|
||||
void from_string (const std::string &s);
|
||||
std::string to_string () const;
|
||||
};
|
||||
|
||||
class StreamImportDialog
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
StreamImportDialog (QWidget *parent, StreamImportData *data);
|
||||
~StreamImportDialog ();
|
||||
|
||||
int exec ();
|
||||
void accept ();
|
||||
void reject ();
|
||||
|
||||
public slots:
|
||||
void next_page ();
|
||||
void last_page ();
|
||||
void browse_filename ();
|
||||
void edit_options ();
|
||||
void reset_options ();
|
||||
void reset ();
|
||||
void mapping_changed ();
|
||||
|
||||
private:
|
||||
StreamImportData *mp_data;
|
||||
Ui::StreamImportDialog *mp_ui;
|
||||
|
||||
void update ();
|
||||
void commit_page ();
|
||||
void enter_page ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,281 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 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 "layStreamImporter.h"
|
||||
#include "layLayoutView.h"
|
||||
#include "tlStream.h"
|
||||
#include "tlString.h"
|
||||
#include "tlString.h"
|
||||
#include "tlLog.h"
|
||||
#include "dbEdgeProcessor.h"
|
||||
#include "dbCellMapping.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QApplication>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Implementation of StreamImporter
|
||||
|
||||
StreamImporter::StreamImporter ()
|
||||
: m_cell_mapping (StreamImportData::Simple), m_layer_mapping (StreamImportData::Original)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
StreamImporter::read (db::Layout &target, db::cell_index_type target_cell_index, std::vector <unsigned int> &new_layers)
|
||||
{
|
||||
// Clear the undo buffer
|
||||
if (target.manager () && !target.manager ()->transacting ()) {
|
||||
target.manager ()->clear ();
|
||||
}
|
||||
|
||||
tl::log << tl::to_string (QObject::tr ("Importing stream data"));
|
||||
// tl::Progress m_progress (tl::to_string (QObject::tr ("Importing stream data")), m_files.size (), 1);
|
||||
|
||||
// TODO: this code should be available otherwise ...
|
||||
// derive the actual global transformation from the reference points
|
||||
db::DCplxTrans global_trans (m_global_trans);
|
||||
if (! m_reference_points.empty ()) {
|
||||
|
||||
db::DPoint p1_pcb = m_reference_points[0].first;
|
||||
db::DPoint p1_ly = m_reference_points[0].second;
|
||||
|
||||
if (m_reference_points.size () > 1) {
|
||||
|
||||
db::DPoint p2_pcb = m_reference_points[1].first;
|
||||
db::DPoint p2_ly = m_reference_points[1].second;
|
||||
|
||||
db::DVector d12_pcb = (p2_pcb - p1_pcb) * (1.0 / p2_pcb.distance (p1_pcb));
|
||||
db::DVector d12_ly = (p2_ly - p1_ly) * (1.0 / p2_ly.distance (p1_ly));
|
||||
|
||||
int ru = -1;
|
||||
int rm = -1;
|
||||
for (int f = 0; f < 8; ++f) {
|
||||
db::DVector d12 = db::DTrans (f) * d12_pcb;
|
||||
if ((d12 - d12_ly).length () < 0.1) {
|
||||
if (f < 4) {
|
||||
ru = f;
|
||||
} else {
|
||||
rm = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ru < 0 || rm < 0) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Unable to deduce rotation from reference points p1 and p2 (imported and existing layout)")));
|
||||
}
|
||||
|
||||
if (m_reference_points.size () > 2) {
|
||||
|
||||
db::DPoint p3_pcb = m_reference_points[2].first;
|
||||
db::DPoint p3_ly = m_reference_points[2].second;
|
||||
|
||||
db::DVector d13_pcb = (p3_pcb - p1_pcb) * (1.0 / p3_pcb.distance (p1_pcb));
|
||||
db::DVector d13_ly = (p3_ly - p1_ly) * (1.0 / p3_ly.distance (p1_ly));
|
||||
|
||||
double vp_pcb = d13_pcb.x () * d12_pcb.y () - d13_pcb.y () * d12_pcb.x ();
|
||||
double vp_gds = d13_ly.x () * d12_ly.y () - d13_ly.y () * d12_ly.x ();
|
||||
|
||||
if (vp_pcb * vp_gds < 0.0) {
|
||||
global_trans = db::DCplxTrans (db::DFTrans (rm));
|
||||
} else {
|
||||
global_trans = db::DCplxTrans (db::DFTrans (ru));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (global_trans.is_mirror ()) {
|
||||
global_trans = db::DCplxTrans (db::DFTrans (rm));
|
||||
} else {
|
||||
global_trans = db::DCplxTrans (db::DFTrans (ru));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
global_trans = db::DCplxTrans (p1_ly - (db::DPoint () + global_trans.disp ())) * global_trans * db::DCplxTrans (db::DPoint () - p1_pcb);
|
||||
|
||||
}
|
||||
|
||||
// Prepare the layout to read
|
||||
db::Layout source;
|
||||
|
||||
// Load the layout
|
||||
{
|
||||
tl::InputStream stream (m_file);
|
||||
db::Reader reader (stream);
|
||||
|
||||
tl::log << tl::to_string (QObject::tr ("Loading file: ")) << m_file;
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, tl::to_string (QObject::tr ("Loading")));
|
||||
reader.read (source, m_options);
|
||||
}
|
||||
|
||||
// Locate the top cell in the source file
|
||||
db::cell_index_type source_topcell;
|
||||
std::vector <db::cell_index_type> source_cells;
|
||||
|
||||
if (m_cell_mapping != StreamImportData::Extra || !m_topcell.empty ()) {
|
||||
|
||||
if (m_topcell.empty ()) {
|
||||
|
||||
db::Layout::top_down_const_iterator t = source.begin_top_down ();
|
||||
if (t == source.end_top_down ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Source layout does not have a top cell")));
|
||||
}
|
||||
|
||||
source_topcell = *t;
|
||||
|
||||
++t;
|
||||
if (t != source.end_top_cells ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Source layout does not have a unique top cell - specify one explicitly")));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
std::pair<bool, db::cell_index_type> t = source.cell_by_name (m_topcell.c_str ());
|
||||
if (! t.first) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Source layout does not have a cell named '%s'")), m_topcell);
|
||||
}
|
||||
|
||||
source_topcell = t.second;
|
||||
|
||||
}
|
||||
|
||||
source_cells.push_back (source_topcell);
|
||||
|
||||
} else {
|
||||
|
||||
// collect source cells
|
||||
for (db::Layout::top_down_const_iterator t = source.begin_top_down (); t != source.end_top_cells (); ++t) {
|
||||
source_cells.push_back (*t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Issue a warning, if the transformation is not ortho etc.
|
||||
if (fabs (global_trans.mag () - floor (global_trans.mag () + 0.5)) > 1e-6 || ! global_trans.is_ortho ()) {
|
||||
|
||||
if (QMessageBox::warning (QApplication::activeWindow (),
|
||||
QObject::tr ("Complex Transformation"),
|
||||
tl::to_qstring (tl::sprintf (tl::to_string (QObject::tr ("The specified transformation (%s) is complex.\nGrid snapping to the database unit grid can occur and\neffectively alter the geometry of the layout.\nPress 'Ok' to continue.")), global_trans.to_string ())),
|
||||
QMessageBox::Ok | QMessageBox::Cancel,
|
||||
QMessageBox::Ok) != QMessageBox::Ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create a layer map
|
||||
std::map <unsigned int, unsigned int> layer_map;
|
||||
for (db::Layout::layer_iterator l = source.begin_layers (); l != source.end_layers (); ++l) {
|
||||
|
||||
db::LayerProperties lp (*(*l).second);
|
||||
if (m_layer_mapping == StreamImportData::Offset) {
|
||||
lp = m_layer_offset.apply (lp);
|
||||
}
|
||||
|
||||
bool layer_found = false;
|
||||
for (db::Layout::layer_iterator ll = target.begin_layers (); ll != target.end_layers () && ! layer_found; ++ll) {
|
||||
if ((*ll).second->log_equal (lp)) {
|
||||
layer_map.insert (std::make_pair ((*l).first, (*ll).first));
|
||||
layer_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (! layer_found) {
|
||||
unsigned int new_layer = target.insert_layer (lp);
|
||||
layer_map.insert (std::make_pair ((*l).first, new_layer));
|
||||
new_layers.push_back (new_layer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Create a cell map
|
||||
std::map <db::cell_index_type, db::cell_index_type> cell_map;
|
||||
|
||||
if (m_cell_mapping == StreamImportData::Simple) {
|
||||
|
||||
cell_map.insert (std::make_pair (source_topcell, target_cell_index));
|
||||
|
||||
} else if (m_cell_mapping == StreamImportData::Extra) {
|
||||
|
||||
// create new top cells for each source top cell
|
||||
for (std::vector<db::cell_index_type>::const_iterator t = source_cells.begin (); t != source_cells.end (); ++t) {
|
||||
db::cell_index_type new_top = target.add_cell (source.cell_name (*t));
|
||||
cell_map.insert (std::make_pair (*t, new_top));
|
||||
}
|
||||
|
||||
} else if (m_cell_mapping == StreamImportData::Instantiate) {
|
||||
|
||||
// Create a new top cell for importing into and use the cell reference to produce the first part of the transformation
|
||||
|
||||
db::cell_index_type new_top = target.add_cell (source.cell_name (source_topcell));
|
||||
cell_map.insert (std::make_pair (source_topcell, new_top));
|
||||
|
||||
db::ICplxTrans gt_dbu = db::VCplxTrans (1.0 / target.dbu ()) * global_trans * db::CplxTrans (source.dbu ());
|
||||
target.cell (target_cell_index).insert (db::CellInstArray (new_top, gt_dbu * db::ICplxTrans (1.0 / global_trans.mag ())));
|
||||
|
||||
global_trans = db::DCplxTrans (global_trans.mag ());
|
||||
|
||||
} else if (m_cell_mapping == StreamImportData::Merge) {
|
||||
|
||||
// Create the cell mapping
|
||||
// TODO: Currently no merging is provided for non-unity transformations
|
||||
if (! global_trans.equal (db::DCplxTrans ())) {
|
||||
|
||||
if (QMessageBox::warning (QApplication::activeWindow (),
|
||||
QObject::tr ("Merge Mode Is Not Available"),
|
||||
tl::to_qstring (tl::sprintf (tl::to_string (QObject::tr ("Merge mode is not supported for the specified transformation (%s).\nSimple mode will be used instead.\nPress 'Ok' to continue.")), global_trans.to_string ())),
|
||||
QMessageBox::Ok | QMessageBox::Cancel,
|
||||
QMessageBox::Ok) != QMessageBox::Ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
cell_map.insert (std::make_pair (source_topcell, target_cell_index));
|
||||
|
||||
} else {
|
||||
|
||||
db::CellMapping cm;
|
||||
cm.create_from_geometry (target, target_cell_index, source, source_topcell);
|
||||
cell_map.insert (cm.begin (), cm.end ());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// And actually merge
|
||||
db::merge_layouts (target, source, db::VCplxTrans (1.0 / target.dbu ()) * global_trans * db::CplxTrans (source.dbu ()), source_cells, cell_map, layer_map);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2018 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_layStreamImporter
|
||||
#define HDR_layStreamImporter
|
||||
|
||||
#include "layPluginCommon.h"
|
||||
|
||||
#include "dbLayout.h"
|
||||
#include "dbTrans.h"
|
||||
#include "dbLoadLayoutOptions.h"
|
||||
#include "tlStream.h"
|
||||
#include "tlProgress.h"
|
||||
#include "layStreamImportDialog.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace db
|
||||
{
|
||||
class Manager;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
class LayoutView;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief The Stream importer object
|
||||
*/
|
||||
class LAY_PLUGIN_PUBLIC StreamImporter
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
StreamImporter ();
|
||||
|
||||
/**
|
||||
* @brief Read into an existing layout
|
||||
*
|
||||
* This method reads the layout specified into the given layout and cell.
|
||||
*/
|
||||
void read (db::Layout &layout, db::cell_index_type cell_index, std::vector <unsigned int> &new_layers);
|
||||
|
||||
/**
|
||||
* @brief Specifies the global transformation
|
||||
*
|
||||
* This specifies the global transformation to apply (in micron units).
|
||||
*/
|
||||
void set_global_trans (const db::DCplxTrans &trans)
|
||||
{
|
||||
m_global_trans = trans;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the global transformation
|
||||
*/
|
||||
const db::DCplxTrans &global_trans () const
|
||||
{
|
||||
return m_global_trans;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the reference points
|
||||
*/
|
||||
void set_reference_points (const std::vector<std::pair <db::DPoint, db::DPoint> > &pts)
|
||||
{
|
||||
m_reference_points = pts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set file which is read.
|
||||
*/
|
||||
void set_file (const std::string &file)
|
||||
{
|
||||
m_file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the file which is read
|
||||
*/
|
||||
const std::string &file () const
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set top cell name which is read.
|
||||
*
|
||||
* If an empty top cell name is specified, the top cell is determined automatically (it must be a unique top cell in some
|
||||
* cases).
|
||||
*/
|
||||
void set_topcell (const std::string &topcell)
|
||||
{
|
||||
m_topcell = topcell;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the top cell name.
|
||||
*/
|
||||
const std::string &topcell () const
|
||||
{
|
||||
return m_topcell;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set cell mapping mode
|
||||
*/
|
||||
void set_cell_mapping (StreamImportData::mode_type cell_mapping)
|
||||
{
|
||||
m_cell_mapping = cell_mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the cell mapping mode
|
||||
*/
|
||||
StreamImportData::mode_type cell_mapping () const
|
||||
{
|
||||
return m_cell_mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set layer mapping mode
|
||||
*/
|
||||
void set_layer_mapping (StreamImportData::layer_mode_type layer_mapping)
|
||||
{
|
||||
m_layer_mapping = layer_mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the layer mapping mode
|
||||
*/
|
||||
StreamImportData::layer_mode_type layer_mapping () const
|
||||
{
|
||||
return m_layer_mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set layer offset
|
||||
*/
|
||||
void set_layer_offset (const db::LayerOffset &layer_offset)
|
||||
{
|
||||
m_layer_offset = layer_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the layer offset
|
||||
*/
|
||||
db::LayerOffset layer_offset () const
|
||||
{
|
||||
return m_layer_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set reader options
|
||||
*/
|
||||
void set_reader_options (const db::LoadLayoutOptions &options)
|
||||
{
|
||||
m_options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the reader options
|
||||
*/
|
||||
const db::LoadLayoutOptions &reader_options () const
|
||||
{
|
||||
return m_options;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_file;
|
||||
std::string m_topcell;
|
||||
db::DCplxTrans m_global_trans;
|
||||
std::vector <std::pair <db::DPoint, db::DPoint> > m_reference_points;
|
||||
StreamImportData::mode_type m_cell_mapping;
|
||||
StreamImportData::layer_mode_type m_layer_mapping;
|
||||
db::LayerOffset m_layer_offset;
|
||||
db::LoadLayoutOptions m_options;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
TARGET = import
|
||||
DESTDIR = $$OUT_PWD/../../../../lay_plugins
|
||||
|
||||
include($$PWD/../../../lay_plugin.pri)
|
||||
|
||||
HEADERS = \
|
||||
layStreamImporter.h \
|
||||
layStreamImportDialog.h
|
||||
|
||||
SOURCES = \
|
||||
layStreamImporter.cc \
|
||||
layStreamImportDialog.cc \
|
||||
layStreamImport.cc
|
||||
|
||||
FORMS = \
|
||||
StreamImportDialog.ui \
|
||||
Reference in New Issue
Block a user