mirror of https://github.com/KLayout/klayout.git
"Find cell" feature: just type into the cell list
This feature includes: * Enhancements to tl::GlobPattern (exact mode, case insensitive) TODO: UTF8 support * Enhancements to DecoratedLineEdit (ESC key handling, Tab key handling)
This commit is contained in:
parent
8e22d7bba8
commit
bf15e46c10
|
|
@ -74,3 +74,6 @@ plugins.depends += lay ext lib ut
|
|||
klayout_main.depends += lay ext lib plugins
|
||||
unit_tests.depends += ut plugins
|
||||
|
||||
RESOURCES += \
|
||||
laybasic/layResources.qrc
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<ui version="4.0" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SimpleCellSelectionForm</class>
|
||||
<widget class="QDialog" name="SimpleCellSelectionForm" >
|
||||
<property name="geometry" >
|
||||
<widget class="QDialog" name="SimpleCellSelectionForm">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
|
|
@ -9,40 +10,58 @@
|
|||
<height>525</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<property name="windowTitle">
|
||||
<string>Select Cell</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame8" >
|
||||
<property name="frameShape" >
|
||||
<widget class="QFrame" name="frame8">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="1" column="0" colspan="2" >
|
||||
<item row="1" column="0" colspan="2">
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>451</width>
|
||||
<height>16</height>
|
||||
|
|
@ -50,62 +69,70 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2" >
|
||||
<widget class="QFrame" name="frame_4" >
|
||||
<property name="frameShape" >
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QFrame" name="frame_4">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLineEdit" name="le_cell_name" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>7</hsizetype>
|
||||
<vsizetype>0</vsizetype>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="le_cell_name">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" >
|
||||
<widget class="QLabel" name="label_5" >
|
||||
<property name="text" >
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>(* and ? can be used to match any text)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_2" >
|
||||
<property name="text" >
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Selected cell</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" >
|
||||
<widget class="QToolButton" name="find_next" >
|
||||
<property name="toolTip" >
|
||||
<string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="find_next">
|
||||
<property name="toolTip">
|
||||
<string><html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Find next</p></body></html></string>
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Find next</p></body></html></string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon" >
|
||||
<iconset resource="layResources.qrc" >:/find.png</iconset>
|
||||
<property name="icon">
|
||||
<iconset resource="../lay/layResources.qrc">
|
||||
<normaloff>:/find.png</normaloff>:/find.png</iconset>
|
||||
</property>
|
||||
<property name="autoRaise" >
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -113,83 +140,95 @@ p, li { white-space: pre-wrap; }
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2" >
|
||||
<widget class="QLabel" name="label_3" >
|
||||
<property name="text" >
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Cell list</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" >
|
||||
<widget class="QTreeView" name="lv_cells" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>5</hsizetype>
|
||||
<vsizetype>7</vsizetype>
|
||||
<item row="3" column="0">
|
||||
<widget class="QTreeView" name="lv_cells">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="selectionMode" >
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="uniformRowHeights" >
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" >
|
||||
<widget class="QFrame" name="frame" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>5</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<item row="3" column="1">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape" >
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<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="QFrame" name="frame_5" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>5</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<widget class="QFrame" name="frame_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape" >
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="1" >
|
||||
<item row="2" column="1">
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
|
|
@ -197,50 +236,46 @@ p, li { white-space: pre-wrap; }
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2" >
|
||||
<widget class="QTreeView" name="lv_parents" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>7</hsizetype>
|
||||
<vsizetype>7</vsizetype>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QTreeView" name="lv_parents">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="uniformRowHeights" >
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2" >
|
||||
<widget class="QLabel" name="textLabel1" >
|
||||
<property name="text" >
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLabel" name="textLabel1">
|
||||
<property name="text">
|
||||
<string>Parents</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" >
|
||||
<widget class="QToolButton" name="tb_set_parent" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>5</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="tb_set_parent">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap" >
|
||||
<pixmap resource="layResources.qrc" >:/right.png</pixmap>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -248,34 +283,41 @@ p, li { white-space: pre-wrap; }
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_6" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>5</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<widget class="QFrame" name="frame_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape" >
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="1" >
|
||||
<item row="2" column="1">
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
|
|
@ -283,50 +325,46 @@ p, li { white-space: pre-wrap; }
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QLabel" name="textLabel2" >
|
||||
<property name="text" >
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="textLabel2">
|
||||
<property name="text">
|
||||
<string>Children</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2" >
|
||||
<widget class="QTreeView" name="lv_children" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>7</hsizetype>
|
||||
<vsizetype>7</vsizetype>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QTreeView" name="lv_children">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="uniformRowHeights" >
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" >
|
||||
<widget class="QToolButton" name="tb_set_child" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>5</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="tb_set_child">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_4" >
|
||||
<property name="text" >
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap" >
|
||||
<pixmap resource="layResources.qrc" >:/right.png</pixmap>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../lay/layResources.qrc">:/right.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -341,13 +379,13 @@ p, li { white-space: pre-wrap; }
|
|||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>611</width>
|
||||
<height>16</height>
|
||||
|
|
@ -356,36 +394,45 @@ p, li { white-space: pre-wrap; }
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_4" >
|
||||
<property name="orientation" >
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame5" >
|
||||
<property name="frameShape" >
|
||||
<widget class="QFrame" name="frame5">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>91</width>
|
||||
<height>31</height>
|
||||
|
|
@ -394,19 +441,19 @@ p, li { white-space: pre-wrap; }
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ok_button" >
|
||||
<property name="text" >
|
||||
<string>_ok</string>
|
||||
<widget class="QPushButton" name="ok_button">
|
||||
<property name="text">
|
||||
<string>Ok</string>
|
||||
</property>
|
||||
<property name="default" >
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancel_button" >
|
||||
<property name="text" >
|
||||
<string>_cancel</string>
|
||||
<widget class="QPushButton" name="cancel_button">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -415,9 +462,9 @@ p, li { white-space: pre-wrap; }
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11" />
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
<include location="layResources.qrc" />
|
||||
<include location="../lay/layResources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
|||
|
|
@ -394,18 +394,22 @@ CellSelectionForm::name_changed (const QString &s)
|
|||
return;
|
||||
}
|
||||
|
||||
QModelIndex mi = model->locate (tl::to_string (s).c_str (), true);
|
||||
if (mi.isValid ()) {
|
||||
|
||||
m_cells_cb_enabled = false;
|
||||
lv_cells->selectionModel ()->setCurrentIndex (mi, QItemSelectionModel::SelectCurrent);
|
||||
lv_cells->scrollTo (mi);
|
||||
update_children_list ();
|
||||
update_parents_list ();
|
||||
m_cells_cb_enabled = true;
|
||||
|
||||
QModelIndex mi;
|
||||
if (!s.isEmpty ()) {
|
||||
mi = model->locate (tl::to_string (s).c_str (), true);
|
||||
} else {
|
||||
model->clear_locate ();
|
||||
}
|
||||
|
||||
m_cells_cb_enabled = false;
|
||||
lv_cells->selectionModel ()->setCurrentIndex (mi, QItemSelectionModel::SelectCurrent);
|
||||
if (mi.isValid ()) {
|
||||
lv_cells->scrollTo (mi);
|
||||
}
|
||||
update_children_list ();
|
||||
update_parents_list ();
|
||||
m_cells_cb_enabled = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "dbPCellHeader.h"
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QPalette>
|
||||
#include <QMimeData>
|
||||
|
||||
#include <string.h>
|
||||
|
|
@ -314,22 +315,24 @@ CellTreeModel::build_top_level ()
|
|||
|
||||
m_flat = true; // no "hierarchical children" yet.
|
||||
|
||||
m_toplevel.reserve (mp_base->child_cells ());
|
||||
|
||||
for (db::Cell::child_cell_iterator child = mp_base->begin_child_cells (); ! child.at_end (); ++child) {
|
||||
CellTreeItem *item = new CellTreeItem (mp_layout, 0, false, *child, true, m_sorting);
|
||||
m_toplevel.push_back (item);
|
||||
if (mp_base) {
|
||||
m_toplevel.reserve (mp_base->child_cells ());
|
||||
for (db::Cell::child_cell_iterator child = mp_base->begin_child_cells (); ! child.at_end (); ++child) {
|
||||
CellTreeItem *item = new CellTreeItem (mp_layout, 0, false, *child, true, m_sorting);
|
||||
m_toplevel.push_back (item);
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((m_flags & Parents) != 0) {
|
||||
|
||||
m_flat = true; // no "hierarchical parents" yet.
|
||||
|
||||
m_toplevel.reserve (mp_base->parent_cells ());
|
||||
|
||||
for (db::Cell::parent_cell_iterator parent = mp_base->begin_parent_cells (); parent != mp_base->end_parent_cells (); ++parent) {
|
||||
CellTreeItem *item = new CellTreeItem (mp_layout, 0, false, *parent, true, m_sorting);
|
||||
m_toplevel.push_back (item);
|
||||
if (mp_base) {
|
||||
m_toplevel.reserve (mp_base->parent_cells ());
|
||||
for (db::Cell::parent_cell_iterator parent = mp_base->begin_parent_cells (); parent != mp_base->end_parent_cells (); ++parent) {
|
||||
CellTreeItem *item = new CellTreeItem (mp_layout, 0, false, *parent, true, m_sorting);
|
||||
m_toplevel.push_back (item);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -498,8 +501,12 @@ CellTreeModel::data (const QModelIndex &index, int role) const
|
|||
|
||||
} else if (role == Qt::BackgroundRole) {
|
||||
|
||||
if (m_selected_indexes.find (index) != m_selected_indexes.end ()) {
|
||||
return QVariant (QColor (Qt::blue).lighter (180));
|
||||
if (m_selected_indexes_set.find (index) != m_selected_indexes_set.end ()) {
|
||||
// for selected items pick a color between Highlight and Base
|
||||
QPalette pl (mp_parent->palette ());
|
||||
QColor c1 = pl.color (QPalette::Highlight);
|
||||
QColor cb = pl.color (QPalette::Base);
|
||||
return QVariant (QColor ((c1.red () + cb.red ()) / 2, (c1.green () + cb.green ()) / 2, (c1.blue () + cb.blue ()) / 2));
|
||||
} else {
|
||||
return QVariant ();
|
||||
}
|
||||
|
|
@ -512,11 +519,11 @@ CellTreeModel::data (const QModelIndex &index, int role) const
|
|||
} else {
|
||||
QPalette pl (mp_parent->palette ());
|
||||
if (mp_view->is_cell_hidden (item->cell_index (), m_cv_index)) {
|
||||
QColor c1 = pl.color (QColorGroup::Text);
|
||||
QColor cb = pl.color (QColorGroup::Base);
|
||||
QColor c1 = pl.color (QPalette::Text);
|
||||
QColor cb = pl.color (QPalette::Base);
|
||||
return QVariant (QColor ((c1.red () + cb.red ()) / 2, (c1.green () + cb.green ()) / 2, (c1.blue () + cb.blue ()) / 2));
|
||||
} else {
|
||||
return QVariant (pl.color (QColorGroup::Text));
|
||||
return QVariant (pl.color (QPalette::Text));
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
@ -693,6 +700,7 @@ CellTreeModel::clear_locate ()
|
|||
{
|
||||
m_selected_indexes.clear ();
|
||||
m_current_index = m_selected_indexes.begin ();
|
||||
m_selected_indexes_set.clear ();
|
||||
|
||||
signal_data_changed ();
|
||||
}
|
||||
|
|
@ -715,8 +723,56 @@ CellTreeModel::locate_next ()
|
|||
}
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
CellTreeModel::locate_prev ()
|
||||
{
|
||||
if (mp_layout->under_construction () || (mp_layout->manager () && mp_layout->manager ()->transacting ())) {
|
||||
return QModelIndex ();
|
||||
}
|
||||
|
||||
if (m_current_index == m_selected_indexes.end ()) {
|
||||
return QModelIndex ();
|
||||
} else {
|
||||
if (m_current_index == m_selected_indexes.begin ()) {
|
||||
m_current_index = m_selected_indexes.end ();
|
||||
}
|
||||
--m_current_index;
|
||||
return *m_current_index;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CellTreeModel::search_children (const tl::GlobPattern &pattern, CellTreeItem *item)
|
||||
{
|
||||
int children = item->children ();
|
||||
for (int i = 0; i < children; ++i) {
|
||||
CellTreeItem *c = item->child (i);
|
||||
if (c) {
|
||||
if (c->name_matches (pattern)) {
|
||||
m_selected_indexes.push_back (model_index (c));
|
||||
}
|
||||
search_children (pattern, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CellTreeModel::search_children (const char *name, CellTreeItem *item)
|
||||
{
|
||||
int children = item->children ();
|
||||
for (int i = 0; i < children; ++i) {
|
||||
CellTreeItem *c = item->child (i);
|
||||
if (c) {
|
||||
if (c->name_equals (name)) {
|
||||
m_selected_indexes.push_back (model_index (c));
|
||||
}
|
||||
search_children (name, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
CellTreeModel::locate (const char *name, bool glob_pattern)
|
||||
CellTreeModel::locate (const char *name, bool glob_pattern, bool case_sensitive, bool top_only)
|
||||
{
|
||||
if (mp_layout->under_construction () || (mp_layout->manager () && mp_layout->manager ()->transacting ())) {
|
||||
return QModelIndex ();
|
||||
|
|
@ -724,25 +780,22 @@ CellTreeModel::locate (const char *name, bool glob_pattern)
|
|||
|
||||
m_selected_indexes.clear ();
|
||||
|
||||
std::vector <CellTreeItem *>::const_iterator lc;
|
||||
if (m_sorting == ByName && ! glob_pattern) {
|
||||
// employ sorting to look for the cell with that name
|
||||
lc = std::lower_bound (m_toplevel.begin (), m_toplevel.end (), name, cmp_cell_tree_item_vs_name_f ());
|
||||
} else if (glob_pattern) {
|
||||
tl::GlobPattern p (std::string (name) + "*");
|
||||
for (lc = m_toplevel.begin (); lc != m_toplevel.end (); ++lc) {
|
||||
if ((*lc)->name_matches (p)) {
|
||||
m_selected_indexes.insert (model_index (*lc));
|
||||
}
|
||||
tl::GlobPattern p = tl::GlobPattern (std::string (name));
|
||||
p.set_case_sensitive (case_sensitive);
|
||||
p.set_exact (!glob_pattern);
|
||||
p.set_header_match (true);
|
||||
|
||||
for (std::vector <CellTreeItem *>::const_iterator lc = m_toplevel.begin (); lc != m_toplevel.end (); ++lc) {
|
||||
if ((*lc)->name_matches (p)) {
|
||||
m_selected_indexes.push_back (model_index (*lc));
|
||||
}
|
||||
} else {
|
||||
// sorting does not help: linear search
|
||||
for (lc = m_toplevel.begin (); lc != m_toplevel.end (); ++lc) {
|
||||
if ((*lc)->name_equals (name)) {
|
||||
m_selected_indexes.insert (model_index (*lc));
|
||||
}
|
||||
if (! top_only) {
|
||||
search_children (p, *lc);
|
||||
}
|
||||
}
|
||||
|
||||
m_selected_indexes_set.clear ();
|
||||
m_selected_indexes_set.insert (m_selected_indexes.begin (), m_selected_indexes.end ());
|
||||
|
||||
signal_data_changed ();
|
||||
|
||||
|
|
|
|||
|
|
@ -168,16 +168,21 @@ public:
|
|||
/**
|
||||
* @brief Locate an index by name (at least closest)
|
||||
*
|
||||
* Only top-level items are searched. An invalid model index is returned if
|
||||
* If top_only is set, only top-level items are searched. An invalid model index is returned if
|
||||
* no corresponding item could be found.
|
||||
*/
|
||||
QModelIndex locate (const char *name, bool glob_pattern = false);
|
||||
QModelIndex locate (const char *name, bool glob_pattern = false, bool case_sensitive = true, bool top_only = true);
|
||||
|
||||
/**
|
||||
* @brief Locate the next index (after the first locate)
|
||||
*/
|
||||
QModelIndex locate_next ();
|
||||
|
||||
/**
|
||||
* @brief Locate the previous index (after the first locate)
|
||||
*/
|
||||
QModelIndex locate_prev ();
|
||||
|
||||
/**
|
||||
* @brief Clears the locate flags
|
||||
*/
|
||||
|
|
@ -226,11 +231,14 @@ private:
|
|||
int m_cv_index;
|
||||
const db::Cell *mp_base;
|
||||
std::vector <CellTreeItem *> m_toplevel;
|
||||
std::set <QModelIndex> m_selected_indexes;
|
||||
std::set <QModelIndex>::const_iterator m_current_index;
|
||||
std::set <QModelIndex> m_selected_indexes_set;
|
||||
std::vector <QModelIndex> m_selected_indexes;
|
||||
std::vector <QModelIndex>::const_iterator m_current_index;
|
||||
|
||||
void build_top_level ();
|
||||
void clear_top_level ();
|
||||
void search_children (const tl::GlobPattern &pattern, CellTreeItem *item);
|
||||
void search_children (const char *name, CellTreeItem *item);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
#include <QCheckBox>
|
||||
|
||||
#include "dbClipboard.h"
|
||||
#include "dbClipboardData.h"
|
||||
|
|
@ -69,13 +70,39 @@ HCPCellTreeWidget::HCPCellTreeWidget (QWidget *parent, const char *name)
|
|||
: QTreeView (parent)
|
||||
{
|
||||
// Don't request focus: this leaves focus on the canvas and the arrow keys functional there
|
||||
setFocusPolicy (Qt::NoFocus);
|
||||
// @@@ setFocusPolicy (Qt::NoFocus); -> solve differently!!!
|
||||
setFocusPolicy (Qt::ClickFocus);
|
||||
|
||||
// Allow dragging from here to
|
||||
setDragDropMode (QAbstractItemView::DragOnly);
|
||||
|
||||
setObjectName (QString::fromUtf8 (name));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
HCPCellTreeWidget::event (QEvent *event)
|
||||
{
|
||||
// Handling this event makes the widget receive all keystrokes
|
||||
if (event->type () == QEvent::ShortcutOverride) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent *> (event);
|
||||
QString t = ke->text ();
|
||||
if (!t.isEmpty () && t[0].isPrint ()) {
|
||||
ke->accept ();
|
||||
}
|
||||
}
|
||||
return QTreeView::event (event);
|
||||
}
|
||||
|
||||
void
|
||||
HCPCellTreeWidget::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
QString t = event->text ();
|
||||
if (!t.isEmpty ()) {
|
||||
emit search_triggered (t);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HCPCellTreeWidget::startDrag (Qt::DropActions supportedActions)
|
||||
{
|
||||
|
|
@ -216,6 +243,71 @@ HierarchyControlPanel::HierarchyControlPanel (lay::LayoutView *view, QWidget *pa
|
|||
mp_selector->setObjectName (QString::fromUtf8 ("cellview_selection"));
|
||||
ly->addWidget (mp_selector);
|
||||
|
||||
mp_search_frame = new QFrame (this);
|
||||
ly->addWidget (mp_search_frame);
|
||||
mp_search_frame->hide ();
|
||||
mp_search_frame->setAutoFillBackground (true);
|
||||
mp_search_frame->setObjectName (QString::fromUtf8 ("panel"));
|
||||
mp_search_frame->setFrameStyle (QFrame::Panel | QFrame::Raised);
|
||||
mp_search_frame->setLineWidth (1);
|
||||
mp_search_frame->setBackgroundRole (QPalette::Highlight);
|
||||
|
||||
QHBoxLayout *sf_ly = new QHBoxLayout (mp_search_frame);
|
||||
sf_ly->setMargin (0);
|
||||
sf_ly->setContentsMargins (0, 0, 0, 0);
|
||||
sf_ly->setSpacing (0);
|
||||
|
||||
mp_search_close_cb = new QCheckBox (mp_search_frame);
|
||||
sf_ly->addWidget (mp_search_close_cb);
|
||||
|
||||
mp_search_close_cb->setFocusPolicy (Qt::NoFocus);
|
||||
mp_search_close_cb->setBackgroundRole (QPalette::Highlight);
|
||||
mp_search_close_cb->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Preferred));
|
||||
QPalette pl (mp_search_close_cb->palette ());
|
||||
pl.setColor (QPalette::Foreground, pl.color (QPalette::Active, QPalette::HighlightedText));
|
||||
mp_search_close_cb->setPalette (pl);
|
||||
mp_search_close_cb->setMaximumSize (QSize (mp_search_close_cb->maximumSize ().width (), mp_search_close_cb->sizeHint ().height () - 4));
|
||||
connect (mp_search_close_cb, SIGNAL (clicked ()), this, SLOT (search_editing_finished ()));
|
||||
|
||||
mp_search_model = 0;
|
||||
mp_search_edit_box = new lay::DecoratedLineEdit (mp_search_frame);
|
||||
mp_search_edit_box->setObjectName (QString::fromUtf8 ("cellview_search_edit_box"));
|
||||
mp_search_edit_box->set_escape_signal_enabled (true);
|
||||
mp_search_edit_box->set_tab_signal_enabled (true);
|
||||
connect (mp_search_edit_box, SIGNAL (returnPressed ()), this, SLOT (search_editing_finished ()));
|
||||
connect (mp_search_edit_box, SIGNAL (textEdited (const QString &)), this, SLOT (search_edited ()));
|
||||
connect (mp_search_edit_box, SIGNAL (esc_pressed ()), this, SLOT (search_editing_finished ()));
|
||||
connect (mp_search_edit_box, SIGNAL (tab_pressed ()), this, SLOT (search_next ()));
|
||||
connect (mp_search_edit_box, SIGNAL (backtab_pressed ()), this, SLOT (search_prev ()));
|
||||
sf_ly->addWidget (mp_search_edit_box);
|
||||
|
||||
mp_use_regular_expressions = new QAction (this);
|
||||
mp_use_regular_expressions->setCheckable (true);
|
||||
mp_use_regular_expressions->setChecked (true);
|
||||
mp_use_regular_expressions->setText (tr ("Use expressions (use * and ? for any character)"));
|
||||
|
||||
mp_case_sensitive = new QAction (this);
|
||||
mp_case_sensitive->setCheckable (true);
|
||||
mp_case_sensitive->setChecked (true);
|
||||
mp_case_sensitive->setText (tr ("Case sensitive search"));
|
||||
|
||||
QMenu *m = new QMenu (mp_search_edit_box);
|
||||
m->addAction (mp_use_regular_expressions);
|
||||
m->addAction (mp_case_sensitive);
|
||||
connect (mp_use_regular_expressions, SIGNAL (triggered ()), this, SLOT (search_edited ()));
|
||||
connect (mp_case_sensitive, SIGNAL (triggered ()), this, SLOT (search_edited ()));
|
||||
|
||||
mp_search_edit_box->set_clear_button_enabled (true);
|
||||
mp_search_edit_box->set_options_button_enabled (true);
|
||||
mp_search_edit_box->set_options_menu (m);
|
||||
|
||||
QToolButton *sf_next = new QToolButton (mp_search_frame);
|
||||
sf_next->setAutoRaise (true);
|
||||
sf_next->setToolTip (tr ("Find next"));
|
||||
sf_next->setIcon (QIcon (QString::fromUtf8 (":/find.png")));
|
||||
connect (sf_next, SIGNAL (clicked ()), this, SLOT (search_next ()));
|
||||
sf_ly->addWidget (sf_next);
|
||||
|
||||
mp_splitter = new QSplitter (Qt::Vertical, this);
|
||||
ly->addWidget (mp_splitter);
|
||||
|
||||
|
|
@ -335,6 +427,105 @@ HierarchyControlPanel::cm_cell_select ()
|
|||
emit cell_selected (path, active ());
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyControlPanel::search_triggered (const QString &t)
|
||||
{
|
||||
mp_search_model = 0;
|
||||
lay::HCPCellTreeWidget *w = dynamic_cast<lay::HCPCellTreeWidget *> (sender ());
|
||||
if (w) {
|
||||
for (size_t i = 0; i < mp_cell_lists.size (); ++i) {
|
||||
if (mp_cell_lists [i] == w) {
|
||||
// Switch the active list for split mode -> CAUTION: this may trigger a search_editing_finished call
|
||||
select_active (int (i));
|
||||
mp_search_model = dynamic_cast<lay::CellTreeModel *> (w->model ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mp_search_model) {
|
||||
mp_search_close_cb->setChecked (true);
|
||||
mp_search_frame->show ();
|
||||
mp_search_edit_box->setText (t);
|
||||
mp_search_edit_box->setFocus ();
|
||||
search_edited ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyControlPanel::search_edited ()
|
||||
{
|
||||
QString t = mp_search_edit_box->text ();
|
||||
|
||||
for (std::vector <QTreeView *>::const_iterator v = mp_cell_lists.begin (); v != mp_cell_lists.end (); ++v) {
|
||||
if ((*v)->model () == mp_search_model) {
|
||||
if (t.isEmpty ()) {
|
||||
mp_search_model->clear_locate ();
|
||||
(*v)->setCurrentIndex (QModelIndex ());
|
||||
} else {
|
||||
QModelIndex found = mp_search_model->locate (t.toUtf8 ().constData (), mp_use_regular_expressions->isChecked (), mp_case_sensitive->isChecked (), false);
|
||||
(*v)->setCurrentIndex (found);
|
||||
if (found.isValid ()) {
|
||||
(*v)->scrollTo (found);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyControlPanel::search_next ()
|
||||
{
|
||||
for (std::vector <QTreeView *>::const_iterator v = mp_cell_lists.begin (); v != mp_cell_lists.end (); ++v) {
|
||||
if ((*v)->model () == mp_search_model) {
|
||||
QModelIndex found = mp_search_model->locate_next ();
|
||||
if (found.isValid ()) {
|
||||
(*v)->setCurrentIndex (found);
|
||||
(*v)->scrollTo (found);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyControlPanel::search_prev ()
|
||||
{
|
||||
for (std::vector <QTreeView *>::const_iterator v = mp_cell_lists.begin (); v != mp_cell_lists.end (); ++v) {
|
||||
if ((*v)->model () == mp_search_model) {
|
||||
QModelIndex found = mp_search_model->locate_prev ();
|
||||
if (found.isValid ()) {
|
||||
(*v)->setCurrentIndex (found);
|
||||
(*v)->scrollTo (found);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyControlPanel::search_editing_finished ()
|
||||
{
|
||||
for (std::vector <QTreeView *>::const_iterator v = mp_cell_lists.begin (); v != mp_cell_lists.end (); ++v) {
|
||||
CellTreeModel *m = dynamic_cast<CellTreeModel *> ((*v)->model ());
|
||||
if (m) {
|
||||
m->clear_locate ();
|
||||
}
|
||||
}
|
||||
|
||||
// give back the focus to the cell list
|
||||
for (size_t i = 0; i < mp_cell_lists.size (); ++i) {
|
||||
if (mp_cell_lists [i]->model () == mp_search_model) {
|
||||
mp_cell_lists [i]->setFocus ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mp_search_frame->hide ();
|
||||
mp_search_model = 0;
|
||||
}
|
||||
|
||||
void
|
||||
HierarchyControlPanel::middle_clicked (const QModelIndex &index)
|
||||
{
|
||||
|
|
@ -469,6 +660,13 @@ void
|
|||
HierarchyControlPanel::set_background_color (QColor c)
|
||||
{
|
||||
m_background_color = c;
|
||||
QColor hl;
|
||||
if (c.green () > 128) {
|
||||
hl = QColor (192, 192, 255);
|
||||
} else {
|
||||
hl = QColor (0, 0, 80);
|
||||
}
|
||||
|
||||
for (std::vector <QTreeView *>::const_iterator f = mp_cell_lists.begin (); f != mp_cell_lists.end (); ++f) {
|
||||
QPalette pl ((*f)->palette ());
|
||||
pl.setColor (QPalette::Base, c);
|
||||
|
|
@ -490,7 +688,7 @@ HierarchyControlPanel::set_text_color (QColor c)
|
|||
void
|
||||
HierarchyControlPanel::do_full_update_content ()
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t i = 0;
|
||||
for (std::vector <lay::CellView>::const_iterator cv = m_cellviews.begin (); cv != m_cellviews.end (); ++cv, ++i) {
|
||||
if (m_needs_update.size () > i) {
|
||||
m_needs_update [i] = true;
|
||||
|
|
@ -614,6 +812,10 @@ HierarchyControlPanel::display_string (int n) const
|
|||
void
|
||||
HierarchyControlPanel::do_update_content (int cv_index)
|
||||
{
|
||||
// close the search box since we will modify the model
|
||||
mp_search_frame->hide ();
|
||||
mp_search_model = 0;
|
||||
|
||||
unsigned int imin = (cv_index < 0 ? 0 : (unsigned int) cv_index);
|
||||
unsigned int imax = (cv_index < 0 ? std::numeric_limits <unsigned int>::max () : (unsigned int) cv_index);
|
||||
|
||||
|
|
@ -709,6 +911,7 @@ HierarchyControlPanel::do_update_content (int cv_index)
|
|||
connect (cell_list, SIGNAL (cell_clicked (const QModelIndex &)), this, SLOT (clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (cell_double_clicked (const QModelIndex &)), this, SLOT (double_clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (cell_middle_clicked (const QModelIndex &)), this, SLOT (middle_clicked (const QModelIndex &)));
|
||||
connect (cell_list, SIGNAL (search_triggered (const QString &)), this, SLOT (search_triggered (const QString &)));
|
||||
|
||||
mp_cell_lists.push_back (cell_list);
|
||||
mp_cell_list_frames.push_back (cl_frame);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "layViewOp.h"
|
||||
#include "layLayoutView.h"
|
||||
#include "layCellTreeModel.h"
|
||||
#include "layWidgets.h"
|
||||
#include "tlDeferredExecution.h"
|
||||
|
||||
class QModelIndex;
|
||||
|
|
@ -44,6 +45,9 @@ class QMenu;
|
|||
class QSplitter;
|
||||
class QFrame;
|
||||
class QToolButton;
|
||||
class QLineEdit;
|
||||
class QAction;
|
||||
class QCheckBox;
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -67,12 +71,15 @@ signals:
|
|||
void cell_clicked (const QModelIndex &);
|
||||
void cell_double_clicked (const QModelIndex &);
|
||||
void cell_middle_clicked (const QModelIndex &);
|
||||
void search_triggered (const QString &t);
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent (QMouseEvent *event);
|
||||
virtual void mousePressEvent (QMouseEvent *event);
|
||||
virtual void mouseReleaseEvent (QMouseEvent *event);
|
||||
virtual void startDrag (Qt::DropActions supportedActions);
|
||||
virtual void keyPressEvent (QKeyEvent *event);
|
||||
virtual bool event (QEvent *event);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -259,6 +266,11 @@ public slots:
|
|||
void middle_clicked (const QModelIndex &index);
|
||||
void selection_changed (int index);
|
||||
void context_menu (const QPoint &pt);
|
||||
void search_triggered (const QString &t);
|
||||
void search_edited ();
|
||||
void search_editing_finished ();
|
||||
void search_next ();
|
||||
void search_prev ();
|
||||
void cm_cell_select ();
|
||||
|
||||
private:
|
||||
|
|
@ -277,6 +289,12 @@ private:
|
|||
bool m_split_mode;
|
||||
CellTreeModel::Sorting m_sorting;
|
||||
QComboBox *mp_selector;
|
||||
lay::DecoratedLineEdit *mp_search_edit_box;
|
||||
QAction *mp_case_sensitive;
|
||||
QAction *mp_use_regular_expressions;
|
||||
CellTreeModel *mp_search_model;
|
||||
QFrame *mp_search_frame;
|
||||
QCheckBox *mp_search_close_cb;
|
||||
QSplitter *mp_splitter;
|
||||
QColor m_background_color;
|
||||
QColor m_text_color;
|
||||
|
|
|
|||
|
|
@ -934,7 +934,8 @@ const int le_decoration_space = 2; // additional distance between decoration ic
|
|||
|
||||
DecoratedLineEdit::DecoratedLineEdit (QWidget *parent)
|
||||
: QLineEdit (parent),
|
||||
m_clear_button_enabled (false), m_options_button_enabled (false), mp_options_menu (0)
|
||||
m_clear_button_enabled (false), m_options_button_enabled (false), mp_options_menu (0),
|
||||
m_escape_signal_enabled (false), m_tab_signal_enabled (false)
|
||||
{
|
||||
mp_options_label = new QLabel (this);
|
||||
mp_options_label->hide ();
|
||||
|
|
@ -957,6 +958,56 @@ DecoratedLineEdit::~DecoratedLineEdit ()
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void DecoratedLineEdit::set_escape_signal_enabled (bool en)
|
||||
{
|
||||
m_escape_signal_enabled = en;
|
||||
}
|
||||
|
||||
void DecoratedLineEdit::set_tab_signal_enabled (bool en)
|
||||
{
|
||||
m_tab_signal_enabled = en;
|
||||
}
|
||||
|
||||
bool DecoratedLineEdit::event (QEvent *event)
|
||||
{
|
||||
// Handling this event makes the widget receive all keystrokes
|
||||
if (event->type () == QEvent::ShortcutOverride) {
|
||||
QKeyEvent *ke = static_cast<QKeyEvent *> (event);
|
||||
if (ke->key () == Qt::Key_Escape && m_escape_signal_enabled) {
|
||||
ke->accept ();
|
||||
}
|
||||
}
|
||||
return QLineEdit::event (event);
|
||||
}
|
||||
|
||||
void DecoratedLineEdit::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
if (m_escape_signal_enabled && event->key () == Qt::Key_Escape) {
|
||||
emit esc_pressed ();
|
||||
event->accept ();
|
||||
} else if (m_tab_signal_enabled && event->key () == Qt::Key_Tab) {
|
||||
emit tab_pressed ();
|
||||
event->accept ();
|
||||
} else if (m_tab_signal_enabled && event->key () == Qt::Key_Backtab) {
|
||||
emit backtab_pressed ();
|
||||
event->accept ();
|
||||
} else {
|
||||
QLineEdit::keyPressEvent (event);
|
||||
}
|
||||
}
|
||||
|
||||
bool DecoratedLineEdit::focusNextPrevChild (bool next)
|
||||
{
|
||||
if (m_tab_signal_enabled && isEnabled ()) {
|
||||
QKeyEvent event (QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier);
|
||||
keyPressEvent (&event);
|
||||
if (event.isAccepted ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QLineEdit::focusNextPrevChild (next);
|
||||
}
|
||||
|
||||
void DecoratedLineEdit::set_clear_button_enabled (bool en)
|
||||
{
|
||||
if (en != m_clear_button_enabled) {
|
||||
|
|
|
|||
|
|
@ -392,17 +392,51 @@ public:
|
|||
*/
|
||||
QMenu *options_menu () const;
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether the widgets accepts ESC keys and sends an esc_pressed signal for this
|
||||
*/
|
||||
void set_escape_signal_enabled (bool f);
|
||||
|
||||
/**
|
||||
* @brief gets a value indicating whether the widgets accepts ESC keys and sends an esc_pressed signal for this
|
||||
*/
|
||||
bool escape_signal_enabled () const
|
||||
{
|
||||
return m_escape_signal_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether the widgets accepts Tab keys and sends an tab_pressed or backtab_pressed signal for this
|
||||
*/
|
||||
void set_tab_signal_enabled (bool f);
|
||||
|
||||
/**
|
||||
* @brief gets a value indicating whether the widgets accepts Tab keys and sends an tab_pressed or backtab_pressed signal for this
|
||||
*/
|
||||
bool tab_signal_enabled () const
|
||||
{
|
||||
return m_tab_signal_enabled;
|
||||
}
|
||||
|
||||
signals:
|
||||
void options_button_clicked ();
|
||||
void esc_pressed ();
|
||||
void tab_pressed ();
|
||||
void backtab_pressed ();
|
||||
|
||||
protected:
|
||||
void mousePressEvent (QMouseEvent *event);
|
||||
void mouseReleaseEvent (QMouseEvent *event);
|
||||
void resizeEvent (QResizeEvent *event);
|
||||
void keyPressEvent (QKeyEvent *event);
|
||||
bool focusNextPrevChild (bool next);
|
||||
bool event (QEvent *event);
|
||||
|
||||
private:
|
||||
bool m_clear_button_enabled;
|
||||
bool m_options_button_enabled;
|
||||
bool m_escape_signal_enabled;
|
||||
bool m_tab_signal_enabled;
|
||||
QLabel *mp_options_label;
|
||||
QLabel *mp_clear_label;
|
||||
QMenu *mp_options_menu;
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ namespace tl
|
|||
{
|
||||
|
||||
static bool
|
||||
do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector<std::pair<unsigned int, const char *> > &bstart)
|
||||
do_match (const char *p, const char *s, bool cs, bool exact, bool hm, std::vector<std::string> *o, std::vector<std::pair<unsigned int, const char *> > &bstart)
|
||||
{
|
||||
while (*p) {
|
||||
|
||||
if (*p == '\\') {
|
||||
if (!exact && *p == '\\') {
|
||||
|
||||
++p;
|
||||
if (!*s || *s != *p) {
|
||||
|
|
@ -42,7 +42,7 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
}
|
||||
++s;
|
||||
|
||||
} else if (*p == '?') {
|
||||
} else if (!exact && *p == '?') {
|
||||
|
||||
++p;
|
||||
if (! *s) {
|
||||
|
|
@ -50,7 +50,7 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
}
|
||||
++s;
|
||||
|
||||
} else if (*p == '*') {
|
||||
} else if (!exact && *p == '*') {
|
||||
|
||||
++p;
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
size_t no = o ? o->size () : 0;
|
||||
|
||||
while (*s) {
|
||||
if (do_match (p, s, o, bstart)) {
|
||||
if (do_match (p, s, cs, exact, hm, o, bstart)) {
|
||||
return true;
|
||||
}
|
||||
bstart = bs;
|
||||
|
|
@ -73,7 +73,7 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
++s;
|
||||
}
|
||||
|
||||
} else if (*p == '[') {
|
||||
} else if (!exact && *p == '[') {
|
||||
|
||||
if (! *s) {
|
||||
return false;
|
||||
|
|
@ -111,7 +111,10 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
}
|
||||
|
||||
if (! hit) {
|
||||
if (*s >= c1 && *s <= c2) {
|
||||
if (cs && *s >= c1 && *s <= c2) {
|
||||
hit = true;
|
||||
// TODO: implement UTF-8 support
|
||||
} else if (!cs && tolower (*s) >= tolower (c1) && tolower (*s) <= tolower (c2)) {
|
||||
hit = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -127,7 +130,7 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
++p;
|
||||
}
|
||||
|
||||
} else if (*p == '{') {
|
||||
} else if (!exact && *p == '{') {
|
||||
|
||||
++p;
|
||||
|
||||
|
|
@ -158,7 +161,10 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
if (hit) {
|
||||
if (! *s) {
|
||||
hit = false;
|
||||
} else if (*p != *s) {
|
||||
} else if (cs && *p != *s) {
|
||||
hit = false;
|
||||
// TODO: implement UTF-8 support
|
||||
} else if (!cs && tolower (*p) != tolower (*s)) {
|
||||
hit = false;
|
||||
} else {
|
||||
++s;
|
||||
|
|
@ -184,7 +190,7 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
return false;
|
||||
}
|
||||
|
||||
} else if (*p == ')') {
|
||||
} else if (!exact && *p == ')') {
|
||||
|
||||
++p;
|
||||
|
||||
|
|
@ -195,7 +201,7 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
bstart.pop_back ();
|
||||
}
|
||||
|
||||
} else if (*p == '(') {
|
||||
} else if (!exact && *p == '(') {
|
||||
|
||||
++p;
|
||||
if (o) {
|
||||
|
|
@ -203,33 +209,78 @@ do_match (const char *p, const char *s, std::vector<std::string> *o, std::vector
|
|||
o->push_back (std::string ());
|
||||
}
|
||||
|
||||
} else if (*s != *p) {
|
||||
return false;
|
||||
} else {
|
||||
++s;
|
||||
++p;
|
||||
|
||||
if (cs) {
|
||||
if (*s != *p) {
|
||||
return false;
|
||||
} else {
|
||||
++s;
|
||||
++p;
|
||||
}
|
||||
} else {
|
||||
// TODO: implement UTF-8 support
|
||||
if (tolower (*s) != tolower (*p)) {
|
||||
return false;
|
||||
} else {
|
||||
++s;
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (*s == 0);
|
||||
return (hm || *s == 0);
|
||||
}
|
||||
|
||||
GlobPattern::GlobPattern ()
|
||||
: m_case_sensitive (true), m_exact (false), m_header_match (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
GlobPattern::GlobPattern (const std::string &p)
|
||||
: m_p (p)
|
||||
: m_p (p), m_case_sensitive (true), m_exact (false), m_header_match (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void GlobPattern::set_case_sensitive (bool f)
|
||||
{
|
||||
m_case_sensitive = f;
|
||||
}
|
||||
|
||||
bool GlobPattern::case_sensitive () const
|
||||
{
|
||||
return m_case_sensitive;
|
||||
}
|
||||
|
||||
void GlobPattern::set_exact (bool f)
|
||||
{
|
||||
m_exact = f;
|
||||
}
|
||||
|
||||
bool GlobPattern::exact () const
|
||||
{
|
||||
return m_exact;
|
||||
}
|
||||
|
||||
void GlobPattern::set_header_match (bool f)
|
||||
{
|
||||
m_header_match = f;
|
||||
}
|
||||
|
||||
bool GlobPattern::header_match () const
|
||||
{
|
||||
return m_header_match;
|
||||
}
|
||||
|
||||
bool GlobPattern::match (const char *s) const
|
||||
{
|
||||
std::vector<std::pair<unsigned int, const char *> > bstart;
|
||||
return do_match (m_p.c_str (), s, 0, bstart);
|
||||
return do_match (m_p.c_str (), s, m_case_sensitive, m_exact, m_header_match, 0, bstart);
|
||||
}
|
||||
|
||||
bool GlobPattern::match (const char *s, std::vector<std::string> &e) const
|
||||
|
|
@ -238,13 +289,13 @@ bool GlobPattern::match (const char *s, std::vector<std::string> &e) const
|
|||
e.clear ();
|
||||
}
|
||||
std::vector<std::pair<unsigned int, const char *> > bstart;
|
||||
return do_match (m_p.c_str (), s, &e, bstart);
|
||||
return do_match (m_p.c_str (), s, m_case_sensitive, m_exact, m_header_match, &e, bstart);
|
||||
}
|
||||
|
||||
bool GlobPattern::match (const std::string &s) const
|
||||
{
|
||||
std::vector<std::pair<unsigned int, const char *> > bstart;
|
||||
return do_match (m_p.c_str (), s.c_str (), 0, bstart);
|
||||
return do_match (m_p.c_str (), s.c_str (), m_case_sensitive, m_exact, m_header_match, 0, bstart);
|
||||
}
|
||||
|
||||
bool GlobPattern::match (const std::string &s, std::vector<std::string> &e) const
|
||||
|
|
@ -253,7 +304,7 @@ bool GlobPattern::match (const std::string &s, std::vector<std::string> &e) cons
|
|||
e.clear ();
|
||||
}
|
||||
std::vector<std::pair<unsigned int, const char *> > bstart;
|
||||
return do_match (m_p.c_str (), s.c_str (), &e, bstart);
|
||||
return do_match (m_p.c_str (), s.c_str (), m_case_sensitive, m_exact, m_header_match, &e, bstart);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,36 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether to treat the match case sensitive
|
||||
*/
|
||||
void set_case_sensitive (bool f);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether to treat the match case sensitive
|
||||
*/
|
||||
bool case_sensitive () const;
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether to match exact (without brackets and wildcards)
|
||||
*/
|
||||
void set_exact (bool f);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether to match exact (without brackets and wildcards)
|
||||
*/
|
||||
bool exact () const;
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether to allow trailing characters in the subject
|
||||
*/
|
||||
void set_header_match (bool f);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether to allow trailing characters in the subject
|
||||
*/
|
||||
bool header_match () const;
|
||||
|
||||
/**
|
||||
* @brief Get the pattern string
|
||||
*/
|
||||
|
|
@ -94,6 +124,9 @@ public:
|
|||
|
||||
private:
|
||||
std::string m_p;
|
||||
bool m_case_sensitive;
|
||||
bool m_exact;
|
||||
bool m_header_match;
|
||||
};
|
||||
|
||||
} // namespace tl
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ TEST(6)
|
|||
EXPECT_EQ (a.match ("ah"), false);
|
||||
}
|
||||
|
||||
TEST(7)
|
||||
TEST(7)
|
||||
{
|
||||
tl::GlobPattern a ("(*({bc,d}))(*)");
|
||||
|
||||
|
|
@ -134,5 +134,64 @@ TEST(7)
|
|||
EXPECT_EQ (v[2], "");
|
||||
}
|
||||
|
||||
TEST(8)
|
||||
{
|
||||
// case insensitive
|
||||
|
||||
tl::GlobPattern a ("(*({bc,d}))(*)");
|
||||
|
||||
std::vector <std::string> v;
|
||||
EXPECT_EQ (a.case_sensitive (), true);
|
||||
EXPECT_EQ (a.match ("aBcG", v), false);
|
||||
|
||||
a.set_case_sensitive (false);
|
||||
EXPECT_EQ (a.case_sensitive (), false);
|
||||
EXPECT_EQ (a.match ("aBcG", v), true);
|
||||
EXPECT_EQ (v.size (), 3);
|
||||
EXPECT_EQ (v[0], "aBc");
|
||||
EXPECT_EQ (v[1], "Bc");
|
||||
EXPECT_EQ (v[2], "G");
|
||||
|
||||
tl::GlobPattern b ("*a[bcd]");
|
||||
|
||||
EXPECT_EQ (b.match ("ab"), true);
|
||||
EXPECT_EQ (b.match ("Ab"), false);
|
||||
EXPECT_EQ (b.match ("aB"), false);
|
||||
|
||||
b.set_case_sensitive (false);
|
||||
EXPECT_EQ (b.match ("ab"), true);
|
||||
EXPECT_EQ (b.match ("Ab"), true);
|
||||
EXPECT_EQ (b.match ("aB"), true);
|
||||
}
|
||||
|
||||
TEST(9)
|
||||
{
|
||||
// exact match
|
||||
|
||||
tl::GlobPattern a ("(*({bc,d}))(*)");
|
||||
a.set_exact (true);
|
||||
|
||||
EXPECT_EQ (a.exact (), true);
|
||||
EXPECT_EQ (a.match ("abcg"), false);
|
||||
EXPECT_EQ (a.match ("(*({bc,d}))(*)"), true);
|
||||
EXPECT_EQ (a.match ("(*({bc,D}))(*)"), false);
|
||||
|
||||
a.set_case_sensitive (false);
|
||||
EXPECT_EQ (a.match ("abcg"), false);
|
||||
EXPECT_EQ (a.match ("(*({bc,d}))(*)"), true);
|
||||
EXPECT_EQ (a.match ("(*({bc,D}))(*)"), true);
|
||||
}
|
||||
|
||||
TEST(10)
|
||||
{
|
||||
// header match
|
||||
|
||||
tl::GlobPattern a ("abc");
|
||||
EXPECT_EQ (a.match ("abcg"), false);
|
||||
EXPECT_EQ (a.match ("abc"), true);
|
||||
|
||||
a.set_header_match (true);
|
||||
EXPECT_EQ (a.header_match (), true);
|
||||
EXPECT_EQ (a.match ("abcg"), true);
|
||||
EXPECT_EQ (a.match ("abc"), true);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue