diff --git a/src/laybasic/laybasic/gsiDeclLayPlugin.cc b/src/laybasic/laybasic/gsiDeclLayPlugin.cc index ae83521cb..d3e1d6f5a 100644 --- a/src/laybasic/laybasic/gsiDeclLayPlugin.cc +++ b/src/laybasic/laybasic/gsiDeclLayPlugin.cc @@ -415,6 +415,16 @@ PluginImpl::key_event (unsigned int key, unsigned int buttons) } } +bool +PluginImpl::shortcut_override_event (unsigned int key, unsigned int buttons) +{ + if (f_shortcut_override_event.can_issue ()) { + return f_shortcut_override_event.issue (&lay::ViewService::shortcut_override_event, key, buttons); + } else { + return lay::EditorServiceBase::shortcut_override_event (key, buttons); + } +} + bool PluginImpl::mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio) { @@ -728,6 +738,17 @@ Class decl_Plugin (decl_PluginBase, "lay", "Plugin", "@param buttons A combination of the constants in the \\ButtonState class which codes both the mouse buttons and the key modifiers (.e. ShiftButton etc).\n" "@return True to terminate dispatcher\n" ) + + callback ("shortcut_override_event", &gsi::PluginImpl::shortcut_override_event, &gsi::PluginImpl::f_shortcut_override_event, gsi::arg ("key"), gsi::arg ("buttons"), + "@brief Allows overriding keyboard shortcuts for this plugin\n" + "If the implementation returns true, the given key is not handled by the shortcut system, but rather\n" + "passed to 'key_event' the usual way.\n" + "\n" + "@param key The Qt key code of the key that was pressed\n" + "@param buttons A combination of the constants in the \\ButtonState class which codes both the mouse buttons and the key modifiers (.e. ShiftButton etc).\n" + "@return True to request 'key_event' handling\n" + "\n" + "This method has been introduced in version 0.30.5." + ) + callback ("mouse_button_pressed_event", &gsi::PluginImpl::mouse_press_event_noref, &gsi::PluginImpl::f_mouse_press_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), "@brief Handles the mouse button pressed event\n" "This method will called by the view when a button is pressed on the mouse.\n" diff --git a/src/laybasic/laybasic/gsiDeclLayPlugin.h b/src/laybasic/laybasic/gsiDeclLayPlugin.h index c1a442633..8bc0e3eb9 100644 --- a/src/laybasic/laybasic/gsiDeclLayPlugin.h +++ b/src/laybasic/laybasic/gsiDeclLayPlugin.h @@ -62,6 +62,7 @@ public: virtual void config_finalize_impl (); virtual void config_finalize (); virtual bool key_event (unsigned int key, unsigned int buttons); + virtual bool shortcut_override_event (unsigned int key, unsigned int buttons); virtual bool mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio) ; bool mouse_press_event_noref (db::DPoint p, unsigned int buttons, bool prio); virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio); @@ -116,6 +117,7 @@ public: gsi::Callback f_configure; gsi::Callback f_config_finalize; gsi::Callback f_key_event; + gsi::Callback f_shortcut_override_event; gsi::Callback f_mouse_press_event; gsi::Callback f_mouse_click_event; gsi::Callback f_mouse_double_click_event; diff --git a/src/laybasic/laybasic/layEditorOptionsPage.cc b/src/laybasic/laybasic/layEditorOptionsPage.cc index cee43ea82..291d815db 100644 --- a/src/laybasic/laybasic/layEditorOptionsPage.cc +++ b/src/laybasic/laybasic/layEditorOptionsPage.cc @@ -70,7 +70,9 @@ EditorOptionsPage::init (lay::LayoutViewBase *view, lay::Dispatcher *dispatcher) int EditorOptionsPage::show () { - if (mp_owner && m_active) { + if (! m_active) { + return -1; + } else if (mp_owner) { if (! is_modal_page ()) { mp_owner->make_page_current (this); return -1; @@ -78,6 +80,7 @@ EditorOptionsPage::show () return mp_owner->exec_modal (this) ? 1 : 0; } } else { + set_focus (); return -1; } } @@ -200,8 +203,10 @@ END_PROTECTED void EditorOptionsPageWidget::set_focus () { - setFocus (Qt::TabFocusReason); - QWidget::focusNextPrevChild (true); + if (isVisible ()) { + setFocus (Qt::TabFocusReason); + QWidget::focusNextPrevChild (true); + } } void diff --git a/src/laybasic/laybasic/layEditorServiceBase.cc b/src/laybasic/laybasic/layEditorServiceBase.cc index a3ae88baf..0783817ba 100644 --- a/src/laybasic/laybasic/layEditorServiceBase.cc +++ b/src/laybasic/laybasic/layEditorServiceBase.cc @@ -379,6 +379,12 @@ EditorServiceBase::key_event (unsigned int key, unsigned int buttons) } } +bool +EditorServiceBase::shortcut_override_event (unsigned int key, unsigned int buttons) +{ + return is_active () && key == Qt::Key_Tab && buttons == 0 && focus_page (); +} + int EditorServiceBase::focus_page_open () { diff --git a/src/laybasic/laybasic/layEditorServiceBase.h b/src/laybasic/laybasic/layEditorServiceBase.h index 641aac92f..86441aadc 100644 --- a/src/laybasic/laybasic/layEditorServiceBase.h +++ b/src/laybasic/laybasic/layEditorServiceBase.h @@ -185,6 +185,11 @@ public: */ virtual bool key_event (unsigned int /*key*/, unsigned int /*buttons*/); + /** + * @brief Shortcut override event handler + */ + virtual bool shortcut_override_event (unsigned int /*key*/, unsigned int /*buttons*/); + /** * @brief Mouse press event handler */ diff --git a/src/laybasic/laybasic/layMove.cc b/src/laybasic/laybasic/layMove.cc index e3866e04d..0664a4bc9 100644 --- a/src/laybasic/laybasic/layMove.cc +++ b/src/laybasic/laybasic/layMove.cc @@ -30,6 +30,7 @@ #if defined(HAVE_QT) # include "layEditorOptionsPage.h" # include +# include // @@@ # include # include #endif @@ -142,16 +143,6 @@ MoveService::show_toolbox (bool visible) } } -int -MoveService::focus_page_open () -{ - // This method is called on "Tab" by "key_event". "fp" is null as we don't have a focus page registered. - if (is_active () && dispatcher ()) { - dispatcher ()->menu_activated ("cm_sel_move"); - } - return 0; -} - bool MoveService::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio) { @@ -415,6 +406,8 @@ public: mp_layout->addStretch (1); hide (); + + set_focus_page (true); set_toolbox_widget (true); } @@ -438,6 +431,35 @@ public: hide (); } + virtual void keyPressEvent (QKeyEvent *event) + { + if (event->key () == Qt::Key_Escape) { + tl::info << "@@@ Escape!"; + view ()->set_focus (); + } else if (event->key () == Qt::Key_Enter || event->key () == Qt::Key_Return) { + tl::info << "@@@ Accept!"; + view ()->set_focus (); + } + QWidget::keyPressEvent (event); + } + + virtual bool event (QEvent *event) + { + if (event->type () == QEvent::ShortcutOverride) { + QKeyEvent *ke = dynamic_cast (event); + if (ke->key () == Qt::Key_Escape || + ke->key () == Qt::Key_Tab || + ke->key () == Qt::Key_Enter || + ke->key () == Qt::Key_Return || + ke->key () == Qt::Key_Backtab) { + // accept the shortcut override event for some keys, so we can handle + // it in keyPressEvent + ke->accept (); + } + } + return QWidget::event (event); + } + private: QHBoxLayout *mp_layout; QLineEdit *mp_x_le, *mp_y_le; diff --git a/src/laybasic/laybasic/layMove.h b/src/laybasic/laybasic/layMove.h index 9fdfaf357..635c25f31 100644 --- a/src/laybasic/laybasic/layMove.h +++ b/src/laybasic/laybasic/layMove.h @@ -56,7 +56,6 @@ private: virtual bool key_event (unsigned int key, unsigned int buttons); virtual void drag_cancel (); virtual void deactivated (); - int focus_page_open (); void show_toolbox (bool visible); bool handle_click (const db::DPoint &p, unsigned int buttons, bool drag_transient, db::Transaction *transaction); diff --git a/src/laybasic/laybasic/layViewObject.cc b/src/laybasic/laybasic/layViewObject.cc index 488ff5fbb..44094faf6 100644 --- a/src/laybasic/laybasic/layViewObject.cc +++ b/src/laybasic/laybasic/layViewObject.cc @@ -257,6 +257,37 @@ public: END_PROTECTED } + bool event (QEvent *e) + { + if (e->type () == QEvent::MaxUser) { + + // GTF probe event + // record the contents (the screenshot) as ASCII text + mp_view->gtf_probe (); + + e->accept (); + return true; + + } else if (e->type () == QEvent::ShortcutOverride) { + + BEGIN_PROTECTED + QKeyEvent *ke = dynamic_cast (e); + if (ke) { + unsigned int buttons = qt_to_buttons (Qt::MouseButtons (), ke->modifiers ()); + if (mp_view->send_shortcut_override_event ((unsigned int) ke->key (), buttons)) { + e->accept (); + return true; + } + } + END_PROTECTED + + return false; + + } else { + return QWidget::event (e); + } + } + DragDropDataBase *get_drag_drop_data (const QMimeData *data) { if (! data || ! data->hasFormat (QString::fromUtf8 (drag_drop_mime_type ()))) { @@ -481,24 +512,6 @@ public: END_PROTECTED } -#if defined(HAVE_QT) - bool event (QEvent *e) - { - if (e->type () == QEvent::MaxUser) { - - // GTF probe event - // record the contents (the screenshot) as ASCII text - mp_view->gtf_probe (); - - e->accept (); - return true; - - } else { - return QWidget::event (e); - } - } -#endif - private: ViewObjectUI *mp_view; }; @@ -674,7 +687,7 @@ ViewObjectUI::realize_cursor () #endif } -void +bool ViewObjectUI::send_key_press_event (unsigned int key, unsigned int buttons) { bool done = false; @@ -685,6 +698,23 @@ ViewObjectUI::send_key_press_event (unsigned int key, unsigned int buttons) if (! done) { key_event (key, buttons); } + + return done; +} + +bool +ViewObjectUI::send_shortcut_override_event(unsigned int key, unsigned int buttons) +{ + bool done = false; + if (mp_active_service) { + done = (mp_active_service->enabled () && mp_active_service->shortcut_override_event (key, buttons)); + } + + if (! done) { + key_event (key, buttons); + } + + return done; } void diff --git a/src/laybasic/laybasic/layViewObject.h b/src/laybasic/laybasic/layViewObject.h index 6ef9b691e..2c680e268 100644 --- a/src/laybasic/laybasic/layViewObject.h +++ b/src/laybasic/laybasic/layViewObject.h @@ -125,6 +125,17 @@ public: */ virtual bool key_event (unsigned int /*key*/, unsigned int /*buttons*/) { return false; } + /** + * @brief Handler for the shortcut override event + * + * This method will be called by the ViewObjectWidget object to + * ask if a plugin wants to consume a key event. + * + * If the implementation returns true, the key is passed through "key_event". Otherwise + * it is handled by the shortcut system. + */ + virtual bool shortcut_override_event (unsigned int /*key*/, unsigned int /*buttons*/) { return false; } + #if defined(HAVE_QT) /** * @brief The drag enter event @@ -1023,7 +1034,15 @@ public: /** * @brief External entry point for key press event generation */ - void send_key_press_event (unsigned int key, unsigned int buttons); + bool send_key_press_event(unsigned int key, unsigned int buttons); + + /** + * @brief External entry point for ShortcutOverride event handling + * + * Editables may return true to indicate that they want to consume the given key + * sequence through "key_pressed" instead of being handled by Qt's shortcut system. + */ + bool send_shortcut_override_event(unsigned int key, unsigned int buttons); /** * @brief External entry point for mouse move event generation