diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index a087bab37..b38114915 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -94,16 +94,23 @@ namespace lay // -------------------------------------------------------------------------------- // Exception handlers +static void close_transaction () +{ + // if any transaction is pending (this may happen when an operation threw an exception) + // close transactions. + // NOTE: don't do this in breakpoint mode as we do not want to interfere with things happening outside + if (lay::MainWindow::instance () && lay::MainWindow::instance ()->manager ().transacting () && + !(lay::MacroEditorDialog::instance () && lay::MacroEditorDialog::instance ()->in_breakpoint ())) { + lay::MainWindow::instance ()->manager ().commit (); + } +} + static void ui_exception_handler_tl (const tl::Exception &ex, QWidget *parent) { // Prevents severe side effects if there are pending deferred methods tl::NoDeferredMethods silent; - // if any transaction is pending (this may happen when an operation threw an exception) - // close transactions. - if (lay::MainWindow::instance () && lay::MainWindow::instance ()->manager ().transacting ()) { - lay::MainWindow::instance ()->manager ().commit (); - } + close_transaction (); const tl::ExitException *gsi_exit = dynamic_cast (&ex); const tl::BreakException *gsi_break = dynamic_cast (&ex); @@ -155,13 +162,9 @@ static void ui_exception_handler_std (const std::exception &ex, QWidget *parent) // Prevents severe side effects if there are pending deferred methods tl::NoDeferredMethods silent; - // if any transaction is pending (this may happen when an operation threw an exception) - // close transactions. - if (lay::MainWindow::instance () && lay::MainWindow::instance ()->manager ().transacting ()) { - lay::MainWindow::instance ()->manager ().commit (); - } + close_transaction (); - tl::error << ex.what (); + tl::error << ex.what (); if (! parent) { parent = QApplication::activeWindow () ? QApplication::activeWindow () : lay::MainWindow::instance (); } @@ -173,11 +176,7 @@ static void ui_exception_handler_def (QWidget *parent) // Prevents severe side effects if there are pending deferred methods tl::NoDeferredMethods silent; - // if any transaction is pending (this may happen when an operation threw an exception) - // close transactions. - if (lay::MainWindow::instance () && lay::MainWindow::instance ()->manager ().transacting ()) { - lay::MainWindow::instance ()->manager ().commit (); - } + close_transaction (); if (! parent) { parent = QApplication::activeWindow () ? QApplication::activeWindow () : lay::MainWindow::instance (); diff --git a/src/lay/lay/layMacroEditorDialog.cc b/src/lay/lay/layMacroEditorDialog.cc index 08df2a280..380b50b3d 100644 --- a/src/lay/lay/layMacroEditorDialog.cc +++ b/src/lay/lay/layMacroEditorDialog.cc @@ -1511,26 +1511,25 @@ MacroEditorDialog::eventFilter (QObject *obj, QEvent *event) if (lay::BusySection::is_busy ()) { -#if 0 - if (dynamic_cast (event) != 0 || dynamic_cast (event) != 0) { + if (m_in_breakpoint && (dynamic_cast (event) != 0 || dynamic_cast (event) != 0)) { - // In breakpoint or execution mode and while processing the events inside the debugger, + // In breakpoint mode and while processing the events inside the debugger, // ignore all input or paint events targeted to widgets which are not children of this or the assistant dialog. // Ignoring the paint event is required because otherwise a repaint action would be triggered on a layout which // is potentially unstable or inconsistent. // We nevertheless allow events send to a HelpDialog or ProgressWidget since those are vital for the application's // functionality and are known not to cause any interference. QObject *rec = obj; - while (rec && (rec != this && !dynamic_cast (rec) && !dynamic_cast (rec))) { + while (rec && rec != this) { rec = rec->parent (); } if (! rec) { // TODO: reschedule the paint events (?) + event->accept (); return true; } } -#endif } else { @@ -2267,19 +2266,35 @@ END_PROTECTED } void -MacroEditorDialog::help_requested(const QString &s) +MacroEditorDialog::help_requested (const QString &s) { +BEGIN_PROTECTED + // Do not allow modal popups in breakpoint mode - this would interfere with + // event filtering during breakpoint execution + if (m_in_breakpoint) { + throw tl::Exception (tl::to_string (tr ("The help function is not available in breakpoint mode."))); + } + lay::MainWindow::instance ()->show_assistant_topic (tl::to_string (s)); +END_PROTECTED } void -MacroEditorDialog::help_button_clicked() +MacroEditorDialog::help_button_clicked () { +BEGIN_PROTECTED + // Do not allow modal popups in breakpoint mode - this would interfere with + // event filtering during breakpoint execution + if (m_in_breakpoint) { + throw tl::Exception (tl::to_string (tr ("The help function is not available in breakpoint mode."))); + } + lay::MainWindow::instance ()->show_assistant_url ("int:/code/index.xml"); +END_PROTECTED } void -MacroEditorDialog::add_button_clicked() +MacroEditorDialog::add_button_clicked () { BEGIN_PROTECTED new_macro (); @@ -2287,7 +2302,7 @@ END_PROTECTED } lym::Macro * -MacroEditorDialog::new_macro() +MacroEditorDialog::new_macro () { ensure_writeable_collection_selected (); @@ -3451,6 +3466,11 @@ MacroEditorDialog::leave_breakpoint_mode () mp_current_interpreter = 0; do_update_ui_to_run_mode (); set_exec_point (0, -1, -1); + + // refresh UI that might have been spoiled because we filter events + if (lay::MainWindow::instance ()) { + lay::MainWindow::instance ()->update (); + } } void diff --git a/src/lay/lay/layMacroEditorDialog.h b/src/lay/lay/layMacroEditorDialog.h index 001829924..85befea08 100644 --- a/src/lay/lay/layMacroEditorDialog.h +++ b/src/lay/lay/layMacroEditorDialog.h @@ -166,6 +166,14 @@ public: return m_in_exec; } + /** + * @brief Returns true while the macro IDE is in breakpoint mode + */ + bool in_breakpoint () const + { + return m_in_breakpoint; + } + /** * @brief Selects the current category in the tree view */