Ignore:
Timestamp:
Mar 8, 2010, 12:52:58 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.2 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/kernel/qsoftkeymanager.cpp

    r561 r651  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4242#include "qapplication.h"
    4343#include "qevent.h"
    44 #ifdef Q_WS_S60
    45 #include "qstyle.h"
    46 #include "private/qt_s60_p.h"
    47 #endif
     44#include "qbitmap.h"
    4845#include "private/qsoftkeymanager_p.h"
    4946#include "private/qobject_p.h"
     47#include "private/qsoftkeymanager_common_p.h"
     48
     49#ifdef Q_WS_S60
     50#include "private/qsoftkeymanager_s60_p.h"
     51#endif
    5052
    5153#ifndef QT_NO_SOFTKEYMANAGER
    5254QT_BEGIN_NAMESPACE
    5355
    54 #ifdef Q_WS_S60
    55 static const int s60CommandStart = 6000;
    56 #endif
    57 
    58 class QSoftKeyManagerPrivate : public QObjectPrivate
    59 {
    60     Q_DECLARE_PUBLIC(QSoftKeyManager)
    61 
    62 public:
    63     static void updateSoftKeys_sys(const QList<QAction*> &softKeys);
    64 
    65 private:
    66     QHash<QAction*, Qt::Key> keyedActions;
    67     static QSoftKeyManager *self;
    68     static QWidget *softKeySource;
    69 };
    70 
    71 QWidget *QSoftKeyManagerPrivate::softKeySource = 0;
    7256QSoftKeyManager *QSoftKeyManagerPrivate::self = 0;
    7357
     
    10690}
    10791
    108 QSoftKeyManager::QSoftKeyManager() : QObject(*(new QSoftKeyManagerPrivate), 0)
     92QSoftKeyManager::QSoftKeyManager() :
     93#ifdef Q_WS_S60
     94    QObject(*(new QSoftKeyManagerPrivateS60), 0)
     95#else
     96    QObject(*(new QSoftKeyManagerPrivate), 0)
     97#endif
    10998{
    11099}
     
    116105    QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey;
    117106    switch (standardKey) {
     107    case MenuSoftKey: // FALL-THROUGH
     108        action->setProperty(MENU_ACTION_PROPERTY, QVariant(true)); // TODO: can be refactored away to use _q_action_menubar
    118109    case OkSoftKey:
    119110    case SelectSoftKey:
    120111    case DoneSoftKey:
    121     case MenuSoftKey:
    122112        softKeyRole = QAction::PositiveSoftKey;
    123113        break;
     
    148138}
    149139
    150 void QSoftKeyManager::cleanupHash(QObject* obj)
     140void QSoftKeyManager::cleanupHash(QObject *obj)
    151141{
    152142    Q_D(QSoftKeyManager);
     
    176166}
    177167
     168bool QSoftKeyManager::appendSoftkeys(const QWidget &source, int level)
     169{
     170    Q_D(QSoftKeyManager);
     171    bool ret = false;
     172    QList<QAction*> actions = source.actions();
     173    for (int i = 0; i < actions.count(); ++i) {
     174        if (actions.at(i)->softKeyRole() != QAction::NoSoftKey) {
     175            d->requestedSoftKeyActions.insert(level, actions.at(i));
     176            ret = true;
     177        }
     178    }
     179    return ret;
     180}
     181
     182QWidget *QSoftKeyManager::softkeySource(QWidget *previousSource, bool& recursiveMerging)
     183{
     184    Q_D(QSoftKeyManager);
     185    QWidget *source = NULL;
     186    if (!previousSource) {
     187        // Initial source is primarily focuswidget and secondarily activeWindow
     188        source = QApplication::focusWidget();
     189        if (!source)
     190            source = QApplication::activeWindow();
     191    } else {
     192        // Softkey merging is based on four criterias
     193        // 1. Implicit merging is used whenever focus widget does not specify any softkeys
     194        bool implicitMerging = d->requestedSoftKeyActions.isEmpty();
     195        // 2. Explicit merging with parent is used whenever WA_MergeSoftkeys widget attribute is set
     196        bool explicitMerging = previousSource->testAttribute(Qt::WA_MergeSoftkeys);
     197        // 3. Explicit merging with all parents
     198        recursiveMerging |= previousSource->testAttribute(Qt::WA_MergeSoftkeysRecursively);
     199        // 4. Implicit and explicit merging always stops at window boundary
     200        bool merging = (implicitMerging || explicitMerging || recursiveMerging) && !previousSource->isWindow();
     201
     202        source = merging ? previousSource->parentWidget() : NULL;
     203    }
     204    return source;
     205}
     206
     207bool QSoftKeyManager::handleUpdateSoftKeys()
     208{
     209    Q_D(QSoftKeyManager);
     210    int level = 0;
     211    d->requestedSoftKeyActions.clear();
     212    bool recursiveMerging = false;
     213    QWidget *source = softkeySource(NULL, recursiveMerging);
     214    do {
     215        if (source) {
     216            bool added = appendSoftkeys(*source, level);
     217            source = softkeySource(source, recursiveMerging);
     218            level = added ? ++level : level;
     219        }
     220    } while (source);
     221
     222    d->updateSoftKeys_sys();
     223    return true;
     224}
     225
    178226bool QSoftKeyManager::event(QEvent *e)
    179227{
    180228#ifndef QT_NO_ACTION
    181     if (e->type() == QEvent::UpdateSoftKeys) {
    182         QList<QAction*> softKeys;
    183         QWidget *source = QApplication::focusWidget();
    184         do {
    185             if (source) {
    186                 QList<QAction*> actions = source->actions();
    187                 for (int i = 0; i < actions.count(); ++i) {
    188                     if (actions.at(i)->softKeyRole() != QAction::NoSoftKey)
    189                         softKeys.append(actions.at(i));
    190                 }
    191 
    192                 QWidget *parent = source->parentWidget();
    193                 if (parent && softKeys.isEmpty() && !source->isWindow())
    194                     source = parent;
    195                 else
    196                     break;
    197             } else {
    198                 source = QApplication::activeWindow();
    199             }
    200         } while (source);
    201 
    202         QSoftKeyManagerPrivate::softKeySource = source;
    203         QSoftKeyManagerPrivate::updateSoftKeys_sys(softKeys);
    204         return true;
    205     }
     229    if (e->type() == QEvent::UpdateSoftKeys)
     230        return handleUpdateSoftKeys();
    206231#endif //QT_NO_ACTION
    207232    return false;
     
    209234
    210235#ifdef Q_WS_S60
    211 void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys)
    212 {
    213     // lets not update softkeys if s60 native dialog or menu is shown
    214     if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
    215             || CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog())
    216         return;
    217 
    218     CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer();
    219     nativeContainer->DrawableWindow()->SetOrdinalPosition(0);
    220     nativeContainer->DrawableWindow()->SetPointerCapturePriority(1); //keep softkeys available in modal dialog
    221     nativeContainer->DrawableWindow()->SetFaded(EFalse, RWindowTreeNode::EFadeIncludeChildren);
    222 
    223     int position = -1;
    224     bool needsExitButton = true;
    225     QT_TRAP_THROWING(
    226         //Using -1 instead of EAknSoftkeyEmpty to avoid flickering.
    227         nativeContainer->SetCommandL(0, -1, KNullDesC);
    228         nativeContainer->SetCommandL(2, -1, KNullDesC);
    229     );
    230 
    231     for (int index = 0; index < softkeys.count(); index++) {
    232         const QAction* softKeyAction = softkeys.at(index);
    233         switch (softKeyAction->softKeyRole()) {
    234         // Positive Actions on the LSK
    235         case QAction::PositiveSoftKey:
    236             position = 0;
    237             break;
    238         case QAction::SelectSoftKey:
    239             position = 0;
    240             break;
    241         // Negative Actions on the RSK
    242         case QAction::NegativeSoftKey:
    243             needsExitButton = false;
    244             position = 2;
    245             break;
    246         default:
    247             break;
    248         }
    249 
    250         int command = (softKeyAction->objectName().contains(QLatin1String("_q_menuSoftKeyAction")))
    251                     ? EAknSoftkeyOptions
    252                     : s60CommandStart + index;
    253 
    254         // _q_menuSoftKeyAction action is set to "invisible" and all invisible actions are by default
    255         // disabled. However we never want to dim options softkey, even it is set to "invisible"
    256         bool dimmed = (command == EAknSoftkeyOptions) ? false : !softKeyAction->isEnabled();
    257 
    258         if (position != -1) {
    259             const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut);
    260             QString iconText = softKeyAction->iconText();
    261             TPtrC text = qt_QString2TPtrC( underlineShortCut ? softKeyAction->text() : iconText);
    262             QT_TRAP_THROWING(
    263                 nativeContainer->SetCommandL(position, command, text);
    264                 nativeContainer->DimCommand(command, dimmed);
    265             );
    266         }
    267     }
    268 
    269     const Qt::WindowType sourceWindowType = QSoftKeyManagerPrivate::softKeySource
    270         ?   QSoftKeyManagerPrivate::softKeySource->window()->windowType()
    271         :   Qt::Widget;
    272 
    273     if (needsExitButton && sourceWindowType != Qt::Dialog && sourceWindowType != Qt::Popup)
    274         QT_TRAP_THROWING(
    275             nativeContainer->SetCommandL(2, EAknSoftkeyExit, qt_QString2TPtrC(QSoftKeyManager::tr("Exit"))));
    276 
    277     nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation
    278 }
    279 
    280236bool QSoftKeyManager::handleCommand(int command)
    281237{
    282     if (command >= s60CommandStart && QSoftKeyManagerPrivate::softKeySource) {
    283         int index = command - s60CommandStart;
    284         const QList<QAction*>& softKeys = QSoftKeyManagerPrivate::softKeySource->actions();
    285         for (int i = 0, j = 0; i < softKeys.count(); ++i) {
    286             QAction *action = softKeys.at(i);
    287             if (action->softKeyRole() != QAction::NoSoftKey) {
    288                 if (j == index) {
    289                     QWidget *parent = action->parentWidget();
    290                     if (parent && parent->isEnabled()) {
    291                         action->activate(QAction::Trigger);
    292                         return true;
    293                     }
    294                 }
    295                 j++;
    296             }
    297         }
    298     }
    299 
    300     return false;
    301 }
    302 
    303 #else
    304 
    305 void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &)
    306 {
    307 }
    308 
     238    return static_cast<QSoftKeyManagerPrivateS60*>(QSoftKeyManager::instance()->d_func())->handleCommand(command);
     239}
    309240#endif
    310241
Note: See TracChangeset for help on using the changeset viewer.