VirtualBox

Ignore:
Timestamp:
Feb 25, 2010 12:19:22 PM (15 years ago)
Author:
vboxsync
Message:

FE/Qt4: new core: global hotkey processing

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/VBoxDefs.h

    r25583 r26790  
    116116        , ShellExecuteEventType
    117117#endif
    118         , ActivateMenuEventType
     118        , ActivateMenuEventType /* remove when new core is active */
     119        , ActivateActionEventType /* New name for new core */
    119120#if defined (Q_WS_MAC)
    120121        , ShowWindowEventType
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.cpp

    r26709 r26790  
    2525#include "UIActionsPool.h"
    2626#include "VBoxGlobal.h"
     27
     28/* Action activation event */
     29class ActivateActionEvent : public QEvent
     30{
     31public:
     32
     33    ActivateActionEvent(QAction *pAction)
     34        : QEvent((QEvent::Type)VBoxDefs::ActivateActionEventType)
     35        , m_pAction(pAction) {}
     36    QAction* action() const { return m_pAction; }
     37
     38private:
     39
     40    QAction *m_pAction;
     41};
    2742
    2843UIAction::UIAction(QObject *pParent, UIActionType type)
     
    849864}
    850865
     866bool UIActionsPool::processHotKey(const QKeySequence &key)
     867{
     868    for (int i = 0; i < m_actionsPool.size(); ++i)
     869    {
     870        UIAction *pAction = m_actionsPool.at(i);
     871        /* Skip menus/separators */
     872        if (pAction->type() == UIActionType_Menu || pAction->type() == UIActionType_Separator)
     873            continue;
     874        QString hotkey = VBoxGlobal::extractKeyFromActionText(pAction->text());
     875        if (pAction->isEnabled() && !hotkey.isEmpty())
     876        {
     877            if (key.matches(QKeySequence(hotkey)) == QKeySequence::ExactMatch)
     878            {
     879                /* We asynchronously post a special event instead of calling
     880                 * pAction->trigger() directly, to let key presses and
     881                 * releases be processed correctly by Qt first.
     882                 * Note: we assume that nobody will delete the menu item
     883                 * corresponding to the key sequence, so that the pointer to
     884                 * menu data posted along with the event will remain valid in
     885                 * the event handler, at least until the main window is closed. */
     886                QApplication::postEvent(this, new ActivateActionEvent(pAction));
     887                return true;
     888            }
     889        }
     890    }
     891
     892    return false;
     893}
     894
     895bool UIActionsPool::event(QEvent *pEvent)
     896{
     897    switch (pEvent->type())
     898    {
     899        case VBoxDefs::ActivateActionEventType:
     900        {
     901            ActivateActionEvent *pActionEvent = static_cast<ActivateActionEvent*>(pEvent);
     902            pActionEvent->action()->trigger();
     903
     904            // TODO_NEW_CORE
     905            /* The main window and its children can be destroyed at this point (if, for example, the activated menu
     906             * item closes the main window). Detect this situation to prevent calls to destroyed widgets: */
     907//            QWidgetList list = QApplication::topLevelWidgets();
     908//            bool destroyed = list.indexOf(machineWindowWrapper()->machineWindow()) < 0;
     909//            if (!destroyed && machineWindowWrapper()->machineWindow()->statusBar())
     910//                machineWindowWrapper()->machineWindow()->statusBar()->clearMessage();
     911
     912            pEvent->accept();
     913            return true;
     914        }
     915        default:
     916            break;
     917    }
     918
     919    return QObject::event(pEvent);
     920}
     921
    851922#include "UIActionsPool.moc"
    852923
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIActionsPool.h

    r26709 r26790  
    111111    UIAction* action(UIActionIndex index) const;
    112112
     113    bool processHotKey(const QKeySequence &key);
     114
     115protected:
     116
     117    bool event(QEvent *pEvent);
     118
    113119private:
    114120
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp

    r26781 r26790  
    8585# include <VBox/err.h>
    8686#endif /* defined (Q_WS_MAC) */
    87 
    88 /* Menu activation event */
    89 class ActivateMenuEvent : public QEvent
    90 {
    91 public:
    92 
    93     ActivateMenuEvent (QAction *pAction)
    94         : QEvent((QEvent::Type)VBoxDefs::ActivateMenuEventType)
    95         , m_pAction(pAction) {}
    96     QAction* action() const { return m_pAction; }
    97 
    98 private:
    99 
    100     QAction *m_pAction;
    101 };
    10287
    10388class VBoxViewport: public QWidget
     
    11021087#endif
    11031088
    1104 #if 0 // TODO: Move that to specific event handler!
    1105         case VBoxDefs::ActivateMenuEventType:
    1106         {
    1107             ActivateMenuEvent *pMenuEvent = static_cast<ActivateMenuEvent*>(pEvent);
    1108             pMenuEvent->action()->trigger();
    1109 
    1110             /* The main window and its children can be destroyed at this point (if, for example, the activated menu
    1111              * item closes the main window). Detect this situation to prevent calls to destroyed widgets: */
    1112             QWidgetList list = QApplication::topLevelWidgets();
    1113             bool destroyed = list.indexOf(machineWindowWrapper()->machineWindow()) < 0;
    1114             if (!destroyed && machineWindowWrapper()->machineWindow()->statusBar())
    1115                 machineWindowWrapper()->machineWindow()->statusBar()->clearMessage();
    1116 
    1117             return true;
    1118         }
    1119 #endif
    1120 
    11211089        case QEvent::KeyPress:
    11221090        case QEvent::KeyRelease:
     
    12461214                {
    12471215                    /* Process hot keys not processed in keyEvent() (as in case of non-alphanumeric keys): */
    1248                     processHotKey(QKeySequence (pKeyEvent->key()), machineWindowWrapper()->menuBar()->actions());
     1216                    processed = machineWindowWrapper()->machineLogic()->actionsPool()->processHotKey(QKeySequence (pKeyEvent->key()));
    12491217                }
    12501218#endif
     
    17231691                ch = 0;
    17241692            if (ch)
    1725                 processed = processHotKey(QKeySequence(Qt::UNICODE_ACCEL + QChar(ch).toUpper().unicode()),
    1726                                           machineWindowWrapper()->menuBar()->actions());
     1693                processed = machineWindowWrapper()->machineLogic()->actionsPool()->processHotKey(QKeySequence((Qt::UNICODE_ACCEL + QChar(ch).toUpper().unicode())));
    17271694        }
    17281695        delete[] list;
     
    17431710#elif defined (Q_WS_MAC)
    17441711        // TODO_NEW_CORE
    1745 //        if (pUniKey && pUniKey [0] && !pUniKey [1])
    1746 //            processed = processHotKey(QKeySequence (Qt::UNICODE_ACCEL + QChar(pUniKey[0]).toUpper().unicode()),
    1747 //                                      machineWindowWrapper()->menuBar()->actions());
     1712        if (pUniKey && pUniKey[0] && !pUniKey[1])
     1713            processed = machineWindowWrapper()->machineLogic()->actionsPool()->processHotKey(QKeySequence(Qt::UNICODE_ACCEL + QChar(pUniKey[0]).toUpper().unicode()));
    17481714
    17491715        /* Don't consider the hot key as pressed since the guest never saw
     
    28332799{
    28342800    ::memcpy(m_pressedKeysCopy, m_pressedKeys, sizeof(m_pressedKeys));
    2835 }
    2836 
    2837 bool UIMachineView::processHotKey(const QKeySequence &key, const QList<QAction*> &actions)
    2838 {
    2839     // TODO: Make it work for all modes:
    2840     foreach (QAction *pAction, actions)
    2841     {
    2842         if (QMenu *menu = pAction->menu())
    2843         {
    2844             /* Process recursively for each sub-menu */
    2845             if (processHotKey(key, menu->actions()))
    2846                 return true;
    2847         }
    2848         else
    2849         {
    2850             QString hotkey = VBoxGlobal::extractKeyFromActionText(pAction->text());
    2851             if (pAction->isEnabled() && !hotkey.isEmpty())
    2852             {
    2853                 if (key.matches(QKeySequence (hotkey)) == QKeySequence::ExactMatch)
    2854                 {
    2855                     /* We asynchronously post a special event instead of calling
    2856                      * pAction->trigger() directly, to let key presses and
    2857                      * releases be processed correctly by Qt first.
    2858                      * Note: we assume that nobody will delete the menu item
    2859                      * corresponding to the key sequence, so that the pointer to
    2860                      * menu data posted along with the event will remain valid in
    2861                      * the event handler, at least until the main window is closed. */
    2862                     QApplication::postEvent(this, new ActivateMenuEvent(pAction));
    2863                     return true;
    2864                 }
    2865             }
    2866         }
    2867     }
    2868 
    2869     return false;
    28702801}
    28712802
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h

    r26773 r26790  
    224224    void captureMouse(bool fCapture, bool fEmitSignal = true);
    225225    void saveKeyStates();
    226     bool processHotKey(const QKeySequence &key, const QList<QAction*> &data);
    227226    void releaseAllPressedKeys(bool aReleaseHostKey = true);
    228227    void sendChangedKeyStates();
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette