diff options
author | aavit <qt-info@nokia.com> | 2010-03-08 11:02:55 (GMT) |
---|---|---|
committer | aavit <qt-info@nokia.com> | 2010-03-08 11:02:55 (GMT) |
commit | f06bc0b434953ba05d822cc1500e5d490c8f629d (patch) | |
tree | 1f6d8b036c4d6ac2e855a04f024fa27570d81769 /src/gui | |
parent | 6f17a21647fe50ea79dd902220c1887b893f25b3 (diff) | |
parent | d2d519f72433d70c342ed4cf0827a10ab0cdfdad (diff) | |
download | Qt-f06bc0b434953ba05d822cc1500e5d490c8f629d.zip Qt-f06bc0b434953ba05d822cc1500e5d490c8f629d.tar.gz Qt-f06bc0b434953ba05d822cc1500e5d490c8f629d.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7
Diffstat (limited to 'src/gui')
36 files changed, 704 insertions, 290 deletions
diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index ffb45aa..f500bd4 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -97,10 +97,14 @@ QT_END_INCLUDE_NAMESPACE #include <QtGui/qpaintdevice.h> +#include <QFlags> + QT_BEGIN_NAMESPACE #define QEGL_NO_CONFIG ((EGLConfig)-1) + + class QEglProperties; namespace QEgl { @@ -116,12 +120,14 @@ namespace QEgl { BestPixelFormat }; - enum ConfigOptions + enum ConfigOption { NoOptions = 0, Translucent = 0x01, Renderable = 0x02 // Config will be compatable with the paint engines (VG or GL) }; + Q_DECLARE_FLAGS(ConfigOptions, ConfigOption); + // Most of the time we use the same config for things like widgets & pixmaps, so rather than // go through the eglChooseConfig loop every time, we use defaultConfig, which will return @@ -153,6 +159,7 @@ namespace QEgl { #endif }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QEgl::ConfigOptions); QT_END_NAMESPACE diff --git a/src/gui/egl/qegl_wince.cpp b/src/gui/egl/qegl_wince.cpp index c07b20b..2d08805 100644 --- a/src/gui/egl/qegl_wince.cpp +++ b/src/gui/egl/qegl_wince.cpp @@ -53,8 +53,7 @@ QT_BEGIN_NAMESPACE EGLNativeDisplayType QEgl::nativeDisplay() { - HWND win = (static_cast<QWidget*>(device))->winId(); - HDC myDc = GetDC(win); + HDC myDc = GetDC(0); if (!myDc) { qWarning("QEglContext::nativeDisplay(): WinCE display is not open"); return EGL_DEFAULT_DISPLAY; diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 483c01d..53c4711 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -41,18 +41,19 @@ #include <QtCore/qdebug.h> -#include <private/qt_x11_p.h> +#include <QtGui/private/qt_x11_p.h> #include <QtGui/qx11info_x11.h> -#include <private/qpixmapdata_p.h> -#include <private/qpixmap_x11_p.h> +#include <QtGui/private/qpixmapdata_p.h> +#include <QtGui/private/qpixmap_x11_p.h> +#include <QtGui/private/qimagepixmapcleanuphooks_p.h> #include <QtGui/qpaintdevice.h> #include <QtGui/qpixmap.h> #include <QtGui/qwidget.h> #include <QtGui/qcolormap.h> -#include "qegl_p.h" -#include "qeglcontext_p.h" +#include "QtGui/private/qegl_p.h" +#include "QtGui/private/qeglcontext_p.h" QT_BEGIN_NAMESPACE @@ -404,9 +405,12 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg else surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); - return eglCreatePixmapSurface(QEgl::display(), config, - (EGLNativePixmapType) x11PixmapData->handle(), - surfaceAttribs.properties()); + EGLSurface surf = eglCreatePixmapSurface(QEgl::display(), config, + (EGLNativePixmapType) x11PixmapData->handle(), + surfaceAttribs.properties()); + x11PixmapData->gl_surface = (Qt::HANDLE)surf; + QImagePixmapCleanupHooks::enableCleanupHooks(x11PixmapData); + return surf; } return EGL_NO_SURFACE; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index d72833b..56f94a2 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -540,10 +540,10 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity NOTIFY opacityChanged FINAL) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged FINAL) - Q_PROPERTY(QPointF pos READ pos WRITE setPos) - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) - Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) - Q_PROPERTY(qreal z READ zValue WRITE setZValue NOTIFY zChanged) + Q_PROPERTY(QPointF pos READ pos WRITE setPos FINAL) + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged FINAL) + Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged FINAL) + Q_PROPERTY(qreal z READ zValue WRITE setZValue NOTIFY zChanged FINAL) Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 365afdd..6bc02cc 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5972,12 +5972,12 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) QList<QGesture *> allGestures = event->gestures(); DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" - << "Delivering gestures:" << allGestures; + << "Gestures:" << allGestures; QSet<QGesture *> startedGestures; - QPoint delta = graphicsView->mapFromGlobal(QPoint()); - QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y()) - * graphicsView->viewportTransform().inverted(); + QPoint delta = viewport->mapFromGlobal(QPoint()); + QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y()) + * graphicsView->viewportTransform().inverted(); foreach (QGesture *gesture, allGestures) { // cache scene coordinates of the hot spot if (gesture->hasHotSpot()) { @@ -6003,7 +6003,8 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) cachedTargetItems = cachedItemGestures.keys(); qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" - << "Conflicting gestures:" << conflictedGestures; + << "Normal gestures:" << normalGestures + << "Conflicting gestures:" << conflictedGestures; // deliver conflicted gestures as override events AND remember // initial gesture targets @@ -6080,6 +6081,10 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType()); if (flags & Qt::IgnoredGesturesPropagateToParent) parentPropagatedGestures.insert(gesture); + } else { + DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" + << "no target for" << gesture << "at" + << gesture->hotSpot() << gesture->d_func()->sceneHotSpot; } } qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 4ec2ae2..fea8c37 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -498,9 +498,7 @@ inline bool QApplicationPrivate::isAlien(QWidget *widget) { if (!widget) return false; -#if defined(Q_WS_MAC) // Fake alien behavior on the Mac :) - return !widget->isWindow() && widget->window()->testAttribute(Qt::WA_DontShowOnScreen); -#elif defined(Q_WS_QWS) +#if defined(Q_WS_QWS) return !widget->isWindow() # ifdef Q_BACKINGSTORE_SUBSURFACES && !(widget->d_func()->maybeTopData() && widget->d_func()->maybeTopData()->windowSurface) @@ -2311,6 +2309,19 @@ static bool qt_detectRTLLanguage() " languages or to 'RTL' in right-to-left languages (such as Hebrew" " and Arabic) to get proper widget layout.") == QLatin1String("RTL")); } +#if defined(QT_MAC_USE_COCOA) +static const char *application_menu_strings[] = { + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Services"), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide %1"), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Hide Others"), + QT_TRANSLATE_NOOP("MAC_APPLICATION_MENU","Show All") + }; +QString qt_mac_applicationmenu_string(int type) +{ + return qApp->translate("MAC_APPLICATION_MENU", + application_menu_strings[type]); +} +#endif #endif /*!\reimp @@ -2339,6 +2350,9 @@ bool QApplication::event(QEvent *e) #ifndef QT_NO_TRANSLATION setLayoutDirection(qt_detectRTLLanguage()?Qt::RightToLeft:Qt::LeftToRight); #endif +#if defined(QT_MAC_USE_COCOA) + qt_mac_post_retranslateAppMenu(); +#endif QWidgetList list = topLevelWidgets(); for (int i = 0; i < list.size(); ++i) { QWidget *w = list.at(i); @@ -3013,7 +3027,7 @@ bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event, return result; } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_MAC) /* This function should only be called when the widget changes visibility, i.e. when the \a widget is shown, hidden or deleted. This function does nothing @@ -3073,7 +3087,7 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget) sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver); #endif // QT_NO_CURSOR } -#endif // Q_WS_WIN || Q_WS_X11 +#endif // Q_WS_WIN || Q_WS_X11 || Q_WS_MAC /*! Returns the desktop widget (also called the root window). diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index babfc72..c7d0e48 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -184,7 +184,8 @@ bool qt_mac_app_fullscreen = false; bool qt_scrollbar_jump_to_pos = false; static bool qt_mac_collapse_on_dblclick = true; extern int qt_antialiasing_threshold; // from qapplication.cpp -QPointer<QWidget> qt_button_down; // widget got last button-down +QWidget * qt_button_down; // widget got last button-down +QPointer<QWidget> qt_last_mouse_receiver; #ifndef QT_MAC_USE_COCOA static bool qt_button_down_in_content; // whether the button_down was in the content area. static bool qt_mac_previous_press_in_popup_mode = false; diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index e0a6103..8653dec 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -514,7 +514,7 @@ public: int symbianResourceChange(const QSymbianEvent *symbianEvent); #endif -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) void sendSyntheticEnterLeave(QWidget *widget); #endif diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index a59bb98..f7c0b6e 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -107,6 +107,12 @@ QT_BEGIN_NAMESPACE store or retrieve the clipboard contents in response to timer or non-user-input events. + \i Since there is no standard way to copy and paste files between + applications on X11, various MIME types and conventions are currently + in use. For instance, Nautilus expects files to be supplied with a + \c{x-special/gnome-copied-files} MIME type with data beginning with + the cut/copy action, a newline character, and the URL of the file. + \endlist \section1 Notes for Mac OS X Users diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 573b763..35d156a 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -48,6 +48,7 @@ #include <private/qt_mac_p.h> #include <private/qmenubar_p.h> #include <qmenubar.h> +#include <private/qt_cocoa_helpers_mac_p.h> QT_FORWARD_DECLARE_CLASS(QCFString) QT_FORWARD_DECLARE_CLASS(QString) @@ -58,6 +59,10 @@ QT_USE_NAMESPACE - (void)awakeFromNib { + servicesItem = [[appMenu itemWithTitle:@"Services"] retain]; + hideAllOthersItem = [[appMenu itemWithTitle:@"Hide Others"] retain]; + showAllItem = [[appMenu itemWithTitle:@"Show All"] retain]; + // Get the names in the nib to match the app name set by Qt. NSString *appName = reinterpret_cast<const NSString*>(QCFString::toCFStringRef(qAppName())); [quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication" @@ -119,6 +124,10 @@ QT_USE_NAMESPACE - (void)dealloc { + [servicesItem release]; + [hideAllOthersItem release]; + [showAllItem release]; + [lastAppSpecificItem release]; [theMenu release]; [appMenu release]; @@ -214,6 +223,17 @@ QT_USE_NAMESPACE QMenuBarPrivate::macUpdateMenuBarImmediatly(); } +- (void)qtTranslateApplicationMenu +{ +#ifndef QT_NO_TRANSLATION + extern QString qt_mac_applicationmenu_string(int type); + [servicesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(0))]; + [hideItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(1).arg(qAppName()))]; + [hideAllOthersItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(2))]; + [showAllItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(3))]; +#endif +} + - (IBAction)qtDispatcherToQAction:(id)sender { QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData); diff --git a/src/gui/kernel/qcocoamenuloader_mac_p.h b/src/gui/kernel/qcocoamenuloader_mac_p.h index 2504b8c..a75ad0a 100644 --- a/src/gui/kernel/qcocoamenuloader_mac_p.h +++ b/src/gui/kernel/qcocoamenuloader_mac_p.h @@ -67,7 +67,9 @@ IBOutlet NSMenuItem *aboutQtItem; IBOutlet NSMenuItem *hideItem; NSMenuItem *lastAppSpecificItem; - + NSMenuItem *servicesItem; + NSMenuItem *hideAllOthersItem; + NSMenuItem *showAllItem; } - (void)ensureAppMenuInMenu:(NSMenu *)menu; - (void)removeActionsFromAppMenu; diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 6a16403..f7cb21f 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -185,6 +185,9 @@ extern "C" { extern NSString *NSTextInputReplacementRangeAttributeName; } +#ifdef ALIEN_DEBUG +static int qCocoaViewCount = 0; +#endif @implementation QT_MANGLE_NAMESPACE(QCocoaView) @@ -195,6 +198,12 @@ extern "C" { [self finishInitWithQWidget:widget widgetPrivate:widgetprivate]; } composingText = new QString(); + +#ifdef ALIEN_DEBUG + ++qCocoaViewCount; + qDebug() << "init: qCocoaViewCount is" << qCocoaViewCount; +#endif + composing = false; sendKeyEvents = true; [self setHidden:YES]; @@ -414,6 +423,12 @@ extern "C" { { delete composingText; [[NSNotificationCenter defaultCenter] removeObserver:self]; + +#ifdef ALIEN_DEBUG + --qCocoaViewCount; + qDebug() << "qCocoaViewCount is" << qCocoaViewCount; +#endif + [super dealloc]; } @@ -523,6 +538,10 @@ extern "C" { CGContextClearRect(cg, NSRectToCGRect(aRect)); } + // Check for alien widgets, use qwidgetPrivate->drawWidget() to draw the widget if this + // is the case. This makes sure child widgets are drawn as well, Cocoa does not know about + // those and wont send them drawRect calls. + if (qwidget->testAttribute(Qt::WA_NativeWindow) && qt_widget_private(qwidget)->hasAlienChildren == false) { if (engine && !qwidget->testAttribute(Qt::WA_NoSystemBackground) && (qwidget->isWindow() || qwidget->autoFillBackground()) || qwidget->testAttribute(Qt::WA_TintedBackground) @@ -542,6 +561,12 @@ extern "C" { e.setErased(true); #endif qt_sendSpontaneousEvent(qwidget, &e); + } else { + qwidget->setAttribute(Qt::WA_WState_InPaintEvent, false); // QWidgetPrivate::drawWidget sets this + QWidgetPrivate *qwidgetPrivate = qt_widget_private(qwidget); + qwidgetPrivate->drawWidget(qwidget, qrgn, QPoint(), QWidgetPrivate::DrawAsRoot | QWidgetPrivate::DrawPaintOnScreen | QWidgetPrivate::DrawRecursive, 0); + } + if (!redirectionOffset.isNull()) QPainter::restoreRedirected(qwidget); if (engine) @@ -1003,7 +1028,10 @@ extern "C" { { if (!qwidget) return NO; - if (qwidget->isWindow()) + // Before accepting the focus for a window, we check that + // the focusWidget (if any) is not contained in the same window. + if (qwidget->isWindow() && (!qApp->focusWidget() + || qApp->focusWidget()->window() != qwidget)) return YES; // Always do it, so that windows can accept key press events. return qwidget->focusPolicy() != Qt::NoFocus; } diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index c776b2a..3fbd978 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -139,7 +139,7 @@ void QMacWindowFader::performFade() extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); // qapplication.cpp; extern QWidget * mac_mouse_grabber; -extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp +extern QWidget *qt_button_down; //qapplication_mac.cpp void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds) { @@ -686,6 +686,12 @@ bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEve if ([event type] == NSKeyDown) { qt_keymapper_private()->updateKeyMap(0, key_event, 0); } + + // Redirect keys to alien widgets. + if (widgetToGetEvent->testAttribute(Qt::WA_NativeWindow) == false) { + widgetToGetEvent = qApp->focusWidget(); + } + if (widgetToGetEvent == 0) return false; @@ -940,7 +946,7 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev [static_cast<QT_MANGLE_NAMESPACE(QCocoaView) *>(tmpView) qt_qwidget]; } } else { - extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp + extern QWidget * qt_button_down; //qapplication_mac.cpp QPoint pos; widgetToGetMouse = QApplicationPrivate::pickMouseReceiver(qwidget, qglobalPoint, pos, eventType, @@ -952,7 +958,20 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev return false; NSPoint localPoint = [tmpView convertPoint:windowPoint fromView:nil]; - QPoint qlocalPoint(localPoint.x, localPoint.y); + QPoint qlocalPoint = QPoint(localPoint.x, localPoint.y); + + // Search for alien child widgets (either on this qwidget or on the popup) + if (widgetToGetMouse->testAttribute(Qt::WA_NativeWindow) == false || qt_widget_private(widgetToGetMouse)->hasAlienChildren) { + QPoint qScreenPoint = flipPoint(globalPoint).toPoint(); +#ifdef ALIEN_DEBUG + qDebug() << "alien mouse event" << qScreenPoint << possibleAlien; +#endif + QWidget *possibleAlien = widgetToGetMouse->childAt(qlocalPoint); + if (possibleAlien) { + qlocalPoint = possibleAlien->mapFromGlobal(widgetToGetMouse->mapToGlobal(qlocalPoint)); + widgetToGetMouse = possibleAlien; + } + } EventRef carbonEvent = static_cast<EventRef>(const_cast<void *>([theEvent eventRef])); if (qt_mac_sendMacEventToWidget(widgetToGetMouse, carbonEvent)) @@ -997,7 +1016,19 @@ bool qt_mac_handleMouseEvent(void * /* NSView * */view, void * /* NSEvent * */ev } [QT_MANGLE_NAMESPACE(QCocoaView) currentMouseEvent]->localPoint = localPoint; QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods); - qt_sendSpontaneousEvent(widgetToGetMouse, &qme); + +#ifdef ALIEN_DEBUG + qDebug() << "sending mouse event to" << widgetToGetMouse; +#endif + extern QWidget *qt_button_down; + extern QPointer<QWidget> qt_last_mouse_receiver; + + if (qwidget->testAttribute(Qt::WA_NativeWindow) && qt_widget_private(qwidget)->hasAlienChildren == false) + qt_sendSpontaneousEvent(widgetToGetMouse, &qme); + else + QApplicationPrivate::sendMouseEvent(widgetToGetMouse, &qme, widgetToGetMouse, qwidget, &qt_button_down, + qt_last_mouse_receiver); + if (eventType == QEvent::MouseButtonPress && button == Qt::RightButton) { QContextMenuEvent qcme(QContextMenuEvent::Mouse, qlocalPoint, qglobalPoint, keyMods); qt_sendSpontaneousEvent(widgetToGetMouse, &qcme); @@ -1355,4 +1386,12 @@ QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool() [(NSAutoreleasePool*)pool release]; } +void qt_mac_post_retranslateAppMenu() +{ +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + qt_cocoaPostMessage([NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)], @selector(qtTranslateApplicationMenu)); +#endif +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index c43ea55..3fd62a4 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -208,4 +208,6 @@ bool qt_cocoaPostMessage(id target, SEL selector); #endif +void qt_mac_post_retranslateAppMenu(); + QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index aa5d259..ed9d5de 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -205,6 +205,7 @@ QWidgetPrivate::QWidgetPrivate(int version) , nativeGesturePanEnabled(0) #elif defined(Q_WS_MAC) , needWindowChange(0) + , hasAlienChildren(0) , window_event(0) , qd_hd(0) #endif @@ -1121,7 +1122,8 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) qFatal("QWidget: Cannot create a QWidget when no GUI is being used"); Q_ASSERT(allWidgets); - allWidgets->insert(q); + if (allWidgets) + allWidgets->insert(q); QWidget *desktopWidget = 0; if (parentWidget && parentWidget->windowType() == Qt::Desktop) { @@ -1168,6 +1170,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) if (f & Qt::MSWindowsOwnDC) q->setAttribute(Qt::WA_NativeWindow); +#ifdef Q_WS_MAC + q->setAttribute(Qt::WA_NativeWindow); +#endif + q->setAttribute(Qt::WA_QuitOnClose); // might be cleared in adjustQuitOnCloseAttribute() adjustQuitOnCloseAttribute(); @@ -1263,6 +1269,10 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) } if (QWidget *parent = parentWidget()) { +#ifdef Q_WS_MAC + if (testAttribute(Qt::WA_NativeWindow) == false) + parent->d_func()->hasAlienChildren = true; +#endif if (type & Qt::Window) { if (!parent->testAttribute(Qt::WA_WState_Created)) parent->createWinId(); @@ -1433,7 +1443,7 @@ QWidget::~QWidget() } } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) else if (!internalWinId() && isVisible()) { qApp->d_func()->sendSyntheticEnterLeave(this); #ifdef Q_WS_QWS @@ -2306,6 +2316,9 @@ QWidget *QWidget::find(WId id) WId QWidget::winId() const { if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) { +#ifdef ALIEN_DEBUG + qDebug() << "QWidget::winId: creating native window for" << this; +#endif QWidget *that = const_cast<QWidget*>(this); that->setAttribute(Qt::WA_NativeWindow); that->d_func()->createWinId(); @@ -2318,6 +2331,10 @@ WId QWidget::winId() const void QWidgetPrivate::createWinId(WId winid) { Q_Q(QWidget); + +#ifdef ALIEN_DEBUG + qDebug() << "QWidgetPrivate::createWinId for" << q << winid; +#endif const bool forceNativeWindow = q->testAttribute(Qt::WA_NativeWindow); if (!q->testAttribute(Qt::WA_WState_Created) || (forceNativeWindow && !q->internalWinId())) { if (!q->isWindow()) { @@ -2360,6 +2377,9 @@ Ensures that the widget has a window system identifier, i.e. that it is known to void QWidget::createWinId() { Q_D(QWidget); +#ifdef ALIEN_DEBUG + qDebug() << "QWidget::createWinId" << this; +#endif // qWarning("QWidget::createWinId is obsolete, please fix your code."); d->createWinId(); } @@ -5249,7 +5269,15 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP QPaintEngine *paintEngine = pdev->paintEngine(); if (paintEngine) { setRedirected(pdev, -offset); +#ifdef Q_WS_MAC + // (Alien support) Special case for Mac when redirecting: If the paint device + // is of the Widget type we need to set WA_WState_InPaintEvent since painting + // outside the paint event is not supported on QWidgets. The attributeis + // restored further down. + if (pdev->devType() == QInternal::Widget) + static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent); +#endif if (sharedPainter) paintEngine->d_func()->systemClip = toBePainted; else @@ -5290,6 +5318,10 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP //restore if (paintEngine) { +#ifdef Q_WS_MAC + if (pdev->devType() == QInternal::Widget) + static_cast<QWidget *>(pdev)->setAttribute(Qt::WA_WState_InPaintEvent, false); +#endif restoreRedirected(); if (!sharedPainter) paintEngine->d_func()->systemRect = QRect(); @@ -6468,7 +6500,7 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second) // QWidget *fp = first->d_func()->focus_prev; QWidget *fn = first->d_func()->focus_next; - if (fn == second) + if (fn == second || first == second) return; QWidget *sp = second->d_func()->focus_prev; @@ -7321,7 +7353,7 @@ void QWidgetPrivate::hide_helper() // next bit tries to move the focus if the focus widget is now // hidden. if (wasVisible) { -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) qApp->d_func()->sendSyntheticEnterLeave(q); #endif @@ -7453,7 +7485,7 @@ void QWidget::setVisible(bool visible) d->show_helper(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) qApp->d_func()->sendSyntheticEnterLeave(this); #endif } @@ -7568,7 +7600,7 @@ void QWidgetPrivate::hideChildren(bool spontaneous) widget->d_func()->hide_sys(); } } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined (Q_WS_QWS) || defined(Q_WS_MAC) qApp->d_func()->sendSyntheticEnterLeave(widget); #endif #ifndef QT_NO_ACCESSIBILITY @@ -9786,7 +9818,7 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) desktopWidget = parent; bool newParent = (parent != parentWidget()) || !wasCreated || desktopWidget; -#if defined(Q_WS_X11) || defined(Q_WS_WIN) +#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_MAC) if (newParent && parent && !desktopWidget) { if (testAttribute(Qt::WA_NativeWindow) && !qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings)) parent->d_func()->enforceNativeChildren(); @@ -10261,6 +10293,29 @@ const QPixmap *QWidget::icon() const #endif // QT3_SUPPORT + /*! + \internal + + This just sets the corresponding attribute bit to 1 or 0 + */ +static void setAttribute_internal(Qt::WidgetAttribute attribute, bool on, QWidgetData *data, + QWidgetPrivate *d) +{ + if (attribute < int(8*sizeof(uint))) { + if (on) + data->widget_attributes |= (1<<attribute); + else + data->widget_attributes &= ~(1<<attribute); + } else { + const int x = attribute - 8*sizeof(uint); + const int int_off = x / (8*sizeof(uint)); + if (on) + d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint)))); + else + d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint)))); + } +} + /*! Sets the attribute \a attribute on this widget if \a on is true; otherwise clears the attribute. @@ -10287,19 +10342,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) } #endif - if (attribute < int(8*sizeof(uint))) { - if (on) - data->widget_attributes |= (1<<attribute); - else - data->widget_attributes &= ~(1<<attribute); - } else { - const int x = attribute - 8*sizeof(uint); - const int int_off = x / (8*sizeof(uint)); - if (on) - d->high_attributes[int_off] |= (1<<(x-(int_off*8*sizeof(uint)))); - else - d->high_attributes[int_off] &= ~(1<<(x-(int_off*8*sizeof(uint)))); - } + setAttribute_internal(attribute, on, data, d); switch (attribute) { @@ -10358,14 +10401,11 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) #ifdef Q_WS_MAC { // We can only have one of these set at a time - static const int MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize, - Qt::WA_MacMiniSize, 0 }; - for (int i = 0; MacSizes[i] != 0; ++i) { - if (MacSizes[i] == attribute) - continue; - int macsize_x = MacSizes[i] - 8*sizeof(uint); - int macsize_int_off = macsize_x / (8*sizeof(uint)); - d->high_attributes[macsize_int_off] &= ~(1<<(macsize_x-(macsize_int_off*8*sizeof(uint)))); + const Qt::WidgetAttribute MacSizes[] = { Qt::WA_MacNormalSize, Qt::WA_MacSmallSize, + Qt::WA_MacMiniSize }; + for (int i = 0; i < 3; ++i) { + if (MacSizes[i] != attribute) + setAttribute_internal(MacSizes[i], false, data, d); } d->macUpdateSizeAttribute(); } @@ -10432,7 +10472,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) } case Qt::WA_PaintOnScreen: d->updateIsOpaque(); -#if defined(Q_WS_WIN) || defined(Q_WS_X11) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC) // Recreate the widget if it's already created as an alien widget and // WA_PaintOnScreen is enabled. Paint on screen widgets must have win id. // So must their children. diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index dcb87fc..6d8c97b 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -459,7 +459,13 @@ static bool qt_isGenuineQWidget(OSViewRef ref) bool qt_isGenuineQWidget(const QWidget *window) { - return window && qt_isGenuineQWidget(OSViewRef(window->winId())); + if (!window) + return false; + + if (!window->internalWinId()) + return true; //alien + + return qt_isGenuineQWidget(OSViewRef(window->internalWinId())); } Q_GUI_EXPORT OSWindowRef qt_mac_window_for(const QWidget *w) @@ -2608,7 +2614,16 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } } else { data.fstrut_dirty = false; // non-toplevel widgets don't have a frame, so no need to update the strut - if(OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) { + +#ifdef QT_MAC_USE_COCOA + if (q->testAttribute(Qt::WA_NativeWindow) == false || + q->internalWinId() != 0) { +#ifdef ALIEN_DEBUG + qDebug() << "Skipping native widget creation for" << this; +#endif + } else +#endif + if (OSViewRef osview = qt_mac_create_widget(q, this, qt_mac_nativeview_for(parentWidget))) { #ifndef QT_MAC_USE_COCOA HIRect bounds = CGRectMake(data.crect.x(), data.crect.y(), data.crect.width(), data.crect.height()); HIViewSetFrame(osview, &bounds); @@ -2869,9 +2884,12 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) q->setAttribute(Qt::WA_WState_Visible, false); q->setAttribute(Qt::WA_WState_Hidden, false); adjustFlags(data.window_flags, q); - // keep compatibility with previous versions, we need to preserve the created state - // (but we recreate the winId for the widget being reparented, again for compatibility) - if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created))) { + // keep compatibility with previous versions, we need to preserve the created state. + // (but we recreate the winId for the widget being reparented, again for compatibility, + // unless this is an alien widget. ) + const bool nonWindowWithCreatedParent = !q->isWindow() && parent->testAttribute(Qt::WA_WState_Created); + const bool nativeWidget = q->internalWinId() != 0; + if (wasCreated || nativeWidget && nonWindowWithCreatedParent) { createWinId(); if (q->isWindow()) { #ifndef QT_MAC_USE_COCOA @@ -2955,7 +2973,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) QPoint QWidget::mapToGlobal(const QPoint &pos) const { Q_D(const QWidget); - if (!testAttribute(Qt::WA_WState_Created)) { + if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) { QPoint p = pos + data->crect.topLeft(); return isWindow() ? p : parentWidget()->mapToGlobal(p); } @@ -2982,7 +3000,7 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const QPoint QWidget::mapFromGlobal(const QPoint &pos) const { Q_D(const QWidget); - if (!testAttribute(Qt::WA_WState_Created)) { + if (!testAttribute(Qt::WA_WState_Created) || !internalWinId()) { QPoint p = isWindow() ? pos : parentWidget()->mapFromGlobal(pos); return p - data->crect.topLeft(); } @@ -3320,10 +3338,20 @@ void QWidgetPrivate::update_sys(const QRegion &rgn) } #else // Cocoa doesn't do regions, it seems more efficient to just update the bounding rect instead of a potential number of message passes for each rect. - const QRect &boundingRect = rgn.boundingRect(); - [qt_mac_nativeview_for(q) setNeedsDisplayInRect:NSMakeRect(boundingRect.x(), - boundingRect.y(), boundingRect.width(), - boundingRect.height())]; + const QRect & boundingRect = rgn.boundingRect(); + + // Alien support: get the first native ancestor widget (will be q itself in the non-alien case), + // map the coordinates from q space to NSView space and invalidate the rect. + QWidget *nativeParent = q->internalWinId() ? q : q->nativeParentWidget(); + if (nativeParent == 0) + return; + const QRect nativeBoundingRect = QRect( + QPoint(q->mapTo(nativeParent, boundingRect.topLeft())), + QSize(boundingRect.size())); + + [qt_mac_nativeview_for(nativeParent) setNeedsDisplayInRect:NSMakeRect(nativeBoundingRect.x(), + nativeBoundingRect.y(), nativeBoundingRect.width(), + nativeBoundingRect.height())]; #endif } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index efd9a0a..2cb8586 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -720,6 +720,7 @@ public: #elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC // This is new stuff uint needWindowChange : 1; + uint hasAlienChildren : 1; // Each wiget keeps a list of all its child and grandchild OpenGL widgets. // This list is used to update the gl context whenever a parent and a granparent diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 0b735a2..cd448a7 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -548,14 +548,14 @@ void QColor::setNamedColor(const QString &name) */ bool QColor::isValidColor(const QString &name) { - return QColor().setColorFromString(name); + return !name.isEmpty() && QColor().setColorFromString(name); } bool QColor::setColorFromString(const QString &name) { if (name.isEmpty()) { invalidate(); - return false; + return true; } if (name.startsWith(QLatin1Char('#'))) { diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index acd286a..5f70cb7 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5072,7 +5072,7 @@ static void blend_tiled_argb8565(int count, const QSpan *spans, void *userData) static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) { -#if defined(QT_QWS_DEPTH_16) +#if !defined(Q_WS_QWS) || defined(QT_QWS_DEPTH_16) QSpanData *data = reinterpret_cast<QSpanData *>(userData); if (data->texture.format == QImage::Format_ARGB8565_Premultiplied) diff --git a/src/gui/styles/qgtkpainter.cpp b/src/gui/styles/qgtkpainter.cpp index 6cc7455..1f68f2f 100644 --- a/src/gui/styles/qgtkpainter.cpp +++ b/src/gui/styles/qgtkpainter.cpp @@ -142,7 +142,7 @@ QPixmap QGtkPainter::renderTheme(uchar *bdata, uchar *wdata, const QRect &rect) } QGtkPainter::QGtkPainter(QPainter *_painter) - : m_window(QGtkStylePrivate::gtkWidget(QLatin1String("GtkWindow"))) + : m_window(QGtkStylePrivate::gtkWidget("GtkWindow")) , m_painter(_painter) , m_alpha(true) , m_hflipped(false) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index b5f052b..e2de43a 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -222,7 +222,7 @@ QPalette QGtkStyle::standardPalette() const QPalette palette = QCleanlooksStyle::standardPalette(); if (d->isThemeAvailable()) { GtkStyle *style = d->gtkStyle(); - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkButton"); GtkWidget *gtkEntry = d->getTextColorWidget(); GdkColor gdkBg, gdkBase, gdkText, gdkForeground, gdkSbg, gdkSfg; @@ -253,7 +253,7 @@ QPalette QGtkStyle::standardPalette() const palette.setColor(QPalette::Base, base); QColor alternateRowColor = palette.base().color().lighter(93); // ref gtkstyle.c draw_flat_box - GtkWidget *gtkTreeView = d->gtkWidget(QLS("GtkTreeView")); + GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView"); GdkColor *gtkAltBase = NULL; d->gtk_widget_style_get(gtkTreeView, "odd-row-color", >kAltBase, NULL); if (gtkAltBase) { @@ -421,14 +421,14 @@ int QGtkStyle::pixelMetric(PixelMetric metric, return 0; case PM_ButtonShiftHorizontal: { - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkButton"); guint horizontal_shift; d->gtk_widget_style_get(gtkButton, "child-displacement-x", &horizontal_shift, NULL); return horizontal_shift; } case PM_ButtonShiftVertical: { - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkButton"); guint vertical_shift; d->gtk_widget_style_get(gtkButton, "child-displacement-y", &vertical_shift, NULL); return vertical_shift; @@ -438,7 +438,7 @@ int QGtkStyle::pixelMetric(PixelMetric metric, return 0; case PM_MenuPanelWidth: { - GtkWidget *gtkMenu = d->gtkWidget(QLS("GtkMenu")); + GtkWidget *gtkMenu = d->gtkWidget("GtkMenu"); guint horizontal_padding = 0; // horizontal-padding is used by Maemo to get thicker borders if (!d->gtk_check_version(2, 10, 0)) @@ -495,7 +495,7 @@ int QGtkStyle::pixelMetric(PixelMetric metric, case PM_SliderThickness: case PM_SliderControlThickness: { - GtkWidget *gtkScale = d->gtkWidget(QLS("GtkHScale")); + GtkWidget *gtkScale = d->gtkWidget("GtkHScale"); gint val; d->gtk_widget_style_get(gtkScale, "slider-width", &val, NULL); if (metric == PM_SliderControlThickness) @@ -506,7 +506,7 @@ int QGtkStyle::pixelMetric(PixelMetric metric, case PM_ScrollBarExtent: { gint sliderLength; gint trough_border; - GtkWidget *hScrollbar = d->gtkWidget(QLS("GtkHScrollbar")); + GtkWidget *hScrollbar = d->gtkWidget("GtkHScrollbar"); d->gtk_widget_style_get(hScrollbar, "trough-border", &trough_border, "slider-width", &sliderLength, @@ -519,34 +519,34 @@ int QGtkStyle::pixelMetric(PixelMetric metric, case PM_SliderLength: gint val; - d->gtk_widget_style_get(d->gtkWidget(QLS("GtkHScale")), "slider-length", &val, NULL); + d->gtk_widget_style_get(d->gtkWidget("GtkHScale"), "slider-length", &val, NULL); return val; case PM_ExclusiveIndicatorWidth: case PM_ExclusiveIndicatorHeight: case PM_IndicatorWidth: case PM_IndicatorHeight: { - GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton")); + GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton"); gint size, spacing; d->gtk_widget_style_get(gtkCheckButton, "indicator-spacing", &spacing, "indicator-size", &size, NULL); return size + 2 * spacing; } case PM_MenuBarVMargin: { - GtkWidget *gtkMenubar = d->gtkWidget(QLS("GtkMenuBar")); + GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar"); return qMax(0, gtkMenubar->style->ythickness); } case PM_ScrollView_ScrollBarSpacing: { gint spacing = 3; - GtkWidget *gtkScrollWindow = d->gtkWidget(QLS("GtkScrolledWindow")); + GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow"); Q_ASSERT(gtkScrollWindow); d->gtk_widget_style_get(gtkScrollWindow, "scrollbar-spacing", &spacing, NULL); return spacing; } case PM_SubMenuOverlap: { gint offset = 0; - GtkWidget *gtkMenu = d->gtkWidget(QLS("GtkMenu")); + GtkWidget *gtkMenu = d->gtkWidget("GtkMenu"); d->gtk_widget_style_get(gtkMenu, "horizontal-offset", &offset, NULL); return offset; } @@ -587,7 +587,7 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg { if (d->isKDE4Session()) return QCleanlooksStyle::styleHint(hint, option, widget, returnData); - GtkWidget *gtkToolbar = d->gtkWidget(QLS("GtkToolbar")); + GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar"); GtkToolbarStyle toolbar_style = GTK_TOOLBAR_ICONS; g_object_get(gtkToolbar, "toolbar-style", &toolbar_style, NULL); switch (toolbar_style) { @@ -610,7 +610,7 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg return int(false); case SH_ComboBox_Popup: { - GtkWidget *gtkComboBox = d->gtkWidget(QLS("GtkComboBox")); + GtkWidget *gtkComboBox = d->gtkWidget("GtkComboBox"); gboolean appears_as_list; d->gtk_widget_style_get((GtkWidget*)gtkComboBox, "appears-as-list", &appears_as_list, NULL); return appears_as_list ? 0 : 1; @@ -634,7 +634,7 @@ int QGtkStyle::styleHint(StyleHint hint, const QStyleOption *option, const QWidg if (widget && widget->isWindow()) scrollbars_within_bevel = true; else if (!d->gtk_check_version(2, 12, 0)) { - GtkWidget *gtkScrollWindow = d->gtkWidget(QLS("GtkScrolledWindow")); + GtkWidget *gtkScrollWindow = d->gtkWidget("GtkScrolledWindow"); d->gtk_widget_style_get(gtkScrollWindow, "scrollbars-within-bevel", &scrollbars_within_bevel, NULL); } return !scrollbars_within_bevel; @@ -712,7 +712,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, GtkStyle *style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "*.GtkScrolledWindow", "*.GtkScrolledWindow", d->gtk_window_get_type()); if (style) - gtkFramePainter.paintShadow(d->gtkWidget(QLS("GtkFrame")), "viewport", pmRect, + gtkFramePainter.paintShadow(d->gtkWidget("GtkFrame"), "viewport", pmRect, option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, shadow_type, style); QPixmapCache::insert(pmKey, pixmap); @@ -739,7 +739,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, break; case PE_PanelTipLabel: { - GtkWidget *gtkWindow = d->gtkWidget(QLS("GtkWindow")); // The Murrine Engine currently assumes a widget is passed + GtkWidget *gtkWindow = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed style = d->gtk_rc_get_style_by_paths(d->gtk_settings_get_default(), "gtk-tooltips", "GtkWindow", d->gtk_window_get_type()); gtkPainter.paintFlatBox(gtkWindow, "tooltip", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_NONE, style); @@ -754,7 +754,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, break; } GtkShadowType shadow_type; - GtkWidget *gtkStatusbarFrame = d->gtkWidget(QLS("GtkStatusbar.GtkFrame")); + GtkWidget *gtkStatusbarFrame = d->gtkWidget("GtkStatusbar.GtkFrame"); d->gtk_widget_style_get(gtkStatusbarFrame->parent, "shadow-type", &shadow_type, NULL); gtkPainter.paintShadow(gtkStatusbarFrame, "frame", option->rect, GTK_STATE_NORMAL, shadow_type, gtkStatusbarFrame->style); @@ -763,7 +763,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, case PE_IndicatorHeaderArrow: if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { - GtkWidget *gtkTreeHeader = d->gtkWidget(QLS("GtkTreeView.GtkButton")); + GtkWidget *gtkTreeHeader = d->gtkWidget("GtkTreeView.GtkButton"); GtkStateType state = gtkPainter.gtkState(option); style = gtkTreeHeader->style; GtkArrowType type = GTK_ARROW_UP; @@ -801,7 +801,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, rect.translate(2, 0); GtkExpanderStyle openState = GTK_EXPANDER_EXPANDED; GtkExpanderStyle closedState = GTK_EXPANDER_COLLAPSED; - GtkWidget *gtkTreeView = d->gtkWidget(QLS("GtkTreeView")); + GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView"); GtkStateType state = GTK_STATE_NORMAL; if (!(option->state & State_Enabled)) @@ -837,7 +837,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, case PE_IndicatorToolBarSeparator: { const int margin = 6; - GtkWidget *gtkSeparator = d->gtkWidget(QLS("GtkToolbar.GtkSeparatorToolItem")); + GtkWidget *gtkSeparator = d->gtkWidget("GtkToolbar.GtkSeparatorToolItem"); if (option->state & State_Horizontal) { const int offset = option->rect.width()/2; QRect rect = option->rect.adjusted(offset, margin, 0, -margin); @@ -857,7 +857,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, break; case PE_IndicatorToolBarHandle: { - GtkWidget *gtkToolbar = d->gtkWidget(QLS("GtkToolbar")); + GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar"); GtkShadowType shadow_type; d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL); //Note when the toolbar is horizontal, the handle is vertical @@ -905,7 +905,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, GtkStateType state = gtkPainter.gtkState(option); QColor arrowColor = option->palette.buttonText().color(); - GtkWidget *gtkArrow = d->gtkWidget(QLS("GtkArrow")); + GtkWidget *gtkArrow = d->gtkWidget("GtkArrow"); GdkColor color = fromQColor(arrowColor); d->gtk_widget_modify_fg (gtkArrow, state, &color); gtkPainter.paintArrow(gtkArrow, "button", arrowRect, @@ -921,7 +921,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, break; case PE_PanelMenu: { - GtkWidget *gtkMenu = d->gtkWidget(QLS("GtkMenu")); + GtkWidget *gtkMenu = d->gtkWidget("GtkMenu"); gtkPainter.setAlphaSupport(false); // Note, alpha disabled for performance reasons gtkPainter.paintBox(gtkMenu, "menu", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, gtkMenu->style, QString()); } @@ -933,7 +933,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, // This is only used by floating tool bars if (qobject_cast<const QToolBar *>(widget)) { - GtkWidget *gtkMenubar = d->gtkWidget(QLS("GtkMenuBar")); + GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar"); gtkPainter.paintBox( gtkMenubar, "toolbar", option->rect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, style); gtkPainter.paintBox( gtkMenubar, "menu", option->rect, @@ -942,7 +942,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, break; case PE_FrameLineEdit: { - GtkWidget *gtkEntry = d->gtkWidget(QLS("GtkEntry")); + GtkWidget *gtkEntry = d->gtkWidget("GtkEntry"); gboolean interior_focus; @@ -976,7 +976,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, case PE_PanelLineEdit: if (const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) { - GtkWidget *gtkEntry = d->gtkWidget(QLS("GtkEntry")); + GtkWidget *gtkEntry = d->gtkWidget("GtkEntry"); if (panel->lineWidth > 0) proxy()->drawPrimitive(PE_FrameLineEdit, option, painter, widget); uint resolve_mask = option->palette.resolve(); @@ -994,7 +994,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, case PE_FrameTabWidget: if (const QStyleOptionTabWidgetFrame *frame = qstyleoption_cast<const QStyleOptionTabWidgetFrame*>(option)) { - GtkWidget *gtkNotebook = d->gtkWidget(QLS("GtkNotebook")); + GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook"); style = gtkPainter.getStyle(gtkNotebook); gtkPainter.setAlphaSupport(false); GtkShadowType shadow = GTK_SHADOW_OUT; @@ -1042,7 +1042,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, GtkStateType state = gtkPainter.gtkState(option); if (option->state & State_On || option->state & State_Sunken) state = GTK_STATE_ACTIVE; - GtkWidget *gtkButton = d->gtkWidget(isTool ? QLS("GtkToolButton.GtkButton") : QLS("GtkButton")); + GtkWidget *gtkButton = isTool ? d->gtkWidget("GtkToolButton.GtkButton") : d->gtkWidget("GtkButton"); gint focusWidth, focusPad; gboolean interiorFocus = false; d->gtk_widget_style_get (gtkButton, @@ -1098,14 +1098,14 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, else shadow = GTK_SHADOW_OUT; - GtkWidget *gtkRadioButton = d->gtkWidget(QLS("GtkRadioButton")); + GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton"); gint spacing; d->gtk_widget_style_get(gtkRadioButton, "indicator-spacing", &spacing, NULL); QRect buttonRect = option->rect.adjusted(spacing, spacing, -spacing, -spacing); gtkPainter.setClipRect(option->rect); // ### Note: Ubuntulooks breaks when the proper widget is passed // Murrine engine requires a widget not to get RGBA check - warnings - GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton")); + GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton"); QString key(QLS("radiobutton")); if (option->state & State_HasFocus) { // Themes such as Nodoka check this flag key += QLatin1Char('f'); @@ -1133,7 +1133,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, int spacing; - GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton")); + GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton"); QString key(QLS("checkbutton")); if (option->state & State_HasFocus) { // Themes such as Nodoka checks this flag key += QLatin1Char('f'); @@ -1275,7 +1275,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom if ((groupBox->subControls & QStyle::SC_GroupBoxLabel) && !groupBox->text.isEmpty()) { // Draw prelight background - GtkWidget *gtkCheckButton = d->gtkWidget(QLS("GtkCheckButton")); + GtkWidget *gtkCheckButton = d->gtkWidget("GtkCheckButton"); if (option->state & State_MouseOver) { QRect bgRect = textRect | checkBoxRect; @@ -1348,7 +1348,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom GtkShadowType shadow = (option->state & State_Sunken || option->state & State_On ) ? GTK_SHADOW_IN : GTK_SHADOW_OUT; - QString comboBoxPath = QLS(comboBox->editable ? "GtkComboBoxEntry" : "GtkComboBox"); + const QHashableLatin1Literal comboBoxPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry") : QHashableLatin1Literal("GtkComboBox"); // We use the gtk widget to position arrows and separators for us GtkWidget *gtkCombo = d->gtkWidget(comboBoxPath); @@ -1356,7 +1356,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom d->gtk_widget_set_direction(gtkCombo, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); d->gtk_widget_size_allocate(gtkCombo, &geometry); - QString buttonPath = comboBoxPath + QLS(".GtkToggleButton"); + QHashableLatin1Literal buttonPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton") + : QHashableLatin1Literal("GtkComboBox.GtkToggleButton"); GtkWidget *gtkToggleButton = d->gtkWidget(buttonPath); d->gtk_widget_set_direction(gtkToggleButton, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); if (gtkToggleButton && (appears_as_list || comboBox->editable)) { @@ -1365,7 +1366,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom // Draw the combo box as a line edit with a button next to it if (comboBox->editable || appears_as_list) { GtkStateType frameState = (state == GTK_STATE_PRELIGHT) ? GTK_STATE_NORMAL : state; - QString entryPath = QLS(comboBox->editable ? "GtkComboBoxEntry.GtkEntry" : "GtkComboBox.GtkFrame"); + QHashableLatin1Literal entryPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkEntry") : QHashableLatin1Literal("GtkComboBox.GtkFrame"); GtkWidget *gtkEntry = d->gtkWidget(entryPath); d->gtk_widget_set_direction(gtkEntry, reverse ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); QRect frameRect = option->rect; @@ -1391,11 +1392,11 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom else { gtkCachedPainter.paintFlatBox(gtkEntry, "entry_bg", contentRect, option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, - GTK_SHADOW_NONE, gtkEntry->style, entryPath + QString::number(focus)); + GTK_SHADOW_NONE, gtkEntry->style, entryPath.toString() + QString::number(focus)); } gtkCachedPainter.paintShadow(gtkEntry, comboBox->editable ? "entry" : "frame", frameRect, frameState, - GTK_SHADOW_IN, gtkEntry->style, entryPath + + GTK_SHADOW_IN, gtkEntry->style, entryPath.toString() + QString::number(focus) + QString::number(comboBox->editable) + QString::number(option->direction)); if (focus) @@ -1416,7 +1417,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom Q_ASSERT(gtkToggleButton); gtkCachedPainter.paintBox( gtkToggleButton, "button", arrowButtonRect, buttonState, - shadow, gtkToggleButton->style, buttonPath + + shadow, gtkToggleButton->style, buttonPath.toString() + QString::number(focus) + QString::number(option->direction)); if (focus) GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); @@ -1429,12 +1430,17 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom gtkCachedPainter.paintBox(gtkToggleButton, "button", buttonRect, state, shadow, gtkToggleButton->style, - buttonPath + QString::number(focus)); + buttonPath.toString() + QString::number(focus)); if (focus) GTK_WIDGET_UNSET_FLAGS(gtkToggleButton, GTK_HAS_FOCUS); + QHashableLatin1Literal buttonPath = comboBox->editable ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton") + : QHashableLatin1Literal("GtkComboBox.GtkToggleButton"); + // Draw the separator between label and arrows - QString vSeparatorPath = buttonPath + QLS(".GtkHBox.GtkVSeparator"); + QHashableLatin1Literal vSeparatorPath = comboBox->editable + ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkVSeparator") + : QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkVSeparator"); if (GtkWidget *gtkVSeparator = d->gtkWidget(vSeparatorPath)) { QRect vLineRect(gtkVSeparator->allocation.x, @@ -1444,7 +1450,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom gtkCachedPainter.paintVline( gtkVSeparator, "vseparator", vLineRect, state, gtkVSeparator->style, - 0, vLineRect.height(), 0, vSeparatorPath); + 0, vLineRect.height(), 0, vSeparatorPath.toString()); gint interiorFocus = true; @@ -1469,8 +1475,18 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom else state = GTK_STATE_NORMAL; - QString arrowPath = comboBoxPath + QLS(appears_as_list ? ".GtkToggleButton.GtkArrow" - : ".GtkToggleButton.GtkHBox.GtkArrow"); + QHashableLatin1Literal arrowPath(""); + if (comboBox->editable) { + if (appears_as_list) + arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkArrow"); + else + arrowPath = QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton.GtkHBox.GtkArrow"); + } else { + if (appears_as_list) + arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkArrow"); + else + arrowPath = QHashableLatin1Literal("GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow"); + } GtkWidget *gtkArrow = d->gtkWidget(arrowPath); gfloat scale = 0.7; @@ -1497,7 +1513,11 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom if (sunken) { int xoff, yoff; - GtkWidget *gtkButton = d->gtkWidget(comboBoxPath + QLS(".GtkToggleButton")); + const QHashableLatin1Literal toggleButtonPath = comboBox->editable + ? QHashableLatin1Literal("GtkComboBoxEntry.GtkToggleButton") + : QHashableLatin1Literal("GtkComboBox.GtkToggleButton"); + + GtkWidget *gtkButton = d->gtkWidget(toggleButtonPath); d->gtk_widget_style_get(gtkButton, "child-displacement-x", &xoff, NULL); d->gtk_widget_style_get(gtkButton, "child-displacement-y", &yoff, NULL); arrowRect = arrowRect.adjusted(xoff, yoff, xoff, yoff); @@ -1509,7 +1529,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom gtkCachedPainter.setClipRect(option->rect); gtkCachedPainter.paintArrow( gtkArrow, "arrow", arrowRect, GTK_ARROW_DOWN, state, GTK_SHADOW_NONE, TRUE, - style, arrowPath + QString::number(option->direction)); + style, arrowPath.toString() + QString::number(option->direction)); } } END_STYLE_PIXMAPCACHE; @@ -1570,7 +1590,7 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom QStyleOptionToolButton label = *toolbutton; label.state = bflags; - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkToolButton.GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton"); QPalette pal = toolbutton->palette; if (option->state & State_Enabled && option->state & State_MouseOver && !(widget && widget->testAttribute(Qt::WA_SetPalette))) { @@ -1605,8 +1625,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom case CC_ScrollBar: if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) { - GtkWidget *gtkHScrollBar = d->gtkWidget(QLS("GtkHScrollbar")); - GtkWidget *gtkVScrollBar = d->gtkWidget(QLS("GtkVScrollbar")); + GtkWidget *gtkHScrollBar = d->gtkWidget("GtkHScrollbar"); + GtkWidget *gtkVScrollBar = d->gtkWidget("GtkVScrollbar"); // Fill background in case the scrollbar is partially transparent painter->fillRect(option->rect, option->palette.background()); @@ -1751,10 +1771,9 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom case CC_SpinBox: if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { - GtkWidget *gtkSpinButton = d->gtkWidget( - spinBox->buttonSymbols == QAbstractSpinBox::NoButtons ? - QLS("GtkEntry") : - QLS("GtkSpinButton")); + GtkWidget *gtkSpinButton = spinBox->buttonSymbols == QAbstractSpinBox::NoButtons + ? d->gtkWidget("GtkEntry") + : d->gtkWidget("GtkSpinButton"); bool isEnabled = (spinBox->state & State_Enabled); bool hover = isEnabled && (spinBox->state & State_MouseOver); bool sunken = (spinBox->state & State_Sunken); @@ -1906,8 +1925,8 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom case CC_Slider: if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { - GtkWidget *hScaleWidget = d->gtkWidget(QLS("GtkHScale")); - GtkWidget *vScaleWidget = d->gtkWidget(QLS("GtkVScale")); + GtkWidget *hScaleWidget = d->gtkWidget("GtkHScale"); + GtkWidget *vScaleWidget = d->gtkWidget("GtkVScale"); QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget); QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget); @@ -2097,7 +2116,7 @@ void QGtkStyle::drawControl(ControlElement element, switch (element) { case CE_ProgressBarLabel: if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { - GtkWidget *gtkProgressBar = d->gtkWidget(QLS("GtkProgressBar")); + GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar"); if (!gtkProgressBar) return; @@ -2200,7 +2219,7 @@ void QGtkStyle::drawControl(ControlElement element, if (button->features & QStyleOptionButton::HasMenu) ir = ir.adjusted(0, 0, -pixelMetric(PM_MenuButtonIndicator, button, widget), 0); - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkButton"); QPalette pal = button->palette; int labelState = GTK_STATE_INSENSITIVE; if (option->state & State_Enabled) @@ -2221,7 +2240,7 @@ void QGtkStyle::drawControl(ControlElement element, bool isRadio = (element == CE_RadioButton); // Draw prelight background - GtkWidget *gtkRadioButton = d->gtkWidget(QLS("GtkRadioButton")); + GtkWidget *gtkRadioButton = d->gtkWidget("GtkRadioButton"); if (option->state & State_MouseOver) { gtkPainter.paintFlatBox(gtkRadioButton, "checkbutton", option->rect, @@ -2289,7 +2308,7 @@ void QGtkStyle::drawControl(ControlElement element, } if (!cb->currentText.isEmpty() && !cb->editable) { - GtkWidget *gtkCombo = d->gtkWidget(QLS("GtkComboBox")); + GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox"); QPalette pal = cb->palette; int labelState = GTK_STATE_INSENSITIVE; @@ -2366,7 +2385,7 @@ void QGtkStyle::drawControl(ControlElement element, // Draws the header in tables. if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(option)) { Q_UNUSED(header); - GtkWidget *gtkTreeView = d->gtkWidget(QLS("GtkTreeView")); + GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView"); // Get the middle column GtkTreeViewColumn *column = d->gtk_tree_view_get_column((GtkTreeView*)gtkTreeView, 1); Q_ASSERT(column); @@ -2387,7 +2406,7 @@ void QGtkStyle::drawControl(ControlElement element, #ifndef QT_NO_SIZEGRIP case CE_SizeGrip: { - GtkWidget *gtkStatusbar = d->gtkWidget(QLS("GtkStatusbar.GtkFrame")); + GtkWidget *gtkStatusbar = d->gtkWidget("GtkStatusbar.GtkFrame"); QRect gripRect = option->rect.adjusted(0, 0, -gtkStatusbar->style->xthickness, -gtkStatusbar->style->ythickness); gtkPainter.paintResizeGrip( gtkStatusbar, "statusbar", gripRect, GTK_STATE_NORMAL, GTK_SHADOW_OUT, QApplication::isRightToLeft() ? @@ -2399,7 +2418,7 @@ void QGtkStyle::drawControl(ControlElement element, #endif // QT_NO_SIZEGRIP case CE_MenuBarEmptyArea: { - GtkWidget *gtkMenubar = d->gtkWidget(QLS("GtkMenuBar")); + GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar"); GdkColor gdkBg = gtkMenubar->style->bg[GTK_STATE_NORMAL]; // Theme can depend on transparency painter->fillRect(option->rect, QColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8)); if (widget) { // See CE_MenuBarItem @@ -2422,8 +2441,8 @@ void QGtkStyle::drawControl(ControlElement element, painter->save(); if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { - GtkWidget *gtkMenubarItem = d->gtkWidget(QLS("GtkMenuBar.GtkMenuItem")); - GtkWidget *gtkMenubar = d->gtkWidget(QLS("GtkMenuBar")); + GtkWidget *gtkMenubarItem = d->gtkWidget("GtkMenuBar.GtkMenuItem"); + GtkWidget *gtkMenubar = d->gtkWidget("GtkMenuBar"); style = gtkMenubarItem->style; @@ -2479,7 +2498,7 @@ void QGtkStyle::drawControl(ControlElement element, break; case CE_Splitter: { - GtkWidget *gtkWindow = d->gtkWidget(QLS("GtkWindow")); // The Murrine Engine currently assumes a widget is passed + GtkWidget *gtkWindow = d->gtkWidget("GtkWindow"); // The Murrine Engine currently assumes a widget is passed gtkPainter.paintHandle(gtkWindow, "splitter", option->rect, gtkPainter.gtkState(option), GTK_SHADOW_NONE, !(option->state & State_Horizontal) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL, style); @@ -2499,7 +2518,7 @@ void QGtkStyle::drawControl(ControlElement element, if (toolbar->positionWithinLine != QStyleOptionToolBar::End) rect.adjust(0, 0, 1, 0); - GtkWidget *gtkToolbar = d->gtkWidget(QLS("GtkToolbar")); + GtkWidget *gtkToolbar = d->gtkWidget("GtkToolbar"); GtkShadowType shadow_type = GTK_SHADOW_NONE; d->gtk_widget_style_get(gtkToolbar, "shadow-type", &shadow_type, NULL); gtkPainter.paintBox( gtkToolbar, "toolbar", rect, @@ -2518,15 +2537,15 @@ void QGtkStyle::drawControl(ControlElement element, const int windowsItemHMargin = 3; // menu item hor text margin const int windowsItemVMargin = 26; // menu item ver text margin const int windowsRightBorder = 15; // right border on windows - GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")) : - d->gtkWidget(QLS("GtkMenu.GtkMenuItem")); + GtkWidget *gtkMenuItem = menuItem->checked ? d->gtkWidget("GtkMenu.GtkCheckMenuItem") : + d->gtkWidget("GtkMenu.GtkMenuItem"); style = gtkPainter.getStyle(gtkMenuItem); QColor borderColor = option->palette.background().color().darker(160); QColor shadow = option->palette.dark().color(); if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { - GtkWidget *gtkMenuSeparator = d->gtkWidget(QLS("GtkMenu.GtkSeparatorMenuItem")); + GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem"); painter->setPen(shadow.lighter(106)); gboolean wide_separators = 0; gint separator_height = 0; @@ -2570,7 +2589,7 @@ void QGtkStyle::drawControl(ControlElement element, bool ignoreCheckMark = false; gint checkSize; - d->gtk_widget_style_get(d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")), "indicator-size", &checkSize, NULL); + d->gtk_widget_style_get(d->gtkWidget("GtkMenu.GtkCheckMenuItem"), "indicator-size", &checkSize, NULL); int checkcol = qMax(menuItem->maxIconWidth, qMax(20, checkSize)); @@ -2781,7 +2800,7 @@ void QGtkStyle::drawControl(ControlElement element, case CE_PushButton: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkButton"); proxy()->drawControl(CE_PushButtonBevel, btn, painter, widget); QStyleOptionButton subopt = *btn; subopt.rect = subElementRect(SE_PushButtonContents, btn, widget); @@ -2807,7 +2826,7 @@ void QGtkStyle::drawControl(ControlElement element, case CE_TabBarTabShape: if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(option)) { - GtkWidget *gtkNotebook = d->gtkWidget(QLS("GtkNotebook")); + GtkWidget *gtkNotebook = d->gtkWidget("GtkNotebook"); style = gtkPainter.getStyle(gtkNotebook); QRect rect = option->rect; @@ -2874,7 +2893,7 @@ void QGtkStyle::drawControl(ControlElement element, case CE_ProgressBarGroove: if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { Q_UNUSED(bar); - GtkWidget *gtkProgressBar = d->gtkWidget(QLS("GtkProgressBar")); + GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar"); GtkStateType state = gtkPainter.gtkState(option); gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, gtkProgressBar->style); } @@ -2884,7 +2903,7 @@ void QGtkStyle::drawControl(ControlElement element, case CE_ProgressBarContents: if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { GtkStateType state = option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE; - GtkWidget *gtkProgressBar = d->gtkWidget(QLS("GtkProgressBar")); + GtkWidget *gtkProgressBar = d->gtkWidget("GtkProgressBar"); style = gtkProgressBar->style; gtkPainter.paintBox( gtkProgressBar, "trough", option->rect, state, GTK_SHADOW_IN, style); int xt = style->xthickness; @@ -3042,7 +3061,7 @@ QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComple case CC_SpinBox: if (const QStyleOptionSpinBox *spinbox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { - GtkWidget *gtkSpinButton = d->gtkWidget(QLS("GtkSpinButton")); + GtkWidget *gtkSpinButton = d->gtkWidget("GtkSpinButton"); int center = spinbox->rect.height() / 2; int xt = spinbox->frame ? gtkSpinButton->style->xthickness : 0; int yt = spinbox->frame ? gtkSpinButton->style->ythickness : 0; @@ -3096,15 +3115,19 @@ QRect QGtkStyle::subControlRect(ComplexControl control, const QStyleOptionComple if (const QStyleOptionComboBox *box = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { // We employ the gtk widget to position arrows and separators for us QString comboBoxPath = box->editable ? QLS("GtkComboBoxEntry") : QLS("GtkComboBox"); - GtkWidget *gtkCombo = d->gtkWidget(comboBoxPath); + GtkWidget *gtkCombo = box->editable ? d->gtkWidget("GtkComboBoxEntry") + : d->gtkWidget("GtkComboBox"); d->gtk_widget_set_direction(gtkCombo, (option->direction == Qt::RightToLeft) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); GtkAllocation geometry = {0, 0, qMax(0, option->rect.width()), qMax(0, option->rect.height())}; d->gtk_widget_size_allocate(gtkCombo, &geometry); int appears_as_list = !proxy()->styleHint(QStyle::SH_ComboBox_Popup, option, widget); - QString arrowPath = comboBoxPath + QLS(".GtkToggleButton"); - - if (!box->editable && !appears_as_list) - arrowPath += QLS(".GtkHBox.GtkArrow"); + QHashableLatin1Literal arrowPath("GtkComboBoxEntry.GtkToggleButton"); + if (!box->editable) { + if (appears_as_list) + arrowPath = "GtkComboBox.GtkToggleButton"; + else + arrowPath = "GtkComboBox.GtkToggleButton.GtkHBox.GtkArrow"; + } GtkWidget *arrowWidget = d->gtkWidget(arrowPath); if (!arrowWidget) @@ -3163,7 +3186,7 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, case CT_ToolButton: if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkToolButton.GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkToolButton.GtkButton"); newSize = size + QSize(2 * gtkButton->style->xthickness, 2 + 2 * gtkButton->style->ythickness); if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) { QSize minSize(0, 25); @@ -3181,14 +3204,14 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, int textMargin = 8; if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { - GtkWidget *gtkMenuSeparator = d->gtkWidget(QLS("GtkMenu.GtkSeparatorMenuItem")); + GtkWidget *gtkMenuSeparator = d->gtkWidget("GtkMenu.GtkSeparatorMenuItem"); GtkRequisition sizeReq = {0, 0}; d->gtk_widget_size_request(gtkMenuSeparator, &sizeReq); newSize = QSize(size.width(), sizeReq.height); break; } - GtkWidget *gtkMenuItem = d->gtkWidget(QLS("GtkMenu.GtkCheckMenuItem")); + GtkWidget *gtkMenuItem = d->gtkWidget("GtkMenu.GtkCheckMenuItem"); GtkStyle* style = gtkMenuItem->style; // Note we get the perfect height for the default font since we @@ -3210,12 +3233,12 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, case CT_SpinBox: // QSpinBox does some nasty things that depends on CT_LineEdit - newSize = size + QSize(0, -d->gtkWidget(QLS("GtkSpinButton"))->style->ythickness * 2); + newSize = size + QSize(0, -d->gtkWidget("GtkSpinButton")->style->ythickness * 2); break; case CT_PushButton: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkButton"); gint focusPadding, focusWidth; d->gtk_widget_style_get(gtkButton, "focus-padding", &focusPadding, NULL); d->gtk_widget_style_get(gtkButton, "focus-line-width", &focusWidth, NULL); @@ -3223,7 +3246,7 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, newSize += QSize(2*gtkButton->style->xthickness + 4, 2*gtkButton->style->ythickness); newSize += QSize(2*(focusWidth + focusPadding + 2), 2*(focusWidth + focusPadding)); - GtkWidget *gtkButtonBox = d->gtkWidget(QLS("GtkHButtonBox")); + GtkWidget *gtkButtonBox = d->gtkWidget("GtkHButtonBox"); gint minWidth = 85, minHeight = 0; d->gtk_widget_style_get(gtkButtonBox, "child-min-width", &minWidth, "child-min-height", &minHeight, NULL); @@ -3236,13 +3259,13 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, break; case CT_Slider: { - GtkWidget *gtkSlider = d->gtkWidget(QLS("GtkHScale")); + GtkWidget *gtkSlider = d->gtkWidget("GtkHScale"); newSize = size + QSize(2*gtkSlider->style->xthickness, 2*gtkSlider->style->ythickness); } break; case CT_LineEdit: { - GtkWidget *gtkEntry = d->gtkWidget(QLS("GtkEntry")); + GtkWidget *gtkEntry = d->gtkWidget("GtkEntry"); newSize = size + QSize(2*gtkEntry->style->xthickness, 2 + 2*gtkEntry->style->ythickness); } break; @@ -3253,7 +3276,7 @@ QSize QGtkStyle::sizeFromContents(ContentsType type, const QStyleOption *option, case CT_ComboBox: if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(option)) { - GtkWidget *gtkCombo = d->gtkWidget(QLS("GtkComboBox")); + GtkWidget *gtkCombo = d->gtkWidget("GtkComboBox"); QRect arrowButtonRect = proxy()->subControlRect(CC_ComboBox, combo, SC_ComboBoxArrow, widget); newSize = size + QSize(12 + arrowButtonRect.width() + 2*gtkCombo->style->xthickness, 4 + 2*gtkCombo->style->ythickness); @@ -3405,7 +3428,7 @@ QRect QGtkStyle::subElementRect(SubElement element, const QStyleOption *option, return option->rect; case SE_PushButtonContents: if (!d->gtk_check_version(2, 10, 0)) { - GtkWidget *gtkButton = d->gtkWidget(QLS("GtkButton")); + GtkWidget *gtkButton = d->gtkWidget("GtkButton"); GtkBorder *border = 0; d->gtk_widget_style_get(gtkButton, "inner-border", &border, NULL); if (border) { diff --git a/src/gui/styles/qgtkstyle_p.cpp b/src/gui/styles/qgtkstyle_p.cpp index a033407..6916c02 100644 --- a/src/gui/styles/qgtkstyle_p.cpp +++ b/src/gui/styles/qgtkstyle_p.cpp @@ -60,6 +60,7 @@ #include <QtCore/QHash> #include <QtCore/QUrl> #include <QtCore/QLibrary> +#include <QtCore/QDebug> #include <private/qapplication_p.h> #include <private/qiconloader_p.h> @@ -233,17 +234,22 @@ static void update_toolbar_style(GtkWidget *gtkToolBar, GParamSpec *, gpointer) } } -static QString classPath(GtkWidget *widget) +static QHashableLatin1Literal classPath(GtkWidget *widget) { - char* class_path; + char *class_path; QGtkStylePrivate::gtk_widget_path (widget, NULL, &class_path, NULL); - QString path = QLS(class_path); + + char *copy = class_path; + if (strncmp(copy, "GtkWindow.", 10) == 0) + copy += 10; + if (strncmp(copy, "GtkFixed.", 9) == 0) + copy += 9; + + copy = strdup(copy); + g_free(class_path); - // Remove the prefixes - path.remove(QLS("GtkWindow.")); - path.remove(QLS("GtkFixed.")); - return path; + return QHashableLatin1Literal::fromData(copy); } @@ -261,6 +267,7 @@ bool QGtkStyleFilter::eventFilter(QObject *obj, QEvent *e) } QList<QGtkStylePrivate *> QGtkStylePrivate::instances; +QGtkStylePrivate::WidgetMap *QGtkStylePrivate::widgetMap = 0; QGtkStylePrivate::QGtkStylePrivate() : QCleanlooksStylePrivate() @@ -282,7 +289,7 @@ void QGtkStylePrivate::init() qApp->installEventFilter(&filter); } -GtkWidget* QGtkStylePrivate::gtkWidget(const QString &path) +GtkWidget* QGtkStylePrivate::gtkWidget(const QHashableLatin1Literal &path) { GtkWidget *widget = gtkWidgetMap()->value(path); if (!widget) { @@ -292,10 +299,10 @@ GtkWidget* QGtkStylePrivate::gtkWidget(const QString &path) return widget; } -GtkStyle* QGtkStylePrivate::gtkStyle(const QString &path) +GtkStyle* QGtkStylePrivate::gtkStyle(const QHashableLatin1Literal &path) { - if (gtkWidgetMap()->contains(path)) - return gtkWidgetMap()->value(path)->style; + if (GtkWidget *w = gtkWidgetMap()->value(path)) + return w->style; return 0; } @@ -497,7 +504,7 @@ void QGtkStylePrivate::initGtkWidgets() const } static QString themeName; - if (!gtkWidgetMap()->contains(QLS("GtkWindow")) && themeName.isEmpty()) { + if (!gtkWidgetMap()->contains("GtkWindow") && themeName.isEmpty()) { themeName = getThemeName(); if (themeName.isEmpty()) { @@ -522,14 +529,14 @@ void QGtkStylePrivate::initGtkWidgets() const QGtkStylePrivate::gtk_widget_realize(gtkWindow); if (displayDepth == -1) displayDepth = QGtkStylePrivate::gdk_drawable_get_depth(gtkWindow->window); - gtkWidgetMap()->insert(QLS("GtkWindow"), gtkWindow); + gtkWidgetMap()->insert(QHashableLatin1Literal::fromData(strdup("GtkWindow")), gtkWindow); // Make all other widgets. respect the text direction if (qApp->layoutDirection() == Qt::RightToLeft) QGtkStylePrivate::gtk_widget_set_default_direction(GTK_TEXT_DIR_RTL); - if (!gtkWidgetMap()->contains(QLS("GtkButton"))) { + if (!gtkWidgetMap()->contains("GtkButton")) { GtkWidget *gtkButton = QGtkStylePrivate::gtk_button_new(); addWidget(gtkButton); g_signal_connect(gtkButton, "style-set", G_CALLBACK(gtkStyleSetCallback), 0); @@ -566,12 +573,12 @@ void QGtkStylePrivate::initGtkWidgets() const // When styles change subwidgets can get rearranged // as with the combo box. We need to update the widget map // to reflect this; - QHash<QString, GtkWidget*> oldMap = *gtkWidgetMap(); + QHash<QHashableLatin1Literal, GtkWidget*> oldMap = *gtkWidgetMap(); gtkWidgetMap()->clear(); - QHashIterator<QString, GtkWidget*> it(oldMap); + QHashIterator<QHashableLatin1Literal, GtkWidget*> it(oldMap); while (it.hasNext()) { it.next(); - if (!it.key().contains(QLatin1Char('.'))) { + if (!strchr(it.key().data(), '.')) { addAllSubWidgets(it.value()); } } @@ -586,8 +593,13 @@ void QGtkStylePrivate::initGtkWidgets() const */ void QGtkStylePrivate::cleanupGtkWidgets() { - if (gtkWidgetMap()->contains(QLS("GtkWindow"))) // Gtk will destroy all children - gtk_widget_destroy(gtkWidgetMap()->value(QLS("GtkWindow"))); + if (!widgetMap) + return; + if (widgetMap->contains("GtkWindow")) // Gtk will destroy all children + gtk_widget_destroy(widgetMap->value("GtkWindow")); + for (QHash<QHashableLatin1Literal, GtkWidget *>::const_iterator it = widgetMap->constBegin(); + it != widgetMap->constEnd(); ++it) + free(const_cast<char *>(it.key().data())); } static bool resolveGConf() @@ -678,7 +690,7 @@ QString QGtkStylePrivate::getThemeName() int QGtkStylePrivate::getSpinboxArrowSize() const { const int MIN_ARROW_WIDTH = 6; - GtkWidget *spinButton = gtkWidget(QLS("GtkSpinButton")); + GtkWidget *spinButton = gtkWidget("GtkSpinButton"); GtkStyle *style = spinButton->style; gint size = pango_font_description_get_size (style->font_desc); gint arrow_size; @@ -698,17 +710,17 @@ bool QGtkStylePrivate::isKDE4Session() void QGtkStylePrivate::applyCustomPaletteHash() { - QPalette menuPal = gtkWidgetPalette(QLS("GtkMenu")); - GdkColor gdkBg = gtkWidget(QLS("GtkMenu"))->style->bg[GTK_STATE_NORMAL]; + QPalette menuPal = gtkWidgetPalette("GtkMenu"); + GdkColor gdkBg = gtkWidget("GtkMenu")->style->bg[GTK_STATE_NORMAL]; QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8); menuPal.setBrush(QPalette::Base, bgColor); menuPal.setBrush(QPalette::Window, bgColor); qApp->setPalette(menuPal, "QMenu"); - QPalette toolbarPal = gtkWidgetPalette(QLS("GtkToolbar")); + QPalette toolbarPal = gtkWidgetPalette("GtkToolbar"); qApp->setPalette(toolbarPal, "QToolBar"); - QPalette menuBarPal = gtkWidgetPalette(QLS("GtkMenuBar")); + QPalette menuBarPal = gtkWidgetPalette("GtkMenuBar"); qApp->setPalette(menuBarPal, "QMenuBar"); } @@ -717,7 +729,7 @@ void QGtkStylePrivate::applyCustomPaletteHash() */ GtkWidget* QGtkStylePrivate::getTextColorWidget() const { - return gtkWidget(QLS("GtkEntry")); + return gtkWidget("GtkEntry"); } void QGtkStylePrivate::setupGtkWidget(GtkWidget* widget) @@ -726,7 +738,7 @@ void QGtkStylePrivate::setupGtkWidget(GtkWidget* widget) static GtkWidget* protoLayout = 0; if (!protoLayout) { protoLayout = QGtkStylePrivate::gtk_fixed_new(); - QGtkStylePrivate::gtk_container_add((GtkContainer*)(gtkWidgetMap()->value(QLS("GtkWindow"))), protoLayout); + QGtkStylePrivate::gtk_container_add((GtkContainer*)(gtkWidgetMap()->value("GtkWindow")), protoLayout); } Q_ASSERT(protoLayout); @@ -739,8 +751,19 @@ void QGtkStylePrivate::setupGtkWidget(GtkWidget* widget) void QGtkStylePrivate::addWidgetToMap(GtkWidget *widget) { if (Q_GTK_IS_WIDGET(widget)) { - gtk_widget_realize(widget); - gtkWidgetMap()->insert(classPath(widget), widget); + gtk_widget_realize(widget); + QHashableLatin1Literal widgetPath = classPath(widget); + + WidgetMap *map = gtkWidgetMap(); + WidgetMap::iterator it = map->find(widgetPath); + if (it != map->end()) { + free(const_cast<char *>(it.key().data())); + map->erase(it); + } + map->insert(widgetPath, widget); +#ifdef DUMP_GTK_WIDGET_TREE + qWarning("Inserted Gtk Widget: %s", widgetPath.data()); +#endif } } @@ -753,7 +776,7 @@ void QGtkStylePrivate::addAllSubWidgets(GtkWidget *widget, gpointer v) } // Updates window/windowtext palette based on the indicated gtk widget -QPalette QGtkStylePrivate::gtkWidgetPalette(const QString >kWidgetName) const +QPalette QGtkStylePrivate::gtkWidgetPalette(const QHashableLatin1Literal >kWidgetName) const { GtkWidget *gtkWidget = QGtkStylePrivate::gtkWidget(gtkWidgetName); Q_ASSERT(gtkWidget); @@ -1089,6 +1112,28 @@ QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info) return icon; } +bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2) +{ + return l1.size() == l2.size() || qstrcmp(l1.data(), l2.data()) == 0; +} + +// copied from qHash.cpp +uint qHash(const QHashableLatin1Literal &key) +{ + int n = key.size(); + const uchar *p = reinterpret_cast<const uchar *>(key.data()); + uint h = 0; + uint g; + + while (n--) { + h = (h << 4) + *p++; + if ((g = (h & 0xf0000000)) != 0) + h ^= g >> 23; + h &= ~g; + } + return h; +} + QT_END_NAMESPACE #endif // !defined(QT_NO_STYLE_GTK) diff --git a/src/gui/styles/qgtkstyle_p.h b/src/gui/styles/qgtkstyle_p.h index db5b9b9..6ee7904 100644 --- a/src/gui/styles/qgtkstyle_p.h +++ b/src/gui/styles/qgtkstyle_p.h @@ -56,6 +56,10 @@ #include <QtCore/qglobal.h> #if !defined(QT_NO_STYLE_GTK) +#include <QtCore/qstring.h> +#include <QtCore/qstringbuilder.h> +#include <QtCore/qcoreapplication.h> + #include <QtGui/QFileDialog> #include <QtGui/QGtkStyle> @@ -72,6 +76,54 @@ typedef unsigned long XID; #define QLS(x) QLatin1String(x) +QT_BEGIN_NAMESPACE + +// ### Qt 4.7 - merge with QLatin1Literal +class QHashableLatin1Literal +{ +public: + int size() const { return m_size; } + const char *data() const { return m_data; } + + template <int N> + QHashableLatin1Literal(const char (&str)[N]) + : m_size(N - 1), m_data(str) {} + + QHashableLatin1Literal(const QHashableLatin1Literal &other) + : m_size(other.m_size), m_data(other.m_data) + {} + + QHashableLatin1Literal &operator=(const QHashableLatin1Literal &other) + { + if (this == &other) + return *this; + *const_cast<int *>(&m_size) = other.m_size; + *const_cast<char **>(&m_data) = const_cast<char *>(other.m_data); + return *this; + } + + QString toString() const { return QString::fromLatin1(m_data, m_size); } + + static QHashableLatin1Literal fromData(const char *str) + { + return QHashableLatin1Literal(str, qstrlen(str)); + } + +private: + QHashableLatin1Literal(const char *str, int length) + : m_size(length), m_data(str) + {} + + const int m_size; + const char *m_data; +}; + +bool operator==(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2); +inline bool operator!=(const QHashableLatin1Literal &l1, const QHashableLatin1Literal &l2) { return !operator==(l1, l2); } +uint qHash(const QHashableLatin1Literal &key); + +QT_END_NAMESPACE + class GConf; class GConfClient; @@ -252,7 +304,6 @@ typedef char* (*Ptr_gnome_icon_lookup_sync) ( GnomeIconLookupFlags flags, GnomeIconLookupResultFlags *result); - class QGtkStylePrivate : public QCleanlooksStylePrivate { Q_DECLARE_PUBLIC(QGtkStyle) @@ -262,8 +313,8 @@ public: QGtkStyleFilter filter; - static GtkWidget* gtkWidget(const QString &path); - static GtkStyle* gtkStyle(const QString &path = QLatin1String("GtkWindow")); + static GtkWidget* gtkWidget(const QHashableLatin1Literal &path); + static GtkStyle* gtkStyle(const QHashableLatin1Literal &path = QHashableLatin1Literal("GtkWindow")); virtual void resolveGtk() const; virtual void initGtkMenu() const; @@ -418,17 +469,25 @@ public: static Ptr_gnome_icon_lookup_sync gnome_icon_lookup_sync; static Ptr_gnome_vfs_init gnome_vfs_init; - virtual QPalette gtkWidgetPalette(const QString >kWidgetName) const; + virtual QPalette gtkWidgetPalette(const QHashableLatin1Literal >kWidgetName) const; protected: - typedef QHash<QString, GtkWidget*> WidgetMap; + typedef QHash<QHashableLatin1Literal, GtkWidget*> WidgetMap; + + static inline void destroyWidgetMap() + { + cleanupGtkWidgets(); + delete widgetMap; + widgetMap = 0; + } static inline WidgetMap *gtkWidgetMap() { - static WidgetMap *map = 0; - if (!map) - map = new WidgetMap(); - return map; + if (!widgetMap) { + widgetMap = new WidgetMap(); + qAddPostRoutine(destroyWidgetMap); + } + return widgetMap; } static QStringList extract_filter(const QString &rawFilter); @@ -443,6 +502,7 @@ protected: private: static QList<QGtkStylePrivate *> instances; + static WidgetMap *widgetMap; friend class QGtkStyleUpdateScheduler; }; diff --git a/src/gui/styles/qstylehelper.cpp b/src/gui/styles/qstylehelper.cpp index 071ec23..359e7e1 100644 --- a/src/gui/styles/qstylehelper.cpp +++ b/src/gui/styles/qstylehelper.cpp @@ -44,6 +44,7 @@ #include <qstyleoption.h> #include <qpainter.h> #include <qpixmapcache.h> +#include <qstringbuilder.h> #include <private/qmath_p.h> #include <private/qstyle_p.h> #include <qmath.h> @@ -56,22 +57,67 @@ QT_BEGIN_NAMESPACE +// internal helper. Converts an integer value to an unique string token +template <typename T> +struct HexString +{ + inline HexString(const T t) + : val(t) + {} + + inline void write(QChar *&dest) const + { + const ushort hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + const char *c = reinterpret_cast<const char *>(&val); + for (uint i = 0; i < sizeof(T); ++i) { + *dest++ = hexChars[*c & 0xf]; + *dest++ = hexChars[(*c & 0xf0) >> 4]; + ++c; + } + } + + const T val; +}; + +// specialization to enable fast concatenating of our string tokens to a string +template <typename T> +struct QConcatenable<HexString<T> > +{ + typedef HexString<T> type; + enum { ExactSize = true }; + static int size(const HexString<T> &str) { return sizeof(str.val) * 2; } + static inline void appendTo(const HexString<T> &str, QChar *&out) { str.write(out); } +}; + namespace QStyleHelper { QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size) { const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option); - QString tmp = QString::fromLatin1("%1-%2-%3-%4-%5-%6x%7").arg(key).arg(uint(option->state)).arg(option->direction) - .arg(complexOption ? uint(complexOption->activeSubControls) : uint(0)) - .arg(option->palette.cacheKey()).arg(size.width()).arg(size.height()); + + QString tmp = key + % QLatin1Char('-') + % HexString<uint>(option->state) + % QLatin1Char('-') + % HexString<uint>(option->direction) + % QLatin1Char('-') + % HexString<uint>(complexOption ? uint(complexOption->activeSubControls) : 0u) + % QLatin1Char('-') + % HexString<quint64>(option->palette.cacheKey()) + % QLatin1Char('-') + % HexString<uint>(size.width()) + % QLatin1Char('x') + % HexString<uint>(size.height()); + #ifndef QT_NO_SPINBOX if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { - tmp.append(QLatin1Char('-')); - tmp.append(QString::number(spinBox->buttonSymbols)); - tmp.append(QLatin1Char('-')); - tmp.append(QString::number(spinBox->stepEnabled)); - tmp.append(QLatin1Char('-')); - tmp.append(QLatin1Char(spinBox->frame ? '1' : '0')); + tmp = tmp + % QLatin1Char('-') + % HexString<uint>(spinBox->buttonSymbols) + % QLatin1Char('-') + % HexString<uint>(spinBox->stepEnabled) + % QLatin1Char('-') + % QLatin1Char(spinBox->frame ? '1' : '0'); } #endif // QT_NO_SPINBOX return tmp; diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index bc1bece..5376386 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -3457,10 +3457,17 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q case CE_RadioButton: case CE_CheckBox: - rule.drawRule(p, opt->rect); - ParentStyle::drawControl(ce, opt, p, w); - return; - + if (rule.hasBox() || !rule.hasNativeBorder() || rule.hasDrawable() || hasStyleRule(w, PseudoElement_Indicator)) { + rule.drawRule(p, opt->rect); + ParentStyle::drawControl(ce, opt, p, w); + return; + } else if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { + QStyleOptionButton butOpt(*btn); + rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button); + baseStyle()->drawControl(ce, &butOpt, p, w); + return; + } + break; case CE_RadioButtonLabel: case CE_CheckBoxLabel: if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) { diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index 6750c09..e594b7e 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -59,23 +59,24 @@ class QSyntaxHighlighterPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QSyntaxHighlighter) public: - inline QSyntaxHighlighterPrivate() : rehighlightPending(false) {} + inline QSyntaxHighlighterPrivate() + : rehighlightPending(false), inReformatBlocks(false) + {} QPointer<QTextDocument> doc; void _q_reformatBlocks(int from, int charsRemoved, int charsAdded); - void reformatBlock(QTextBlock block); - + void reformatBlocks(int from, int charsRemoved, int charsAdded); + void reformatBlock(const QTextBlock &block); + inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) { - QObject::disconnect(doc, SIGNAL(contentsChange(int,int,int)), - q_func(), SLOT(_q_reformatBlocks(int,int,int))); + inReformatBlocks = true; cursor.beginEditBlock(); int from = cursor.position(); cursor.movePosition(operation); - _q_reformatBlocks(from, 0, cursor.position() - from); + reformatBlocks(from, 0, cursor.position() - from); cursor.endEditBlock(); - QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), - q_func(), SLOT(_q_reformatBlocks(int,int,int))); + inReformatBlocks = false; } inline void _q_delayedRehighlight() { @@ -83,17 +84,19 @@ public: return; rehighlightPending = false; q_func()->rehighlight(); - return; } void applyFormatChanges(); QVector<QTextCharFormat> formatChanges; QTextBlock currentBlock; bool rehighlightPending; + bool inReformatBlocks; }; void QSyntaxHighlighterPrivate::applyFormatChanges() { + bool formatsChanged = false; + QTextLayout *layout = currentBlock.layout(); QList<QTextLayout::FormatRange> ranges = layout->additionalFormats(); @@ -101,19 +104,26 @@ void QSyntaxHighlighterPrivate::applyFormatChanges() const int preeditAreaStart = layout->preeditAreaPosition(); const int preeditAreaLength = layout->preeditAreaText().length(); - QList<QTextLayout::FormatRange>::Iterator it = ranges.begin(); - while (it != ranges.end()) { - if (it->start >= preeditAreaStart - && it->start + it->length <= preeditAreaStart + preeditAreaLength) - ++it; - else - it = ranges.erase(it); + if (preeditAreaLength != 0) { + QList<QTextLayout::FormatRange>::Iterator it = ranges.begin(); + while (it != ranges.end()) { + if (it->start >= preeditAreaStart + && it->start + it->length <= preeditAreaStart + preeditAreaLength) { + ++it; + } else { + it = ranges.erase(it); + formatsChanged = true; + } + } + } else if (!ranges.isEmpty()) { + ranges.clear(); + formatsChanged = true; } QTextCharFormat emptyFormat; QTextLayout::FormatRange r; - r.start = r.length = -1; + r.start = -1; int i = 0; while (i < formatChanges.count()) { @@ -135,34 +145,46 @@ void QSyntaxHighlighterPrivate::applyFormatChanges() r.length = i - r.start; - if (r.start >= preeditAreaStart) { - r.start += preeditAreaLength; - } else if (r.start + r.length >= preeditAreaStart) { - r.length += preeditAreaLength; + if (preeditAreaLength != 0) { + if (r.start >= preeditAreaStart) + r.start += preeditAreaLength; + else if (r.start + r.length >= preeditAreaStart) + r.length += preeditAreaLength; } ranges << r; - r.start = r.length = -1; + formatsChanged = true; + r.start = -1; } if (r.start != -1) { r.length = formatChanges.count() - r.start; - if (r.start >= preeditAreaStart) { - r.start += preeditAreaLength; - } else if (r.start + r.length >= preeditAreaStart) { - r.length += preeditAreaLength; + if (preeditAreaLength != 0) { + if (r.start >= preeditAreaStart) + r.start += preeditAreaLength; + else if (r.start + r.length >= preeditAreaStart) + r.length += preeditAreaLength; } ranges << r; + formatsChanged = true; } - layout->setAdditionalFormats(ranges); + if (formatsChanged) { + layout->setAdditionalFormats(ranges); + doc->markContentsDirty(currentBlock.position(), currentBlock.length()); + } } void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int charsAdded) { - Q_UNUSED(charsRemoved); + if (!inReformatBlocks) + reformatBlocks(from, charsRemoved, charsAdded); +} + +void QSyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded) +{ rehighlightPending = false; QTextBlock block = doc->findBlock(from); @@ -191,21 +213,18 @@ void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, in formatChanges.clear(); } -void QSyntaxHighlighterPrivate::reformatBlock(QTextBlock block) +void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block) { Q_Q(QSyntaxHighlighter); Q_ASSERT_X(!currentBlock.isValid(), "QSyntaxHighlighter::reformatBlock()", "reFormatBlock() called recursively"); currentBlock = block; - QTextBlock previous = block.previous(); formatChanges.fill(QTextCharFormat(), block.length() - 1); q->highlightBlock(block.text()); applyFormatChanges(); - doc->markContentsDirty(block.position(), block.length()); - currentBlock = QTextBlock(); } @@ -349,8 +368,8 @@ void QSyntaxHighlighter::setDocument(QTextDocument *doc) if (d->doc) { connect(d->doc, SIGNAL(contentsChange(int,int,int)), this, SLOT(_q_reformatBlocks(int,int,int))); - QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight())); d->rehighlightPending = true; + QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight())); } } @@ -391,11 +410,16 @@ void QSyntaxHighlighter::rehighlight() void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) { Q_D(QSyntaxHighlighter); - if (!d->doc) + if (!d->doc || !block.isValid() || block.document() != d->doc) return; + const bool rehighlightPending = d->rehighlightPending; + QTextCursor cursor(block); d->rehighlight(cursor, QTextCursor::EndOfBlock); + + if (rehighlightPending) + d->rehighlightPending = rehighlightPending; } /*! @@ -460,7 +484,6 @@ void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) void QSyntaxHighlighter::setFormat(int start, int count, const QTextCharFormat &format) { Q_D(QSyntaxHighlighter); - if (start < 0 || start >= d->formatChanges.count()) return; @@ -628,7 +651,7 @@ QTextBlockUserData *QSyntaxHighlighter::currentBlockUserData() const \since 4.4 Returns the current text block. - */ +*/ QTextBlock QSyntaxHighlighter::currentBlock() const { Q_D(const QSyntaxHighlighter); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 02eae98..b826588 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -81,7 +81,7 @@ public: void generate(int start, int length, QFont::Capitalization caps) { if ((int)caps == (int)QFont::SmallCaps) - generateScriptItemsSmallCaps(m_string.utf16(), start, length); + generateScriptItemsSmallCaps(reinterpret_cast<const ushort *>(m_string.unicode()), start, length); else if(caps == QFont::Capitalize) generateScriptItemsCapitalize(start, length); else if(caps != QFont::MixedCase) { @@ -1434,9 +1434,7 @@ void QTextEngine::itemize() const layoutData->hasBidi = bidiItemize(const_cast<QTextEngine *>(this), analysis, control); } - const ushort *unicode = layoutData->string.utf16(); - // correctly assign script, isTab and isObject to the script analysis - const ushort *uc = unicode; + const ushort *uc = reinterpret_cast<const ushort *>(layoutData->string.unicode()); const ushort *e = uc + length; int lastScript = QUnicodeTables::Common; while (uc < e) { diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index 4a6235c..7e2f20d 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1248,8 +1248,11 @@ void QAbstractSpinBox::contextMenuEvent(QContextMenuEvent *event) #else Q_D(QAbstractSpinBox); - d->reset(); QPointer<QMenu> menu = d->edit->createStandardContextMenu(); + if (!menu) + return; + + d->reset(); QAction *selAll = new QAction(tr("&Select All"), menu); menu->insertAction(d->edit->d_func()->selectAllAction, diff --git a/src/gui/widgets/qlabel_p.h b/src/gui/widgets/qlabel_p.h index 21eb128..fba7224 100644 --- a/src/gui/widgets/qlabel_p.h +++ b/src/gui/widgets/qlabel_p.h @@ -55,7 +55,7 @@ #include "qlabel.h" -#include "../text/qtextdocumentlayout_p.h" +#include "private/qtextdocumentlayout_p.h" #include "private/qtextcontrol_p.h" #include "qtextdocumentfragment.h" #include "qframe_p.h" diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index db099e8..9ec0feb 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE Updates the display text based of the current edit text If the text has changed will emit displayTextChanged() */ -void QLineControl::updateDisplayText() +void QLineControl::updateDisplayText(bool forceUpdate) { QString orig = m_textLayout.text(); QString str; @@ -102,7 +102,7 @@ void QLineControl::updateDisplayText() m_textLayout.endLayout(); m_ascent = qRound(l.ascent()); - if (str != orig) + if (str != orig || forceUpdate) emit displayTextChanged(str); } @@ -476,7 +476,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event) } } m_textLayout.setAdditionalFormats(formats); - updateDisplayText(); + updateDisplayText(/*force*/ true); if (cursorPositionChanged) emitCursorPositionChanged(); if (isGettingInput) diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index d6f2705..3f1bc2c 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -239,7 +239,7 @@ private: void init(const QString &txt); void removeSelectedText(); void internalSetText(const QString &txt, int pos = -1, bool edited = true); - void updateDisplayText(); + void updateDisplayText(bool forceUpdate = false); void internalInsert(const QString &s); void internalDelete(bool wasBackspace = false); diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 0ba8b9f..817547c 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -383,8 +383,6 @@ void QLineEdit::setText(const QString& text) d->control->setText(text); } -// ### Qt 4.7: remove this #if guard -#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) /*! \since 4.7 @@ -414,7 +412,6 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText) update(); } } -#endif /*! \property QLineEdit::displayText @@ -542,11 +539,16 @@ void QLineEdit::setEchoMode(EchoMode mode) if (mode == (EchoMode)d->control->echoMode()) return; Qt::InputMethodHints imHints = inputMethodHints(); - if (mode == Password) { + if (mode == Password || mode == NoEcho) { imHints |= Qt::ImhHiddenText; } else { imHints &= ~Qt::ImhHiddenText; } + if (mode != Normal) { + imHints |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + } else { + imHints &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + } setInputMethodHints(imHints); d->control->setEchoMode(mode); update(); @@ -2038,9 +2040,10 @@ void QLineEdit::dropEvent(QDropEvent* e) */ void QLineEdit::contextMenuEvent(QContextMenuEvent *event) { - QMenu *menu = createStandardContextMenu(); - menu->setAttribute(Qt::WA_DeleteOnClose); - menu->popup(event->globalPos()); + if (QMenu *menu = createStandardContextMenu()) { + menu->setAttribute(Qt::WA_DeleteOnClose); + menu->popup(event->globalPos()); + } } #if defined(Q_WS_WIN) diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index fa04bfc..94e0dbe 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -83,10 +83,7 @@ class Q_GUI_EXPORT QLineEdit : public QWidget Q_PROPERTY(bool undoAvailable READ isUndoAvailable) Q_PROPERTY(bool redoAvailable READ isRedoAvailable) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) -// ### Qt 4.7: remove this #if guard -#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) -#endif public: explicit QLineEdit(QWidget* parent=0); @@ -102,11 +99,8 @@ public: QString displayText() const; -// ### Qt 4.7: remove this #if guard -#if (QT_VERSION >= 0x407000) || defined(Q_WS_MAEMO_5) QString placeholderText() const; void setPlaceholderText(const QString &); -#endif int maxLength() const; void setMaxLength(int); diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 4620597..bdab6fb 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -1478,7 +1478,8 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set) return; // ### Disable the unified toolbar when using anything but the native graphics system. - if (windowSurface()) + // ### Disable when using alien widgets as well + if (windowSurface() || testAttribute(Qt::WA_NativeWindow) == false) return; d->useHIToolBar = set; diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 9a4916e..ebc05d9 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -260,9 +260,6 @@ void QMenuPrivate::updateActionRects() const icone = style->pixelMetric(QStyle::PM_SmallIconSize, &opt, q); const int fw = style->pixelMetric(QStyle::PM_MenuPanelWidth, &opt, q); const int deskFw = style->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, &opt, q); - - const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width(); - const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); const int tearoffHeight = tearoff ? style->pixelMetric(QStyle::PM_MenuTearoffHeight, &opt, q) : 0; //for compatability now - will have to refactor this away.. @@ -336,7 +333,7 @@ void QMenuPrivate::updateActionRects() const if (!sz.isEmpty()) { - max_column_width = qMax(min_column_width, qMax(max_column_width, sz.width())); + max_column_width = qMax(max_column_width, sz.width()); //wrapping if (!scroll && y+sz.height()+vmargin > dh - (deskFw * 2)) { @@ -350,6 +347,10 @@ void QMenuPrivate::updateActionRects() const } max_column_width += tabWidth; //finally add in the tab width + const int sfcMargin = style->sizeFromContents(QStyle::CT_Menu, &opt, QApplication::globalStrut(), q).width() - QApplication::globalStrut().width(); + const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); + max_column_width = qMax(min_column_width, max_column_width); + //calculate position const int base_y = vmargin + fw + topmargin + diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 99c550f..2570cb5 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -924,14 +924,27 @@ static QString qt_mac_menu_merge_text(QMacMenuAction *action) else if (action->command == kHICommandQuit) ret = QMenuBar::tr("Quit %1").arg(qAppName()); #else - else if (action->menuItem == [loader aboutMenuItem]) - ret = QMenuBar::tr("About %1").arg(qAppName()); - else if (action->menuItem == [loader aboutQtMenuItem]) - ret = QMenuBar::tr("About Qt"); - else if (action->menuItem == [loader preferencesMenuItem]) - ret = QMenuBar::tr("Preferences"); - else if (action->menuItem == [loader quitMenuItem]) - ret = QMenuBar::tr("Quit %1").arg(qAppName()); + else if (action->menuItem == [loader aboutMenuItem]) { + if (action->action->text() == QString("About %1").arg(qAppName())) + ret = QMenuBar::tr("About %1").arg(qAppName()); + else + ret = action->action->text(); + } else if (action->menuItem == [loader aboutQtMenuItem]) { + if (action->action->text() == QString("About Qt")) + ret = QMenuBar::tr("About Qt"); + else + ret = action->action->text(); + } else if (action->menuItem == [loader preferencesMenuItem]) { + if (action->action->text() == QString("Preferences")) + ret = QMenuBar::tr("Preferences"); + else + ret = action->action->text(); + } else if (action->menuItem == [loader quitMenuItem]) { + if (action->action->text() == QString("Quit %1").arg(qAppName())) + ret = QMenuBar::tr("About %1").arg(qAppName()); + else + ret = action->action->text(); + } #endif return ret; } @@ -2180,3 +2193,4 @@ static OSMenuRef qt_mac_create_menu(QWidget *w) QT_END_NAMESPACE + |