diff options
Diffstat (limited to 'src/kernel/qstyle.cpp')
-rw-r--r-- | src/kernel/qstyle.cpp | 391 |
1 files changed, 381 insertions, 10 deletions
diff --git a/src/kernel/qstyle.cpp b/src/kernel/qstyle.cpp index f8c0fd9..01c09d1 100644 --- a/src/kernel/qstyle.cpp +++ b/src/kernel/qstyle.cpp @@ -44,6 +44,10 @@ #include "qpainter.h" #include "qbitmap.h" #include "qpixmapcache.h" +#include "qframe.h" +#include "qlayout.h" +#include "qobjectlist.h" +#include "qwidgetlist.h" #include <limits.h> @@ -394,6 +398,10 @@ public: */ QStyle::QStyle() { + m_eventHandlerInstallationHook = NULL; + m_eventHandlerRemovalHook = NULL; + m_widgetActionRequestHook = NULL; + conditionalAcceleratorsEnabled = false; d = new QStylePrivate; } @@ -414,8 +422,6 @@ QStyle::~QStyle() style. Current supported values are Qt::WindowsStyle and Qt::MotifStyle. */ - - /*! Initializes the appearance of a widget. @@ -439,8 +445,9 @@ QStyle::~QStyle() \sa unPolish() */ -void QStyle::polish( QWidget*) -{ +void QStyle::polish( QWidget *widget ) { + QStyleControlElementData ceData = populateControlElementDataFromWidget(widget, QStyleOption()); + polish(ceData, getControlElementFlagsForObject(widget, ceData.widgetObjectTypes, QStyleOption()), widget); } /*! @@ -453,10 +460,62 @@ void QStyle::polish( QWidget*) \sa polish() */ -void QStyle::unPolish( QWidget*) -{ +void QStyle::unPolish( QWidget *widget ) { + QStyleControlElementData ceData = populateControlElementDataFromWidget(widget, QStyleOption()); + unPolish(ceData, getControlElementFlagsForObject(widget, ceData.widgetObjectTypes, QStyleOption()), widget); +} + +/*! + Initializes the appearance of a widget. + + This function is called for every widget at some point after it + has been fully created but just \e before it is shown the very + first time. + + Reasonable actions in this function might be to install a widget + event handler for the style. An example of highly unreasonable + use would be setting the geometry! With Qt 3.0's style engine + you will rarely need to write your own polish(); instead reimplement + drawItem(), drawPrimitive(), etc. + + The \a objectTypes object may provide enough information to + allow class-specific customizations. But be careful not to + hard-code things too much because new QStyle subclasses are + expected to work reasonably with all current and \e future + widgets. + + You may specify either a QWidget pointer or a custom pointer. + If a custom pointer is specified, you must be careful to intercept any event + handler installation/removal calls via setEventHandlerInstallationHook and + setEventHandlerRemovalHook. + + \sa unPolish() +*/ +void QStyle::polish( QStyleControlElementData ceData, ControlElementFlags, void *ptr ) { + if (ceData.widgetObjectTypes.contains("QWidget")) { + // Enable dynamic hide/show of accelerator shortcuts + QWidget* widget = reinterpret_cast<QWidget*>(ptr); + widget->installEventFilter(this); + } } +/*! + Undoes the initialization of a widget's appearance. + + This function is the counterpart to polish. It is called for every + polished widget when the style is dynamically changed. The former + style has to unpolish its settings before the new style can polish + them again. + + \sa polish() +*/ +void QStyle::unPolish( QStyleControlElementData ceData, ControlElementFlags, void *ptr ) { + if (ceData.widgetObjectTypes.contains("QWidget")) { + // Disable dynamic hide/show of accelerator shortcuts + QWidget* widget = reinterpret_cast<QWidget*>(ptr); + widget->installEventFilter(this); + } +} /*! \overload @@ -464,8 +523,10 @@ void QStyle::unPolish( QWidget*) \sa unPolish() */ -void QStyle::polish( QApplication*) -{ +void QStyle::polish( QApplication *app ) { + QStyleControlElementData ceData; + ceData.widgetObjectTypes = getObjectTypeListForObject(app); + applicationPolish(ceData, getControlElementFlagsForObject(app, ceData.widgetObjectTypes, QStyleOption()), app); } /*! @@ -475,8 +536,41 @@ void QStyle::polish( QApplication*) \sa polish() */ -void QStyle::unPolish( QApplication*) -{ +void QStyle::unPolish( QApplication *app ) { + QStyleControlElementData ceData; + ceData.widgetObjectTypes = getObjectTypeListForObject(app); + applicationUnPolish(ceData, getControlElementFlagsForObject(app, ceData.widgetObjectTypes, QStyleOption()), app); +} + +/*! + \overload + Late initialization of the QApplication object or other global application object. + + You may specify either a QApplication pointer or a custom pointer. + If a custom pointer is specified, you must be careful to intercept any event + handler installation/removal calls via setEventHandlerInstallationHook and + setEventHandlerRemovalHook. + + \sa unPolish() +*/ +void QStyle::applicationPolish( QStyleControlElementData, ControlElementFlags, void * ) { + // +} + +/*! + \overload + + Undoes the application polish. + + You may specify either a QApplication pointer or a custom pointer. + If a custom pointer is specified, you must be careful to intercept any event + handler installation/removal calls via setEventHandlerInstallationHook and + setEventHandlerRemovalHook. + + \sa polish() +*/ +void QStyle::applicationUnPolish( QStyleControlElementData, ControlElementFlags, void * ) { + // } /*! @@ -1958,6 +2052,283 @@ QRect QStyle::visualRect( const QRect &logical, const QRect &boundingRect ) } /*! + \fn void QStyle::installObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ); + + Intercepts events generated by \a source and sends them to \a handler via + the bool QStyle::objectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QEvent *e ) virtual method. + + \sa void QStyle::removeObjectEventHandler( QObject* source, QStyle* handler ) + \sa bool QStyle::objectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QEvent *e ) +*/ +void QStyle::installObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ) { + bool cbret = false; + if (m_eventHandlerInstallationHook) { + cbret = (*m_eventHandlerInstallationHook)(ceData, elementFlags, source, handler); + } + if (!cbret) { + if (ceData.widgetObjectTypes.contains("QObject")) { + QObject* o = reinterpret_cast<QObject*>(source); + o->installEventFilter(this); + m_objectEventSourceToHandlerMap[source] = handler; + m_objectEventSourceDataToHandlerMap[source] = ceData; + m_objectEventSourceFlagsToHandlerMap[source] = elementFlags; + } + } +} + +/*! + \fn void QStyle::removeObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ); + + Stops intercepting events generated by \a source. + + \sa void QStyle::installObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ) +*/ +void QStyle::removeObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ) { + bool cbret = false; + if (m_eventHandlerRemovalHook) { + cbret = (*m_eventHandlerRemovalHook)(ceData, elementFlags, source, handler); + } + if (!cbret) { + if (ceData.widgetObjectTypes.contains("QObject")) { + QObject* o = reinterpret_cast<QObject*>(source); + m_objectEventSourceToHandlerMap.remove(source); + m_objectEventSourceDataToHandlerMap.remove(source); + m_objectEventSourceFlagsToHandlerMap.remove(source); + o->removeEventFilter(this); + } + } +} + +/*! + \fn void QStyle::setEventHandlerInstallationHook( EventHandlerInstallationHook hook ); + + Sets a callback function \a hook which will be called whenever a new intercept request + is made via the QStyle::installObjectEventHandler method. The callback function must + use this definition: bool callbackFunction( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ). + + \sa void QStyle::installObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ) +*/ +void QStyle::setEventHandlerInstallationHook( EventHandlerInstallationHook hook ) { + m_eventHandlerInstallationHook = hook; +} + +/*! + \fn void QStyle::setEventHandlerRemovalHook( EventHandlerRemovalHook hook ); + + Sets a callback function \a hook which will be called whenever a new intercept deactivation request + is made via the QStyle::removeObjectEventHandler method. The callback function must + use this definition: bool callbackFunction( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ). + + \sa void QStyle::removeObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ) +*/ +void QStyle::setEventHandlerRemovalHook( EventHandlerRemovalHook hook ) { + m_eventHandlerRemovalHook = hook; +} + +/*! + \fn bool QStyle::objectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QEvent *e ); + + Override this virtual function to intercept events requested by a previous call to + QStyle::installObjectEventHandler. + + \sa void QStyle::installObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ) + \sa void QStyle::removeObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ) +*/ +bool QStyle::objectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QEvent *e ) { + Q_UNUSED(ceData); + Q_UNUSED(elementFlags); + Q_UNUSED(source); + Q_UNUSED(e); + return false; +} + +/*! + \fn bool QStyle::eventFilter(QObject *o, QEvent *e); + \internal +*/ +bool QStyle::eventFilter(QObject *o, QEvent *e) { + acceleratorKeypressEventMonitor(o, e); + + if (m_objectEventSourceToHandlerMap.contains(o)) { + QStyle* handler = m_objectEventSourceToHandlerMap[o]; + QStyleControlElementData ceData = m_objectEventSourceDataToHandlerMap[o]; + ControlElementFlags elementFlags = m_objectEventSourceFlagsToHandlerMap[o]; + bool ret = handler->objectEventHandler(ceData, elementFlags, o, e); + if (ret) { + return ret; + } + else { + return QObject::eventFilter(o, e); + } + } + else { + return QObject::eventFilter(o, e); + } +} + +/*! + \fn void QStyle::setWidgetActionRequestHook( WidgetActionRequestHook hook ); + + Sets a callback function \a hook which will be called whenever a new widget action request + is made via the QStyle::installObjectEventHandler method. The callback function must + use this definition: bool callbackFunction( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ). + + \sa void QStyle::installObjectEventHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, QStyle* handler ) +*/ +void QStyle::setWidgetActionRequestHook( WidgetActionRequestHook hook ) { + m_widgetActionRequestHook = hook; +} + +/*! + \fn bool widgetActionRequestHandler( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, WidgetActionRequest request ); + + Handles widget action requests. Return FALSE to continue processing in base classes, TRUE to eat the request and halt processing. +*/ +bool QStyle::widgetActionRequest( QStyleControlElementData ceData, ControlElementFlags elementFlags, void* source, WidgetActionRequest request, QStyleWidgetActionRequestData requestData ) { + bool cbret = false; + if (m_widgetActionRequestHook) { + cbret = (*m_widgetActionRequestHook)(ceData, elementFlags, source, request, requestData); + } + if (!cbret) { + if (ceData.widgetObjectTypes.contains("QWidget")) { + QWidget* widget = reinterpret_cast<QWidget*>(source); + if (request == WAR_Repaint) { + widget->repaint(FALSE); + } + else if (request == WAR_RepaintRect) { + widget->repaint(requestData.rect, FALSE); + } + else if (request == WAR_EnableMouseTracking) { + widget->setMouseTracking(TRUE); + } + else if (request == WAR_DisableMouseTracking) { + widget->setMouseTracking(FALSE); + } + else if (request == WAR_FrameSetStyle) { + QFrame* frame = dynamic_cast<QFrame*>(widget); + if (frame) { + frame->setFrameStyle(requestData.metric1); + } + } + else if (request == WAR_FrameSetLineWidth) { + QFrame* frame = dynamic_cast<QFrame*>(widget); + if (frame) { + frame->setLineWidth(requestData.metric1); + } + } + else if (request == WAR_SetLayoutMargin) { + QLayout* layout = widget->layout(); + if (layout) { + layout->setMargin(requestData.metric1); + } + } + else if (request == WAR_SetPalette) { + widget->setPalette(requestData.palette); + } + else if (request == WAR_SetBackgroundMode) { + widget->setBackgroundMode((Qt::BackgroundMode)requestData.metric1); + } + else if (request == WAR_SetFont) { + widget->setFont(requestData.font); + } + else if (request == WAR_RepaintAllAccelerators) { + QWidgetList *list = QApplication::topLevelWidgets(); + QWidgetListIt it( *list ); + QWidget * widget; + while ((widget=it.current()) != 0) { + ++it; + + QObjectList *l = widget->queryList("QWidget"); + QObjectListIt it2( *l ); + QWidget *w; + while ( (w = (QWidget*)it2.current()) != 0 ) { + ++it2; + if (w->isTopLevel() || !w->isVisible() || w->style().styleHint(SH_UnderlineAccelerator, QStyleControlElementData(), CEF_None, w)) { + l->removeRef(w); + } + } + + // Repaint all relevant widgets + it2.toFirst(); + while ( (w = (QWidget*)it2.current()) != 0 ) { + ++it2; + w->repaint(FALSE); + } + delete l; + } + delete list; + } + return true; + } + } + return true; +} + +void QStyle::acceleratorKeypressEventMonitor( QObject *o, QEvent *e ) { + // RAJA FIXME + // Also, SH_HideUnderlineAcceleratorWhenAltUp should probably be set to 1 in the QWindowsStyle::styleHint overridden method + // Additionally, the common styleHint code in TDE (that controls popupmenu settings and such via configuration files) needs to be modified to add a config option for this new style hint + + if (styleHint(SH_HideUnderlineAcceleratorWhenAltUp, QStyleControlElementData(), CEF_None, QStyleOption::Default, NULL, NULL) != 0) { + QWidget *widget = dynamic_cast<QWidget*>(o); + if (widget) { + switch(e->type()) { + case QEvent::KeyPress: + if (((QKeyEvent*)e)->key() == Key_Alt) { + conditionalAcceleratorsEnabled = true; + widgetActionRequest(QStyleControlElementData(), CEF_None, o, WAR_RepaintAllAccelerators); + } + break; + case QEvent::KeyRelease: + if (((QKeyEvent*)e)->key() == Key_Alt) { + conditionalAcceleratorsEnabled = false; + widgetActionRequest(QStyleControlElementData(), CEF_None, o, WAR_RepaintAllAccelerators); + } + break; + default: + break; + } + } + } + else { + conditionalAcceleratorsEnabled = false; + } +} + +bool QStyle::acceleratorsShown() const { + if (styleHint(SH_HideUnderlineAcceleratorWhenAltUp, QStyleControlElementData(), CEF_None, QStyleOption::Default, NULL, NULL) != 0) { + return conditionalAcceleratorsEnabled; + } + else { + return true; + } +} + +QStyleWidgetActionRequestData::QStyleWidgetActionRequestData() { + // +} +QStyleWidgetActionRequestData::QStyleWidgetActionRequestData(int param1, int param2) { + metric1 = param1; + metric2 = param2; +} + +QStyleWidgetActionRequestData::QStyleWidgetActionRequestData(QPalette param) { + palette = param; +} + +QStyleWidgetActionRequestData::QStyleWidgetActionRequestData(QFont param) { + font = param; +} + +QStyleWidgetActionRequestData::QStyleWidgetActionRequestData(QRect param) { + rect = param; +} + +QStyleWidgetActionRequestData::~QStyleWidgetActionRequestData() { + // +} + +/*! \fn int QStyle::defaultFrameWidth() const \obsolete */ |