diff options
Diffstat (limited to 'src/gui/kernel/qwidget.cpp')
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 235 |
1 files changed, 216 insertions, 19 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 304d72a..b93bedc 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -99,6 +99,10 @@ #endif #include <private/qpaintengine_raster_p.h> +#if defined(Q_WS_S60) +#include "private/qt_s60_p.h" +#endif + #include "qwidget_p.h" #include "qaction_p.h" #include "qlayout_p.h" @@ -212,6 +216,7 @@ QWidgetPrivate::QWidgetPrivate(int version) , window_event(0) , qd_hd(0) #endif + ,imHints(Qt::ImhNone) { if (!qApp) { qFatal("QWidget: Must construct a QApplication before a QPaintDevice"); @@ -402,6 +407,7 @@ void QWidget::setEditFocus(bool on) QApplication::sendEvent(f, &event); QApplication::sendEvent(f->style(), &event); } + f->repaint(); // Widget might want to repaint a focus indicator } #endif @@ -890,6 +896,30 @@ void QWidget::setAutoFillBackground(bool enabled) \endlist \sa QEvent, QPainter, QGridLayout, QBoxLayout + + \section1 SoftKeys + \since 4.6 + \preliminary + + Softkeys API is a platform independent way of mapping actions to (hardware)keys + and toolbars provided by the underlying platform. + + There are three major use cases supported. First one is a mobile device + with keypad navigation and no touch ui. Second use case is a mobile + device with touch ui. Third use case is desktop. For now the softkey API is + only implemented for Series60. + + QActions are set to widget(s) via softkey API. Actions in focused widget are + mapped to native toolbar or hardware keys. Even though the API allows to set + any amount of widgets there might be physical restrictions to amount of + softkeys that can be used by the device. + + \o Series60: For series60 menu button is automatically mapped to left + soft key if there is QMainWindow with QMenuBar in widgets parent hierarchy. + + \sa softKeys() + \sa setSoftKey() + */ QWidgetMapper *QWidgetPrivate::mapper = 0; // widget with wid @@ -933,6 +963,23 @@ QRegion qt_dirtyRegion(QWidget *widget) \endlist */ +struct QWidgetExceptionCleaner +{ + /* this cleans up when the constructor throws an exception */ + static inline void cleanup(QWidget *that, QWidgetPrivate *d) + { +#ifndef QT_NO_EXCEPTIONS + QWidgetPrivate::uncreatedWidgets->remove(that); + if (d->focus_next != that) { + if (d->focus_next) + d->focus_next->d_func()->focus_prev = d->focus_prev; + if (d->focus_prev) + d->focus_prev->d_func()->focus_next = d->focus_next; + } +#endif + } +}; + /*! Constructs a widget which is a child of \a parent, with widget flags set to \a f. @@ -962,7 +1009,12 @@ QRegion qt_dirtyRegion(QWidget *widget) QWidget::QWidget(QWidget *parent, Qt::WindowFlags f) : QObject(*new QWidgetPrivate, 0), QPaintDevice() { - d_func()->init(parent, f); + QT_TRY { + d_func()->init(parent, f); + } QT_CATCH(...) { + QWidgetExceptionCleaner::cleanup(this, d_func()); + QT_RETHROW; + } } #ifdef QT3_SUPPORT @@ -973,8 +1025,13 @@ QWidget::QWidget(QWidget *parent, Qt::WindowFlags f) QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f) : QObject(*new QWidgetPrivate, 0), QPaintDevice() { - d_func()->init(parent , f); - setObjectName(QString::fromAscii(name)); + QT_TRY { + d_func()->init(parent , f); + setObjectName(QString::fromAscii(name)); + } QT_CATCH(...) { + QWidgetExceptionCleaner::cleanup(this, d_func()); + QT_RETHROW; + } } #endif @@ -983,7 +1040,13 @@ QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f) QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f) : QObject(dd, 0), QPaintDevice() { - d_func()->init(parent, f); + Q_D(QWidget); + QT_TRY { + d->init(parent, f); + } QT_CATCH(...) { + QWidgetExceptionCleaner::cleanup(this, d_func()); + QT_RETHROW; + } } /*! @@ -1265,7 +1328,7 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) d->create_sys(window, initializeWindow, destroyOldWindow); // a real toplevel window needs a backing store - if (isWindow()) { + if (isWindow() && windowType() != Qt::Desktop) { delete d->topData()->backingStore; // QWidgetBackingStore will check this variable, hence it must be 0 d->topData()->backingStore = 0; @@ -1933,6 +1996,9 @@ void QWidgetPrivate::setOpaque(bool opaque) #ifdef Q_WS_WIN winUpdateIsOpaque(); #endif +#ifdef Q_WS_S60 + s60UpdateIsOpaque(); +#endif } void QWidgetPrivate::updateIsTranslucent() @@ -1946,6 +2012,9 @@ void QWidgetPrivate::updateIsTranslucent() #ifdef Q_WS_WIN winUpdateIsOpaque(); #endif +#ifdef Q_WS_S60 + s60UpdateIsOpaque(); +#endif } /*! @@ -1981,11 +2050,19 @@ static inline void fillRegion(QPainter *painter, const QRegion &rgn, const QPoin extern void qt_mac_fill_background(QPainter *painter, const QRegion &rgn, const QPoint &offset, const QBrush &brush); qt_mac_fill_background(painter, rgn, offset, brush); #else - const QRegion translated = rgn.translated(offset); - const QRect rect(translated.boundingRect()); - painter->setClipRegion(translated); - painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); -#endif +#if !defined(QT_NO_STYLE_S60) + // Defined in qs60style.cpp + extern bool qt_s60_fill_background(QPainter *painter, const QRegion &rgn, + const QPoint &offset, const QBrush &brush); + if (!qt_s60_fill_background(painter, rgn, offset, brush)) +#endif // !defined(QT_NO_STYLE_S60) + { + const QRegion translated = rgn.translated(offset); + const QRect rect(translated.boundingRect()); + painter->setClipRegion(translated); + painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft()); + } +#endif // Q_WS_MAC } else { const QVector<QRect> &rects = rgn.rects(); for (int i = 0; i < rects.size(); ++i) @@ -2007,6 +2084,7 @@ void QWidgetPrivate::paintBackground(QPainter *painter, const QRegion &rgn, cons painter->setCompositionMode(QPainter::CompositionMode_Source); //copy alpha straight in #endif fillRegion(painter, rgn, offset, bg); + } if (q->autoFillBackground()) @@ -2558,7 +2636,7 @@ bool QWidget::isMaximized() const */ Qt::WindowStates QWidget::windowState() const { - return (Qt::WindowStates)data->window_state; + return Qt::WindowStates(data->window_state); } /*!\internal @@ -2570,7 +2648,7 @@ Qt::WindowStates QWidget::windowState() const */ void QWidget::overrideWindowState(Qt::WindowStates newstate) { - QWindowStateChangeEvent e((Qt::WindowStates)data->window_state, true); + QWindowStateChangeEvent e(Qt::WindowStates(data->window_state), true); data->window_state = newstate; QApplication::sendEvent(this, &e); } @@ -4810,6 +4888,13 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, d->extra->inRenderWithPainter = false; } +#if !defined(Q_WS_S60) +void QWidgetPrivate::setSoftKeys_sys(const QList<QAction*> &softkeys) +{ + Q_UNUSED(softkeys) +} +#endif // !defined(Q_WS_S60) + bool QWidgetPrivate::isAboutToShow() const { if (data.in_show) @@ -4998,7 +5083,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP #ifndef QT_NO_SCROLLAREA QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(parent); if (scrollArea && scrollArea->viewport() == q) { - QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr; + QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data(); QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate); scrollAreaOffset = priv->contentsOffset(); p.translate(-scrollAreaOffset); @@ -5645,9 +5730,11 @@ bool QWidget::hasFocus() const void QWidget::setFocus(Qt::FocusReason reason) { + Q_D(QWidget); + if (!isEnabled()) return; - + QWidget *f = this; while (f->d_func()->extra && f->d_func()->extra->focus_proxy) f = f->d_func()->extra->focus_proxy; @@ -6703,7 +6790,7 @@ void QWidgetPrivate::show_helper() // On Windows, show the popup now so that our own focus handling // stores the correct old focus widget even if it's stolen in the // showevent -#if defined(Q_WS_WIN) || defined(Q_WS_MAC) +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_WS_S60) if (!isEmbedded && q->windowType() == Qt::Popup) qApp->d_func()->openPopup(q); #endif @@ -6720,7 +6807,7 @@ void QWidgetPrivate::show_helper() show_sys(); -#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC) +#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_WS_S60) if (!isEmbedded && q->windowType() == Qt::Popup) qApp->d_func()->openPopup(q); #endif @@ -7290,7 +7377,7 @@ QSize QWidgetPrivate::adjustedSize() const #else // all others QRect screen = QApplication::desktop()->screenGeometry(q->pos()); #endif -#if defined (Q_WS_WINCE) +#if defined (Q_WS_WINCE) || defined (Q_OS_SYMBIAN) s.setWidth(qMin(s.width(), screen.width())); s.setHeight(qMin(s.height(), screen.height())); #else @@ -7602,6 +7689,7 @@ bool QWidget::event(QEvent *event) } break; case QEvent::FocusIn: + d->setSoftKeys_sys(softKeys()); focusInEvent((QFocusEvent*)event); break; @@ -7751,6 +7839,10 @@ bool QWidget::event(QEvent *event) if (w && w->isVisible() && !w->isWindow()) QApplication::sendEvent(w, event); } + + if (isWindow() && isActiveWindow()) + d->setSoftKeys_sys(softKeys()); + break; } case QEvent::LanguageChange: @@ -8466,7 +8558,7 @@ void QWidget::inputMethodEvent(QInputMethodEvent *event) \a query specifies which property is queried. - \sa inputMethodEvent(), QInputMethodEvent, QInputContext + \sa inputMethodEvent(), QInputMethodEvent, QInputContext, inputMethodHints */ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const { @@ -8475,11 +8567,54 @@ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const return QRect(width()/2, 0, 1, height()); case Qt::ImFont: return font(); + case Qt::ImAnchorPosition: + // Fallback. + return inputMethodQuery(Qt::ImCursorPosition); default: return QVariant(); } } +/*! + \property QWidget::inputMethodHints + \brief What input method specific hints the widget has. + + This is only relevant for input widgets. It is used by + the input method to retrieve hints as to how the input method + should operate. For example, if the Qt::ImhFormattedNumbersOnly flag + is set, the input method may change its visual components to reflect + that only numbers can be entered. + + \note The flags are only hints, so the particular input method + implementation is free to ignore them. If you want to be + sure that a certain type of characters are entered, + you should also set a QValidator on the widget. + + The default value is Qt::ImhNone. + + \since 4.6 + + \sa inputMethodQuery(), QInputContext +*/ +Qt::InputMethodHints QWidget::inputMethodHints() const +{ + Q_D(const QWidget); + return d->imHints; +} + +void QWidget::setInputMethodHints(Qt::InputMethodHints hints) +{ + Q_D(QWidget); + d->imHints = hints; + // Optimisation to update input context only it has already been created. + if (d->ic || qApp->d_func()->inputContext) { + QInputContext *ic = inputContext(); + if (ic) + ic->update(); + } +} + + #ifndef QT_NO_DRAGANDDROP /*! @@ -10289,7 +10424,7 @@ void QWidget::setShortcutAutoRepeat(int id, bool enable) */ void QWidget::updateMicroFocus() { -#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS)) +#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_S60)) Q_D(QWidget); // and optimisation to update input context only it has already been created. if (d->ic || qApp->d_func()->inputContext) { @@ -11520,6 +11655,68 @@ void QWidget::clearMask() setMask(QRegion()); } +/*! + \preliminary + \since 4.6 + + Returns the (possibly empty) list of this widget's softkeys. + Returned list cannot be changed. Softkeys should be added + and removed via method called setSoftKeys + + \sa setSoftKey(), setSoftKeys() +*/ +const QList<QAction*>& QWidget::softKeys() const +{ + Q_D(const QWidget); + if( d->softKeys.count() > 0) + return d->softKeys; + if (isWindow() || !parentWidget()) + return d->softKeys; + + return parentWidget()->softKeys(); +} + +/*! + \preliminary + \since 4.6 + + Sets the softkey \a softkey to this widget's list of softkeys, + Setting 0 as softkey will clear all the existing softkeys set + to the widget + A QWidget can have 0 or more softkeys + + \sa softKeys(), setSoftKeys() +*/ +void QWidget::setSoftKey(QAction *softKey) +{ + Q_D(QWidget); + qDeleteAll(d->softKeys); + d->softKeys.clear(); + if (softKey) + d->softKeys.append(softKey); + if ((!QApplication::focusWidget() && this == QApplication::activeWindow()) + || QApplication::focusWidget() == this) + d->setSoftKeys_sys(this->softKeys()); +} + +/*! + Sets the list of softkeys \a softkeys to this widget's list of softkeys, + A QWidget can have 0 or more softkeys + + \sa softKeys(), setSoftKey() +*/ +void QWidget::setSoftKeys(const QList<QAction*> &softKeys) +{ + Q_D(QWidget); + qDeleteAll(d->softKeys); + d->softKeys.clear(); + d->softKeys = softKeys; + + if ((!QApplication::focusWidget() && this == QApplication::activeWindow()) + || QApplication::focusWidget() == this) + d->setSoftKeys_sys(this->softKeys()); +} + /*! \fn const QX11Info &QWidget::x11Info() const Returns information about the configuration of the X display used to display the widget. |