Merge pull request #1301 from KLayout/wip

Wip
This commit is contained in:
Matthias Köfferlein 2023-03-04 19:32:06 +01:00 committed by GitHub
commit addb7148f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 73 additions and 55 deletions

View File

@ -133,6 +133,12 @@ Object::Object (const ant::Object &d)
// .. nothing else ..
}
Object::~Object ()
{
// .. nothing yet ..
}
Object &
Object::operator= (const ant::Object &d)
{

View File

@ -137,6 +137,11 @@ public:
*/
Object &operator= (const ant::Object &d);
/**
* @brief Destructor
*/
~Object ();
/**
* @brief Less operator
*/

View File

@ -1009,6 +1009,7 @@ View::ruler (const ant::Object *r)
void
View::render (const lay::Viewport &vp, lay::ViewObjectCanvas &canvas)
{
// .. nothing yet ..
if (! mp_ruler) {
return;
}
@ -1700,6 +1701,7 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type)
void
Service::selection_to_view ()
{
clear_transient_selection ();
annotation_selection_changed_event ();
// the selection objects need to be recreated since we destroyed the old rulers

View File

@ -260,17 +260,23 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
}
{
std::string group ("[" + m_group_prefix + " options - CIF and DXF specific]");
std::string group ("[" + m_group_prefix + " options - generic]");
cmd << tl::arg (group +
"-" + m_prefix + "d|--" + m_long_prefix + "dbu-in=dbu", this, &GenericReaderOptions::set_dbu, "Specifies the database unit to use",
"This option specifies the database unit the resulting layer will have. "
"The value is given in micrometer units. The default value is 1nm (0.001)."
"This option specifies the database unit the resulting layout will have. "
"The value is given in micrometer units. The default value is 1nm (0.001). "
"Note that for DEF, UNITS is not taken for the database unit, but this value is used instead.\n"
"\n"
"CAUTION: for GDS2 and OASIS, this value is ignored and the database unit of the first file "
"is used instead. Beware of trouble when blending multiple GDS or OASIS files with different database units."
)
<< tl::arg (group +
"#--" + m_long_prefix + "keep-layer-names", this, &GenericReaderOptions::set_read_named_layers, "Keeps layer names",
"If this option is used, layers names are kept as pure names and no attempt is made to\n"
"translate them into GDS layer/datatypes."
"translate them into GDS layer/datatypes.\n"
"\n"
"This option does not apply to GDS2 and OASIS files."
)
;
}

View File

@ -62,7 +62,7 @@ static tl::PixelBuffer read_pixel_buffer (const std::string &file)
#if defined(HAVE_PNG)
tl::InputStream stream (file);
return tl::PixelBuffer::read_png (stream);
#elif defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
#elif defined(HAVE_QT)
// QImage is fallback
QImage img;
img.load (tl::to_qstring (file), "PNG");
@ -80,7 +80,7 @@ static tl::PixelBuffer pixel_buffer_from_png (const std::vector<char> &data)
tl::InputMemoryStream data_stream (data.begin ().operator-> (), data.size ());
tl::InputStream stream (data_stream);
return tl::PixelBuffer::read_png (stream);
#elif defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
#elif defined(HAVE_QT)
// QImage is fallback
tl_assert (data.size () < std::numeric_limits<int>::max ());
QImage img = QImage::fromData ((const uchar *) data.begin ().operator-> (), int (data.size ()));
@ -96,7 +96,7 @@ static void write_pixel_buffer (const tl::PixelBuffer *pb, const std::string &fi
#if defined(HAVE_PNG)
tl::OutputStream stream (file);
pb->write_png (stream);
#elif defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
#elif defined(HAVE_QT)
// QImage is fallback
QImage img = pb->to_image ();
img.save (tl::to_qstring (file), "PNG");
@ -115,7 +115,7 @@ static std::vector<char> pixel_buffer_to_png (const tl::PixelBuffer *pb)
pb->write_png (stream);
}
return std::vector<char> (data_stream.data (), data_stream.data () + data_stream.size ());
#elif defined(HAVE_QT) && defined(HAVE_QTBINDINGS)
#elif defined(HAVE_QT)
// QImage is fallback
QImage img = pb->to_image ();
QBuffer data;

View File

@ -418,7 +418,7 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view)
mp_transient_view (0),
m_move_mode (Service::move_none),
m_moved_landmark (0),
m_keep_selection_for_landmark (false),
m_keep_selection_for_move (false),
m_images_visible (true)
{
// place images behind the grid
@ -623,7 +623,7 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
m_move_mode = mm;
m_moved_landmark = ml;
m_keep_selection_for_landmark = true;
m_keep_selection_for_move = true;
// found a handle of one of the selected object: make the moved image the selection
clear_selection ();
@ -660,7 +660,7 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
m_move_mode = mm;
m_moved_landmark = ml;
m_keep_selection_for_landmark = false;
m_keep_selection_for_move = false;
// found anything: make the moved image the selection
clear_selection ();
@ -893,7 +893,7 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type)
image_changed_event (id);
// clear the selection (that was artificially created before)
if (! m_keep_selection_for_landmark) {
if (! m_keep_selection_for_move) {
clear_selection ();
} else {
selection_to_view ();
@ -907,7 +907,11 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type)
image_changed_event (id);
// clear the selection (that was artificially created before)
clear_selection ();
if (! m_keep_selection_for_move) {
clear_selection ();
} else {
selection_to_view ();
}
}
@ -956,6 +960,7 @@ Service::find_image (const db::DPoint &p, const db::DBox &search_box, double l,
void
Service::selection_to_view (img::View::Mode mode)
{
clear_transient_selection ();
image_selection_changed_event ();
// the selection objects need to be recreated since we destroyed the old images
@ -1006,8 +1011,10 @@ Service::transform (const db::DCplxTrans &trans)
void
Service::edit_cancel ()
{
m_move_mode = move_none;
selection_to_view ();
if (m_move_mode != move_none) {
m_move_mode = move_none;
selection_to_view ();
}
}
void

View File

@ -506,7 +506,7 @@ private:
// The index of the landmark being moved
size_t m_moved_landmark;
// Flag indicating that we want to keep the selection after the landmark was moved
bool m_keep_selection_for_landmark;
bool m_keep_selection_for_move;
// Flag indicating whether images are visible
bool m_images_visible;

View File

@ -3152,11 +3152,6 @@ MacroEditorDialog::translate_pseudo_id (size_t &file_id, int &line)
}
}
static void exit_from_macro ()
{
throw tl::ExitException ();
}
void
MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_id, int line, const std::string &eclass, const std::string &emsg, const gsi::StackTraceProvider *stack_trace_provider)
{
@ -3165,9 +3160,7 @@ MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_
return;
}
if (!m_in_exec) {
exit_from_macro ();
}
exit_if_needed ();
// avoid recursive breakpoints and exception catches from the console while in a breakpoint or exception stop
if (lay::BusySection::is_busy ()) {
@ -3251,17 +3244,25 @@ MacroEditorDialog::exception_thrown (gsi::Interpreter *interpreter, size_t file_
throw;
}
if (! m_in_exec) {
exit_from_macro ();
exit_if_needed ();
}
void
MacroEditorDialog::exit_if_needed ()
{
// Exit if a stop is requested.
// NOTE: we must not raise ExitException from outside events (e.g. PyQt5 events)
// as ExitException would otherwise terminate the application.
// "mp_exec_controller" is 0 in that case.
if (! m_in_exec && mp_exec_controller != 0) {
throw tl::ExitException ();
}
}
void
MacroEditorDialog::trace (gsi::Interpreter *interpreter, size_t file_id, int line, const gsi::StackTraceProvider *stack_trace_provider)
{
if (!m_in_exec) {
exit_from_macro ();
}
exit_if_needed ();
// avoid recursive breakpoints and exception catches from the console while in a breakpoint or exception stop
if (lay::BusySection::is_busy ()) {
@ -3310,9 +3311,7 @@ MacroEditorDialog::trace (gsi::Interpreter *interpreter, size_t file_id, int lin
throw;
}
if (! m_in_exec) {
exit_from_macro ();
}
exit_if_needed ();
} else if (++m_trace_count == 20) {
@ -3328,9 +3327,7 @@ MacroEditorDialog::trace (gsi::Interpreter *interpreter, size_t file_id, int lin
m_last_process_events = tl::Clock::current ();
m_process_events_interval = std::max (0.05, std::min (2.0, (m_last_process_events - start).seconds () * 5.0));
if (!m_in_exec) {
exit_from_macro ();
}
exit_if_needed ();
}

View File

@ -302,6 +302,7 @@ private:
bool configure (const std::string &name, const std::string &value);
void config_finalize ();
void translate_pseudo_id (size_t &file_id, int &line);
void exit_if_needed ();
lay::Dispatcher *mp_plugin_root;
lym::MacroCollection *mp_root;

View File

@ -195,7 +195,7 @@ AnnotationShapes::replace (iterator pos, const shape_type &&sh)
manager ()->queue (this, new AnnotationLayerOp (true /*insert*/, sh));
}
invalidate_state (); // HINT: must come before the change is done!
m_layer.replace (pos, sh);
m_layer.replace (pos, std::move (sh));
}
return *pos;
}

View File

@ -177,7 +177,7 @@ public:
virtual void plugin_removed (lay::PluginDeclaration *cls)
{
if (mp_delegate) {
mp_delegate->plugin_registered (cls);
mp_delegate->plugin_removed (cls);
}
}

View File

@ -318,7 +318,6 @@ Editables::transient_to_selection ()
{
bool had_transient_selection = false;
bool had_selection = false;
cancel_edits ();
for (iterator e = begin (); e != end (); ++e) {
if (e->has_selection ()) {
had_selection = true;

View File

@ -5305,6 +5305,7 @@ LayoutViewBase::paste_interactive ()
void
LayoutViewBase::copy ()
{
cancel_edits ();
if (! lay::Editables::has_selection ()) {
// try to use the transient selection for the real one
lay::Editables::transient_to_selection ();
@ -5316,6 +5317,7 @@ LayoutViewBase::copy ()
void
LayoutViewBase::cut ()
{
cancel_edits ();
if (! lay::Editables::has_selection ()) {
// try to use the transient selection for the real one
lay::Editables::transient_to_selection ();

View File

@ -590,6 +590,7 @@ LayoutView::show_properties ()
return;
}
cancel_edits ();
if (! has_selection ()) {
// try to use the transient selection for the real one
transient_to_selection ();

View File

@ -1,3 +1,4 @@
import klayout.dbcore # enables stream reader plugins
import klayout.laycore
from klayout.laycore import *

View File

@ -139,25 +139,16 @@ class LAYPixelBuffer_TestClass < TestBase
assert_equal(compare(pb, pb_copy), true)
end
png = nil
begin
png = pb.to_png_data
rescue => ex
# No PNG support
end
png = pb.to_png_data
if png
assert_equal(png.size > 20 && png.size < 200, true) # some range because implementations may differ
pb_copy = RBA::PixelBuffer.from_png_data(png)
assert_equal(compare(pb, pb_copy), true)
assert_equal(png.size > 20 && png.size < 200, true) # some range because implementations may differ
pb_copy = RBA::PixelBuffer.from_png_data(png)
assert_equal(compare(pb, pb_copy), true)
tmp = File::join($ut_testtmp, "tmp.png")
pb.write_png(tmp)
pb_copy = RBA::PixelBuffer.read_png(tmp)
assert_equal(compare(pb, pb_copy), true)
end
tmp = File::join($ut_testtmp, "tmp.png")
pb.write_png(tmp)
pb_copy = RBA::PixelBuffer.read_png(tmp)
assert_equal(compare(pb, pb_copy), true)
end