mirror of https://github.com/KLayout/klayout.git
Merge pull request #2242 from KLayout/bugfix/issue-2234
Bugfix/issue 2234
This commit is contained in:
commit
4f30ad36db
|
|
@ -762,9 +762,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co
|
|||
{
|
||||
if (! point_mode ()) {
|
||||
|
||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
|
|
@ -897,9 +897,9 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co
|
|||
|
||||
} else {
|
||||
|
||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (hit_box))) {
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (hit_box))) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
|
|
|
|||
|
|
@ -328,6 +328,12 @@ set_menu_items_hidden (lay::MainWindow *mw, const std::map<std::string, bool> &h
|
|||
mw->dispatcher ()->config_set (lay::cfg_menu_items_hidden, lay::pack_menu_items_hidden (hv));
|
||||
}
|
||||
|
||||
static void
|
||||
clear_message (lay::MainWindow *mw, int priority)
|
||||
{
|
||||
mw->message (std::string (), 0, priority);
|
||||
}
|
||||
|
||||
Class<lay::MainWindow> decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "MainWindow",
|
||||
|
||||
// Dispatcher interface and convenience functions
|
||||
|
|
@ -475,15 +481,36 @@ Class<lay::MainWindow> decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "M
|
|||
"\n"
|
||||
"This method has been added in version 0.24."
|
||||
) +
|
||||
gsi::method ("message", &lay::MainWindow::message, gsi::arg ("message"), gsi::arg ("time", -1, "infinite"),
|
||||
gsi::method_ext ("clear_message", &clear_message, gsi::arg ("priority", -1, "all priorities"),
|
||||
"@brief Clears the message\n"
|
||||
"When calling this method with a priority, it will clear the message in the given priority slot, thus "
|
||||
"unhiding the messages with lower priority. This is equivalent to calling \\message with an empty string.\n"
|
||||
"\n"
|
||||
"When calling without a priority, all messages in all priority slots will be cleared.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.30.6."
|
||||
) +
|
||||
gsi::method ("message", &lay::MainWindow::message, gsi::arg ("message"), gsi::arg ("time", -1, "infinite"), gsi::arg ("priority", 0),
|
||||
"@brief Displays a message in the status bar\n"
|
||||
"\n"
|
||||
"@param message The message to display\n"
|
||||
"@param time The time how long to display the message in ms. A negative value means 'infinitely'.\n"
|
||||
"@param priority The priority of the message. Higher-priority messages have precendence over lower-priority ones.\n"
|
||||
"\n"
|
||||
"This given message is shown in the status bar for the given time.\n"
|
||||
"If a priority is given, higher-priority messages have precedence over lower-priority ones.\n"
|
||||
"Placing an empty message clears a message with a given priority and unhides messages with lower "
|
||||
"priority. Standard messages like selection descriptions have priority 0, which is the lowest priority.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.18. The 'time' parameter was made optional in version 0.28.10."
|
||||
"Messages generated during modal actions (e.g. 'Click on first point') by convention should have priority 10 "
|
||||
"and should be tied to the active state of a plugin. This ensures there is only one such message.\n"
|
||||
"Higher-priority messages must be cleared (set to empty string) explicitly to unhide lower-priority messages "
|
||||
"when the indicated action is finished.\n"
|
||||
"\n"
|
||||
"\\clear_message is a convenience method that will clear messages.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.18. The 'time' parameter was made optional in version 0.28.10.\n"
|
||||
"The 'priority' argument has been added in version 0.30.6."
|
||||
) +
|
||||
gsi::method ("resize", (void (lay::MainWindow::*)(int, int)) &lay::MainWindow::resize, gsi::arg ("width"), gsi::arg ("height"),
|
||||
"@brief Resizes the window\n"
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled)
|
|||
m_synchronous (false),
|
||||
m_busy (false),
|
||||
mp_app (app),
|
||||
m_message_timer_priority (-1),
|
||||
m_manager (undo_enabled)
|
||||
{
|
||||
setAnimated (false);
|
||||
|
|
@ -823,10 +824,15 @@ static int fm_width (const QFontMetrics &fm, const QString &s)
|
|||
void
|
||||
MainWindow::format_message ()
|
||||
{
|
||||
std::string msg;
|
||||
if (! m_messages.empty ()) {
|
||||
msg = (--m_messages.end ())->second;
|
||||
}
|
||||
|
||||
QFontMetrics fm (mp_msg_label->font ());
|
||||
|
||||
std::string full_message;
|
||||
for (const char *c = m_message.c_str (); *c; ++c) {
|
||||
for (const char *c = msg.c_str (); *c; ++c) {
|
||||
if (*c == '\\' && (c[1] == '(' || c[1] == ')')) {
|
||||
++c;
|
||||
} else {
|
||||
|
|
@ -847,7 +853,7 @@ MainWindow::format_message ()
|
|||
|
||||
short_message.clear ();
|
||||
|
||||
for (const char *c = m_message.c_str (); *c; ++c) {
|
||||
for (const char *c = msg.c_str (); *c; ++c) {
|
||||
if (*c == '\\' && c[1] == '(') {
|
||||
if (nsection++ < ndrop) {
|
||||
in_drop = true;
|
||||
|
|
@ -875,24 +881,53 @@ MainWindow::format_message ()
|
|||
}
|
||||
|
||||
void
|
||||
MainWindow::message (const std::string &s, int ms)
|
||||
MainWindow::message (const std::string &s, int ms, int priority)
|
||||
{
|
||||
m_message = s;
|
||||
format_message ();
|
||||
if (s.empty () && priority < 0) {
|
||||
|
||||
m_messages.clear ();
|
||||
|
||||
} else if (s.empty ()) {
|
||||
|
||||
m_messages.erase (priority);
|
||||
|
||||
} else {
|
||||
|
||||
// simulate timeout of previous message timer
|
||||
if (m_message_timer_priority >= 0) {
|
||||
m_messages.erase (m_message_timer_priority);
|
||||
}
|
||||
|
||||
m_messages[priority] = s;
|
||||
|
||||
if (ms >= 0) {
|
||||
m_message_timer_priority = priority;
|
||||
m_message_timer.start (ms);
|
||||
} else {
|
||||
m_message_timer_priority = -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
format_message ();
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::clear_message ()
|
||||
MainWindow::clear_messages ()
|
||||
{
|
||||
m_message.clear ();
|
||||
m_message_timer.start (0);
|
||||
m_message_timer.stop ();
|
||||
m_message_timer_priority = -1;
|
||||
m_messages.clear ();
|
||||
format_message ();
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::message_timer ()
|
||||
{
|
||||
m_message.clear ();
|
||||
if (m_message_timer_priority >= 0) {
|
||||
m_messages.erase (m_message_timer_priority);
|
||||
}
|
||||
m_message_timer_priority = -1;
|
||||
format_message ();
|
||||
}
|
||||
|
||||
|
|
@ -2467,7 +2502,7 @@ MainWindow::select_view (int index)
|
|||
update_editor_options_dock ();
|
||||
clear_current_pos ();
|
||||
edits_enabled_changed ();
|
||||
clear_message ();
|
||||
clear_messages ();
|
||||
menu_needs_update ();
|
||||
|
||||
m_disable_tab_selected = dis;
|
||||
|
|
@ -2994,7 +3029,7 @@ MainWindow::close_view (int index)
|
|||
clear_current_pos ();
|
||||
edits_enabled_changed ();
|
||||
menu_needs_update ();
|
||||
clear_message ();
|
||||
clear_messages ();
|
||||
|
||||
update_dock_widget_state ();
|
||||
|
||||
|
|
@ -3479,7 +3514,7 @@ MainWindow::add_view (lay::LayoutViewWidget *view)
|
|||
connect (view, SIGNAL (dirty_changed (lay::LayoutView *)), this, SLOT (view_title_changed (lay::LayoutView *)));
|
||||
connect (view, SIGNAL (edits_enabled_changed ()), this, SLOT (edits_enabled_changed ()));
|
||||
connect (view, SIGNAL (menu_needs_update ()), this, SLOT (menu_needs_update ()));
|
||||
connect (view, SIGNAL (show_message (const std::string &, int)), this, SLOT (message (const std::string &, int)));
|
||||
connect (view, SIGNAL (show_message (const std::string &, int, int)), this, SLOT (message (const std::string &, int, int)));
|
||||
connect (view, SIGNAL (current_pos_changed (double, double, bool)), this, SLOT (current_pos (double, double, bool)));
|
||||
connect (view, SIGNAL (clear_current_pos ()), this, SLOT (clear_current_pos ()));
|
||||
connect (view, SIGNAL (mode_change (int)), this, SLOT (select_mode (int)));
|
||||
|
|
|
|||
|
|
@ -649,12 +649,12 @@ public slots:
|
|||
/**
|
||||
* @brief Displays a status message next to the coordinates
|
||||
*/
|
||||
void message (const std::string &s, int ms);
|
||||
void message (const std::string &s, int ms, int);
|
||||
|
||||
/**
|
||||
* @brief Clears the current message
|
||||
*/
|
||||
void clear_message ();
|
||||
void clear_messages ();
|
||||
|
||||
/**
|
||||
* @brief Selects the given mode
|
||||
|
|
@ -789,7 +789,8 @@ private:
|
|||
QApplication *mp_app;
|
||||
lay::HelpDialog *mp_assistant;
|
||||
std::string m_current_session;
|
||||
std::string m_message;
|
||||
int m_message_timer_priority;
|
||||
std::map<int, std::string> m_messages;
|
||||
std::unique_ptr<QPrinter> mp_printer;
|
||||
std::vector<QString> m_changed_files;
|
||||
std::string m_title;
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ Finder::closer (double d)
|
|||
}
|
||||
|
||||
void
|
||||
Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<int> &layers)
|
||||
Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<unsigned int> &layers)
|
||||
{
|
||||
const lay::CellView &cv = view->cellview (cv_index);
|
||||
|
||||
|
|
@ -100,8 +100,8 @@ Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vect
|
|||
|
||||
if (layers.size () == 1) {
|
||||
|
||||
m_box_convert = db::box_convert <db::CellInst, false> (*mp_layout, (unsigned int) layers [0]);
|
||||
m_cell_box_convert = db::box_convert <db::Cell, false> ((unsigned int) layers [0]);
|
||||
m_box_convert = db::box_convert <db::CellInst, false> (*mp_layout, layers [0]);
|
||||
m_cell_box_convert = db::box_convert <db::Cell, false> (layers [0]);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ Finder::do_find (const db::Cell &cell, int level, const db::DCplxTrans &vp, cons
|
|||
if (level <= m_max_level /*take level of cell itself*/
|
||||
&& cell.is_proxy ()
|
||||
&& m_layers.size () == 1
|
||||
&& (unsigned int) m_layers [0] == mp_layout->guiding_shape_layer ()) {
|
||||
&& m_layers [0] == mp_layout->guiding_shape_layer ()) {
|
||||
|
||||
// when looking at the guiding shape layer, we can visit this cell as well allowing to find the guiding shapes
|
||||
|
||||
|
|
@ -339,7 +339,7 @@ ShapeFinder::find (LayoutViewBase *view, const db::DBox ®ion_mu)
|
|||
|
||||
std::sort (lprops.begin (), lprops.end (), LPContextCompareOp ());
|
||||
|
||||
std::vector<int> layers;
|
||||
std::vector<unsigned int> layers;
|
||||
for (std::vector<lay::LayerPropertiesConstIterator>::const_iterator llp = lprops.begin (); llp != lprops.end (); ) {
|
||||
|
||||
layers.clear ();
|
||||
|
|
@ -347,7 +347,10 @@ ShapeFinder::find (LayoutViewBase *view, const db::DBox ®ion_mu)
|
|||
lay::LayerPropertiesConstIterator lp0 = *llp;
|
||||
LPContextEqualOp eq;
|
||||
do {
|
||||
layers.push_back ((*llp)->layer_index ());
|
||||
int li = (*llp)->layer_index ();
|
||||
if (li >= 0) {
|
||||
layers.push_back ((unsigned int) li);
|
||||
}
|
||||
++llp;
|
||||
} while (llp != lprops.end () && eq(lp0, *llp));
|
||||
|
||||
|
|
@ -398,8 +401,11 @@ ShapeFinder::find (lay::LayoutViewBase *view, const lay::LayerProperties &lprops
|
|||
lay::TextInfo text_info (view);
|
||||
mp_text_info = (m_flags & db::ShapeIterator::Texts) != 0 ? &text_info : 0;
|
||||
|
||||
std::vector<int> layers;
|
||||
layers.push_back (lprops.layer_index ());
|
||||
std::vector<unsigned int> layers;
|
||||
int li = lprops.layer_index ();
|
||||
if (li >= 0) {
|
||||
layers.push_back ((unsigned int) li);
|
||||
}
|
||||
bool result = find_internal (view, lprops.cellview_index (), &lprops.prop_sel (), lprops.inverse_prop_sel (), lprops.hier_levels (), lprops.trans (), layers, region_mu);
|
||||
|
||||
mp_progress = 0;
|
||||
|
|
@ -407,7 +413,7 @@ ShapeFinder::find (lay::LayoutViewBase *view, const lay::LayerProperties &lprops
|
|||
}
|
||||
|
||||
bool
|
||||
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 ®ion_mu)
|
||||
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 ®ion_mu)
|
||||
{
|
||||
m_cv_index = cv_index;
|
||||
|
||||
|
|
@ -511,13 +517,13 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
|||
|
||||
if (! point_mode ()) {
|
||||
|
||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
const db::Shapes &shapes = cell.shapes ((unsigned int) *l);
|
||||
const db::Shapes &shapes = cell.shapes (*l);
|
||||
|
||||
db::ShapeIterator shape = shapes.begin_touching (scan_box, m_flags, mp_prop_sel, m_inv_prop_sel);
|
||||
while (! shape.at_end ()) {
|
||||
|
|
@ -563,9 +569,9 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
|
|||
|
||||
} else {
|
||||
|
||||
for (std::vector<int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
for (std::vector<unsigned int>::const_iterator l = layers ().begin (); l != layers ().end (); ++l) {
|
||||
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox ((unsigned int) *l).touches (scan_box))) {
|
||||
if (layers ().size () == 1 || (layers ().size () > 1 && cell.bbox (*l).touches (scan_box))) {
|
||||
|
||||
checkpoint ();
|
||||
|
||||
|
|
@ -793,7 +799,7 @@ InstFinder::find_internal (LayoutViewBase *view, unsigned int cv_index, const db
|
|||
try {
|
||||
std::vector<db::DCplxTrans> tv;
|
||||
tv.push_back (trans_mu);
|
||||
start (view, cv_index, tv, region_mu, region_mu, view->get_min_hier_levels (), view->get_max_hier_levels (), std::vector<int> ());
|
||||
start (view, cv_index, tv, region_mu, region_mu, view->get_min_hier_levels (), view->get_max_hier_levels (), std::vector<unsigned int> ());
|
||||
} catch (StopException) {
|
||||
// ..
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
const std::vector<int> &layers () const
|
||||
const std::vector<unsigned int> &layers () const
|
||||
{
|
||||
return m_layers;
|
||||
}
|
||||
|
|
@ -183,7 +183,7 @@ protected:
|
|||
* @param max_level The maximum hierarchy level to check
|
||||
* @param layers A set of layers to check
|
||||
*/
|
||||
void start (LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<int> &layers = std::vector<int> ());
|
||||
void start (LayoutViewBase *view, unsigned int cv_index, const std::vector<db::DCplxTrans> &trans, const db::DBox ®ion, const db::DBox &scan_region, int min_level, int max_level, const std::vector<unsigned int> &layers = std::vector<unsigned int> ());
|
||||
|
||||
/**
|
||||
* @brief Provide a basic edge test facility
|
||||
|
|
@ -232,7 +232,7 @@ private:
|
|||
unsigned int m_cv_index;
|
||||
db::Box m_region;
|
||||
db::Box m_scan_region;
|
||||
std::vector<int> m_layers;
|
||||
std::vector<unsigned int> m_layers;
|
||||
double m_distance;
|
||||
bool m_point_mode;
|
||||
bool m_catch_all;
|
||||
|
|
@ -267,8 +267,8 @@ public:
|
|||
*/
|
||||
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);
|
||||
|
||||
bool find (LayoutViewBase *view, const lay::LayerProperties &lprops, const db::DBox ®ion_mu);
|
||||
bool find (LayoutViewBase *view, const db::DBox ®ion_mu);
|
||||
bool find (lay::LayoutViewBase *view, const lay::LayerProperties &lprops, const db::DBox ®ion_mu);
|
||||
bool find (lay::LayoutViewBase *view, const db::DBox ®ion_mu);
|
||||
|
||||
iterator begin () const
|
||||
{
|
||||
|
|
@ -327,7 +327,7 @@ private:
|
|||
bool inv_prop_sel,
|
||||
const lay::HierarchyLevelSelection &hier_sel,
|
||||
const std::vector<db::DCplxTrans> &trans_mu,
|
||||
const std::vector<int> &layers,
|
||||
const std::vector<unsigned int> &layers,
|
||||
const db::DBox ®ion_mu);
|
||||
|
||||
const std::set<lay::ObjectInstPath> *mp_excludes;
|
||||
|
|
|
|||
|
|
@ -694,7 +694,7 @@ LayoutViewBase::set_synchronous (bool s)
|
|||
}
|
||||
|
||||
void
|
||||
LayoutViewBase::message (const std::string & /*s*/, int /*timeout*/)
|
||||
LayoutViewBase::message (const std::string & /*s*/, int /*timeout*/, int /*priority*/)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -4164,7 +4164,7 @@ void
|
|||
LayoutViewBase::cancel_edits ()
|
||||
{
|
||||
// clear any messages
|
||||
message ();
|
||||
message (std::string (), 0, -1);
|
||||
|
||||
// the move service takes a special role here as it manages the
|
||||
// transaction for the collective move operation.
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ public:
|
|||
/**
|
||||
* @brief Display a status message
|
||||
*/
|
||||
virtual void message (const std::string &s = "", int timeout = 10);
|
||||
virtual void message (const std::string &s = "", int timeout = 10, int priority = 0);
|
||||
|
||||
/**
|
||||
* @brief Sets the keyboard focus to the view
|
||||
|
|
|
|||
|
|
@ -1585,10 +1585,10 @@ LayoutView::signal_selection_changed ()
|
|||
}
|
||||
|
||||
void
|
||||
LayoutView::message (const std::string &s, int timeout)
|
||||
LayoutView::message (const std::string &s, int timeout, int priority)
|
||||
{
|
||||
if (mp_widget) {
|
||||
mp_widget->emit_show_message (s, timeout * 1000);
|
||||
mp_widget->emit_show_message (s, timeout * 1000, priority);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ public:
|
|||
/**
|
||||
* @brief Displays a status message
|
||||
*/
|
||||
void message (const std::string &s = "", int timeout = 10);
|
||||
virtual void message (const std::string &s = "", int timeout = 10, int priority = 0);
|
||||
|
||||
/**
|
||||
* @brief Sets the keyboard focus to the view
|
||||
|
|
@ -773,7 +773,7 @@ public:
|
|||
|
||||
void emit_title_changed (lay::LayoutView *view) { emit title_changed (view); }
|
||||
void emit_dirty_changed (lay::LayoutView *view) { emit dirty_changed (view); }
|
||||
void emit_show_message (const std::string &s, int ms) { emit show_message (s, ms); }
|
||||
void emit_show_message (const std::string &s, int ms, int priority) { emit show_message (s, ms, priority); }
|
||||
void emit_current_pos_changed (double x, double y, bool dbu_units) { emit current_pos_changed (x, y, dbu_units); }
|
||||
void emit_clear_current_pos () { emit clear_current_pos (); }
|
||||
void emit_edits_enabled_changed () { emit edits_enabled_changed (); }
|
||||
|
|
@ -826,7 +826,7 @@ signals:
|
|||
/**
|
||||
* @brief This signal is emitted when the view wants to show a message for the given time (of infinitely for ms == 0)
|
||||
*/
|
||||
void show_message (const std::string &s, int ms);
|
||||
void show_message (const std::string &s, int ms, int priority);
|
||||
|
||||
/**
|
||||
* @brief This signal is emitted when the view wants to indicate a mouse position change
|
||||
|
|
|
|||
|
|
@ -337,6 +337,16 @@ NetTracerData::requires_booleans (unsigned int from_layer) const
|
|||
return r->second;
|
||||
}
|
||||
|
||||
std::set<unsigned int>
|
||||
NetTracerData::original_layers () const
|
||||
{
|
||||
std::set<unsigned int> ol;
|
||||
for (std::map <unsigned int, std::set <unsigned int> >::const_iterator g = m_original_layers.begin (); g != m_original_layers.end (); ++g) {
|
||||
ol.insert (g->second.begin (), g->second.end ());
|
||||
}
|
||||
return ol;
|
||||
}
|
||||
|
||||
void
|
||||
NetTracerData::clean_l2n_regions ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -626,6 +626,13 @@ public:
|
|||
*/
|
||||
void configure_l2n (db::LayoutToNetlist &l2n);
|
||||
|
||||
/**
|
||||
* @brief Gets the original layers
|
||||
*
|
||||
* These are the layer indexes used for computing the net tracer functions
|
||||
*/
|
||||
std::set<unsigned int> original_layers () const;
|
||||
|
||||
private:
|
||||
unsigned int m_next_log_layer;
|
||||
std::vector <NetTracerConnection> m_connections;
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ NetTracerDialog::drag_cancel ()
|
|||
{
|
||||
if (m_mouse_state > 0) {
|
||||
|
||||
view ()->message ();
|
||||
view ()->message (std::string (), 0, 10);
|
||||
ui ()->ungrab_mouse (this);
|
||||
set_cursor (lay::Cursor::none);
|
||||
|
||||
|
|
@ -241,7 +241,7 @@ NetTracerDialog::mouse_click_event (const db::DPoint &p, unsigned int buttons, b
|
|||
m_mouse_first_point = p;
|
||||
m_mouse_state = 3;
|
||||
|
||||
view ()->message (tl::to_string (QObject::tr ("Click on the second point in the net")));
|
||||
view ()->message (tl::to_string (QObject::tr ("Click on the second point in the net")), -1 /*infinitely*/, 10);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -414,9 +414,24 @@ NetTracerDialog::get_net_tracer_setup (const lay::CellView &cv, db::NetTracerDat
|
|||
db::NetTracerNet *
|
||||
NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &stop_search_box, bool trace_path)
|
||||
{
|
||||
// determine the cellview
|
||||
lay::CellView cv = view ()->cellview (m_cv_index);
|
||||
if (! cv.is_valid ()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set up the net tracer environment
|
||||
db::NetTracerData tracer_data;
|
||||
if (! get_net_tracer_setup (cv, tracer_data)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::set<unsigned int> original_layers = tracer_data.original_layers ();
|
||||
|
||||
unsigned int start_layer = 0;
|
||||
db::Point start_point;
|
||||
db::Shape start_shape;
|
||||
db::ICplxTrans start_trans;
|
||||
|
||||
// locate the seed
|
||||
{
|
||||
|
|
@ -426,7 +441,7 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
|||
|
||||
// go through all visible layers of all cellviews and find a seed shape
|
||||
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
||||
if (lprop->is_visual ()) {
|
||||
if (lprop->is_visual () && lprop->cellview_index () == m_cv_index && original_layers.find ((unsigned int) lprop->layer_index ()) != original_layers.end ()) {
|
||||
finder.find (view (), *lprop, start_search_box);
|
||||
}
|
||||
}
|
||||
|
|
@ -440,15 +455,10 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
|||
m_cv_index = r->cv_index ();
|
||||
start_shape = r->shape ();
|
||||
start_layer = r->layer ();
|
||||
start_trans = r->trans ();
|
||||
|
||||
}
|
||||
|
||||
// determine the cellview
|
||||
lay::CellView cv = view ()->cellview (m_cv_index);
|
||||
if (! cv.is_valid ()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// determine the start point
|
||||
{
|
||||
|
||||
|
|
@ -463,20 +473,15 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
|||
|
||||
// stop if the center start point is not inside the start polygon
|
||||
db::Polygon poly;
|
||||
if (start_shape.polygon (poly) && db::inside_poly (poly.begin_edge (), start_point) < 0) {
|
||||
if (start_shape.polygon (poly) && db::inside_poly (poly.begin_edge (), start_trans.inverted () * start_point) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Set up the net tracer environment
|
||||
db::NetTracerData tracer_data;
|
||||
if (! get_net_tracer_setup (cv, tracer_data)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int stop_layer = 0;
|
||||
db::Point stop_point;
|
||||
db::ICplxTrans stop_trans;
|
||||
|
||||
// locate the stop shape (the second mouse click)
|
||||
if (trace_path) {
|
||||
|
|
@ -486,7 +491,7 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
|||
|
||||
// go through all visible layers of all cellviews and find a seed shape
|
||||
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
||||
if (lprop->is_visual ()) {
|
||||
if (lprop->is_visual () && lprop->cellview_index () == m_cv_index && original_layers.find ((unsigned int) lprop->layer_index ()) != original_layers.end ()) {
|
||||
finder.find (view (), *lprop, stop_search_box);
|
||||
}
|
||||
}
|
||||
|
|
@ -510,10 +515,11 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
|||
|
||||
stop_point = tt.inverted ().trans (stop_search_box.center ());
|
||||
stop_layer = r->layer ();
|
||||
stop_trans = r->trans ();
|
||||
|
||||
// stop if the center stop point is not inside the stop polygon
|
||||
db::Polygon poly;
|
||||
if (r->shape ().polygon (poly) && db::inside_poly (poly.begin_edge (), stop_point) < 0) {
|
||||
if (r->shape ().polygon (poly) && db::inside_poly (poly.begin_edge (), stop_trans.inverted () * stop_point) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1258,7 +1264,7 @@ BEGIN_PROTECTED
|
|||
commit ();
|
||||
net_list->setCurrentItem (0);
|
||||
m_mouse_state = 2;
|
||||
view ()->message (tl::to_string (QObject::tr ("Click on the first point in the net")));
|
||||
view ()->message (tl::to_string (QObject::tr ("Click on the first point in the net")), -1 /*infinitely*/, 10);
|
||||
ui ()->grab_mouse (this, false);
|
||||
END_PROTECTED
|
||||
}
|
||||
|
|
@ -1270,7 +1276,7 @@ BEGIN_PROTECTED
|
|||
commit ();
|
||||
net_list->setCurrentItem (0);
|
||||
m_mouse_state = 1;
|
||||
view ()->message (tl::to_string (QObject::tr ("Click on a point in the net")));
|
||||
view ()->message (tl::to_string (QObject::tr ("Click on a point in the net")), -1 /*infinitely*/, 10);
|
||||
ui ()->grab_mouse (this, false);
|
||||
END_PROTECTED
|
||||
}
|
||||
|
|
@ -1293,7 +1299,7 @@ NetTracerDialog::release_mouse ()
|
|||
add_pb->setChecked (false);
|
||||
add2_pb->setChecked (false);
|
||||
m_mouse_state = 0;
|
||||
view ()->message ();
|
||||
view ()->message (std::string (), 0, 10);
|
||||
ui ()->ungrab_mouse (this);
|
||||
set_cursor (lay::Cursor::none);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue