Merge branch 'master' of github.com:KLayout/klayout

This commit is contained in:
Matthias Koefferlein 2021-04-19 22:30:08 +02:00
commit 13536e95b4
28 changed files with 238 additions and 69 deletions

View File

@ -887,7 +887,13 @@ Service::catch_distance ()
return double (view ()->search_range ()) / widget ()->mouse_event_trans ().mag ();
}
void
double
Service::catch_distance_box ()
{
return double (view ()->search_range_box ()) / widget ()->mouse_event_trans ().mag ();
}
void
Service::drag_cancel ()
{
if (m_drawing) {
@ -2037,7 +2043,7 @@ Service::select (const db::DBox &box, lay::Editable::SelectionMode mode)
} else {
// compute search box
double l = catch_distance ();
double l = box.is_point () ? catch_distance () : catch_distance_box ();
db::DBox search_dbox = box.enlarged (db::DVector (l, l));
if (! box.is_point ()) {

View File

@ -276,11 +276,16 @@ public:
virtual double click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mode);
/**
* @brief Gets the catch distance
* @brief Gets the catch distance (for single click)
*/
virtual double catch_distance ();
/**
/**
* @brief Gets the catch distance (for box)
*/
virtual double catch_distance_box ();
/**
* @brief "select" operation
*/
virtual bool select (const db::DBox &box, lay::Editable::SelectionMode mode);

View File

@ -2349,7 +2349,13 @@ PartialService::catch_distance ()
return double (view ()->search_range ()) / widget ()->mouse_event_trans ().mag ();
}
db::DPoint
double
PartialService::catch_distance_box ()
{
return double (view ()->search_range_box ()) / widget ()->mouse_event_trans ().mag ();
}
db::DPoint
PartialService::single_selected_point () const
{
// build the transformation variants cache and
@ -2576,7 +2582,7 @@ PartialService::partial_select (const db::DBox &box, lay::Editable::SelectionMod
clear_partial_transient_selection ();
// compute search box
double l = catch_distance ();
double l = box.is_point () ? catch_distance () : catch_distance_box ();
db::DBox search_box = box.enlarged (db::DVector (l, l));
bool needs_update = false;

View File

@ -235,11 +235,16 @@ public:
virtual void transform (const db::DCplxTrans &tr);
/**
* @brief Gets the catch distance
* @brief Gets the catch distance (for single click)
*/
virtual double catch_distance ();
/**
/**
* @brief Gets the catch distance (for box)
*/
virtual double catch_distance_box ();
/**
* @brief Indicates whether objects are selected
*/
virtual bool has_selection ();

View File

@ -895,7 +895,13 @@ Service::catch_distance ()
return double (view ()->search_range ()) / widget ()->mouse_event_trans ().mag ();
}
double
double
Service::catch_distance_box ()
{
return double (view ()->search_range_box ()) / widget ()->mouse_event_trans ().mag ();
}
double
Service::click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mode)
{
// compute search box
@ -1231,7 +1237,7 @@ bool
Service::select (const db::DBox &box, lay::Editable::SelectionMode mode)
{
// compute search box
double l = catch_distance ();
double l = box.is_point () ? catch_distance () : catch_distance_box ();
db::DBox search_box = box.enlarged (db::DVector (l, l));
bool needs_update = false;

View File

@ -179,11 +179,16 @@ public:
virtual double click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mode);
/**
* @brief Gets the catch distance
* @brief Gets the catch distance (for single click)
*/
virtual double catch_distance ();
/**
/**
* @brief Gets the catch distance (for box)
*/
virtual double catch_distance_box ();
/**
* @brief "select" operation
*/
virtual bool select (const db::DBox &box, lay::Editable::SelectionMode mode);

View File

@ -1153,6 +1153,12 @@ Service::catch_distance ()
return double (view ()->search_range ()) / widget ()->mouse_event_trans ().mag ();
}
double
Service::catch_distance_box ()
{
return double (view ()->search_range_box ()) / widget ()->mouse_event_trans ().mag ();
}
double
Service::click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mode)
{
@ -1293,7 +1299,7 @@ Service::select (const db::DBox &box, lay::Editable::SelectionMode mode)
} else {
// compute search box
double l = catch_distance ();
double l = box.is_point () ? catch_distance () : catch_distance_box ();
db::DBox search_dbox = box.enlarged (db::DVector (l, l));
if (! box.is_point ()) {

View File

@ -295,10 +295,15 @@ public:
virtual double click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mode);
/**
* @brief Gets the catch distance
* @brief Gets the catch distance for single click
*/
virtual double catch_distance ();
/**
* @brief Gets the catch distance for box
*/
virtual double catch_distance_box ();
/**
* @brief "select" operation
*/

View File

@ -202,20 +202,6 @@ static int klayout_main_cont (int &argc, char **argv);
*/
int
klayout_main (int &argc, char **argv)
{
// This special initialization is required by the Ruby interpreter because it wants to mark the stack
int ret = rba::RubyInterpreter::initialize (argc, argv, &klayout_main_cont);
// clean up all static data now, since we don't trust the static destructors.
// NOTE: this needs to happen after the Ruby interpreter went down since otherwise the GC will
// access objects that are already cleaned up.
tl::StaticObjects::cleanup ();
return ret;
}
int
klayout_main_cont (int &argc, char **argv)
{
// install the version strings
lay::Version::set_exe_name (prg_exe_name);
@ -237,6 +223,37 @@ klayout_main_cont (int &argc, char **argv)
about_text += prg_about_text;
lay::Version::set_about_text (about_text.c_str ());
// Capture the shortcut command line arguments
for (int i = 1; i < argc; ++i) {
if (argv [i] == std::string ("-v")) {
tl::info << lay::ApplicationBase::version ();
return 0;
} else if (argv [i] == std::string ("-h")) {
tl::info << lay::ApplicationBase::usage () << tl::noendl;
return 0;
}
}
// This special initialization is required by the Ruby interpreter because it wants to mark the stack
int ret = rba::RubyInterpreter::initialize (argc, argv, &klayout_main_cont);
// clean up all static data now, since we don't trust the static destructors.
// NOTE: this needs to happen after the Ruby interpreter went down since otherwise the GC will
// access objects that are already cleaned up.
tl::StaticObjects::cleanup ();
return ret;
}
int
klayout_main_cont (int &argc, char **argv)
{
#if QT_VERSION >= 0x050000
qInstallMessageHandler (myMessageOutput);
#else

View File

@ -81,6 +81,12 @@ static std::string arch (C *)
return tl::arch_string ();
}
template <class C>
static std::string version (C *)
{
return C::version ();
}
template <class C>
static gsi::Methods application_methods ()
{
@ -213,7 +219,7 @@ static gsi::Methods application_methods ()
"\n"
"This method has been added in version 0.22."
) +
method<C, std::string> ("version", &C::version,
method_ext<C, std::string> ("version", &version<C>,
"@brief Returns the application's version string\n"
) +
method_ext<C, std::string> ("arch", &arch<C>,

View File

@ -483,16 +483,6 @@ ApplicationBase::parse_cmd (int &argc, char **argv)
m_packages_with_dep = true;
} else if (a == "-v") {
tl::info << lay::Version::name () << " " << lay::Version::version ();
exit (0);
} else if (a == "-h") {
tl::info << usage () << tl::noendl;
exit (0);
} else if (a == "-m" && (i + 1) < argc) {
m_files.push_back (std::make_pair (rdb_file, std::make_pair (std::string (args [++i]), std::string ())));
@ -929,7 +919,7 @@ ApplicationBase::instance ()
}
std::string
ApplicationBase::version () const
ApplicationBase::version ()
{
return std::string (lay::Version::name ()) + " " + lay::Version::version ();
}

View File

@ -100,12 +100,12 @@ public:
/**
* @brief Return the program's version
*/
std::string version () const;
static std::string version ();
/**
* @brief Return the program's usage string
*/
std::string usage ();
static std::string usage ();
/**
* @brief Returns the main window's reference

View File

@ -283,7 +283,7 @@ HelpSource::initialize_index ()
try {
tl::XMLFileSource in (*c);
help_index_structure.parse (in, *this);
if (m_klayout_version == lay::ApplicationBase::instance ()->version ()) {
if (m_klayout_version == lay::ApplicationBase::version ()) {
ok = true;
}
} catch (tl::Exception &ex) {
@ -352,7 +352,7 @@ HelpSource::create_index_file (const std::string &path)
std::string
HelpSource::klayout_version () const
{
return lay::ApplicationBase::instance ()->version ();
return lay::ApplicationBase::version ();
}
void

View File

@ -3543,9 +3543,9 @@ MainWindow::update_window_title ()
if (current_view ()->is_dirty ()) {
sep += "[+] ";
}
setWindowTitle (tl::to_qstring (lay::ApplicationBase::instance ()->version () + sep + current_view ()->title ()));
setWindowTitle (tl::to_qstring (lay::ApplicationBase::version () + sep + current_view ()->title ()));
} else {
setWindowTitle (tl::to_qstring (lay::ApplicationBase::instance ()->version ()));
setWindowTitle (tl::to_qstring (lay::ApplicationBase::version ()));
}
}

View File

@ -214,7 +214,7 @@
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
@ -227,28 +227,14 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Capture range to mouse cursor</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="search_range_spinbx">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item>
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>pixel</string>
</property>
</widget>
</item>
<item>
<item row="0" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -261,6 +247,41 @@
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="search_range_spinbx">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Capture range to mouse cursor (single click)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Capture range to mouse cursor (box)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="search_range_box_spinbx">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_6">
<property name="text">
<string>pixel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -156,7 +156,7 @@ public:
}
/**
* @brief The catch distance
* @brief The catch distance (for single click)
*
* The catch distance is a typical value for the "fuzzyness" of a mouse click.
* It is given in micron.
@ -166,6 +166,17 @@ public:
return 0.0;
}
/**
* @brief The catch distance (for box)
*
* The catch distance is a typical value for the "fuzzyness" of a box selection.
* It is given in micron.
*/
virtual double catch_distance_box ()
{
return 0.0;
}
/**
* @brief transient selection
*

View File

@ -463,6 +463,7 @@ LayoutView::init (db::Manager *mgr, QWidget * /*parent*/)
m_always_show_ld = true;
m_always_show_layout_index = false;
m_search_range = 5;
m_search_range_box = 0;
m_layer_properties_lists.push_back (new LayerPropertiesList ());
m_layer_properties_lists.back ()->attach_view (this, (unsigned int) (m_layer_properties_lists.size () - 1));
@ -1250,6 +1251,13 @@ LayoutView::configure (const std::string &name, const std::string &value)
set_search_range (n);
return true;
} else if (name == cfg_search_range_box) {
unsigned int n;
tl::from_string (value, n);
set_search_range_box (n);
return true;
} else if (name == cfg_abstract_mode_enabled) {
bool e;
@ -5882,6 +5890,18 @@ LayoutView::set_search_range (unsigned int sr)
m_search_range = sr;
}
unsigned int
LayoutView::search_range_box ()
{
return m_search_range_box;
}
void
LayoutView::set_search_range_box (unsigned int sr)
{
m_search_range_box = sr;
}
void
LayoutView::message (const std::string &s, int timeout)
{

View File

@ -2277,17 +2277,29 @@ public:
}
/**
* @brief Gets the "search range" in pixels
* @brief Gets the "search range" in pixels (for single click)
* The search range applies whenever some object is looked up in the vicinity of the
* mouse cursor. This value gives the search range in pixels.
*/
unsigned int search_range ();
/**
* @brief Sets the "search range" in pixels
* @brief Sets the "search range" in pixels (for single click)
*/
void set_search_range (unsigned int sr);
/**
* @brief Gets the "search range" in pixels (for box)
* The search range applies whenever some object is looked up in the vicinity of the
* mouse cursor. This value gives the search range in pixels.
*/
unsigned int search_range_box ();
/**
* @brief Sets the "search range" in pixels (for box)
*/
void set_search_range_box (unsigned int sr);
/**
* @brief Return true, if any cellview is editable
*/
@ -2808,6 +2820,7 @@ private:
bool m_marker_halo;
unsigned int m_search_range;
unsigned int m_search_range_box;
bool m_transient_selection_mode;
bool m_sel_inside_pcells;

View File

@ -374,6 +374,10 @@ LayoutViewConfigPage2c::setup (lay::Dispatcher *root)
unsigned int sr = 0;
root->config_get (cfg_search_range, sr);
mp_ui->search_range_spinbx->setValue (sr);
unsigned int srbox = 0;
root->config_get (cfg_search_range_box, srbox);
mp_ui->search_range_box_spinbx->setValue (srbox);
}
void
@ -388,6 +392,7 @@ LayoutViewConfigPage2c::commit (lay::Dispatcher *root)
root->config_set (cfg_sel_transient_mode, mp_ui->transient_mode_cb->isChecked ());
root->config_set (cfg_sel_inside_pcells_mode, mp_ui->sel_inside_pcells_cb->isChecked ());
root->config_set (cfg_search_range, (unsigned int) mp_ui->search_range_spinbx->value ());
root->config_set (cfg_search_range_box, (unsigned int) mp_ui->search_range_box_spinbx->value ());
}
// ------------------------------------------------------------
@ -1564,6 +1569,7 @@ public:
options.push_back (std::pair<std::string, std::string> (cfg_child_ctx_hollow, "false"));
options.push_back (std::pair<std::string, std::string> (cfg_child_ctx_enabled, "false"));
options.push_back (std::pair<std::string, std::string> (cfg_search_range, "5"));
options.push_back (std::pair<std::string, std::string> (cfg_search_range_box, "0"));
options.push_back (std::pair<std::string, std::string> (cfg_abstract_mode_width, "10.0"));
options.push_back (std::pair<std::string, std::string> (cfg_abstract_mode_enabled, "false"));
options.push_back (std::pair<std::string, std::string> (cfg_fit_new_cell, "true"));

View File

@ -62,6 +62,7 @@ static const std::string cfg_child_ctx_hollow ("child-context-hollow");
static const std::string cfg_child_ctx_enabled ("child-context-enabled");
static const std::string cfg_search_range ("search-range");
static const std::string cfg_search_range_box ("search-range-box");
static const std::string cfg_abstract_mode_enabled ("abstract-mode-enabled");
static const std::string cfg_abstract_mode_width ("abstract-mode-width");

View File

@ -282,10 +282,12 @@ tl::Variant python2c_func<tl::Variant>::operator() (PyObject *rval)
return tl::Variant (python2c<std::string> (rval));
#else
} else if (PyBytes_Check (rval)) {
return tl::Variant (python2c<std::string> (rval));
return tl::Variant (python2c<std::vector<char> > (rval));
#endif
} else if (PyUnicode_Check (rval) || PyByteArray_Check (rval)) {
} else if (PyUnicode_Check (rval)) {
return tl::Variant (python2c<std::string> (rval));
} else if (PyByteArray_Check (rval)) {
return tl::Variant (python2c<std::vector<char> > (rval));
} else if (PyList_Check (rval)) {
size_t len = PyList_Size (rval);
@ -496,6 +498,8 @@ PyObject *c2python_func<const tl::Variant &>::operator() (const tl::Variant &c)
return c2python (c.to_bool ());
} else if (c.is_a_string ()) {
return c2python (c.to_string ());
} else if (c.is_a_bytearray ()) {
return c2python (c.to_bytearray ());
} else if (c.is_long ()) {
return c2python (c.to_long ());
} else if (c.is_ulong ()) {

View File

@ -262,6 +262,8 @@ VALUE c2ruby<tl::Variant> (const tl::Variant &c)
return c2ruby<bool> (c.to_bool ());
} else if (c.is_a_string ()) {
return c2ruby<std::string> (c.to_string ());
} else if (c.is_a_bytearray ()) {
return c2ruby<std::vector<char> > (c.to_bytearray ());
} else if (c.is_long () || c.is_char ()) {
return c2ruby<long> (c.to_long ());
} else if (c.is_ulong ()) {

View File

@ -146,7 +146,7 @@ public:
error (tl::to_string (tr ("Unexpected end of file")));
}
std::string l = get_line ();
std::string l = m_input_stream.get_line ();
if (l.size () > 3 && l[0] == 'W' && l[1] == 'E' && isdigit (l[2])) {
size_t n = 0;

View File

@ -76,3 +76,8 @@ TEST(2)
{
run_rve_test (_this, "rve2.db", "rve2_au.txt");
}
TEST(3)
{
run_rve_test (_this, "rve3.db", "rve3_au.txt");
}

View File

@ -1304,6 +1304,13 @@ class BasicTest(unittest.TestCase):
self.assertEqual( str(b.b22c()), "hallo" )
self.assertEqual( type(b.b22c()).__name__, "LayerInfo" )
# byte arrays through Variants
if sys.version_info >= (3, 0):
self.assertEqual( b.b22a( [ bytes('abc', 'utf-8') ] ), 1 )
self.assertEqual( str(b.b22c()), "b'abc'" )
self.assertEqual( str(b.b22d()), "b'abc'" )
self.assertEqual( str(b.var()), "b'abc'" )
def test_23(self):
b = pya.B()

View File

@ -629,6 +629,16 @@ class QtBindingTest(unittest.TestCase):
self.assertEqual(len(buf.data) > 100, True)
self.assertEqual(buf.data[0:8], b'\x89PNG\r\n\x1a\n')
def test_53(self):
# issue #771 (QMimeData not working)
mimeData = pya.QMimeData()
mimeData.setData("application/json",'{"test":"test"}')
jsonData = mimeData.data("application/json");
if sys.version_info < (3, 0):
self.assertEqual(str(jsonData), '{"test":"test"}')
else:
self.assertEqual(str(jsonData), 'b\'{"test":"test"}\'')
# run unit tests
if __name__ == '__main__':

View File

@ -183,6 +183,7 @@ class LAYLayoutView_TestClass < TestBase
assert_equal(view.has_selection?, false)
assert_equal(view.selection_size, 0)
view.set_config("search-range-box", "5")
view.select_from(RBA::DBox::new(-1.0, -1.0, 1.0, 1.0))
assert_equal(selection_changed, 1)
assert_equal(view.selection_size, 4)

View File

@ -744,6 +744,17 @@ class QtBinding_TestClass < TestBase
end
def test_53
# issue #771 (QMimeData not working)
mimeData = RBA::QMimeData::new
mimeData.setData("application/json", '{"test":"test"}')
jsonData = mimeData.data("application/json");
assert_equal(jsonData.to_s, '{"test":"test"}')
end
end
load("test_epilogue.rb")