Skip to content

Commit 4f30ad3

Browse files
Merge pull request #2242 from KLayout/bugfix/issue-2234
Bugfix/issue 2234
2 parents d84d5e1 + 389a099 commit 4f30ad3

File tree

13 files changed

+164
-72
lines changed

13 files changed

+164
-72
lines changed

src/edt/edt/edtPartialService.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -762,9 +762,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co
762762
{
763763
if (! point_mode ()) {
764764

765-
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
765+
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
766766

767-
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
767+
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
768768

769769
checkpoint ();
770770

@@ -897,9 +897,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co
897897

898898
} else {
899899

900-
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
900+
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
901901

902-
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (hit_box))) {
902+
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (hit_box))) {
903903

904904
checkpoint ();
905905

src/lay/lay/gsiDeclLayMainWindow.cc

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ set_menu_items_hidden (lay::MainWindow *mw, const std::map<std::string, bool> &h
328328
mw->dispatcher ()->config_set (lay::cfg_menu_items_hidden, lay::pack_menu_items_hidden (hv));
329329
}
330330

331+
static void
332+
clear_message (lay::MainWindow *mw, int priority)
333+
{
334+
mw->message (std::string (), 0, priority);
335+
}
336+
331337
Class<lay::MainWindow> decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "MainWindow",
332338

333339
// Dispatcher interface and convenience functions
@@ -475,15 +481,36 @@ Class<lay::MainWindow> decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "M
475481
"\n"
476482
"This method has been added in version 0.24."
477483
) +
478-
gsi::method ("message", &lay::MainWindow::message, gsi::arg ("message"), gsi::arg ("time", -1, "infinite"),
484+
gsi::method_ext ("clear_message", &clear_message, gsi::arg ("priority", -1, "all priorities"),
485+
"@brief Clears the message\n"
486+
"When calling this method with a priority, it will clear the message in the given priority slot, thus "
487+
"unhiding the messages with lower priority. This is equivalent to calling \\message with an empty string.\n"
488+
"\n"
489+
"When calling without a priority, all messages in all priority slots will be cleared.\n"
490+
"\n"
491+
"This method has been added in version 0.30.6."
492+
) +
493+
gsi::method ("message", &lay::MainWindow::message, gsi::arg ("message"), gsi::arg ("time", -1, "infinite"), gsi::arg ("priority", 0),
479494
"@brief Displays a message in the status bar\n"
480495
"\n"
481496
"@param message The message to display\n"
482497
"@param time The time how long to display the message in ms. A negative value means 'infinitely'.\n"
498+
"@param priority The priority of the message. Higher-priority messages have precendence over lower-priority ones.\n"
483499
"\n"
484500
"This given message is shown in the status bar for the given time.\n"
501+
"If a priority is given, higher-priority messages have precedence over lower-priority ones.\n"
502+
"Placing an empty message clears a message with a given priority and unhides messages with lower "
503+
"priority. Standard messages like selection descriptions have priority 0, which is the lowest priority.\n"
504+
"\n"
505+
"Messages generated during modal actions (e.g. 'Click on first point') by convention should have priority 10 "
506+
"and should be tied to the active state of a plugin. This ensures there is only one such message.\n"
507+
"Higher-priority messages must be cleared (set to empty string) explicitly to unhide lower-priority messages "
508+
"when the indicated action is finished.\n"
509+
"\n"
510+
"\\clear_message is a convenience method that will clear messages.\n"
485511
"\n"
486-
"This method has been added in version 0.18. The 'time' parameter was made optional in version 0.28.10."
512+
"This method has been added in version 0.18. The 'time' parameter was made optional in version 0.28.10.\n"
513+
"The 'priority' argument has been added in version 0.30.6."
487514
) +
488515
gsi::method ("resize", (void (lay::MainWindow::*)(int, int)) &lay::MainWindow::resize, gsi::arg ("width"), gsi::arg ("height"),
489516
"@brief Resizes the window\n"

src/lay/lay/layMainWindow.cc

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled)
186186
m_synchronous (false),
187187
m_busy (false),
188188
mp_app (app),
189+
m_message_timer_priority (-1),
189190
m_manager (undo_enabled)
190191
{
191192
setAnimated (false);
@@ -823,10 +824,15 @@ static int fm_width (const QFontMetrics &fm, const QString &s)
823824
void
824825
MainWindow::format_message ()
825826
{
827+
std::string msg;
828+
if (! m_messages.empty ()) {
829+
msg = (--m_messages.end ())->second;
830+
}
831+
826832
QFontMetrics fm (mp_msg_label->font ());
827833

828834
std::string full_message;
829-
for (const char *c = m_message.c_str (); *c; ++c) {
835+
for (const char *c = msg.c_str (); *c; ++c) {
830836
if (*c == '\\' && (c[1] == '(' || c[1] == ')')) {
831837
++c;
832838
} else {
@@ -847,7 +853,7 @@ MainWindow::format_message ()
847853

848854
short_message.clear ();
849855

850-
for (const char *c = m_message.c_str (); *c; ++c) {
856+
for (const char *c = msg.c_str (); *c; ++c) {
851857
if (*c == '\\' && c[1] == '(') {
852858
if (nsection++ < ndrop) {
853859
in_drop = true;
@@ -875,24 +881,53 @@ MainWindow::format_message ()
875881
}
876882

877883
void
878-
MainWindow::message (const std::string &s, int ms)
884+
MainWindow::message (const std::string &s, int ms, int priority)
879885
{
880-
m_message = s;
886+
if (s.empty () && priority < 0) {
887+
888+
m_messages.clear ();
889+
890+
} else if (s.empty ()) {
891+
892+
m_messages.erase (priority);
893+
894+
} else {
895+
896+
// simulate timeout of previous message timer
897+
if (m_message_timer_priority >= 0) {
898+
m_messages.erase (m_message_timer_priority);
899+
}
900+
901+
m_messages[priority] = s;
902+
903+
if (ms >= 0) {
904+
m_message_timer_priority = priority;
905+
m_message_timer.start (ms);
906+
} else {
907+
m_message_timer_priority = -1;
908+
}
909+
910+
}
911+
881912
format_message ();
882-
m_message_timer.start (ms);
883913
}
884914

885915
void
886-
MainWindow::clear_message ()
916+
MainWindow::clear_messages ()
887917
{
888-
m_message.clear ();
889-
m_message_timer.start (0);
918+
m_message_timer.stop ();
919+
m_message_timer_priority = -1;
920+
m_messages.clear ();
921+
format_message ();
890922
}
891923

892924
void
893925
MainWindow::message_timer ()
894926
{
895-
m_message.clear ();
927+
if (m_message_timer_priority >= 0) {
928+
m_messages.erase (m_message_timer_priority);
929+
}
930+
m_message_timer_priority = -1;
896931
format_message ();
897932
}
898933

@@ -2467,7 +2502,7 @@ MainWindow::select_view (int index)
24672502
update_editor_options_dock ();
24682503
clear_current_pos ();
24692504
edits_enabled_changed ();
2470-
clear_message ();
2505+
clear_messages ();
24712506
menu_needs_update ();
24722507

24732508
m_disable_tab_selected = dis;
@@ -2994,7 +3029,7 @@ MainWindow::close_view (int index)
29943029
clear_current_pos ();
29953030
edits_enabled_changed ();
29963031
menu_needs_update ();
2997-
clear_message ();
3032+
clear_messages ();
29983033

29993034
update_dock_widget_state ();
30003035

@@ -3479,7 +3514,7 @@ MainWindow::add_view (lay::LayoutViewWidget *view)
34793514
connect (view, SIGNAL (dirty_changed (lay::LayoutView *)), this, SLOT (view_title_changed (lay::LayoutView *)));
34803515
connect (view, SIGNAL (edits_enabled_changed ()), this, SLOT (edits_enabled_changed ()));
34813516
connect (view, SIGNAL (menu_needs_update ()), this, SLOT (menu_needs_update ()));
3482-
connect (view, SIGNAL (show_message (const std::string &, int)), this, SLOT (message (const std::string &, int)));
3517+
connect (view, SIGNAL (show_message (const std::string &, int, int)), this, SLOT (message (const std::string &, int, int)));
34833518
connect (view, SIGNAL (current_pos_changed (double, double, bool)), this, SLOT (current_pos (double, double, bool)));
34843519
connect (view, SIGNAL (clear_current_pos ()), this, SLOT (clear_current_pos ()));
34853520
connect (view, SIGNAL (mode_change (int)), this, SLOT (select_mode (int)));

src/lay/lay/layMainWindow.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -649,12 +649,12 @@ public slots:
649649
/**
650650
* @brief Displays a status message next to the coordinates
651651
*/
652-
void message (const std::string &s, int ms);
652+
void message (const std::string &s, int ms, int);
653653

654654
/**
655655
* @brief Clears the current message
656656
*/
657-
void clear_message ();
657+
void clear_messages ();
658658

659659
/**
660660
* @brief Selects the given mode
@@ -789,7 +789,8 @@ protected slots:
789789
QApplication *mp_app;
790790
lay::HelpDialog *mp_assistant;
791791
std::string m_current_session;
792-
std::string m_message;
792+
int m_message_timer_priority;
793+
std::map<int, std::string> m_messages;
793794
std::unique_ptr<QPrinter> mp_printer;
794795
std::vector<QString> m_changed_files;
795796
std::string m_title;

src/laybasic/laybasic/layFinder.cc

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Finder::closer (double d)
8787
}
8888

8989
void
90-
Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox &region, const db::DBox &scan_region, int min_level, int max_level, const std::vector<int> &layers)
90+
Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox &region, const db::DBox &scan_region, int min_level, int max_level, const std::vector<unsigned int> &layers)
9191
{
9292
const lay::CellView &cv = view->cellview (cv_index);
9393

@@ -100,8 +100,8 @@ Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vect
100100

101101
if (layers.size () == 1) {
102102

103-
m_box_convert = db::box_convert <db::CellInst, false> (*mp_layout, (unsigned int) layers [0]);
104-
m_cell_box_convert = db::box_convert <db::Cell, false> ((unsigned int) layers [0]);
103+
m_box_convert = db::box_convert <db::CellInst, false> (*mp_layout, layers [0]);
104+
m_cell_box_convert = db::box_convert <db::Cell, false> (layers [0]);
105105

106106
} else {
107107

@@ -202,7 +202,7 @@ Finder::do_find (const db::Cell &cell, int level, const db::DCplxTrans &vp, cons
202202
if (level <= m_max_level /*take level of cell itself*/
203203
&& cell.is_proxy ()
204204
&& m_layers.size () == 1
205-
&& (unsigned int) m_layers [0] == mp_layout->guiding_shape_layer ()) {
205+
&& m_layers [0] == mp_layout->guiding_shape_layer ()) {
206206

207207
// when looking at the guiding shape layer, we can visit this cell as well allowing to find the guiding shapes
208208

@@ -339,15 +339,18 @@ ShapeFinder::find (LayoutViewBase *view, const db::DBox &region_mu)
339339

340340
std::sort (lprops.begin (), lprops.end (), LPContextCompareOp ());
341341

342-
std::vector<int> layers;
342+
std::vector<unsigned int> layers;
343343
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator llp = lprops.begin (); llp != lprops.end (); ) {
344344

345345
layers.clear ();
346346

347347
lay::LayerPropertiesConstIterator lp0 = *llp;
348348
LPContextEqualOp eq;
349349
do {
350-
layers.push_back ((*llp)->layer_index ());
350+
int li = (*llp)->layer_index ();
351+
if (li >= 0) {
352+
layers.push_back ((unsigned int) li);
353+
}
351354
++llp;
352355
} while (llp != lprops.end () && eq(lp0, *llp));
353356

@@ -398,16 +401,19 @@ ShapeFinder::find (lay::LayoutViewBase *view, const lay::LayerProperties &lprops
398401
lay::TextInfo text_info (view);
399402
mp_text_info = (m_flags & db::ShapeIterator::Texts) != 0 ? &text_info : 0;
400403

401-
std::vector<int> layers;
402-
layers.push_back (lprops.layer_index ());
404+
std::vector<unsigned int> layers;
405+
int li = lprops.layer_index ();
406+
if (li >= 0) {
407+
layers.push_back ((unsigned int) li);
408+
}
403409
bool result = find_internal (view, lprops.cellview_index (), &lprops.prop_sel (), lprops.inverse_prop_sel (), lprops.hier_levels (), lprops.trans (), layers, region_mu);
404410

405411
mp_progress = 0;
406412
return result;
407413
}
408414

409-
bool
410-
ShapeFinder::find_internal (lay::LayoutViewBase *view, unsigned int cv_index, const std::set<db::properties_id_type> *prop_sel, bool inv_prop_sel, const lay::HierarchyLevelSelection &hier_sel, const std::vector<db::DCplxTrans> &trans_mu, const std::vector<int> &layers, const db::DBox &region_mu)
415+
bool
416+
ShapeFinder::find_internal (lay::LayoutViewBase *view, unsigned int cv_index, const std::set<db::properties_id_type> *prop_sel, bool inv_prop_sel, const lay::HierarchyLevelSelection &hier_sel, const std::vector<db::DCplxTrans> &trans_mu, const std::vector<unsigned int> &layers, const db::DBox &region_mu)
411417
{
412418
m_cv_index = cv_index;
413419

@@ -511,13 +517,13 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
511517

512518
if (! point_mode ()) {
513519

514-
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
520+
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
515521

516-
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
522+
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
517523

518524
checkpoint ();
519525

520-
const db::Shapes &shapes = cell.shapes ((unsigned int) *l);
526+
const db::Shapes &shapes = cell.shapes (*l);
521527

522528
db::ShapeIterator shape = shapes.begin_touching (scan_box, m_flags, mp_prop_sel, m_inv_prop_sel);
523529
while (! shape.at_end ()) {
@@ -563,9 +569,9 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
563569

564570
} else {
565571

566-
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
572+
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
567573

568-
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
574+
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
569575

570576
checkpoint ();
571577

@@ -793,7 +799,7 @@ InstFinder::find_internal (LayoutViewBase *view, unsigned int cv_index, const db
793799
try {
794800
std::vector<db::DCplxTrans> tv;
795801
tv.push_back (trans_mu);
796-
start (view, cv_index, tv, region_mu, region_mu, view->get_min_hier_levels (), view->get_max_hier_levels (), std::vector<int> ());
802+
start (view, cv_index, tv, region_mu, region_mu, view->get_min_hier_levels (), view->get_max_hier_levels (), std::vector<unsigned int> ());
797803
} catch (StopException) {
798804
// ..
799805
}

src/laybasic/laybasic/layFinder.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class LAYBASIC_PUBLIC Finder
132132
}
133133

134134
protected:
135-
const std::vector<int> &layers () const
135+
const std::vector<unsigned int> &layers () const
136136
{
137137
return m_layers;
138138
}
@@ -183,7 +183,7 @@ class LAYBASIC_PUBLIC Finder
183183
* @param max_level The maximum hierarchy level to check
184184
* @param layers A set of layers to check
185185
*/
186-
void start (LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox &region, const db::DBox &scan_region, int min_level, int max_level, const std::vector<int> &layers = std::vector<int> ());
186+
void start (LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox &region, const db::DBox &scan_region, int min_level, int max_level, const std::vector<unsigned int> &layers = std::vector<unsigned int> ());
187187

188188
/**
189189
* @brief Provide a basic edge test facility
@@ -232,7 +232,7 @@ class LAYBASIC_PUBLIC Finder
232232
unsigned int m_cv_index;
233233
db::Box m_region;
234234
db::Box m_scan_region;
235-
std::vector<int> m_layers;
235+
std::vector<unsigned int> m_layers;
236236
double m_distance;
237237
bool m_point_mode;
238238
bool m_catch_all;
@@ -267,8 +267,8 @@ class LAYBASIC_PUBLIC ShapeFinder
267267
*/
268268
ShapeFinder (bool point_mode, bool top_level_sel, db::ShapeIterator::flags_type flags, const std::set<lay::ObjectInstPath> *excludes = 0, bool capture_all_shapes = false);
269269

270-
bool find (LayoutViewBase *view, const lay::LayerProperties &lprops, const db::DBox &region_mu);
271-
bool find (LayoutViewBase *view, const db::DBox &region_mu);
270+
bool find (lay::LayoutViewBase *view, const lay::LayerProperties &lprops, const db::DBox &region_mu);
271+
bool find (lay::LayoutViewBase *view, const db::DBox &region_mu);
272272

273273
iterator begin () const
274274
{
@@ -327,7 +327,7 @@ class LAYBASIC_PUBLIC ShapeFinder
327327
bool inv_prop_sel,
328328
const lay::HierarchyLevelSelection &hier_sel,
329329
const std::vector<db::DCplxTrans> &trans_mu,
330-
const std::vector<int> &layers,
330+
const std::vector<unsigned int> &layers,
331331
const db::DBox &region_mu);
332332

333333
const std::set<lay::ObjectInstPath> *mp_excludes;

src/laybasic/laybasic/layLayoutViewBase.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,7 @@ LayoutViewBase::set_synchronous (bool s)
694694
}
695695

696696
void
697-
LayoutViewBase::message (const std::string & /*s*/, int /*timeout*/)
697+
LayoutViewBase::message (const std::string & /*s*/, int /*timeout*/, int /*priority*/)
698698
{
699699
// .. nothing yet ..
700700
}
@@ -4164,7 +4164,7 @@ void
41644164
LayoutViewBase::cancel_edits ()
41654165
{
41664166
// clear any messages
4167-
message ();
4167+
message (std::string (), 0, -1);
41684168

41694169
// the move service takes a special role here as it manages the
41704170
// transaction for the collective move operation.

0 commit comments

Comments
 (0)