mirror of https://github.com/KLayout/klayout.git
Merge branch 'master' of https://github.com/KLayout/klayout
This commit is contained in:
commit
bbb8e1f430
|
|
@ -901,11 +901,6 @@ Service::drag_cancel ()
|
|||
delete mp_active_ruler;
|
||||
mp_active_ruler = 0;
|
||||
}
|
||||
|
||||
if (mp_transient_ruler) {
|
||||
delete mp_transient_ruler;
|
||||
mp_transient_ruler = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -1030,6 +1025,8 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
|
|||
// cancel any pending move or drag operations, reset mp_active_ruler
|
||||
widget ()->drag_cancel (); // KLUDGE: every service does this to the same service manager
|
||||
|
||||
clear_transient_selection ();
|
||||
|
||||
// choose move mode
|
||||
if (mode == lay::Editable::Selected) {
|
||||
|
||||
|
|
@ -1486,6 +1483,7 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
|
||||
// stop dragging
|
||||
drag_cancel ();
|
||||
clear_transient_selection ();
|
||||
|
||||
// end the transaction
|
||||
manager ()->commit ();
|
||||
|
|
@ -1535,6 +1533,7 @@ void
|
|||
Service::deactivated ()
|
||||
{
|
||||
drag_cancel ();
|
||||
clear_transient_selection ();
|
||||
}
|
||||
|
||||
std::pair<bool, db::DPoint>
|
||||
|
|
@ -1576,6 +1575,8 @@ struct RulerIdComp
|
|||
void
|
||||
Service::reduce_rulers (int num)
|
||||
{
|
||||
clear_transient_selection ();
|
||||
|
||||
lay::AnnotationShapes::iterator rfrom = mp_view->annotation_shapes ().begin ();
|
||||
lay::AnnotationShapes::iterator rto = mp_view->annotation_shapes ().end ();
|
||||
|
||||
|
|
@ -1921,6 +1922,21 @@ Service::clear_transient_selection ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Service::transient_to_selection ()
|
||||
{
|
||||
if (mp_transient_ruler) {
|
||||
for (lay::AnnotationShapes::iterator r = mp_view->annotation_shapes ().begin (); r != mp_view->annotation_shapes ().end (); ++r) {
|
||||
const ant::Object *robj = dynamic_cast <const ant::Object *> (r->ptr ());
|
||||
if (robj == mp_transient_ruler->ruler ()) {
|
||||
m_selected.insert (std::make_pair (r, 0));
|
||||
selection_to_view ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Service::clear_previous_selection ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -284,6 +284,11 @@ public:
|
|||
*/
|
||||
virtual void clear_previous_selection ();
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
virtual void transient_to_selection ();
|
||||
|
||||
/**
|
||||
* @brief Establish a transient selection
|
||||
*/
|
||||
|
|
@ -548,7 +553,7 @@ private:
|
|||
bool select (obj_iterator obj, lay::Editable::SelectionMode mode);
|
||||
|
||||
/**
|
||||
* @brief Clear the selection
|
||||
* @brief Clears the selection
|
||||
*/
|
||||
void clear_selection ();
|
||||
|
||||
|
|
|
|||
|
|
@ -1063,7 +1063,7 @@ public:
|
|||
typedef AnnotationRef value_type;
|
||||
typedef std::map<ant::Service::obj_iterator, unsigned int>::const_iterator iterator_type;
|
||||
typedef void pointer;
|
||||
typedef const value_type &reference;
|
||||
typedef value_type reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef void difference_type;
|
||||
|
||||
|
|
@ -1088,7 +1088,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
value_type operator* () const
|
||||
reference operator* () const
|
||||
{
|
||||
return value_type (*(static_cast<const ant::Object *> (m_iter->first->ptr ())), m_services[m_service]->view ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ void NetlistSpiceReader::read (tl::InputStream &stream, db::Netlist &netlist)
|
|||
mp_circuit = 0;
|
||||
mp_nets_by_name.reset (0);
|
||||
m_global_nets.clear ();
|
||||
m_circuits_read.clear ();
|
||||
|
||||
try {
|
||||
|
||||
|
|
@ -891,11 +892,16 @@ void NetlistSpiceReader::read_circuit (tl::Extractor &ex, const std::string &nc)
|
|||
} else {
|
||||
|
||||
if (cc->pin_count () != nn.size () + m_global_nets.size ()) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Pin count mismatch between implicit (through call) and explicit circuit definition: %d expected, got %d")), int (cc->pin_count ()), int (nn.size ())));
|
||||
error (tl::sprintf (tl::to_string (tr ("Pin count mismatch between implicit (through call) and explicit circuit definition: %d expected, got %d in circuit %s")), int (cc->pin_count ()), int (nn.size ()), nc));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_circuits_read.find (cc) != m_circuits_read.end ()) {
|
||||
error (tl::sprintf (tl::to_string (tr ("Redefinition of circuit %s")), nc));
|
||||
}
|
||||
m_circuits_read.insert (cc);
|
||||
|
||||
std::auto_ptr<std::map<std::string, db::Net *> > n2n (mp_nets_by_name.release ());
|
||||
mp_nets_by_name.reset (0);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#include "tlStream.h"
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace db
|
||||
|
|
@ -129,6 +131,7 @@ private:
|
|||
std::string m_stored_line;
|
||||
std::map<std::string, bool> m_captured;
|
||||
std::vector<std::string> m_global_nets;
|
||||
std::set<const db::Circuit *> m_circuits_read;
|
||||
|
||||
void push_stream (const std::string &path);
|
||||
void pop_stream ();
|
||||
|
|
|
|||
|
|
@ -384,3 +384,21 @@ TEST(10_SubcircuitsNoPins)
|
|||
);
|
||||
}
|
||||
|
||||
TEST(11_ErrorOnCircuitRedefinition)
|
||||
{
|
||||
db::Netlist nl;
|
||||
|
||||
std::string path = tl::combine_path (tl::combine_path (tl::combine_path (tl::testsrc (), "testdata"), "algo"), "nreader11.cir");
|
||||
|
||||
std::string msg;
|
||||
try {
|
||||
db::NetlistSpiceReader reader;
|
||||
tl::InputStream is (path);
|
||||
reader.read (is, nl);
|
||||
} catch (tl::Exception &ex) {
|
||||
msg = ex.msg ();
|
||||
}
|
||||
|
||||
EXPECT_EQ (tl::replaced (msg, path, "?"), "Redefinition of circuit SUBCKT in ?, line 20");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<ui version="4.0" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CopyModeDialog</class>
|
||||
<widget class="QDialog" name="CopyModeDialog" >
|
||||
<property name="geometry" >
|
||||
<widget class="QDialog" name="CopyModeDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
|
|
@ -9,38 +10,56 @@
|
|||
<height>164</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<property name="windowTitle">
|
||||
<string>Copy Options</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="QGroupBox" name="groupBox" >
|
||||
<property name="title" >
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Copy Mode</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="QRadioButton" name="shallow_rb" >
|
||||
<property name="text" >
|
||||
<widget class="QRadioButton" name="shallow_rb">
|
||||
<property name="text">
|
||||
<string>Shallow copy (instances only)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="deep_rb" >
|
||||
<property name="text" >
|
||||
<widget class="QRadioButton" name="deep_rb">
|
||||
<property name="text">
|
||||
<string>Deep copy (instances plus cell)</string>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -48,12 +67,19 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="dont_ask_cbx">
|
||||
<property name="text">
|
||||
<string>Don't ask again (you can always reset this in the editor options)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
|
|
@ -62,12 +88,12 @@
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="orientation" >
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons" >
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -81,11 +107,11 @@
|
|||
<receiver>CopyModeDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
|
|
@ -97,11 +123,11 @@
|
|||
<receiver>CopyModeDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<ui version="4.0" >
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditorOptionsGeneric</class>
|
||||
<widget class="QWidget" name="EditorOptionsGeneric" >
|
||||
<property name="geometry" >
|
||||
<widget class="QWidget" name="EditorOptionsGeneric">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
|
|
@ -9,34 +10,52 @@
|
|||
<height>417</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<property name="windowTitle">
|
||||
<string>Form</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="QGroupBox" name="groupBox" >
|
||||
<property name="title" >
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Snapping</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="4" >
|
||||
<item row="0" column="4">
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>148</width>
|
||||
<height>16</height>
|
||||
|
|
@ -44,15 +63,15 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2" >
|
||||
<item row="0" column="2">
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
|
|
@ -60,57 +79,55 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="3" >
|
||||
<widget class="QLineEdit" name="edit_grid_le" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>0</hsizetype>
|
||||
<vsizetype>0</vsizetype>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLineEdit" name="edit_grid_le">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip" >
|
||||
<string>Enter the grid in micron. Can be anisotropic ("gx,gy")</string>
|
||||
<property name="toolTip">
|
||||
<string>Enter the grid in micron. Can be anisotropic ("gx,gy")</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_5" >
|
||||
<property name="text" >
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Grid</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="label_6" >
|
||||
<property name="text" >
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Objects </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QComboBox" name="grid_cb" >
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="grid_cb">
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>No grid</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Global grid</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Other grid ...</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4" >
|
||||
<widget class="QCheckBox" name="snap_objects_cbx" >
|
||||
<property name="text" >
|
||||
<item row="1" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="snap_objects_cbx">
|
||||
<property name="text">
|
||||
<string>Snap to other objects</string>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -119,75 +136,84 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2" >
|
||||
<property name="title" >
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Angle Constraints</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="1" column="0" >
|
||||
<widget class="QLabel" name="label_3" >
|
||||
<property name="text" >
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Movements </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>Connections </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QComboBox" name="conn_angle_cb" >
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="conn_angle_cb">
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Any Angle</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Diagonal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Manhattan</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QComboBox" name="move_angle_cb" >
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="move_angle_cb">
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Any Direction</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Diagonal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<property name="text">
|
||||
<string>Manhattan</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="2" row="0" column="2" >
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>257</width>
|
||||
<height>41</height>
|
||||
|
|
@ -199,36 +225,91 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3" >
|
||||
<property name="title" >
|
||||
<string>Selection Mode</string>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Hierarchical Features</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<layout class="QGridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QCheckBox" name="hier_sel_cbx" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>7</hsizetype>
|
||||
<vsizetype>0</vsizetype>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Copy mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Shallow select</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="hier_copy_mode_cbx">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Select top level objects only</string>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContentsOnFirstShow</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Shallow mode (instance only)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Deep mode (instance and cell)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Ask</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_4" >
|
||||
<property name="text" >
|
||||
<string>Hierarchy </string>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="hier_sel_cbx">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select top level objects only</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -236,30 +317,37 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4" >
|
||||
<property name="title" >
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Instance Display</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<layout class="QHBoxLayout">
|
||||
<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="QCheckBox" name="show_shapes_cbx" >
|
||||
<property name="text" >
|
||||
<widget class="QCheckBox" name="show_shapes_cbx">
|
||||
<property name="text">
|
||||
<string>Show shapes when moving (max.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="max_shapes_le" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>5</hsizetype>
|
||||
<vsizetype>0</vsizetype>
|
||||
<widget class="QLineEdit" name="max_shapes_le">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
|
|
@ -267,18 +355,18 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_13" >
|
||||
<property name="text" >
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>shapes)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
|
|
@ -291,10 +379,10 @@
|
|||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>121</width>
|
||||
<height>51</height>
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ std::string cfg_edit_inst_column_x ("edit-inst-column_x");
|
|||
std::string cfg_edit_inst_column_y ("edit-inst-column_y");
|
||||
std::string cfg_edit_inst_place_origin ("edit-inst-place-origin");
|
||||
std::string cfg_edit_top_level_selection ("edit-top-level-selection");
|
||||
std::string cfg_edit_hier_copy_mode ("edit-hier-copy-mode");
|
||||
std::string cfg_edit_show_shapes_of_instances ("edit-show-shapes-of-instances");
|
||||
std::string cfg_edit_max_shapes_of_instances ("edit-max-shapes-of-instances");
|
||||
std::string cfg_edit_global_grid ("grid-micron");
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ extern EDT_PUBLIC std::string cfg_edit_inst_column_x;
|
|||
extern EDT_PUBLIC std::string cfg_edit_inst_column_y;
|
||||
extern EDT_PUBLIC std::string cfg_edit_inst_place_origin;
|
||||
extern EDT_PUBLIC std::string cfg_edit_top_level_selection;
|
||||
extern EDT_PUBLIC std::string cfg_edit_hier_copy_mode;
|
||||
extern EDT_PUBLIC std::string cfg_edit_combine_mode;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ CopyModeDialog::~CopyModeDialog ()
|
|||
}
|
||||
|
||||
bool
|
||||
CopyModeDialog::exec_dialog (unsigned int &mode)
|
||||
CopyModeDialog::exec_dialog (unsigned int &mode, bool &dont_ask)
|
||||
{
|
||||
if (mode == 0) {
|
||||
shallow_rb->setChecked (true);
|
||||
|
|
@ -207,6 +207,7 @@ CopyModeDialog::exec_dialog (unsigned int &mode)
|
|||
} else {
|
||||
mode = 1;
|
||||
}
|
||||
dont_ask = dont_ask_cbx->isChecked ();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public:
|
|||
CopyModeDialog (QWidget *parent);
|
||||
virtual ~CopyModeDialog ();
|
||||
|
||||
bool exec_dialog (unsigned int &mode);
|
||||
bool exec_dialog (unsigned int &mode, bool &dont_ask);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -265,6 +265,8 @@ EditorOptionsGeneric::apply (lay::Plugin *root)
|
|||
root->config_set (cfg_edit_connect_angle_mode, acc.to_string (lay::angle_constraint_type (mp_ui->conn_angle_cb->currentIndex ())));
|
||||
|
||||
root->config_set (cfg_edit_top_level_selection, tl::to_string (mp_ui->hier_sel_cbx->isChecked ()));
|
||||
int cpm = mp_ui->hier_copy_mode_cbx->currentIndex ();
|
||||
root->config_set (cfg_edit_hier_copy_mode, tl::to_string ((cpm < 0 || cpm > 1) ? -1 : cpm));
|
||||
root->config_set (cfg_edit_snap_to_objects, tl::to_string (mp_ui->snap_objects_cbx->isChecked ()));
|
||||
|
||||
unsigned int max_shapes = 1000;
|
||||
|
|
@ -321,6 +323,10 @@ EditorOptionsGeneric::setup (lay::Plugin *root)
|
|||
root->config_get (cfg_edit_top_level_selection, top_level_sel);
|
||||
mp_ui->hier_sel_cbx->setChecked (top_level_sel);
|
||||
|
||||
int cpm = -1;
|
||||
root->config_get (cfg_edit_hier_copy_mode, cpm);
|
||||
mp_ui->hier_copy_mode_cbx->setCurrentIndex ((cpm < 0 || cpm > 1) ? 2 : cpm);
|
||||
|
||||
bool snap_to_objects = false;
|
||||
root->config_get (cfg_edit_snap_to_objects, snap_to_objects);
|
||||
mp_ui->snap_objects_cbx->setChecked (snap_to_objects);
|
||||
|
|
|
|||
|
|
@ -1641,7 +1641,7 @@ MainService::boolean_op (int mode)
|
|||
|
||||
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
|
||||
for (edt::Service::obj_iterator s = (*es)->selection ().begin (); s != (*es)->selection ().end (); ++s) {
|
||||
if (int (s->layer ()) == layer_index && ! s->is_cell_inst () && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
|
||||
if (! s->is_cell_inst () && int (s->layer ()) == layer_index && (s->shape ().is_polygon () || s->shape ().is_path () || s->shape ().is_box ())) {
|
||||
db::Cell &cell = view ()->cellview (s->cv_index ())->layout ().cell (s->cell_index ());
|
||||
if (cell.shapes (s->layer ()).is_valid (s->shape ())) {
|
||||
cell.shapes (s->layer ()).erase_shape (s->shape ());
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ public:
|
|||
virtual void get_options (std::vector < std::pair<std::string, std::string> > &options) const
|
||||
{
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_edit_top_level_selection, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_edit_hier_copy_mode, "-1"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_edit_grid, ""));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_edit_snap_to_objects, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_edit_move_angle_mode, "any"));
|
||||
|
|
|
|||
|
|
@ -113,6 +113,7 @@ Service::Service (db::Manager *manager, lay::LayoutView *view, db::ShapeIterator
|
|||
m_connect_ac (lay::AC_Any), m_move_ac (lay::AC_Any), m_alt_ac (lay::AC_Global),
|
||||
m_snap_to_objects (false),
|
||||
m_top_level_sel (false), m_show_shapes_of_instances (true), m_max_shapes_of_instances (1000),
|
||||
m_hier_copy_mode (-1),
|
||||
m_indicate_secondary_selection (false),
|
||||
m_seq (0),
|
||||
dm_selection_to_view (this, &edt::Service::do_selection_to_view)
|
||||
|
|
@ -134,6 +135,7 @@ Service::Service (db::Manager *manager, lay::LayoutView *view)
|
|||
m_connect_ac (lay::AC_Any), m_move_ac (lay::AC_Any), m_alt_ac (lay::AC_Global),
|
||||
m_snap_to_objects (true),
|
||||
m_top_level_sel (false), m_show_shapes_of_instances (true), m_max_shapes_of_instances (1000),
|
||||
m_hier_copy_mode (-1),
|
||||
m_indicate_secondary_selection (false),
|
||||
m_seq (0),
|
||||
dm_selection_to_view (this, &edt::Service::do_selection_to_view)
|
||||
|
|
@ -255,6 +257,8 @@ Service::configure (const std::string &name, const std::string &value)
|
|||
return true; // taken
|
||||
} else if (name == cfg_edit_top_level_selection) {
|
||||
tl::from_string (value, m_top_level_sel);
|
||||
} else if (name == cfg_edit_hier_copy_mode) {
|
||||
tl::from_string (value, m_hier_copy_mode);
|
||||
}
|
||||
|
||||
return false; // not taken
|
||||
|
|
@ -309,18 +313,30 @@ Service::copy_selected ()
|
|||
edt::CopyModeDialog mode_dialog (view ());
|
||||
|
||||
bool need_to_ask_for_copy_mode = false;
|
||||
for (objects::const_iterator r = m_selection.begin (); r != m_selection.end () && ! need_to_ask_for_copy_mode; ++r) {
|
||||
if (r->is_cell_inst ()) {
|
||||
const db::Cell &cell = view ()->cellview (r->cv_index ())->layout ().cell (r->back ().inst_ptr.cell_index ());
|
||||
if (! cell.is_proxy ()) {
|
||||
need_to_ask_for_copy_mode = true;
|
||||
unsigned int inst_mode = 0;
|
||||
|
||||
if (m_hier_copy_mode < 0) {
|
||||
for (objects::const_iterator r = m_selection.begin (); r != m_selection.end () && ! need_to_ask_for_copy_mode; ++r) {
|
||||
if (r->is_cell_inst ()) {
|
||||
const db::Cell &cell = view ()->cellview (r->cv_index ())->layout ().cell (r->back ().inst_ptr.cell_index ());
|
||||
if (! cell.is_proxy ()) {
|
||||
need_to_ask_for_copy_mode = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
inst_mode = (unsigned int) m_hier_copy_mode;
|
||||
}
|
||||
|
||||
unsigned int inst_mode = 0;
|
||||
bool dont_ask_again = false;
|
||||
|
||||
if (! need_to_ask_for_copy_mode || mode_dialog.exec_dialog (inst_mode)) {
|
||||
if (! need_to_ask_for_copy_mode || mode_dialog.exec_dialog (inst_mode, dont_ask_again)) {
|
||||
|
||||
// store the given value "forever"
|
||||
if (dont_ask_again) {
|
||||
plugin_root ()->config_set (cfg_edit_hier_copy_mode, tl::to_string (inst_mode));
|
||||
plugin_root ()->config_end ();
|
||||
}
|
||||
|
||||
// create one ClipboardData object per cv_index because, this one assumes that there is
|
||||
// only one source layout object.
|
||||
|
|
@ -357,6 +373,9 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
|
|||
{
|
||||
if (view ()->is_editable () && mode == lay::Editable::Selected) {
|
||||
|
||||
// flush any pending updates of the markers
|
||||
dm_selection_to_view.execute ();
|
||||
|
||||
m_move_start = p;
|
||||
m_move_trans = db::DTrans ();
|
||||
m_move_sel = true; // TODO: there is no "false". Remove this.
|
||||
|
|
@ -1187,6 +1206,15 @@ Service::selection_applies (const lay::ObjectInstPath & /*sel*/) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Service::transient_to_selection ()
|
||||
{
|
||||
if (! m_transient_selection.empty ()) {
|
||||
m_selection.insert (m_transient_selection.begin (), m_transient_selection.end ());
|
||||
selection_to_view ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Service::clear_previous_selection ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -184,11 +184,6 @@ public:
|
|||
*/
|
||||
virtual bool select (const db::DBox &box, lay::Editable::SelectionMode mode);
|
||||
|
||||
/**
|
||||
* @brief Clears the previous selection
|
||||
*/
|
||||
virtual void clear_previous_selection ();
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the given selected object is handled by this service
|
||||
*/
|
||||
|
|
@ -269,11 +264,21 @@ public:
|
|||
*/
|
||||
bool select (const lay::ObjectInstPath &obj, lay::Editable::SelectionMode mode);
|
||||
|
||||
/**
|
||||
* @brief Clears the previous selection
|
||||
*/
|
||||
void clear_previous_selection ();
|
||||
|
||||
/**
|
||||
* @brief Establish a transient selection
|
||||
*/
|
||||
bool transient_select (const db::DPoint &pos);
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
virtual void transient_to_selection ();
|
||||
|
||||
/**
|
||||
* @brief Clear the transient selection
|
||||
*/
|
||||
|
|
@ -574,6 +579,9 @@ private:
|
|||
bool m_show_shapes_of_instances;
|
||||
unsigned int m_max_shapes_of_instances;
|
||||
|
||||
// Hierarchical copy mode (-1: ask, 0: shallow, 1: deep)
|
||||
int m_hier_copy_mode;
|
||||
|
||||
// Sequence number of selection
|
||||
bool m_indicate_secondary_selection;
|
||||
unsigned long m_seq;
|
||||
|
|
|
|||
|
|
@ -1063,6 +1063,15 @@ Service::clear_previous_selection ()
|
|||
m_previous_selection.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
Service::transient_to_selection ()
|
||||
{
|
||||
if (mp_transient_view) {
|
||||
m_selected.insert (std::make_pair (mp_transient_view->image_ref (), 0));
|
||||
selection_to_view ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Service::select (obj_iterator obj, lay::Editable::SelectionMode mode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -304,6 +304,11 @@ public:
|
|||
*/
|
||||
virtual bool transient_select (const db::DPoint &pos);
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
virtual void transient_to_selection ();
|
||||
|
||||
/**
|
||||
* @brief Clear the transient selection
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2275,7 +2275,7 @@ MainWindow::do_cm_duplicate (bool interactive)
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (current_view () && current_view ()->has_selection ()) {
|
||||
if (current_view ()) {
|
||||
|
||||
// Do duplicate simply by concatenating copy & paste currently.
|
||||
// Save the clipboard state before in order to preserve the current content
|
||||
|
|
@ -2327,7 +2327,7 @@ MainWindow::cm_copy ()
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (current_view () && current_view ()->has_selection ()) {
|
||||
if (current_view ()) {
|
||||
current_view ()->copy ();
|
||||
current_view ()->clear_selection ();
|
||||
}
|
||||
|
|
@ -2370,7 +2370,7 @@ MainWindow::cm_cut ()
|
|||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (current_view () && current_view ()->has_selection ()) {
|
||||
if (current_view ()) {
|
||||
current_view ()->cut ();
|
||||
current_view ()->cancel (); // see del() for reason why cancel is after cut
|
||||
current_view ()->clear_selection ();
|
||||
|
|
@ -2766,21 +2766,6 @@ MainWindow::update_action_states ()
|
|||
|
||||
}
|
||||
|
||||
if (mp_menu->is_valid ("edit_menu.copy")) {
|
||||
Action copy_action = mp_menu->action ("edit_menu.copy");
|
||||
copy_action.set_enabled (current_view () && current_view ()->has_selection () && edits_enabled ());
|
||||
}
|
||||
|
||||
if (mp_menu->is_valid ("edit_menu.duplicate")) {
|
||||
Action copy_action = mp_menu->action ("edit_menu.duplicate");
|
||||
copy_action.set_enabled (current_view () && current_view ()->has_selection () && edits_enabled ());
|
||||
}
|
||||
|
||||
if (mp_menu->is_valid ("edit_menu.cut")) {
|
||||
Action cut_action = mp_menu->action ("edit_menu.cut");
|
||||
cut_action.set_enabled (current_view () && current_view ()->has_selection () && edits_enabled ());
|
||||
}
|
||||
|
||||
if (mp_menu->is_valid ("edit_menu.paste")) {
|
||||
Action paste_action = mp_menu->action ("edit_menu.paste");
|
||||
paste_action.set_enabled (! db::Clipboard::instance ().empty () && edits_enabled ());
|
||||
|
|
|
|||
|
|
@ -821,6 +821,29 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
|
|||
"selection. Calling this method is useful to ensure there are no potential interactions with the script's "
|
||||
"functionality.\n"
|
||||
) +
|
||||
gsi::method ("clear_selection", &lay::LayoutView::clear_selection,
|
||||
"@brief Clears the selection of all objects (shapes, annotations, images ...)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2\n"
|
||||
) +
|
||||
gsi::method ("clear_transient_selection", &lay::LayoutView::clear_transient_selection,
|
||||
"@brief Clears the transient selection (mouse-over hightlights) of all objects (shapes, annotations, images ...)\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2\n"
|
||||
) +
|
||||
gsi::method ("transient_to_selection", &lay::LayoutView::transient_to_selection,
|
||||
"@brief Turns the transient selection into the actual selection\n"
|
||||
"\n"
|
||||
"The current selection is cleared before. All highlighted objects under the mouse will become selected. "
|
||||
"This applies to all types of objects (rulers, shapes, images ...).\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2\n"
|
||||
) +
|
||||
gsi::method ("selection_bbox", &lay::LayoutView::selection_bbox,
|
||||
"@brief Returns the bounding box of the current selection\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26.2\n"
|
||||
) +
|
||||
gsi::method ("stop", &lay::LayoutView::stop,
|
||||
"@brief Stops redraw thread and close any browsers\n"
|
||||
"This method usually does not need to be called explicitly. The redraw thread is stopped automatically."
|
||||
|
|
@ -1077,7 +1100,6 @@ Class<lay::LayoutView> decl_LayoutView (QT_EXTERNAL_BASE (QWidget) "lay", "Layou
|
|||
) +
|
||||
gsi::method_ext ("delete_layers", &delete_layers1, gsi::arg ("iterators"),
|
||||
"@brief Deletes the layer properties nodes specified by the iterator\n"
|
||||
"@args iterators\n"
|
||||
"\n"
|
||||
"This method deletes the nodes specifies by the iterators. This method is the most convenient way to "
|
||||
"delete multiple entries.\n"
|
||||
|
|
@ -1837,9 +1859,8 @@ static void cv_show_all_cells (lay::CellViewRef *cv)
|
|||
}
|
||||
|
||||
Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
||||
method ("==", static_cast<bool (lay::CellViewRef::*) (const lay::CellViewRef &) const> (&lay::CellViewRef::operator==),
|
||||
method ("==", static_cast<bool (lay::CellViewRef::*) (const lay::CellViewRef &) const> (&lay::CellViewRef::operator==), gsi::arg ("other"),
|
||||
"@brief Equality: indicates whether the cellviews refer to the same one\n"
|
||||
"@args other\n"
|
||||
"In version 0.25, the definition of the equality operator has been changed to reflect identity of the "
|
||||
"cellview. Before that version, identity of the cell shown was implied."
|
||||
) +
|
||||
|
|
@ -1868,32 +1889,28 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
"@brief Returns true, if the cellview is valid\n"
|
||||
"A cellview may become invalid if the corresponding tab is closed for example."
|
||||
) +
|
||||
method ("path=|set_path", &lay::CellViewRef::set_unspecific_path,
|
||||
method ("path=|set_path", &lay::CellViewRef::set_unspecific_path, gsi::arg ("path"),
|
||||
"@brief Sets the unspecific part of the path explicitly\n"
|
||||
"@args path\n"
|
||||
"\n"
|
||||
"Setting the unspecific part of the path will clear the context path component and\n"
|
||||
"update the context and target cell.\n"
|
||||
) +
|
||||
method ("context_path=|set_context_path", &lay::CellViewRef::set_specific_path,
|
||||
method ("context_path=|set_context_path", &lay::CellViewRef::set_specific_path, gsi::arg ("path"),
|
||||
"@brief Sets the context path explicitly\n"
|
||||
"@args path\n"
|
||||
"\n"
|
||||
"This method assumes that the unspecific part of the path \n"
|
||||
"is established already and that the context path starts\n"
|
||||
"from the context cell.\n"
|
||||
) +
|
||||
method ("cell_index=|set_cell", (void (lay::CellViewRef::*) (lay::CellViewRef::cell_index_type)) &lay::CellViewRef::set_cell,
|
||||
method ("cell_index=|set_cell", (void (lay::CellViewRef::*) (lay::CellViewRef::cell_index_type)) &lay::CellViewRef::set_cell, gsi::arg ("cell_index"),
|
||||
"@brief Sets the path to the given cell\n"
|
||||
"@args cell_index\n"
|
||||
"\n"
|
||||
"This method will construct any path to this cell, not a \n"
|
||||
"particular one. It will clear the context path\n"
|
||||
"and update the context and target cell. Note that the cell is specified by it's index.\n"
|
||||
) +
|
||||
method ("cell_name=|set_cell_name", (void (lay::CellViewRef::*) (const std::string &)) &lay::CellViewRef::set_cell,
|
||||
method ("cell_name=|set_cell_name", (void (lay::CellViewRef::*) (const std::string &)) &lay::CellViewRef::set_cell, gsi::arg ("cell_name"),
|
||||
"@brief Sets the cell by name\n"
|
||||
"@args cell_name\n"
|
||||
"\n"
|
||||
"If the name is not a valid one, the cellview will become\n"
|
||||
"invalid.\n"
|
||||
|
|
@ -1901,9 +1918,8 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
"particular one. It will clear the context path\n"
|
||||
"and update the context and target cell.\n"
|
||||
) +
|
||||
method_ext ("cell=", set_cell,
|
||||
method_ext ("cell=", set_cell, gsi::arg ("cell"),
|
||||
"@brief Sets the cell by reference to a Cell object\n"
|
||||
"@args cell\n"
|
||||
"Setting the cell reference to nil invalidates the cellview. "
|
||||
"This method will construct any path to this cell, not a \n"
|
||||
"particular one. It will clear the context path\n"
|
||||
|
|
@ -1961,9 +1977,8 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
"@brief Returns the technology name for the layout behind the given cell view\n"
|
||||
"This method has been added in version 0.23.\n"
|
||||
) +
|
||||
method_ext ("technology=", &apply_technology,
|
||||
method_ext ("technology=", &apply_technology, gsi::arg ("tech_name"),
|
||||
"@brief Sets the technology for the layout behind the given cell view\n"
|
||||
"@args tech_name\n"
|
||||
"According to the specification of the technology, new layer properties may be loaded "
|
||||
"or the net tracer may be reconfigured. If the layout is shown in multiple views, the "
|
||||
"technology is updated for all views.\n"
|
||||
|
|
@ -1972,9 +1987,8 @@ Class<lay::CellViewRef> decl_CellView ("lay", "CellView",
|
|||
method_ext ("layout", &get_layout,
|
||||
"@brief Gets the reference to the layout object addressed by this view\n"
|
||||
) +
|
||||
method_ext ("descend", &cv_descend,
|
||||
method_ext ("descend", &cv_descend, gsi::arg ("path"),
|
||||
"@brief Descends further into the hierarchy.\n"
|
||||
"@args path\n"
|
||||
"Adds the given path (given as an array of InstElement objects) to the specific path of the "
|
||||
"cellview with the given index. In effect, the cell addressed by the terminal of the new path "
|
||||
"components can be shown in the context of the upper cells, if the minimum hierarchy level is "
|
||||
|
|
|
|||
|
|
@ -301,6 +301,22 @@ Editables::clear_transient_selection ()
|
|||
signal_transient_selection_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Editables::transient_to_selection ()
|
||||
{
|
||||
cancel_edits ();
|
||||
for (iterator e = begin (); e != end (); ++e) {
|
||||
e->select (db::DBox (), lay::Editable::Reset); // clear selection
|
||||
e->clear_previous_selection ();
|
||||
e->transient_to_selection ();
|
||||
e->clear_transient_selection ();
|
||||
}
|
||||
|
||||
// send a signal to the observers
|
||||
signal_transient_selection_changed ();
|
||||
signal_selection_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
Editables::clear_selection ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -182,6 +182,14 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
virtual void transient_to_selection ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the transient selection
|
||||
*
|
||||
|
|
@ -418,7 +426,7 @@ public:
|
|||
* or must be given in micron units.
|
||||
*/
|
||||
db::DBox selection_bbox ();
|
||||
|
||||
|
||||
/**
|
||||
* @brief transform the selection
|
||||
*
|
||||
|
|
@ -457,6 +465,11 @@ public:
|
|||
*/
|
||||
void clear_transient_selection ();
|
||||
|
||||
/**
|
||||
* @brief Turns the transient selection to the selection
|
||||
*/
|
||||
void transient_to_selection ();
|
||||
|
||||
/**
|
||||
* @brief Clear the previous selection
|
||||
*
|
||||
|
|
|
|||
|
|
@ -5154,7 +5154,7 @@ LayoutView::paste_interactive ()
|
|||
// operations.
|
||||
trans->close ();
|
||||
|
||||
if (mp_move_service->begin_move (trans.release ())) {
|
||||
if (mp_move_service->begin_move (trans.release (), false)) {
|
||||
switch_mode (-1); // move mode
|
||||
}
|
||||
}
|
||||
|
|
@ -5167,7 +5167,14 @@ LayoutView::copy ()
|
|||
} else if (mp_control_panel && mp_control_panel->has_focus ()) {
|
||||
mp_control_panel->copy ();
|
||||
} else {
|
||||
|
||||
if (lay::Editables::selection_size () == 0) {
|
||||
// try to use the transient selection for the real one
|
||||
lay::Editables::transient_to_selection ();
|
||||
}
|
||||
|
||||
lay::Editables::copy ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5182,8 +5189,15 @@ LayoutView::cut ()
|
|||
db::Transaction trans (manager (), tl::to_string (QObject::tr ("Cut Layers")));
|
||||
mp_control_panel->cut ();
|
||||
} else {
|
||||
|
||||
if (lay::Editables::selection_size () == 0) {
|
||||
// try to use the transient selection for the real one
|
||||
lay::Editables::transient_to_selection ();
|
||||
}
|
||||
|
||||
db::Transaction trans (manager (), tl::to_string (QObject::tr ("Cut")));
|
||||
lay::Editables::cut ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ MoveService::MoveService (lay::LayoutView *view)
|
|||
: QObject (),
|
||||
lay::ViewService (view->view_object_widget ()),
|
||||
m_dragging (false),
|
||||
m_dragging_transient (false),
|
||||
mp_editables (view),
|
||||
mp_view (view),
|
||||
m_global_grid (0.001)
|
||||
|
|
@ -148,6 +149,9 @@ MoveService::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool p
|
|||
|
||||
}
|
||||
|
||||
// track mouse position for the infix move initiation
|
||||
m_mouse_pos = p;
|
||||
|
||||
return ret; // not taken to allow the mouse tracker to receive events as well
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +167,7 @@ MoveService::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool
|
|||
return true;
|
||||
}
|
||||
if (prio && (buttons & lay::LeftButton) != 0) {
|
||||
if (handle_dragging (p, buttons, 0)) {
|
||||
if (handle_dragging (p, buttons, false, 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -216,7 +220,7 @@ bool
|
|||
MoveService::mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
||||
{
|
||||
if (prio && (buttons & lay::LeftButton) != 0) {
|
||||
if (handle_dragging (p, buttons, 0)) {
|
||||
if (handle_dragging (p, buttons, false, 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -230,26 +234,50 @@ MoveService::mouse_press_event (const db::DPoint &p, unsigned int buttons, bool
|
|||
}
|
||||
|
||||
bool
|
||||
MoveService::begin_move (db::Transaction *transaction)
|
||||
MoveService::begin_move (db::Transaction *transaction, bool selected_after_move)
|
||||
{
|
||||
if (m_dragging) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::auto_ptr<db::Transaction> trans_holder (transaction);
|
||||
|
||||
drag_cancel ();
|
||||
bool drag_transient = ! selected_after_move;
|
||||
if (mp_editables->selection_size () == 0) {
|
||||
// try to use the transient selection for the real one
|
||||
mp_editables->transient_to_selection ();
|
||||
drag_transient = true;
|
||||
}
|
||||
|
||||
if (mp_editables->selection_size () == 0) {
|
||||
// still nothing selected
|
||||
return false;
|
||||
}
|
||||
|
||||
db::DBox bbox = mp_editables->selection_bbox ();
|
||||
if (bbox.empty ()) {
|
||||
// nothing selected
|
||||
// nothing (useful) selected
|
||||
return false;
|
||||
}
|
||||
|
||||
set_cursor (lay::Cursor::size_all);
|
||||
|
||||
// emulate a "begin move" at the center of the selection bbox - this will become the reference point
|
||||
return handle_dragging (bbox.center (), 0, trans_holder.release ());
|
||||
// emulate a "begin move" at the current mouse position if inside the box or the closest point
|
||||
// of the box.
|
||||
|
||||
db::DPoint pstart = m_mouse_pos;
|
||||
if (! bbox.contains (pstart)) {
|
||||
pstart.set_x (std::max (pstart.x (), bbox.p1 ().x ()));
|
||||
pstart.set_x (std::min (pstart.x (), bbox.p2 ().x ()));
|
||||
pstart.set_y (std::max (pstart.y (), bbox.p1 ().y ()));
|
||||
pstart.set_y (std::min (pstart.y (), bbox.p2 ().y ()));
|
||||
}
|
||||
|
||||
return handle_dragging (pstart, 0, drag_transient, trans_holder.release ());
|
||||
}
|
||||
|
||||
bool
|
||||
MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons, db::Transaction *transaction)
|
||||
MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons, bool drag_transient, db::Transaction *transaction)
|
||||
{
|
||||
std::auto_ptr<db::Transaction> trans_holder (transaction);
|
||||
|
||||
|
|
@ -267,6 +295,7 @@ MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons, db::Tra
|
|||
mp_view->clear_transient_selection ();
|
||||
|
||||
m_dragging = true;
|
||||
m_dragging_transient = drag_transient;
|
||||
widget ()->grab_mouse (this, false);
|
||||
|
||||
m_shift = db::DPoint ();
|
||||
|
|
@ -278,8 +307,14 @@ MoveService::handle_dragging (const db::DPoint &p, unsigned int buttons, db::Tra
|
|||
} else {
|
||||
|
||||
m_dragging = false;
|
||||
|
||||
widget ()->ungrab_mouse (this);
|
||||
mp_editables->end_move (p, ac_from_buttons (buttons), mp_transaction.release ());
|
||||
|
||||
if (m_dragging_transient) {
|
||||
mp_editables->clear_selection ();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public:
|
|||
~MoveService ();
|
||||
|
||||
virtual bool configure (const std::string &name, const std::string &value);
|
||||
bool begin_move (db::Transaction *transaction = 0);
|
||||
bool begin_move (db::Transaction *transaction = 0, bool selected_after_move = true);
|
||||
|
||||
private:
|
||||
virtual bool mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
|
|
@ -62,13 +62,15 @@ private:
|
|||
virtual void drag_cancel ();
|
||||
virtual void deactivated ();
|
||||
|
||||
bool handle_dragging (const db::DPoint &p, unsigned int buttons, db::Transaction *transaction);
|
||||
bool handle_dragging (const db::DPoint &p, unsigned int buttons, bool drag_transient, db::Transaction *transaction);
|
||||
|
||||
bool m_dragging;
|
||||
bool m_dragging_transient;
|
||||
lay::Editables *mp_editables;
|
||||
lay::LayoutView *mp_view;
|
||||
double m_global_grid;
|
||||
db::DPoint m_shift;
|
||||
db::DPoint m_mouse_pos;
|
||||
std::auto_ptr<db::Transaction> mp_transaction;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -240,7 +240,8 @@ void Macro::load_from (const std::string &fn)
|
|||
} else if (m_format == PlainTextFormat || m_format == PlainTextWithHashAnnotationsFormat) {
|
||||
|
||||
tl::InputStream stream (path);
|
||||
m_text = stream.read_all ();
|
||||
tl::TextInputStream text_stream (stream);
|
||||
m_text = text_stream.read_all ();
|
||||
sync_properties_with_text ();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -422,6 +422,30 @@ TextInputStream::TextInputStream (InputStream &stream)
|
|||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
TextInputStream::read_all ()
|
||||
{
|
||||
return read_all (std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
std::string
|
||||
TextInputStream::read_all (size_t max_count)
|
||||
{
|
||||
std::string text;
|
||||
|
||||
while (! at_end () && max_count > 0) {
|
||||
char c = get_char ();
|
||||
if (c == 0) {
|
||||
break;
|
||||
} else {
|
||||
--max_count;
|
||||
text += c;
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
const std::string &
|
||||
TextInputStream::get_line ()
|
||||
{
|
||||
|
|
@ -430,9 +454,7 @@ TextInputStream::get_line ()
|
|||
|
||||
while (! at_end ()) {
|
||||
char c = get_char ();
|
||||
if (c == '\r') {
|
||||
// simply skip CR
|
||||
} else if (c == '\n' || c == 0) {
|
||||
if (c == '\n' || c == 0) {
|
||||
break;
|
||||
} else {
|
||||
m_line_buffer += c;
|
||||
|
|
@ -445,31 +467,35 @@ TextInputStream::get_line ()
|
|||
char
|
||||
TextInputStream::get_char ()
|
||||
{
|
||||
m_line = m_next_line;
|
||||
const char *c = m_stream.get (1);
|
||||
if (c == 0) {
|
||||
m_at_end = true;
|
||||
return 0;
|
||||
} else {
|
||||
if (*c == '\n') {
|
||||
++m_next_line;
|
||||
while (true) {
|
||||
m_line = m_next_line;
|
||||
const char *c = m_stream.get (1);
|
||||
if (c == 0) {
|
||||
m_at_end = true;
|
||||
return 0;
|
||||
} else if (*c != '\r' && *c) {
|
||||
if (*c == '\n') {
|
||||
++m_next_line;
|
||||
}
|
||||
return *c;
|
||||
}
|
||||
return *c;
|
||||
}
|
||||
}
|
||||
|
||||
char
|
||||
TextInputStream::peek_char ()
|
||||
{
|
||||
m_line = m_next_line;
|
||||
const char *c = m_stream.get (1);
|
||||
if (c == 0) {
|
||||
m_at_end = true;
|
||||
return 0;
|
||||
} else {
|
||||
char cc = *c;
|
||||
m_stream.unget (1);
|
||||
return cc;
|
||||
while (true) {
|
||||
m_line = m_next_line;
|
||||
const char *c = m_stream.get (1);
|
||||
if (c == 0) {
|
||||
m_at_end = true;
|
||||
return 0;
|
||||
} else if (*c != '\r' && *c) {
|
||||
char cc = *c;
|
||||
m_stream.unget (1);
|
||||
return cc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@ private:
|
|||
// ---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief An ASCII input stream
|
||||
* @brief A text input stream (UTF8 encoded)
|
||||
*
|
||||
* This class is put in front of a InputStream to format the input as text input stream.
|
||||
*/
|
||||
|
|
@ -591,6 +591,18 @@ public:
|
|||
*/
|
||||
const std::string &get_line ();
|
||||
|
||||
/**
|
||||
* @brief Reads all remaining bytes into the string
|
||||
*/
|
||||
std::string read_all ();
|
||||
|
||||
/**
|
||||
* @brief Reads all remaining bytes into the string
|
||||
*
|
||||
* This function reads all remaining of max_count bytes.
|
||||
*/
|
||||
std::string read_all (size_t max_count);
|
||||
|
||||
/**
|
||||
* @brief Get a single character
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -107,3 +107,41 @@ TEST(TextOutputStream)
|
|||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(TextInputStream)
|
||||
{
|
||||
std::string fn = tmp_file ("test.txt");
|
||||
|
||||
{
|
||||
tl::OutputStream os (fn, tl::OutputStream::OM_Auto, false);
|
||||
os << "Hello, world!\nWith another line\n\r\r\nseparated by a LFCR and CRLF.";
|
||||
}
|
||||
|
||||
{
|
||||
tl::InputStream is (fn);
|
||||
tl::TextInputStream tis (is);
|
||||
EXPECT_EQ (tis.get_line (), "Hello, world!");
|
||||
EXPECT_EQ (tis.line_number (), 1);
|
||||
EXPECT_EQ (tis.get_line (), "With another line");
|
||||
EXPECT_EQ (tis.line_number (), 2);
|
||||
EXPECT_EQ (tis.peek_char (), '\n');
|
||||
EXPECT_EQ (tis.get_line (), "");
|
||||
EXPECT_EQ (tis.line_number (), 3);
|
||||
EXPECT_EQ (tis.peek_char (), 's');
|
||||
EXPECT_EQ (tis.get_line (), "separated by a LFCR and CRLF.");
|
||||
EXPECT_EQ (tis.line_number (), 4);
|
||||
EXPECT_EQ (tis.at_end (), true);
|
||||
}
|
||||
|
||||
{
|
||||
tl::InputStream is (fn);
|
||||
tl::TextInputStream tis (is);
|
||||
EXPECT_EQ (tis.read_all (5), "Hello");
|
||||
}
|
||||
|
||||
{
|
||||
tl::InputStream is (fn);
|
||||
tl::TextInputStream tis (is);
|
||||
EXPECT_EQ (tis.read_all (), "Hello, world!\nWith another line\n\nseparated by a LFCR and CRLF.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
* written by unit test
|
||||
|
||||
* cell SUBCKT
|
||||
* pin
|
||||
* pin A
|
||||
* pin V42
|
||||
* pin Z
|
||||
* pin gnd
|
||||
* pin gnd
|
||||
.SUBCKT SUBCKT \$1 A[5]<1> V42\x28\x25\x29 Z gnd gnd$1
|
||||
XD_$1 V42\x28\x25\x29 \$3 Z \$1 HVPMOS PARAMS: L=0.2 W=1 AS=0.18 AD=0.18
|
||||
+ PS=2.16 PD=2.16
|
||||
* device instance $2 r0 *1 0,0 HVPMOS
|
||||
XD_$2 V42\x28\x25\x29 A[5]<1> \$3 \$1 HVPMOS PARAMS: L=0.2 W=1 AS=0.18 AD=0.18
|
||||
+ PS=2.16 PD=2.16
|
||||
XD_$3 gnd \$3 gnd gnd$1 HVNMOS PARAMS: L=1.13 W=2.12 PS=6 PD=6 AS=0 AD=0
|
||||
XD_$4 gnd \$3 Z gnd$1 HVNMOS PARAMS: L=0.4 W=0.4 PS=1.16 PD=1.16 AS=0.19 AD=0.19
|
||||
XD_$5 gnd A[5]<1> \$3 gnd$1 HVNMOS PARAMS: L=0.4 W=0.4 PS=1.76 PD=1.76 AS=0.19 AD=0.19
|
||||
.ENDS SUBCKT
|
||||
.SUBCKT SUBCKT \$1 A[5]<1> V42\x28\x25\x29 Z gnd gnd$1
|
||||
XD_$13 gnd \$3 gnd gnd$1 HVNMOS PARAMS: L=1.13 W=2.12 PS=6 PD=6 AS=0 AD=0
|
||||
.ENDS SUBCKT
|
||||
|
|
@ -530,6 +530,40 @@ class Ant_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
# each_annotation_selected
|
||||
def test_4
|
||||
|
||||
if !RBA.constants.member?(:Application)
|
||||
return
|
||||
end
|
||||
|
||||
mw = RBA::Application::instance.main_window
|
||||
mw.close_all
|
||||
mw.create_layout( 0 )
|
||||
lv = mw.current_view
|
||||
|
||||
a = annot_obj( RBA::DPoint::new( 1.0, 2.0 ), RBA::DPoint::new( 3.0, 4.0 ), "a", "b", "c", 1, 2, false, 3 )
|
||||
assert_equal( a.is_valid?, false )
|
||||
lv.insert_annotation( a )
|
||||
|
||||
mw.cm_select_all
|
||||
|
||||
arr = []
|
||||
lv.each_annotation_selected { |a| arr.push(a) }
|
||||
assert_equal(arr.size, 1)
|
||||
assert_equal(arr[0].to_s, "p1=1,2, p2=3,4, fmt=a, fmt_x=b, fmt_y=c, style=arrow_end, outline=diag_xy, snap=false, ac=horizontal")
|
||||
|
||||
arr[0].p1 = RBA::DPoint::new(11, 12)
|
||||
|
||||
arr = []
|
||||
lv.each_annotation_selected { |a| arr.push(a) }
|
||||
assert_equal(arr.size, 1)
|
||||
assert_equal(arr[0].to_s, "p1=11,12, p2=3,4, fmt=a, fmt_x=b, fmt_y=c, style=arrow_end, outline=diag_xy, snap=false, ac=horizontal")
|
||||
|
||||
mw.close_all
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
|
|
|||
Loading…
Reference in New Issue