diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-30 08:44:56 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-30 08:44:56 (GMT) |
commit | 36c82d1a6c6d84b95c65b9df48d38093cadfd94a (patch) | |
tree | f172db63847b2240f22db5fae4df07a9eab0fa7e /src/gui | |
parent | 1acc9bcf4c43851af2096539eda88da9ef58bce3 (diff) | |
parent | b371999d3e9c207047be6afda89d008b6cf04763 (diff) | |
download | Qt-36c82d1a6c6d84b95c65b9df48d38093cadfd94a.zip Qt-36c82d1a6c6d84b95c65b9df48d38093cadfd94a.tar.gz Qt-36c82d1a6c6d84b95c65b9df48d38093cadfd94a.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7
Diffstat (limited to 'src/gui')
63 files changed, 696 insertions, 553 deletions
diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/gui/animation/qguivariantanimation.cpp index 52303f5..28cde3e 100644 --- a/src/gui/animation/qguivariantanimation.cpp +++ b/src/gui/animation/qguivariantanimation.cpp @@ -38,12 +38,11 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - -#ifndef QT_NO_ANIMATION - #include <QtCore/qvariantanimation.h> #include <private/qvariantanimation_p.h> +#ifndef QT_NO_ANIMATION + #include <QtGui/qcolor.h> #include <QtGui/qvector2d.h> #include <QtGui/qvector3d.h> diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 3b5fb9f..cb74a3c 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -723,15 +723,19 @@ void QFileDialog::setVisible(bool visible) // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below // updates the state correctly, but skips showing the non-native version: setAttribute(Qt::WA_DontShowOnScreen); +#ifndef QT_NO_FSCOMPLETER //So the completer don't try to complete and therefore to show a popup d->completer->setModel(0); +#endif } else { d->nativeDialogInUse = false; setAttribute(Qt::WA_DontShowOnScreen, false); +#ifndef QT_NO_FSCOMPLETER if (d->proxyModel != 0) d->completer->setModel(d->proxyModel); else d->completer->setModel(d->model); +#endif } } diff --git a/src/gui/dialogs/qfiledialog.ui b/src/gui/dialogs/qfiledialog.ui index b52bd8a..1f35abb 100644 --- a/src/gui/dialogs/qfiledialog.ui +++ b/src/gui/dialogs/qfiledialog.ui @@ -83,6 +83,12 @@ <property name="toolTip" > <string>Back</string> </property> + <property name="accessibleName"> + <string>Back</string> + </property> + <property name="accessibleDescription"> + <string>Go back</string> + </property> </widget> </item> <item> @@ -90,6 +96,12 @@ <property name="toolTip" > <string>Forward</string> </property> + <property name="accessibleName"> + <string>Forward</string> + </property> + <property name="accessibleDescription"> + <string>Go forward</string> + </property> </widget> </item> <item> @@ -97,6 +109,12 @@ <property name="toolTip" > <string>Parent Directory</string> </property> + <property name="accessibleName"> + <string>Parent Directory</string> + </property> + <property name="accessibleDescription"> + <string>Go to the parent directory</string> + </property> </widget> </item> <item> @@ -104,6 +122,12 @@ <property name="toolTip" > <string>Create New Folder</string> </property> + <property name="accessibleName"> + <string>Create New Folder</string> + </property> + <property name="accessibleDescription"> + <string>Create a New Folder</string> + </property> </widget> </item> <item> @@ -111,6 +135,12 @@ <property name="toolTip" > <string>List View</string> </property> + <property name="accessibleName"> + <string>List View</string> + </property> + <property name="accessibleDescription"> + <string>Change to list view mode</string> + </property> </widget> </item> <item> @@ -118,6 +148,12 @@ <property name="toolTip" > <string>Detail View</string> </property> + <property name="accessibleName"> + <string>Detail View</string> + </property> + <property name="accessibleDescription"> + <string>Change to detail view mode</string> + </property> </widget> </item> </layout> diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index afeed8e..258707c 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -218,7 +218,6 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent, memset(ofn, 0, sizeof(OPENFILENAME)); ofn->lStructSize = sizeof(OPENFILENAME); - Q_ASSERT(!parent ||parent->testAttribute(Qt::WA_WState_Created)); ofn->hwndOwner = parent ? parent->winId() : 0; ofn->lpstrFilter = (wchar_t*)tFilters.utf16(); ofn->lpstrFile = tInitSel; diff --git a/src/gui/dialogs/qprintdialog_unix.cpp b/src/gui/dialogs/qprintdialog_unix.cpp index 9b4d6e8..e3c62be 100644 --- a/src/gui/dialogs/qprintdialog_unix.cpp +++ b/src/gui/dialogs/qprintdialog_unix.cpp @@ -703,7 +703,7 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p) } #endif -#ifndef QT_NO_FILESYSTEMMODEL +#if !defined(QT_NO_FILESYSTEMMODEL) && !defined(QT_NO_COMPLETER) QFileSystemModel *fsm = new QFileSystemModel(widget.filename); fsm->setRootPath(QDir::homePath()); widget.filename->setCompleter(new QCompleter(fsm, widget.filename)); diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index 540cd3d..f81add6 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -139,6 +139,12 @@ QT_BEGIN_NAMESPACE typedef void *EGLImageKHR; #define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) #define EGL_IMAGE_PRESERVED_KHR 0x30D2 +#define EGL_KHR_image_base +#endif + +#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_pixmap) +#define EGL_NATIVE_PIXMAP_KHR 0x30B0 +#define EGL_KHR_image_pixmap #endif // It is possible that something has included eglext.h (like Symbian 10.1's broken egl.h), in @@ -154,9 +160,6 @@ extern Q_GUI_EXPORT _eglCreateImageKHR eglCreateImageKHR; extern Q_GUI_EXPORT _eglDestroyImageKHR eglDestroyImageKHR; #endif // (defined(EGL_KHR_image) || defined(EGL_KHR_image_base)) && !defined(EGL_EGLEXT_PROTOTYPES) -#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_pixmap) -#define EGL_NATIVE_PIXMAP_KHR 0x30B0 -#endif class QEglProperties; diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 91423c8..5341ea1 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -147,9 +147,6 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) EGLint configAlphaSize = 0; eglGetConfigAttrib(display(), config, EGL_ALPHA_SIZE, &configAlphaSize); - eglGetConfigAttrib(display(), config, EGL_BUFFER_SIZE, &eglValue); - int configBitDepth = eglValue; - eglGetConfigAttrib(display(), config, EGL_CONFIG_ID, &eglValue); int configId = eglValue; @@ -166,28 +163,53 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) int matchingCount = 0; chosenVisualInfo = XGetVisualInfo(X11->display, VisualIDMask, &visualInfoTemplate, &matchingCount); if (chosenVisualInfo) { - if (configBitDepth == chosenVisualInfo->depth) { + int visualRedSize = countBits(chosenVisualInfo->red_mask); + int visualGreenSize = countBits(chosenVisualInfo->green_mask); + int visualBlueSize = countBits(chosenVisualInfo->blue_mask); + int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size + #if !defined(QT_NO_XRENDER) + if (X11->use_xrender) { // If we have XRender, actually check the visual supplied by EGL is ARGB - if (configAlphaSize > 0) { - XRenderPictFormat *format; - format = XRenderFindVisualFormat(X11->display, chosenVisualInfo->visual); - if (!format || (format->type != PictTypeDirect) || (!format->direct.alphaMask)) { - qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this is not ARGB", - (int)visualId, configId); - visualId = 0; - } - } + XRenderPictFormat *format; + format = XRenderFindVisualFormat(X11->display, chosenVisualInfo->visual); + if (format && (format->type == PictTypeDirect)) + visualAlphaSize = countBits(format->direct.alphaMask); + } #endif - } else { - qWarning("Warning: EGL suggested using X visual ID %d (%d bpp) for config %d (%d bpp), but the depths do not match!", - (int)visualId, chosenVisualInfo->depth, configId, configBitDepth); + + bool visualMatchesConfig = false; + if ( visualRedSize == configRedSize && + visualGreenSize == configGreenSize && + visualBlueSize == configBlueSize ) + { + // We need XRender to check the alpha channel size of the visual. If we don't have + // the alpha size, we don't check it against the EGL config's alpha size. + if (visualAlphaSize >= 0) + visualMatchesConfig = visualAlphaSize == configAlphaSize; + else + visualMatchesConfig = true; + } + + if (!visualMatchesConfig) { + if (visualAlphaSize >= 0) { + qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable", + (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize, + configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize); + } else { + qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable", + (int)visualId, visualRedSize, visualGreenSize, visualBlueSize, + configId, configRedSize, configGreenSize, configBlueSize); + } visualId = 0; } + } else { + qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID", + (int)visualId, configId); + visualId = 0; } XFree(chosenVisualInfo); } - if (visualId) { #ifdef QT_DEBUG_X11_VISUAL_SELECTION if (configAlphaSize > 0) @@ -201,17 +223,16 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) // If EGL didn't give us a valid visual ID, try XRender #if !defined(QT_NO_XRENDER) - if (!visualId) { + if (!visualId && X11->use_xrender) { XVisualInfo visualInfoTemplate; memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); - visualInfoTemplate.depth = configBitDepth; visualInfoTemplate.c_class = TrueColor; XVisualInfo *matchingVisuals; int matchingCount = 0; matchingVisuals = XGetVisualInfo(X11->display, - VisualDepthMask|VisualClassMask, + VisualClassMask, &visualInfoTemplate, &matchingCount); @@ -246,19 +267,27 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) // Finally, if XRender also failed to find a visual (or isn't present), try to - // use XGetVisualInfo and only use the bit depth to match on: + // use XGetVisualInfo and only use the bit depths to match on: if (!visualId) { XVisualInfo visualInfoTemplate; memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); - - visualInfoTemplate.depth = configBitDepth; - XVisualInfo *matchingVisuals; int matchingCount = 0; + + visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize; matchingVisuals = XGetVisualInfo(X11->display, VisualDepthMask, &visualInfoTemplate, &matchingCount); + if (!matchingVisuals) { + // Try again without taking the alpha channel into account: + visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize; + matchingVisuals = XGetVisualInfo(X11->display, + VisualDepthMask, + &visualInfoTemplate, + &matchingCount); + } + if (matchingVisuals) { visualId = matchingVisuals[0].visualid; XFree(matchingVisuals); diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp index 8a21022..1effcfa 100644 --- a/src/gui/embedded/qscreenlinuxfb_qws.cpp +++ b/src/gui/embedded/qscreenlinuxfb_qws.cpp @@ -91,6 +91,7 @@ public: int startuph; int startupd; bool blank; + QLinuxFbScreen::DriverTypes driverType; bool doGraphicsMode; #ifdef QT_QWS_DEPTH_GENERIC @@ -165,6 +166,36 @@ void QLinuxFbScreenPrivate::closeTty() } /*! + \enum QLinuxFbScreen::DriverTypes + + This enum describes the driver type. + + \value GenericDriver Generic Linux framebuffer driver + \value EInk8Track e-Ink framebuffer driver using the 8Track chipset + */ + +/*! + \fn QLinuxFbScreen::fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo) + + Adjust the values returned by the framebuffer driver, to work + around driver bugs or nonstandard behavior in certain drivers. + \a finfo and \a vinfo specify the fixed and variable screen info + returned by the driver. + */ +void QLinuxFbScreen::fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo) +{ + // 8Track e-ink devices (as found in Sony PRS-505) lie + // about their bit depth -- they claim they're 1 bit per + // pixel while the only supported mode is 8 bit per pixel + // grayscale. + // Caused by this, they also miscalculate their line length. + if(!strcmp(finfo.id, "8TRACKFB") && vinfo.bits_per_pixel == 1) { + vinfo.bits_per_pixel = 8; + finfo.line_length = vinfo.xres; + } +} + +/*! \internal \class QLinuxFbScreen @@ -306,6 +337,8 @@ bool QLinuxFbScreen::connect(const QString &displaySpec) return false; } + d_ptr->driverType = strcmp(finfo.id, "8TRACKFB") ? GenericDriver : EInk8Track; + if (finfo.type == FB_TYPE_VGA_PLANES) { qWarning("VGA16 video mode not supported"); return false; @@ -318,6 +351,8 @@ bool QLinuxFbScreen::connect(const QString &displaySpec) return false; } + fixupScreenInfo(finfo, vinfo); + grayscale = vinfo.grayscale; d = vinfo.bits_per_pixel; if (d == 24) { @@ -664,11 +699,6 @@ bool QLinuxFbScreen::initDevice() vinfo.transp.msb_right); #endif - d_ptr->startupw=vinfo.xres; - d_ptr->startuph=vinfo.yres; - d_ptr->startupd=vinfo.bits_per_pixel; - grayscale = vinfo.grayscale; - if (ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) { perror("QLinuxFbScreen::initDevice"); qCritical("Error reading fixed information in card init"); @@ -677,6 +707,13 @@ bool QLinuxFbScreen::initDevice() return true; } + fixupScreenInfo(finfo, vinfo); + + d_ptr->startupw=vinfo.xres; + d_ptr->startuph=vinfo.yres; + d_ptr->startupd=vinfo.bits_per_pixel; + grayscale = vinfo.grayscale; + #ifdef __i386__ // Now init mtrr if(!::getenv("QWS_NOMTRR")) { @@ -1122,6 +1159,7 @@ void QLinuxFbScreen::setMode(int nw,int nh,int nd) qFatal("Error reading fixed information"); } + fixupScreenInfo(finfo, vinfo); disconnect(); connect(d_ptr->displaySpec); exposeRegion(region(), 0); @@ -1200,6 +1238,26 @@ int QLinuxFbScreen::sharedRamSize(void * end) /*! \reimp */ +void QLinuxFbScreen::setDirty(const QRect &r) +{ + if(d_ptr->driverType == EInk8Track) { + // e-Ink displays need a trigger to actually show what is + // in their framebuffer memory. The 8-Track driver does this + // by adding custom IOCTLs - FBIO_EINK_DISP_PIC (0x46a2) takes + // an argument specifying whether or not to flash the screen + // while updating. + // There doesn't seem to be a way to tell it to just update + // a subset of the screen. + if(r.left() == 0 && r.top() == 0 && r.width() == dw && r.height() == dh) + ioctl(d_ptr->fd, 0x46a2, 1); + else + ioctl(d_ptr->fd, 0x46a2, 0); + } +} + +/*! + \reimp +*/ void QLinuxFbScreen::blank(bool on) { if (d_ptr->blank == on) @@ -1315,7 +1373,9 @@ void QLinuxFbScreen::setPixelFormat(struct fb_var_screeninfo info) bool QLinuxFbScreen::useOffscreen() { - if ((mapsize - size) < 16*1024) + // Not done for 8Track because on e-Ink displays, + // everything is offscreen anyway + if (d_ptr->driverType == EInk8Track || ((mapsize - size) < 16*1024)) return false; return true; diff --git a/src/gui/embedded/qscreenlinuxfb_qws.h b/src/gui/embedded/qscreenlinuxfb_qws.h index ac488b7..6abadbf 100644 --- a/src/gui/embedded/qscreenlinuxfb_qws.h +++ b/src/gui/embedded/qscreenlinuxfb_qws.h @@ -88,6 +88,8 @@ public: virtual bool useOffscreen(); + enum DriverTypes { GenericDriver, EInk8Track }; + virtual void disconnect(); virtual void shutdownDevice(); virtual void setMode(int,int,int); @@ -98,6 +100,7 @@ public: virtual uchar * cache(int); virtual void uncache(uchar *); virtual int sharedRamSize(void *); + virtual void setDirty(const QRect&); QLinuxFb_Shared * shared; @@ -109,6 +112,7 @@ protected: int dataoffset; int cacheStart; + virtual void fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo); static void clearCache(QScreen *instance, int); private: diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index d6daf4d..150343e 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -7615,11 +7615,26 @@ void QGraphicsObject::updateMicroFocus() QGraphicsItem::updateMicroFocus(); } -void QGraphicsItemPrivate::append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item) +void QGraphicsItemPrivate::children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item) { QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast<QGraphicsObject *>(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0); } +int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObject> *list) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object)); + return d->children.count(); +} + +QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index) +{ + QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object)); + if (index >= 0 && index < d->children.count()) + return d->children.at(index)->toGraphicsObject(); + else + return 0; +} + /*! Returns a list of this item's children. @@ -7632,7 +7647,8 @@ QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList() Q_Q(QGraphicsItem); if (isObject) { QGraphicsObject *that = static_cast<QGraphicsObject *>(q); - return QDeclarativeListProperty<QGraphicsObject>(that, &children, QGraphicsItemPrivate::append); + return QDeclarativeListProperty<QGraphicsObject>(that, &children, children_append, + children_count, children_at); } else { //QGraphicsItem is not supported for this property return QDeclarativeListProperty<QGraphicsObject>(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 73b8f04..922581d 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -480,9 +480,12 @@ public: void resetFocusProxy(); virtual void subFocusItemChange(); + static void children_append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item); + static int children_count(QDeclarativeListProperty<QGraphicsObject> *list); + static QGraphicsObject *children_at(QDeclarativeListProperty<QGraphicsObject> *list, int); + inline QTransform transformToParent() const; inline void ensureSortedChildren(); - static void append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item); static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b); void ensureSequentialSiblingIndex(); inline void sendScenePosChange(); diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 483eb62..2132526 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -1435,7 +1435,7 @@ void QGraphicsProxyWidget::paint(QPainter *painter, const QStyleOptionGraphicsIt return; // Filter out repaints on the window frame. - const QRect exposedWidgetRect = (option->exposedRect & rect()).toRect(); + const QRect exposedWidgetRect = (option->exposedRect & rect()).toAlignedRect(); if (exposedWidgetRect.isEmpty()) return; diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 8e439be..bc8ccb01 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1116,13 +1116,13 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant & QApplication::sendEvent(this, &event); break; } - case ItemCursorChange: { + case ItemCursorHasChanged: { // Deliver CursorChange. QEvent event(QEvent::CursorChange); QApplication::sendEvent(this, &event); break; } - case ItemToolTipChange: { + case ItemToolTipHasChanged: { // Deliver ToolTipChange. QEvent event(QEvent::ToolTipChange); QApplication::sendEvent(this, &event); diff --git a/src/gui/gui.pro b/src/gui/gui.pro index b22f732..300a03f 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -55,7 +55,7 @@ DEFINES += Q_INTERNAL_QAPP_SRC symbian { TARGET.UID3=0x2001B2DD - symbian-abld:symbian-sbsv2 { + symbian-abld|symbian-sbsv2 { # ro-section in gui can exceed default allocated space, so move rw-section a little further QMAKE_LFLAGS.ARMCC += --rw-base 0x800000 QMAKE_LFLAGS.GCCE += -Tdata 0xC00000 diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index ce1d6d3..d226baf 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -5709,6 +5709,9 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) else *this = convertToFormat(QImage::Format_ARGB32_Premultiplied); + if (isNull()) + return; + // Slight optimization since alphachannels are returned as 8-bit grays. if (alphaChannel.d->depth == 8 && alphaChannel.isGrayscale()) { const uchar *src_data = alphaChannel.d->data; diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index a5f7b31..503a1b2 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -197,6 +197,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device, for (int i = 0; i < keys.size(); ++i) { QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i))); if (plugin && (plugin->capabilities(device, testFormat) & QImageIOPlugin::CanWrite)) { + delete handler; handler = plugin->create(device, testFormat); break; } diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 5a882af..6bebefc 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -383,7 +383,7 @@ struct QX11AlphaDetector return has; // Will implicitly also check format and return quickly for opaque types... checked = true; - has = const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels(); + has = image->isNull() ? false : const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels(); return has; } diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index f321ab3..5dbd1f0 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -254,7 +254,9 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX); #endif - if (val) { + + // Even if GetFileInfo returns a valid result, hIcon can be empty in some cases + if (val && info.hIcon) { if (fileInfo.isDir() && !fileInfo.isRoot()) { //using the unique icon index provided by windows save us from duplicate keys key = QString::fromLatin1("qt_dir_%1").arg(info.iIcon); @@ -293,7 +295,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX); #endif - if (val) { + if (val && info.hIcon) { if (fileInfo.isDir() && !fileInfo.isRoot()) { //using the unique icon index provided by windows save us from duplicate keys key = QString::fromLatin1("qt_dir_%1").arg(info.iIcon); diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index d6e68f6..f848321 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -292,6 +292,27 @@ static void indexesFromRange(const QItemSelectionRange &range, QModelIndexList & } /*! + Returns true if the selection range contains no selectable item + \since 4.7 +*/ + +bool QItemSelectionRange::isEmpty() const +{ + if (!isValid() || !model()) + return true; + + for (int column = left(); column <= right(); ++column) { + for (int row = top(); row <= bottom(); ++row) { + QModelIndex index = model()->index(row, column, parent()); + Qt::ItemFlags flags = model()->flags(index); + if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled)) + return false; + } + } + return true; +} + +/*! Returns the list of model index items stored in the selection. */ diff --git a/src/gui/itemviews/qitemselectionmodel.h b/src/gui/itemviews/qitemselectionmodel.h index 9980d0f..436514f 100644 --- a/src/gui/itemviews/qitemselectionmodel.h +++ b/src/gui/itemviews/qitemselectionmodel.h @@ -108,6 +108,8 @@ public: && top() <= bottom() && left() <= right()); } + bool isEmpty() const; + QModelIndexList indexes() const; private: diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 43445b4..80334a6 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -114,15 +114,14 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height) } } else if (old_height > span->height()) { //remove the span from all the subspans lists that intersect the columns not covered anymore - Index::iterator it_y = index.lowerBound(-span->bottom()); - if (it_y == index.end()) - it_y = index.find(-span->top()); // This is the only span remaining and we are deleting it. + Index::iterator it_y = index.lowerBound(-qMax(span->bottom(), span->top())); //qMax usefull if height is 0 Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list while (-it_y.key() <= span->top() + old_height -1) { if (-it_y.key() > span->bottom()) { - (*it_y).remove(-span->left()); + int removed = (*it_y).remove(-span->left()); + Q_ASSERT(removed == 1); Q_UNUSED(removed); if (it_y->isEmpty()) { - it_y = index.erase(it_y) - 1; + it_y = index.erase(it_y); } } if(it_y == index.begin()) @@ -1847,7 +1846,9 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF selection.append(QItemSelectionRange(topLeft, bottomRight)); } } else { // nothing moved - selection.append(QItemSelectionRange(tl, br)); + QItemSelectionRange range(tl, br); + if (!range.isEmpty()) + selection.append(range); } d->selectionModel->select(selection, command); diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index c3ff2bd..b797776 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -3428,25 +3428,6 @@ int QTreeViewPrivate::columnAt(int x) const return header->logicalIndexAt(x); } -void QTreeViewPrivate::relayout(const QModelIndex &parent) -{ - Q_Q(QTreeView); - // do a local relayout of the items - if (parent.isValid()) { - int parentViewIndex = viewIndex(parent); - if (parentViewIndex > -1 && viewItems.at(parentViewIndex).expanded) { - collapse(parentViewIndex, false); // remove the current layout - expand(parentViewIndex, false); // do the relayout - q->updateGeometries(); - viewport->update(); - } - } else { - viewItems.clear(); - q->doItemsLayout(); - } -} - - void QTreeViewPrivate::updateScrollBars() { Q_Q(QTreeView); diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 261af31..cbbfd0e 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -150,7 +150,6 @@ public: int columnAt(int x) const; bool hasVisibleChildren( const QModelIndex& parent) const; - void relayout(const QModelIndex &parent); bool expandOrCollapseItemAtPos(const QPoint &pos); void updateScrollBars(); diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp index 19ed10b..4c80325 100644 --- a/src/gui/itemviews/qtreewidget.cpp +++ b/src/gui/itemviews/qtreewidget.cpp @@ -3039,10 +3039,14 @@ QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const Q_D(const QTreeWidget); QModelIndexList indexes = selectionModel()->selectedIndexes(); QList<QTreeWidgetItem*> items; + items.reserve(indexes.count()); + QSet<QTreeWidgetItem *> seen; + seen.reserve(indexes.count()); for (int i = 0; i < indexes.count(); ++i) { QTreeWidgetItem *item = d->item(indexes.at(i)); - if (isItemHidden(item) || items.contains(item)) // ### slow, optimize later + if (isItemHidden(item) || seen.contains(item)) continue; + seen.insert(item); items.append(item); } return items; diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp index 8ddd051..a6d2594 100644 --- a/src/gui/kernel/qaction.cpp +++ b/src/gui/kernel/qaction.cpp @@ -81,6 +81,7 @@ static QString qt_strippedText(QString s) QActionPrivate::QActionPrivate() : group(0), enabled(1), forceDisabled(0), visible(1), forceInvisible(0), checkable(0), checked(0), separator(0), fontSet(false), + forceEnabledInSoftkeys(false), menuActionSoftkeys(false), menuRole(QAction::TextHeuristicRole), softKeyRole(QAction::NoSoftKey), priority(QAction::NormalPriority), iconVisibleInMenu(-1) { diff --git a/src/gui/kernel/qaction_p.h b/src/gui/kernel/qaction_p.h index b57e5d2..899b01b 100644 --- a/src/gui/kernel/qaction_p.h +++ b/src/gui/kernel/qaction_p.h @@ -75,6 +75,11 @@ public: QActionPrivate(); ~QActionPrivate(); + static QActionPrivate *get(QAction *q) + { + return q->d_func(); + } + bool showStatusText(QWidget *w, const QString &str); QPointer<QActionGroup> group; @@ -103,10 +108,16 @@ public: uint checked : 1; uint separator : 1; uint fontSet : 1; - QAction::MenuRole menuRole; - QAction::SoftKeyRole softKeyRole; - QAction::Priority priority; + + //for soft keys management + uint forceEnabledInSoftkeys : 1; + uint menuActionSoftkeys : 1; + + QAction::MenuRole menuRole : 3; + QAction::SoftKeyRole softKeyRole : 2; + QAction::Priority priority : 14; int iconVisibleInMenu : 3; // Only has values -1, 0, and 1 + QList<QWidget *> widgets; #ifndef QT_NO_GRAPHICSVIEW QList<QGraphicsWidget *> graphicsWidgets; diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index be2683d..b0a23d4 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -5292,9 +5292,9 @@ QInputContext *QApplication::inputContext() const QApplication *that = const_cast<QApplication *>(this); const QStringList keys = QInputContextFactory::keys(); // Try hbim and coefep first, then try others. - if (keys.contains("hbim")) { + if (keys.contains(QLatin1String("hbim"))) { that->d_func()->inputContext = QInputContextFactory::create(QLatin1String("hbim"), that); - } else if (keys.contains("coefep")) { + } else if (keys.contains(QLatin1String("coefep"))) { that->d_func()->inputContext = QInputContextFactory::create(QLatin1String("coefep"), that); } else { for (int c = 0; c < keys.size() && !d->inputContext; ++c) { diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 28072fc..321492d 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1221,7 +1221,7 @@ void qt_init(QApplicationPrivate *priv, int) } #endif - if (!app_proc_ae_handlerUPP) { + if (!app_proc_ae_handlerUPP && !QApplication::testAttribute(Qt::AA_MacPluginApplication)) { app_proc_ae_handlerUPP = AEEventHandlerUPP(QApplicationPrivate::globalAppleEventProcessor); for(uint i = 0; i < sizeof(app_apple_events) / sizeof(QMacAppleEventTypeSpec); ++i) { // Install apple event handler, but avoid overwriting an already @@ -2446,25 +2446,30 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event } if(!handled_event) { if(cmd.commandID == kHICommandQuit) { - handled_event = true; - HiliteMenu(0); - bool handle_quit = true; - if(QApplicationPrivate::modalState()) { - int visible = 0; - const QWidgetList tlws = QApplication::topLevelWidgets(); - for(int i = 0; i < tlws.size(); ++i) { - if(tlws.at(i)->isVisible()) - ++visible; + // Quitting the application is not Qt's responsibility if + // used in a plugin or just embedded into a native application. + // In that case, let the event pass down to the native apps event handler. + if (!QApplication::testAttribute(Qt::AA_MacPluginApplication)) { + handled_event = true; + HiliteMenu(0); + bool handle_quit = true; + if(QApplicationPrivate::modalState()) { + int visible = 0; + const QWidgetList tlws = QApplication::topLevelWidgets(); + for(int i = 0; i < tlws.size(); ++i) { + if(tlws.at(i)->isVisible()) + ++visible; + } + handle_quit = (visible <= 1); + } + if(handle_quit) { + QCloseEvent ev; + QApplication::sendSpontaneousEvent(app, &ev); + if(ev.isAccepted()) + app->quit(); + } else { + QApplication::beep(); } - handle_quit = (visible <= 1); - } - if(handle_quit) { - QCloseEvent ev; - QApplication::sendSpontaneousEvent(app, &ev); - if(ev.isAccepted()) - app->quit(); - } else { - QApplication::beep(); } } else if(cmd.commandID == kHICommandSelectWindow) { if((GetCurrentKeyModifiers() & cmdKey)) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 25a7bbe..c735d1f 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -372,8 +372,13 @@ QSymbianControl::~QSymbianControl() { if (S60->curWin == this) S60->curWin = 0; - if (!QApplicationPrivate::is_app_closing) - setFocusSafely(false); + if (!QApplicationPrivate::is_app_closing) { + QT_TRY { + setFocusSafely(false); + } QT_CATCH(const std::exception&) { + // ignore exceptions, nothing can be done + } + } S60->appUi()->RemoveFromStack(this); delete m_longTapDetector; } @@ -989,7 +994,7 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) } #endif } else if (QApplication::activeWindow() == qwidget->window()) { - if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) { + if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) { QWidget *fw = QApplication::focusWidget(); if (fw) { QFocusEvent event(QEvent::FocusOut, Qt::PopupFocusReason); @@ -1239,6 +1244,7 @@ void qt_init(QApplicationPrivate * /* priv */, int) } S60->avkonComponentsSupportTransparency = false; + S60->menuBeingConstructed = false; #ifdef Q_WS_S60 TUid KCRUidAvkon = { 0x101F876E }; diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 129e0a5..ec00915 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp extern const QStringList& qEnabledDraggedTypes(); // qmime_mac.cpp -extern bool qt_blockCocoaSettingModalWindowLevel; // qeventdispatcher_mac_p.h Q_GLOBAL_STATIC(QPointer<QWidget>, currentDragTarget); @@ -102,30 +101,6 @@ QT_END_NAMESPACE return !(isPopup || isToolTip || isTool); } -- (void)orderWindow:(NSWindowOrderingMode)orderingMode relativeTo:(NSInteger)otherWindowNumber -{ - if (qt_blockCocoaSettingModalWindowLevel) { - // To avoid windows popping in front while restoring modal sessions - // in the event dispatcher, we block cocoa from ordering this window - // to front. The result of not doing this can be seen if executing - // a native color dialog on top of another executing dialog. - return; - } - [super orderWindow:orderingMode relativeTo:otherWindowNumber]; -} - -- (void)setLevel:(NSInteger)windowLevel -{ - if (qt_blockCocoaSettingModalWindowLevel) { - // To avoid windows popping in front while restoring modal sessions - // in the event dispatcher, we block cocoa from ordering this window - // to front. The result of not doing this can be seen if executing - // a native color dialog on top of another executing dialog. - return; - } - [super setLevel:windowLevel]; -} - - (void)toggleToolbarShown:(id)sender { macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]); diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 06eb7ff..9c5380b 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -657,23 +657,33 @@ static int qCocoaViewCount = 0; { if (!qwidget) return; - if (qwidgetprivate->data.in_destructor) return; - QEvent enterEvent(QEvent::Enter); - NSPoint windowPoint = [event locationInWindow]; - NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint]; - NSPoint viewPoint = [self convertPoint:windowPoint fromView:nil]; + if (!qAppInstance()->activeModalWidget() || QApplicationPrivate::tryModalHelper(qwidget, 0)) { + QEvent enterEvent(QEvent::Enter); + NSPoint windowPoint = [event locationInWindow]; + NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint]; + NSPoint viewPoint = [self convertPoint:windowPoint fromView:nil]; QApplication::sendEvent(qwidget, &enterEvent); qt_mouseover = qwidget; - // Update cursor and dispatch hover events. + // Update cursor icon: qt_mac_update_cursor_at_global_pos(flipPoint(globalPoint).toPoint()); - if (qwidget->testAttribute(Qt::WA_Hover) && - (!qAppInstance()->activePopupWidget() || qAppInstance()->activePopupWidget() == qwidget->window())) { - QHoverEvent he(QEvent::HoverEnter, QPoint(viewPoint.x, viewPoint.y), QPoint(-1, -1)); - QApplicationPrivate::instance()->notify_helper(qwidget, &he); + + // Send mouse move and hover events as well: + if (!qAppInstance()->activePopupWidget() || qAppInstance()->activePopupWidget() == qwidget->window()) { + if (qwidget->testAttribute(Qt::WA_MouseTracking)) { + NSEvent *mouseEvent = [NSEvent mouseEventWithType:NSMouseMoved + location:windowPoint modifierFlags:[event modifierFlags] timestamp:[event timestamp] + windowNumber:[event windowNumber] context:[event context] eventNumber:[event eventNumber] + clickCount:0 pressure:0]; + qt_mac_handleMouseEvent(self, mouseEvent, QEvent::MouseMove, Qt::NoButton); + } + if (qwidget->testAttribute(Qt::WA_Hover)) { + QHoverEvent he(QEvent::HoverEnter, QPoint(viewPoint.x, viewPoint.y), QPoint(-1, -1)); + QApplicationPrivate::instance()->notify_helper(qwidget, &he); + } } } } diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index a7f1224..0d93b9f 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -97,11 +97,6 @@ QT_BEGIN_NAMESPACE QT_USE_NAMESPACE /***************************************************************************** - Internal variables and functions - *****************************************************************************/ -bool qt_blockCocoaSettingModalWindowLevel = false; - -/***************************************************************************** Externals *****************************************************************************/ extern void qt_event_request_timer(MacTimerInfo *); //qapplication_mac.cpp @@ -752,7 +747,6 @@ bool QEventDispatcherMacPrivate::interrupt = false; #ifdef QT_MAC_USE_COCOA QStack<QCocoaModalSessionInfo> QEventDispatcherMacPrivate::cocoaModalSessionStack; bool QEventDispatcherMacPrivate::currentExecIsNSAppRun = false; -bool QEventDispatcherMacPrivate::modalSessionsTemporarilyStopped = false; bool QEventDispatcherMacPrivate::nsAppRunCalledByQt = false; bool QEventDispatcherMacPrivate::cleanupModalSessionsNeeded = false; NSModalSession QEventDispatcherMacPrivate::currentModalSessionCached = 0; @@ -788,19 +782,14 @@ void QEventDispatcherMacPrivate::temporarilyStopAllModalSessions() // we need to stop all the modal session first. To avoid changing // the stacking order of the windows while doing so, we put // up a block that is used in QCocoaWindow and QCocoaPanel: - QBoolBlocker block1(blockSendPostedEvents, true); - QBoolBlocker block2(qt_blockCocoaSettingModalWindowLevel, true); - int stackSize = cocoaModalSessionStack.size(); for (int i=stackSize-1; i>=0; --i) { QCocoaModalSessionInfo &info = cocoaModalSessionStack[i]; if (info.session) { - [NSApp runModalSession:info.session]; [NSApp endModalSession:info.session]; info.session = 0; } } - modalSessionsTemporarilyStopped = true; currentModalSessionCached = 0; } @@ -834,29 +823,12 @@ NSModalSession QEventDispatcherMacPrivate::currentModalSession() // When creating a modal session cocoa will rearrange the windows. // In order to avoid windows to be put behind another we need to // keep the window level. - { - int level = [window level]; - info.session = [NSApp beginModalSessionForWindow:window]; - [window setLevel:level]; - } + int level = [window level]; + info.session = [NSApp beginModalSessionForWindow:window]; + [window setLevel:level]; } currentModalSessionCached = info.session; } - - if (modalSessionsTemporarilyStopped && currentModalSessionCached) { - // After a call to temporarilyStopAllModalSessions, cocoa have - // now posted events to restore ended modal session windows to - // the correct window level. Those events will be processed - // _after_ our new calls to beginModalSessionForWindow have - // taken effect, which will end up stacking the windows wrong on - // screen. To work around this, we block cocoa from changing the - // stacking order of the windows, and flush out the pending events - // (the block is used in QCocoaWindow and QCocoaPanel): - QBoolBlocker block1(blockSendPostedEvents, true); - QBoolBlocker block2(qt_blockCocoaSettingModalWindowLevel, true); - [NSApp runModalSession:currentModalSessionCached]; - } - modalSessionsTemporarilyStopped = false; return currentModalSessionCached; } diff --git a/src/gui/kernel/qeventdispatcher_mac_p.h b/src/gui/kernel/qeventdispatcher_mac_p.h index 8ac7c65..a0afb84 100644 --- a/src/gui/kernel/qeventdispatcher_mac_p.h +++ b/src/gui/kernel/qeventdispatcher_mac_p.h @@ -176,7 +176,6 @@ public: static bool currentExecIsNSAppRun; static bool nsAppRunCalledByQt; static bool cleanupModalSessionsNeeded; - static bool modalSessionsTemporarilyStopped; static NSModalSession currentModalSessionCached; static NSModalSession currentModalSession(); static void updateChildrenWorksWhenModal(); diff --git a/src/gui/kernel/qgridlayout.cpp b/src/gui/kernel/qgridlayout.cpp index dbd3c01..81a4d04 100644 --- a/src/gui/kernel/qgridlayout.cpp +++ b/src/gui/kernel/qgridlayout.cpp @@ -1852,7 +1852,7 @@ void QGridLayout::invalidate() /*! \fn int QGridLayout::colSpacing(int col) const - Use columnSpacing() instead. + Use columnMinimumWidth() instead. */ /*! diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 923144a..04e4685 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -43,7 +43,7 @@ #include "qevent.h" #include "qbitmap.h" #include "private/qsoftkeymanager_p.h" -#include "private/qobject_p.h" +#include "private/qaction_p.h" #include "private/qsoftkeymanager_common_p.h" #ifdef Q_WS_S60 @@ -104,7 +104,7 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey; switch (standardKey) { case MenuSoftKey: // FALL-THROUGH - action->setProperty(MENU_ACTION_PROPERTY, QVariant(true)); // TODO: can be refactored away to use _q_action_menubar + QActionPrivate::get(action)->menuActionSoftkeys = true; case OkSoftKey: case SelectSoftKey: case DoneSoftKey: @@ -242,6 +242,7 @@ bool QSoftKeyManager::handleUpdateSoftKeys() d->requestedSoftKeyActions.clear(); bool recursiveMerging = false; QWidget *source = softkeySource(NULL, recursiveMerging); + d->initialSoftKeySource = source; while (source) { if (appendSoftkeys(*source, level)) ++level; @@ -254,16 +255,12 @@ bool QSoftKeyManager::handleUpdateSoftKeys() void QSoftKeyManager::setForceEnabledInSoftkeys(QAction *action) { - action->setProperty(FORCE_ENABLED_PROPERTY, QVariant(true)); + QActionPrivate::get(action)->forceEnabledInSoftkeys = true; } bool QSoftKeyManager::isForceEnabledInSofkeys(QAction *action) { - bool ret = false; - QVariant property = action->property(FORCE_ENABLED_PROPERTY); - if (property.isValid() && property.toBool()) - ret = true; - return ret; + return QActionPrivate::get(action)->forceEnabledInSoftkeys; } bool QSoftKeyManager::event(QEvent *e) diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h index 460d0dc..04ddf7d 100644 --- a/src/gui/kernel/qsoftkeymanager_common_p.h +++ b/src/gui/kernel/qsoftkeymanager_common_p.h @@ -70,6 +70,7 @@ protected: static QSoftKeyManager *self; QHash<QAction*, Qt::Key> keyedActions; QMultiHash<int, QAction*> requestedSoftKeyActions; + QWidget *initialSoftKeySource; }; @@ -79,4 +80,4 @@ QT_END_NAMESPACE QT_END_HEADER -#endif // QSOFTKEYMANAGER_COMMON_P_H
\ No newline at end of file +#endif // QSOFTKEYMANAGER_COMMON_P_H diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h index a5b258b..6eedfa8 100644 --- a/src/gui/kernel/qsoftkeymanager_p.h +++ b/src/gui/kernel/qsoftkeymanager_p.h @@ -63,9 +63,6 @@ QT_BEGIN_NAMESPACE class QSoftKeyManagerPrivate; -const char MENU_ACTION_PROPERTY[] = "_q_menuAction"; -const char FORCE_ENABLED_PROPERTY[] = "_q_forceEnabledInSoftkeys"; - class Q_AUTOTEST_EXPORT QSoftKeyManager : public QObject { Q_OBJECT diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp index 9812d72..e4990b1 100644 --- a/src/gui/kernel/qsoftkeymanager_s60.cpp +++ b/src/gui/kernel/qsoftkeymanager_s60.cpp @@ -46,6 +46,7 @@ #include "qmenubar.h" #include "private/qt_s60_p.h" #include "private/qmenu_p.h" +#include "private/qaction_p.h" #include "private/qsoftkeymanager_p.h" #include "private/qsoftkeymanager_s60_p.h" #include "private/qobject_p.h" @@ -312,17 +313,8 @@ bool QSoftKeyManagerPrivateS60::setMiddleSoftkey(CEikButtonGroupContainer &cba) bool QSoftKeyManagerPrivateS60::setRightSoftkey(CEikButtonGroupContainer &cba) { if (!setSoftkey(cba, QAction::NegativeSoftKey, RSK_POSITION)) { - Qt::WindowType windowType = Qt::Window; - QAction *action = requestedSoftKeyActions.value(0); - if (action) { - QWidget *actionParent = action->parentWidget(); - Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!"); - - QWidget *actionWindow = actionParent->window(); - Q_ASSERT_X(actionWindow, Q_FUNC_INFO, "Softkey action does not have window!"); - windowType = actionWindow->windowType(); - } - + const Qt::WindowType windowType = initialSoftKeySource + ? initialSoftKeySource->window()->windowType() : Qt::Window; if (windowType != Qt::Dialog && windowType != Qt::Popup) { QString text(QSoftKeyManager::tr("Exit")); TPtrC nativeText = qt_QString2TPtrC(text); @@ -374,17 +366,30 @@ void QSoftKeyManagerPrivateS60::updateSoftKeys_sys() nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation } +static void resetMenuBeingConstructed(TAny* /*aAny*/) +{ + S60->menuBeingConstructed = false; +} + +void QSoftKeyManagerPrivateS60::tryDisplayMenuBarL() +{ + CleanupStack::PushL(TCleanupItem(resetMenuBeingConstructed, NULL)); + S60->menuBeingConstructed = true; + S60->menuBar()->TryDisplayMenuBarL(); + CleanupStack::PopAndDestroy(); // Reset menuBeingConstructed to false in all cases +} + bool QSoftKeyManagerPrivateS60::handleCommand(int command) { QAction *action = realSoftKeyActions.value(command); if (action) { - QVariant property = action->property(MENU_ACTION_PROPERTY); - if (property.isValid() && property.toBool()) { - QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL()); + bool property = QActionPrivate::get(action)->menuActionSoftkeys; + if (property) { + QT_TRAP_THROWING(tryDisplayMenuBarL()); } else if (action->menu()) { // TODO: This is hack, in order to use exising QMenuBar implementation for Symbian // menubar needs to have widget to which it is associated. Since we want to associate - // menubar to action (which is inherited from QObejct), we create and associate QWidget + // menubar to action (which is inherited from QObject), we create and associate QWidget // to action and pass that for QMenuBar. This associates the menubar to action, and we // can have own menubar for each action. QWidget *actionContainer = action->property("_q_action_widget").value<QWidget*>(); @@ -403,15 +408,15 @@ bool QSoftKeyManagerPrivateS60::handleCommand(int command) action->setProperty("_q_action_widget", v); } qt_symbian_next_menu_from_action(actionContainer); - QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL()); - } else { - Q_ASSERT(action->softKeyRole() != QAction::NoSoftKey); - QWidget *actionParent = action->parentWidget(); - Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!"); - if (actionParent->isEnabled()) { - action->activate(QAction::Trigger); - return true; - } + QT_TRAP_THROWING(tryDisplayMenuBarL()); + } + + Q_ASSERT(action->softKeyRole() != QAction::NoSoftKey); + QWidget *actionParent = action->parentWidget(); + Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!"); + if (actionParent->isEnabled()) { + action->activate(QAction::Trigger); + return true; } } return false; diff --git a/src/gui/kernel/qsoftkeymanager_s60_p.h b/src/gui/kernel/qsoftkeymanager_s60_p.h index a5e5016..d14993c 100644 --- a/src/gui/kernel/qsoftkeymanager_s60_p.h +++ b/src/gui/kernel/qsoftkeymanager_s60_p.h @@ -78,6 +78,7 @@ public: bool handleCommand(int command); private: + void tryDisplayMenuBarL(); bool skipCbaUpdate(); void ensureCbaVisibilityAndResponsiviness(CEikButtonGroupContainer &cba); void clearSoftkeys(CEikButtonGroupContainer &cba); diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index b1e4c94..a05c7d5 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -882,7 +882,15 @@ void qt_mac_dispatchNCMouseMessage(void * /* NSWindow* */eventWindow, void * /* } } - QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, button, keyMods); + Qt::MouseButtons buttons = 0; + { + UInt32 mac_buttons; + if (GetEventParameter((EventRef)[event eventRef], kEventParamMouseChord, typeUInt32, 0, + sizeof(mac_buttons), 0, &mac_buttons) == noErr) + buttons = qt_mac_get_buttons(mac_buttons); + } + + QMouseEvent qme(eventType, qlocalPoint, qglobalPoint, button, buttons, keyMods); qt_sendSpontaneousEvent(widgetToGetEvent, &qme); // We don't need to set the implicit grab widget here because we won't diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 7c6b754..a714221 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -122,6 +122,7 @@ public: int qtOwnsS60Environment : 1; int supportsPremultipliedAlpha : 1; int avkonComponentsSupportTransparency : 1; + int menuBeingConstructed : 1; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type static inline void updateScreenSize(); static inline RWsSession& wsSession(); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e88026c..4fba8cf 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1478,7 +1478,7 @@ QWidget::~QWidget() QObjectPrivate::clearGuards(this); if (d->declarativeData) { - d->declarativeData->destroyed(this); + QDeclarativeData::destroyed(d->declarativeData, this); d->declarativeData = 0; // don't activate again in ~QObject } @@ -1506,8 +1506,12 @@ QWidget::~QWidget() if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication QWidgetPrivate::allWidgets->remove(this); - QEvent e(QEvent::Destroy); - QCoreApplication::sendEvent(this, &e); + QT_TRY { + QEvent e(QEvent::Destroy); + QCoreApplication::sendEvent(this, &e); + } QT_CATCH(const std::exception&) { + // if this fails we can't do anything about it but at least we are not allowed to throw. + } } int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 3d86936..d7cd2eb 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -4267,6 +4267,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QMacCocoaAutoReleasePool pool; bool realWindow = isRealWindow(); + BOOL needDisplay = realWindow ? YES : NO; if (realWindow && !q->testAttribute(Qt::WA_DontShowOnScreen)){ adjustWithinMaxAndMinSize(w, h); @@ -4314,7 +4315,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) if (currTopLeft.x() == x && currTopLeft.y() == y && cocoaFrameRect.size.width != 0 && cocoaFrameRect.size.height != 0) { - [window setFrame:cocoaFrameRect display:NO]; + [window setFrame:cocoaFrameRect display:needDisplay]; } else { // The window is moved and resized (or resized to zero). // Since Cocoa usually only sends us a resize callback after @@ -4323,7 +4324,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) // would have the same origin as the setFrame call) we shift the // window back and forth inbetween. cocoaFrameRect.origin.y += 1; - [window setFrame:cocoaFrameRect display:NO]; + [window setFrame:cocoaFrameRect display:needDisplay]; cocoaFrameRect.origin.y -= 1; [window setFrameOrigin:cocoaFrameRect.origin]; } diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp index ea7fe4f..a08c79e 100644 --- a/src/gui/painting/qbezier.cpp +++ b/src/gui/painting/qbezier.cpp @@ -117,8 +117,8 @@ QBezier QBezier::mapBy(const QTransform &transform) const return QBezier::fromPoints(transform.map(pt1()), transform.map(pt2()), transform.map(pt3()), transform.map(pt4())); } -//0.5 is really low -static const qreal flatness = 0.5; +//0.05 is really low, but required for scaled-up beziers... +static const qreal flatness = 0.05; //based on "Fast, precise flattening of cubic Bezier path and offset curves" // by T. F. Hain, A. L. Ahmad, S. V. R. Racherla and D. D. Langan diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index a82d0f9..182cce9 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -989,7 +989,8 @@ QDebug operator<<(QDebug dbg, const QBrush &b) "LinearGradientPattern", "RadialGradientPattern", "ConicalGradientPattern", - "TexturePattern" + 0, 0, 0, 0, 0, 0, + "TexturePattern" // 24 }; dbg.nospace() << "QBrush(" << b.color() << ',' << BRUSH_STYLES[b.style()] << ')'; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 917b910..b440fce 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -70,8 +70,10 @@ static uint gccBug(uint value) constants and structures */ -static const int fixed_scale = 1 << 16; -static const int half_point = 1 << 15; +enum { + fixed_scale = 1 << 16, + half_point = 1 << 15 +}; static const int buffer_size = 2048; struct LinearGradientValues @@ -691,37 +693,42 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * fy -= half_point; while (b < end) { int x1 = (fx >> 16); - int x2 = x1 + 1; + int x2; int y1 = (fy >> 16); - int y2 = y1 + 1; - - int distx = ((fx - (x1 << 16)) >> 8); - int disty = ((fy - (y1 << 16)) >> 8); - int idistx = 256 - distx; - int idisty = 256 - disty; + int y2; if (blendType == BlendTransformedBilinearTiled) { x1 %= image_width; + if (x1 < 0) x1 += image_width; + x2 = x1 + 1; x2 %= image_width; - y1 %= image_height; - y2 %= image_height; - if (x1 < 0) x1 += image_width; - if (x2 < 0) x2 += image_width; + y1 %= image_height; if (y1 < 0) y1 += image_height; - if (y2 < 0) y2 += image_height; - - Q_ASSERT(x1 >= 0 && x1 < image_width); - Q_ASSERT(x2 >= 0 && x2 < image_width); - Q_ASSERT(y1 >= 0 && y1 < image_height); - Q_ASSERT(y2 >= 0 && y2 < image_height); + y2 = y1 + 1; + y2 %= image_height; } else { - x1 = qBound(0, x1, image_width - 1); - x2 = qBound(0, x2, image_width - 1); - y1 = qBound(0, y1, image_height - 1); - y2 = qBound(0, y2, image_height - 1); + if (x1 < 0) { + x2 = x1 = 0; + } else if (x1 >= image_width - 1) { + x2 = x1 = image_width - 1; + } else { + x2 = x1 + 1; + } + if (y1 < 0) { + y2 = y1 = 0; + } else if (y1 >= image_height - 1) { + y2 = y1 = image_height - 1; + } else { + y2 = y1 + 1; + } } + Q_ASSERT(x1 >= 0 && x1 < image_width); + Q_ASSERT(x2 >= 0 && x2 < image_width); + Q_ASSERT(y1 >= 0 && y1 < image_height); + Q_ASSERT(y2 >= 0 && y2 < image_height); + const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); @@ -730,6 +737,11 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * uint bl = fetch(s2, x1, data->texture.colorTable); uint br = fetch(s2, x2, data->texture.colorTable); + int distx = (fx & 0x0000ffff) >> 8; + int disty = (fy & 0x0000ffff) >> 8; + int idistx = 256 - distx; + int idisty = 256 - disty; + uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); @@ -753,9 +765,9 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * const qreal py = fy * iw - 0.5; int x1 = int(px) - (px < 0); - int x2 = x1 + 1; + int x2; int y1 = int(py) - (py < 0); - int y2 = y1 + 1; + int y2; int distx = int((px - x1) * 256); int disty = int((py - y1) * 256); @@ -764,26 +776,36 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator * if (blendType == BlendTransformedBilinearTiled) { x1 %= image_width; + if (x1 < 0) x1 += image_width; + x2 = x1 + 1; x2 %= image_width; - y1 %= image_height; - y2 %= image_height; - if (x1 < 0) x1 += image_width; - if (x2 < 0) x2 += image_width; + y1 %= image_height; if (y1 < 0) y1 += image_height; - if (y2 < 0) y2 += image_height; - - Q_ASSERT(x1 >= 0 && x1 < image_width); - Q_ASSERT(x2 >= 0 && x2 < image_width); - Q_ASSERT(y1 >= 0 && y1 < image_height); - Q_ASSERT(y2 >= 0 && y2 < image_height); + y2 = y1 + 1; + y2 %= image_height; } else { - x1 = qBound(0, x1, image_width - 1); - x2 = qBound(0, x2, image_width - 1); - y1 = qBound(0, y1, image_height - 1); - y2 = qBound(0, y2, image_height - 1); + if (x1 < 0) { + x2 = x1 = 0; + } else if (x1 >= image_width - 1) { + x2 = x1 = image_width - 1; + } else { + x2 = x1 + 1; + } + if (y1 < 0) { + y2 = y1 = 0; + } else if (y1 >= image_height - 1) { + y2 = y1 = image_height - 1; + } else { + y2 = y1 + 1; + } } + Q_ASSERT(x1 >= 0 && x1 < image_width); + Q_ASSERT(x2 >= 0 && x2 < image_width); + Q_ASSERT(y1 >= 0 && y1 < image_height); + Q_ASSERT(y2 >= 0 && y2 < image_height); + const uchar *s1 = data->texture.scanLine(y1); const uchar *s2 = data->texture.scanLine(y2); @@ -5141,7 +5163,7 @@ static void blend_tiled_rgb444(int count, const QSpan *spans, void *userData) } -template <SpanMethod spanMethod> +template <SpanMethod spanMethod, TextureBlendType blendType> /* blendType must be either BlendTransformedBilinear or BlendTransformedBilinearTiled */ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); @@ -5154,10 +5176,12 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode]; uint buffer[buffer_size]; - int image_x1 = data->texture.x1; - int image_y1 = data->texture.y1; - int image_x2 = data->texture.x2; - int image_y2 = data->texture.y2; + const int image_x1 = data->texture.x1; + const int image_y1 = data->texture.y1; + const int image_x2 = data->texture.x2; + const int image_y2 = data->texture.y2; + const int image_width = data->texture.width; + const int image_height = data->texture.height; const int scanline_offset = data->texture.bytesPerLine / 4; if (data->fast_matrix) { @@ -5187,19 +5211,41 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const uint *b = buffer; while (b < end) { int x1 = (x >> 16); - int x2 = x1 + 1; + int x2; int y1 = (y >> 16); - int y2 = y1 + 1; - - int distx = ((x - (x1 << 16)) >> 8); - int disty = ((y - (y1 << 16)) >> 8); - int idistx = 256 - distx; - int idisty = 256 - disty; - - x1 = qBound(image_x1, x1, image_x2 - 1); - x2 = qBound(image_x1, x2, image_x2 - 1); - y1 = qBound(image_y1, y1, image_y2 - 1); - y2 = qBound(image_y1, y2, image_y2 - 1); + int y2; + + if (blendType == BlendTransformedBilinearTiled) { + x1 %= image_width; + if (x1 < 0) x1 += image_width; + x2 = x1 + 1; + x2 %= image_width; + + y1 %= image_height; + if (y1 < 0) y1 += image_height; + y2 = y1 + 1; + y2 %= image_height; + + Q_ASSERT(x1 >= 0 && x1 < image_width); + Q_ASSERT(x2 >= 0 && x2 < image_width); + Q_ASSERT(y1 >= 0 && y1 < image_height); + Q_ASSERT(y2 >= 0 && y2 < image_height); + } else { + if (x1 < image_x1) { + x2 = x1 = image_x1; + } else if (x1 >= image_x2 - 1) { + x2 = x1 = image_x2 - 1; + } else { + x2 = x1 + 1; + } + if (y1 < image_y1) { + y2 = y1 = image_y1; + } else if (y1 >= image_y2 - 1) { + y2 = y1 = image_y2 - 1; + } else { + y2 = y1 + 1; + } + } int y1_offset = y1 * scanline_offset; int y2_offset = y2 * scanline_offset; @@ -5216,6 +5262,11 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const uint br = image_bits[y2_offset + x2]; #endif + int distx = (x & 0x0000ffff) >> 8; + int disty = (y & 0x0000ffff) >> 8; + int idistx = 256 - distx; + int idisty = 256 - disty; + uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); @@ -5265,19 +5316,46 @@ Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_argb(int count, const const qreal py = y * iw - 0.5; int x1 = int(px) - (px < 0); - int x2 = x1 + 1; + int x2; int y1 = int(py) - (py < 0); - int y2 = y1 + 1; + int y2; int distx = int((px - x1) * 256); int disty = int((py - y1) * 256); int idistx = 256 - distx; int idisty = 256 - disty; - x1 = qBound(image_x1, x1, image_x2 - 1); - x2 = qBound(image_x1, x2, image_x2 - 1); - y1 = qBound(image_y1, y1, image_y2 - 1); - y2 = qBound(image_y1, y2, image_y2 - 1); + if (blendType == BlendTransformedBilinearTiled) { + x1 %= image_width; + if (x1 < 0) x1 += image_width; + x2 = x1 + 1; + x2 %= image_width; + + y1 %= image_height; + if (y1 < 0) y1 += image_height; + y2 = y1 + 1; + y2 %= image_height; + + Q_ASSERT(x1 >= 0 && x1 < image_width); + Q_ASSERT(x2 >= 0 && x2 < image_width); + Q_ASSERT(y1 >= 0 && y1 < image_height); + Q_ASSERT(y2 >= 0 && y2 < image_height); + } else { + if (x1 < image_x1) { + x2 = x1 = image_x1; + } else if (x1 >= image_x2 - 1) { + x2 = x1 = image_x2 - 1; + } else { + x2 = x1 + 1; + } + if (y1 < image_y1) { + y2 = y1 = image_y1; + } else if (y1 >= image_y2 - 1) { + y2 = y1 = image_y2 - 1; + } else { + y2 = y1 + 1; + } + } int y1_offset = y1 * scanline_offset; int y2_offset = y2 * scanline_offset; @@ -5366,17 +5444,27 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan SRC *b = buffer; while (b < end) { int x1 = (x >> 16); - int x2 = x1 + 1; + int x2; int y1 = (y >> 16); - int y2 = y1 + 1; + int y2; - const int distx = ((x - (x1 << 16)) >> 8); - const int disty = ((y - (y1 << 16)) >> 8); - x1 = qBound(src_minx, x1, src_maxx); - x2 = qBound(src_minx, x2, src_maxx); - y1 = qBound(src_miny, y1, src_maxy); - y2 = qBound(src_miny, y2, src_maxy); + const int distx = (x & 0x0000ffff) >> 8; + const int disty = (y & 0x0000ffff) >> 8; + if (x1 < src_minx) { + x2 = x1 = src_minx; + } else if (x1 >= src_maxx) { + x2 = x1 = src_maxx; + } else { + x2 = x1 + 1; + } + if (y1 < src_miny) { + y2 = y1 = src_miny; + } else if (y1 >= src_maxy) { + y2 = y1 = src_maxy; + } else { + y2 = y1 + 1; + } #if 0 if (x1 == x2) { if (y1 == y2) { @@ -5467,17 +5555,27 @@ Q_STATIC_TEMPLATE_FUNCTION void blendTransformedBilinear(int count, const QSpan const qreal py = y * iw - qreal(0.5); int x1 = int(px) - (px < 0); - int x2 = x1 + 1; + int x2; int y1 = int(py) - (py < 0); - int y2 = y1 + 1; + int y2; const int distx = int((px - x1) * 256); const int disty = int((py - y1) * 256); - x1 = qBound(src_minx, x1, src_maxx); - x2 = qBound(src_minx, x2, src_maxx); - y1 = qBound(src_miny, y1, src_maxy); - y2 = qBound(src_miny, y2, src_maxy); + if (x1 < src_minx) { + x2 = x1 = src_minx; + } else if (x1 >= src_maxx) { + x2 = x1 = src_maxx; + } else { + x2 = x1 + 1; + } + if (y1 < src_miny) { + y2 = y1 = src_miny; + } else if (y1 >= src_maxy) { + y2 = y1 = src_maxy; + } else { + y2 = y1 + 1; + } const SRC *src1 = (SRC*)data->texture.scanLine(y1); const SRC *src2 = (SRC*)data->texture.scanLine(y2); @@ -5646,197 +5744,6 @@ static void blend_transformed_bilinear_rgb444(int count, const QSpan *spans, voi } template <SpanMethod spanMethod> -Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_bilinear_tiled_argb(int count, const QSpan *spans, void *userData) -{ - QSpanData *data = reinterpret_cast<QSpanData *>(userData); - if (data->texture.format != QImage::Format_ARGB32_Premultiplied - && data->texture.format != QImage::Format_RGB32) { - blend_src_generic<spanMethod>(count, spans, userData); - return; - } - - CompositionFunction func = functionForMode[data->rasterBuffer->compositionMode]; - uint buffer[buffer_size]; - - int image_width = data->texture.width; - int image_height = data->texture.height; - const int scanline_offset = data->texture.bytesPerLine / 4; - - if (data->fast_matrix) { - // The increment pr x in the scanline - int fdx = (int)(data->m11 * fixed_scale); - int fdy = (int)(data->m12 * fixed_scale); - - while (count--) { - void *t = data->rasterBuffer->scanLine(spans->y); - - uint *target = ((uint *)t) + spans->x; - uint *image_bits = (uint *)data->texture.imageData; - - const qreal cx = spans->x + 0.5; - const qreal cy = spans->y + 0.5; - - int x = int((data->m21 * cy - + data->m11 * cx + data->dx) * fixed_scale) - half_point; - int y = int((data->m22 * cy - + data->m12 * cx + data->dy) * fixed_scale) - half_point; - - int length = spans->len; - const int coverage = (spans->coverage * data->texture.const_alpha) >> 8; - while (length) { - int l = qMin(length, buffer_size); - const uint *end = buffer + l; - uint *b = buffer; - while (b < end) { - int x1 = (x >> 16); - int x2 = (x1 + 1); - int y1 = (y >> 16); - int y2 = (y1 + 1); - - int distx = ((x - (x1 << 16)) >> 8); - int disty = ((y - (y1 << 16)) >> 8); - int idistx = 256 - distx; - int idisty = 256 - disty; - - x1 %= image_width; - x2 %= image_width; - y1 %= image_height; - y2 %= image_height; - - if (x1 < 0) x1 += image_width; - if (x2 < 0) x2 += image_width; - if (y1 < 0) y1 += image_height; - if (y2 < 0) y2 += image_height; - - Q_ASSERT(x1 >= 0 && x1 < image_width); - Q_ASSERT(x2 >= 0 && x2 < image_width); - Q_ASSERT(y1 >= 0 && y1 < image_height); - Q_ASSERT(y2 >= 0 && y2 < image_height); - - int y1_offset = y1 * scanline_offset; - int y2_offset = y2 * scanline_offset; - -#if defined(Q_IRIX_GCC3_3_WORKAROUND) - uint tl = gccBug(image_bits[y1_offset + x1]); - uint tr = gccBug(image_bits[y1_offset + x2]); - uint bl = gccBug(image_bits[y2_offset + x1]); - uint br = gccBug(image_bits[y2_offset + x2]); -#else - uint tl = image_bits[y1_offset + x1]; - uint tr = image_bits[y1_offset + x2]; - uint bl = image_bits[y2_offset + x1]; - uint br = image_bits[y2_offset + x2]; -#endif - - uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); - uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); - *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); - ++b; - x += fdx; - y += fdy; - } - if (spanMethod == RegularSpans) - func(target, buffer, l, coverage); - else - drawBufferSpan(data, buffer, buffer_size, - spans->x + spans->len - length, - spans->y, l, coverage); - target += l; - length -= l; - } - ++spans; - } - } else { - const qreal fdx = data->m11; - const qreal fdy = data->m12; - const qreal fdw = data->m13; - while (count--) { - void *t = data->rasterBuffer->scanLine(spans->y); - - uint *target = ((uint *)t) + spans->x; - uint *image_bits = (uint *)data->texture.imageData; - - const qreal cx = spans->x + 0.5; - const qreal cy = spans->y + 0.5; - - qreal x = data->m21 * cy + data->m11 * cx + data->dx; - qreal y = data->m22 * cy + data->m12 * cx + data->dy; - qreal w = data->m23 * cy + data->m13 * cx + data->m33; - - int length = spans->len; - const int coverage = (spans->coverage * data->texture.const_alpha) >> 8; - while (length) { - int l = qMin(length, buffer_size); - const uint *end = buffer + l; - uint *b = buffer; - while (b < end) { - const qreal iw = w == 0 ? 1 : 1 / w; - const qreal px = x * iw - 0.5; - const qreal py = y * iw - 0.5; - - int x1 = int(px) - (px < 0); - int x2 = x1 + 1; - int y1 = int(py) - (py < 0); - int y2 = y1 + 1; - - int distx = int((px - x1) * 256); - int disty = int((py - y1) * 256); - int idistx = 256 - distx; - int idisty = 256 - disty; - - x1 %= image_width; - x2 %= image_width; - y1 %= image_height; - y2 %= image_height; - - if (x1 < 0) x1 += image_width; - if (x2 < 0) x2 += image_width; - if (y1 < 0) y1 += image_height; - if (y2 < 0) y2 += image_height; - - Q_ASSERT(x1 >= 0 && x1 < image_width); - Q_ASSERT(x2 >= 0 && x2 < image_width); - Q_ASSERT(y1 >= 0 && y1 < image_height); - Q_ASSERT(y2 >= 0 && y2 < image_height); - - int y1_offset = y1 * scanline_offset; - int y2_offset = y2 * scanline_offset; - -#if defined(Q_IRIX_GCC3_3_WORKAROUND) - uint tl = gccBug(image_bits[y1_offset + x1]); - uint tr = gccBug(image_bits[y1_offset + x2]); - uint bl = gccBug(image_bits[y2_offset + x1]); - uint br = gccBug(image_bits[y2_offset + x2]); -#else - uint tl = image_bits[y1_offset + x1]; - uint tr = image_bits[y1_offset + x2]; - uint bl = image_bits[y2_offset + x1]; - uint br = image_bits[y2_offset + x2]; -#endif - - uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx); - uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx); - *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty); - ++b; - x += fdx; - y += fdy; - w += fdw; - } - if (spanMethod == RegularSpans) - func(target, buffer, l, coverage); - else - drawBufferSpan(data, buffer, buffer_size, - spans->x + spans->len - length, - spans->y, l, coverage); - target += l; - length -= l; - } - ++spans; - } - } -} - -template <SpanMethod spanMethod> Q_STATIC_TEMPLATE_FUNCTION void blend_transformed_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast<QSpanData *>(userData); @@ -6738,7 +6645,7 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 - SPANFUNC_POINTER(blend_transformed_bilinear_argb, RegularSpans), // ARGB32_Premultiplied + blend_transformed_bilinear_argb<RegularSpans, BlendTransformedBilinear>, // ARGB32_Premultiplied blend_transformed_bilinear_rgb565, blend_transformed_bilinear_argb8565, blend_transformed_bilinear_rgb666, @@ -6757,7 +6664,7 @@ static const ProcessSpans processTextureSpans[NBlendTypes][QImage::NImageFormats SPANFUNC_POINTER(blend_src_generic, RegularSpans), // Indexed8 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB32 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB32 - SPANFUNC_POINTER(blend_transformed_bilinear_tiled_argb, RegularSpans), // ARGB32_Premultiplied + blend_transformed_bilinear_argb<RegularSpans, BlendTransformedBilinearTiled>, // ARGB32_Premultiplied SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB16 SPANFUNC_POINTER(blend_src_generic, RegularSpans), // ARGB8565_Premultiplied SPANFUNC_POINTER(blend_src_generic, RegularSpans), // RGB666 @@ -6856,7 +6763,7 @@ static const ProcessSpans processTextureSpansCallback[NBlendTypes][QImage::NImag blend_src_generic<CallbackSpans>, // Indexed8 blend_src_generic<CallbackSpans>, // RGB32 blend_src_generic<CallbackSpans>, // ARGB32 - blend_transformed_bilinear_argb<CallbackSpans>, // ARGB32_Premultiplied + blend_transformed_bilinear_argb<CallbackSpans, BlendTransformedBilinear>, // ARGB32_Premultiplied blend_src_generic<CallbackSpans>, // RGB16 blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied blend_src_generic<CallbackSpans>, // RGB666 @@ -6875,7 +6782,7 @@ static const ProcessSpans processTextureSpansCallback[NBlendTypes][QImage::NImag blend_src_generic<CallbackSpans>, // Indexed8 blend_src_generic<CallbackSpans>, // RGB32 blend_src_generic<CallbackSpans>, // ARGB32 - blend_transformed_bilinear_tiled_argb<CallbackSpans>, // ARGB32_Premultiplied + blend_transformed_bilinear_argb<CallbackSpans, BlendTransformedBilinearTiled>, // ARGB32_Premultiplied blend_src_generic<CallbackSpans>, // RGB16 blend_src_generic<CallbackSpans>, // ARGB8565_Premultiplied blend_src_generic<CallbackSpans>, // RGB666 @@ -7135,6 +7042,11 @@ void qt_build_pow_tables() { int winSmooth; if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) smoothing = winSmooth / 1000.0; + + // Safeguard ourselves against corrupt registry values... + if (smoothing > 5 || smoothing < 1) + smoothing = 1.4; + #endif #ifdef Q_WS_X11 diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index f5b17ea..acf765c 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -69,6 +69,13 @@ QT_BEGIN_NAMESPACE +#if defined(Q_OS_MAC) && (defined(__ppc__) || defined(__ppc64__)) +#undef QT_HAVE_MMX +#undef QT_HAVE_SSE +#undef QT_HAVE_SSE2 +#undef QT_HAVE_3DNOW +#endif + #if defined(Q_CC_MSVC) && _MSCVER <= 1300 && !defined(Q_CC_INTEL) #define Q_STATIC_TEMPLATE_SPECIALIZATION static #else diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 949a820..00e74ba 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -935,10 +935,9 @@ qreal QWingedEdge::delta(int vertex, int a, int b) const qreal result = b_angle - a_angle; - if (qFuzzyIsNull(result) || qFuzzyCompare(result, 128)) - return 0; - - if (result < 0) + if (result >= 128.) + return result - 128.; + else if (result < 0) return result + 128.; else return result; diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 9eda0ef..631a9cf 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -79,6 +79,7 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const m_current_fontengine = fontEngine; const int margin = glyphMargin(); + const int paddingDoubled = glyphPadding() * 2; QHash<glyph_t, Coord> listItemCoordinates; int rowHeight = 0; @@ -124,7 +125,7 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const if (listItemCoordinates.isEmpty()) return; - rowHeight += margin * 2; + rowHeight += margin * 2 + paddingDoubled; if (isNull()) createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, qt_next_power_of_two(rowHeight)); @@ -138,7 +139,7 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const if (m_cx + c.w > m_w) { // no room on the current line, start new glyph strip m_cx = 0; - m_cy += m_currentRowHeight; + m_cy += m_currentRowHeight + paddingDoubled; m_currentRowHeight = 0; // New row } if (m_cy + c.h > m_h) { @@ -156,7 +157,7 @@ void QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const fillTexture(c, iter.key()); coords.insert(iter.key(), c); - m_cx += c.w; + m_cx += c.w + paddingDoubled; ++iter; } diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index 8c2f5b4..390fe51 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -98,6 +98,7 @@ public: virtual void createTextureData(int width, int height) = 0; virtual void resizeTextureData(int width, int height) = 0; virtual int glyphMargin() const { return 0; } + virtual int glyphPadding() const { return 0; } virtual void fillTexture(const Coord &coord, glyph_t glyph) = 0; diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index cc0ce08..a1a98ba 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -3169,8 +3169,8 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC if (subRule1.hasDrawable()) { QRect r(gr.topLeft(), slider->orientation == Qt::Horizontal - ? QPoint(hr.x()+hr.width()/2, gr.y()+gr.height()) - : QPoint(gr.x()+gr.width(), hr.y()+hr.height()/2)); + ? QPoint(hr.x()+hr.width()/2, gr.y()+gr.height() - 1) + : QPoint(gr.x()+gr.width() - 1, hr.y()+hr.height()/2)); subRule1.drawRule(p, r); } diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 938decd..b3d2526 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -895,7 +895,7 @@ void ValueExtractor::borderValue(const Declaration &decl, int *width, QCss::Bord BorderData data = qvariant_cast<BorderData>(decl.d->parsed); *width = lengthValueFromData(data.width, f); *style = data.style; - *color = brushFromData(data.color, pal); + *color = data.color.type != BrushData::Invalid ? brushFromData(data.color, pal) : QBrush(QColor()); return; } diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 99b9f40..24887b5 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1286,9 +1286,11 @@ QFont::StyleHint QFont::styleHint() const \value PreferAntialias antialias if possible. \value OpenGLCompatible forces the use of OpenGL compatible fonts. - \value NoFontMerging If a font does not contain a character requested - to draw then Qt automatically chooses a similar looking for that contains - the character. This flag disables this feature. + \value NoFontMerging If the font selected for a certain writing system + does not contain a character requested to draw, then Qt automatically chooses a similar + looking font that contains the character. The NoFontMerging flag disables this feature. + Please note that enabling this flag will not prevent Qt from automatically picking a + suitable font when the selected font does not support the writing system of the text. Any of these may be OR-ed with one of these flags: @@ -2614,8 +2616,10 @@ void QFontCache::cleanup() } QT_CATCH (const std::bad_alloc &) { // no cache - just ignore } - if (cache && cache->hasLocalData()) + if (cache && cache->hasLocalData()) { + cache->localData()->clear(); cache->setLocalData(0); + } } #endif // QT_NO_THREAD diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index 3ea084b..c9ff661 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -79,6 +79,31 @@ QByteArray QFontEngineS60Extensions::getSfntTable(uint tag) const return result; } +bool QFontEngineS60Extensions::getSfntTableData(uint tag, uchar *buffer, uint *length) const +{ + if (!m_trueTypeExtension->HasTrueTypeTable(tag)) + return false; + + bool result = true; + TInt error = KErrNone; + TInt tableByteLength; + TAny *table = + q_check_ptr(m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength)); + + if (error != KErrNone) { + return false; + } else if (*length > 0 && *length < tableByteLength) { + result = false; // Caller did not allocate enough memory + } else { + *length = tableByteLength; + if (buffer) + qMemCopy(buffer, table, tableByteLength); + } + + m_trueTypeExtension->ReleaseTrueTypeTable(table); + return result; +} + const unsigned char *QFontEngineS60Extensions::cmap() const { if (!m_cmap) { @@ -326,6 +351,11 @@ QByteArray QFontEngineS60::getSfntTable(uint tag) const return m_extensions->getSfntTable(tag); } +bool QFontEngineS60::getSfntTableData(uint tag, uchar *buffer, uint *length) const +{ + return m_extensions->getSfntTableData(tag, buffer, length); +} + QFontEngine::Type QFontEngineS60::type() const { return QFontEngine::S60FontEngine; diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h index 5834cc4..a80af4d 100644 --- a/src/gui/text/qfontengine_s60_p.h +++ b/src/gui/text/qfontengine_s60_p.h @@ -69,6 +69,7 @@ public: QFontEngineS60Extensions(CFont* fontOwner, COpenFont *font); QByteArray getSfntTable(uint tag) const; + bool getSfntTableData(uint tag, uchar *buffer, uint *length) const; const unsigned char *cmap() const; QPainterPath glyphOutline(glyph_t glyph) const; CFont *fontOwner() const; @@ -106,6 +107,7 @@ public: qreal minRightBearing() const { return 0; } QByteArray getSfntTable(uint tag) const; + bool getSfntTableData(uint tag, uchar *buffer, uint *length) const; static qreal pixelsToPoints(qreal pixels, Qt::Orientation orientation = Qt::Horizontal); static qreal pointsToPixels(qreal points, Qt::Orientation orientation = Qt::Horizontal); diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 671dfc0..3c596e5 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1201,7 +1201,8 @@ void QTextControlPrivate::keyPressEvent(QKeyEvent *e) blockFmt.setIndent(blockFmt.indent() - 1); cursor.setBlockFormat(blockFmt); } else { - cursor.deletePreviousChar(); + QTextCursor localCursor = cursor; + localCursor.deletePreviousChar(); } goto accept; } @@ -1239,7 +1240,8 @@ void QTextControlPrivate::keyPressEvent(QKeyEvent *e) } #endif else if (e == QKeySequence::Delete) { - cursor.deleteChar(); + QTextCursor localCursor = cursor; + localCursor.deleteChar(); } else if (e == QKeySequence::DeleteEndOfWord) { if (!cursor.hasSelection()) diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 302a349..e2bca04 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -870,6 +870,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) undoEnabled = false; beginEditBlock(); int editPos = -1; + int editLength = -1; while (1) { if (undo) --undoState; @@ -882,12 +883,16 @@ int QTextDocumentPrivate::undoRedo(bool undo) PMDEBUG(" erase: from %d, length %d", c.pos, c.length); c.command = QTextUndoCommand::Removed; editPos = c.pos; + editLength = 0; break; case QTextUndoCommand::Removed: PMDEBUG(" insert: format %d (from %d, length %d, strpos=%d)", c.format, c.pos, c.length, c.strPos); insert_string(c.pos, c.strPos, c.length, c.format, (QTextUndoCommand::Operation)c.operation); c.command = QTextUndoCommand::Inserted; - editPos = c.pos + c.length; + if (editPos != (int)c.pos) + editLength = 0; + editPos = c.pos; + editLength += c.length; break; case QTextUndoCommand::BlockInserted: case QTextUndoCommand::BlockAdded: @@ -898,6 +903,7 @@ int QTextDocumentPrivate::undoRedo(bool undo) else c.command = QTextUndoCommand::BlockDeleted; editPos = c.pos; + editLength = 0; break; case QTextUndoCommand::BlockRemoved: case QTextUndoCommand::BlockDeleted: @@ -908,7 +914,10 @@ int QTextDocumentPrivate::undoRedo(bool undo) c.command = QTextUndoCommand::BlockInserted; else c.command = QTextUndoCommand::BlockAdded; - editPos = c.pos + 1; + if (editPos != (int)c.pos) + editLength = 0; + editPos = c.pos; + editLength += 1; break; case QTextUndoCommand::CharFormatChanged: { resetBlockRevision = -1; // ## TODO @@ -919,7 +928,10 @@ int QTextDocumentPrivate::undoRedo(bool undo) int oldFormat = it.value()->format; setCharFormat(c.pos, c.length, formats.charFormat(c.format)); c.format = oldFormat; - editPos = c.pos + c.length; + if (editPos != (int)c.pos) + editLength = 0; + editPos = c.pos; + editLength += c.length; break; } case QTextUndoCommand::BlockFormatChanged: { @@ -987,13 +999,19 @@ int QTextDocumentPrivate::undoRedo(bool undo) break; } undoEnabled = true; - if (editPos < 0 && docChangeFrom >= 0) { - editPos = qMin(docChangeFrom + docChangeLength, length() - 1); - } + + int newCursorPos = -1; + + if (editPos >=0) + newCursorPos = editPos + editLength; + else if (docChangeFrom >= 0) + newCursorPos= qMin(docChangeFrom + docChangeLength, length() - 1); + endEditBlock(); emitUndoAvailable(isUndoAvailable()); emitRedoAvailable(isRedoAvailable()); - return editPos; + + return newCursorPos; } /*! diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 7dc2c26..6485966 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1647,7 +1647,7 @@ glyph_metrics_t QTextEngine::boundingBox(int from, int len) const } } - glyph_t glyph = glyphs.glyphs[logClusters[pos + ilen - 1]]; + glyph_t glyph = glyphs.glyphs[logClusters[ilen - 1]]; glyph_metrics_t gi = fe->boundingBox(glyph); if (gi.isValid()) gm.width -= qRound(gi.xoff - gi.x - gi.width); diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp index c095b3b..8e7ec80 100644 --- a/src/gui/util/qcompleter.cpp +++ b/src/gui/util/qcompleter.cpp @@ -1689,8 +1689,10 @@ QString QCompleter::pathFromIndex(const QModelIndex& index) const QString t; if (isDirModel) t = sourceModel->data(idx, Qt::EditRole).toString(); +#ifndef QT_NO_FILESYSTEMMODEL else t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString(); +#endif list.prepend(t); QModelIndex parent = idx.parent(); idx = parent.sibling(parent.row(), index.column()); diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp index cc74a53..732dbc9 100644 --- a/src/gui/widgets/qdialogbuttonbox.cpp +++ b/src/gui/widgets/qdialogbuttonbox.cpp @@ -258,6 +258,7 @@ static const int layouts[2][5][14] = } }; +#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION) class QDialogButtonEnabledProxy : public QObject { public: @@ -281,7 +282,7 @@ private: QWidget *source; QAction *target; }; - +#endif class QDialogButtonBoxPrivate : public QWidgetPrivate { @@ -314,7 +315,7 @@ public: void addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse); void retranslateStrings(); const char *standardButtonText(QDialogButtonBox::StandardButton sbutton) const; -#ifdef QT_SOFTKEYS_ENABLED +#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION) QAction *createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role); #endif }; @@ -571,7 +572,7 @@ void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBo QObject::connect(button, SIGNAL(clicked()), q, SLOT(_q_handleButtonClicked())); QObject::connect(button, SIGNAL(destroyed()), q, SLOT(_q_handleButtonDestroyed())); buttonLists[role].append(button); -#ifdef QT_SOFTKEYS_ENABLED +#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION) QAction *action = createSoftKey(button, role); softKeyActions.insert(button, action); new QDialogButtonEnabledProxy(action, button, action); @@ -580,7 +581,7 @@ void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBo layoutButtons(); } -#ifdef QT_SOFTKEYS_ENABLED +#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION) QAction* QDialogButtonBoxPrivate::createSoftKey(QAbstractButton *button, QDialogButtonBox::ButtonRole role) { Q_Q(QDialogButtonBox); @@ -718,7 +719,7 @@ void QDialogButtonBoxPrivate::retranslateStrings() if (buttonText) { QPushButton *button = it.key(); button->setText(QDialogButtonBox::tr(buttonText)); -#ifdef QT_SOFTKEYS_ENABLED +#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION) QAction *action = softKeyActions.value(button, 0); if (action) action->setText(button->text()); @@ -997,7 +998,7 @@ void QDialogButtonBox::removeButton(QAbstractButton *button) } } } -#ifdef QT_SOFTKEYS_ENABLED +#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION) QAction *action = d->softKeyActions.value(button, 0); if (action) { d->softKeyActions.remove(button); @@ -1243,7 +1244,7 @@ bool QDialogButtonBox::event(QEvent *event) }else if (event->type() == QEvent::LanguageChange) { d->retranslateStrings(); } -#ifdef QT_SOFTKEYS_ENABLED +#if defined(QT_SOFTKEYS_ENABLED) && !defined(QT_NO_ACTION) else if (event->type() == QEvent::ParentChange) { QWidget *dialog = 0; QWidget *p = this; diff --git a/src/gui/widgets/qframe.cpp b/src/gui/widgets/qframe.cpp index c2e4b35..f51ddfd 100644 --- a/src/gui/widgets/qframe.cpp +++ b/src/gui/widgets/qframe.cpp @@ -244,7 +244,7 @@ QFrame::~QFrame() /*! Returns the frame style. - The default value is QFrame::NoFrame. + The default value is QFrame::Plain. \sa setFrameStyle(), frameShape(), frameShadow() */ diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 404d46e..f9b132e 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1398,12 +1398,14 @@ QMenu::QMenu(QMenuPrivate &dd, QWidget *parent) QMenu::~QMenu() { Q_D(QMenu); - QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin(); - for (; it != d->widgetItems.end(); ++it) { - if (QWidget *widget = it.value()) { - QWidgetAction *action = static_cast<QWidgetAction *>(it.key()); - action->releaseWidget(widget); - *it = 0; + if (!d->widgetItems.isEmpty()) { // avoid detach on shared null hash + QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin(); + for (; it != d->widgetItems.end(); ++it) { + if (QWidget *widget = it.value()) { + QWidgetAction *action = static_cast<QWidgetAction *>(it.key()); + action->releaseWidget(widget); + *it = 0; + } } } @@ -1803,7 +1805,7 @@ QSize QMenu::sizeHint() const void QMenu::popup(const QPoint &p, QAction *atAction) { Q_D(QMenu); - if (d->scroll) { //reset scroll state from last popup + if (d->scroll) { // reset scroll state from last popup d->scroll->scrollOffset = 0; d->scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; } @@ -1858,9 +1860,9 @@ void QMenu::popup(const QPoint &p, QAction *atAction) } #endif if (d->ncols > 1) { - pos.setY(screen.top()+desktopFrame); + pos.setY(screen.top() + desktopFrame); } else if (atAction) { - for(int i = 0, above_height = 0; i < d->actions.count(); i++) { + for (int i = 0, above_height = 0; i < d->actions.count(); i++) { QAction *action = d->actions.at(i); if (action == atAction) { int newY = pos.y() - above_height; @@ -1875,7 +1877,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) { int below_height = above_height + d->scroll->scrollOffset; - for(int i2 = i; i2 < d->actionRects.count(); i2++) + for (int i2 = i; i2 < d->actionRects.count(); i2++) below_height += d->actionRects.at(i2).height(); size.setHeight(below_height); } @@ -1888,28 +1890,28 @@ void QMenu::popup(const QPoint &p, QAction *atAction) QPoint mouse = QCursor::pos(); d->mousePopupPos = mouse; - const bool snapToMouse = (QRect(p.x()-3, p.y()-3, 6, 6).contains(mouse)); + const bool snapToMouse = (QRect(p.x() - 3, p.y() - 3, 6, 6).contains(mouse)); if (adjustToDesktop) { - //handle popup falling "off screen" + // handle popup falling "off screen" if (isRightToLeft()) { - if(snapToMouse) //position flowing left from the mouse - pos.setX(mouse.x()-size.width()); + if (snapToMouse) // position flowing left from the mouse + pos.setX(mouse.x() - size.width()); #ifndef QT_NO_MENUBAR - //if in a menubar, it should be right-aligned + // if in a menubar, it should be right-aligned if (qobject_cast<QMenuBar*>(d->causedPopup.widget)) pos.rx() -= size.width(); #endif //QT_NO_MENUBAR - if (pos.x() < screen.left()+desktopFrame) - pos.setX(qMax(p.x(), screen.left()+desktopFrame)); - if (pos.x()+size.width()-1 > screen.right()-desktopFrame) - pos.setX(qMax(p.x()-size.width(), screen.right()-desktopFrame-size.width()+1)); + if (pos.x() < screen.left() + desktopFrame) + pos.setX(qMax(p.x(), screen.left() + desktopFrame)); + if (pos.x() + size.width() - 1 > screen.right() - desktopFrame) + pos.setX(qMax(p.x() - size.width(), screen.right() - desktopFrame - size.width() + 1)); } else { - if (pos.x()+size.width()-1 > screen.right()-desktopFrame) - pos.setX(screen.right()-desktopFrame-size.width()+1); - if (pos.x() < screen.left()+desktopFrame) + if (pos.x() + size.width() - 1 > screen.right() - desktopFrame) + pos.setX(screen.right() - desktopFrame - size.width() + 1); + if (pos.x() < screen.left() + desktopFrame) pos.setX(screen.left() + desktopFrame); } if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { @@ -1923,14 +1925,14 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if (pos.y() < screen.top() + desktopFrame) pos.setY(screen.top() + desktopFrame); - if (pos.y()+size.height()-1 > screen.bottom() - desktopFrame) { + if (pos.y() + size.height() - 1 > screen.bottom() - desktopFrame) { if (d->scroll) { d->scroll->scrollFlags |= uint(QMenuPrivate::QMenuScroller::ScrollDown); int y = qMax(screen.y(),pos.y()); - size.setHeight(screen.bottom()-(desktopFrame*2)-y); + size.setHeight(screen.bottom() - (desktopFrame * 2) - y); } else { // Too big for screen, bias to see bottom of menu (for some reason) - pos.setY(screen.bottom()-size.height()+1); + pos.setY(screen.bottom() - size.height() + 1); } } } @@ -1939,19 +1941,19 @@ void QMenu::popup(const QPoint &p, QAction *atAction) int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll; int vGuess = QEffects::DownScroll; if (isRightToLeft()) { - if ((snapToMouse && (pos.x() + size.width()/2 > mouse.x())) || - (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 > d->causedPopup.widget->x())) + if ((snapToMouse && (pos.x() + size.width() / 2 > mouse.x())) || + (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 > d->causedPopup.widget->x())) hGuess = QEffects::RightScroll; } else { - if ((snapToMouse && (pos.x() + size.width()/2 < mouse.x())) || - (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width()/2 < d->causedPopup.widget->x())) + if ((snapToMouse && (pos.x() + size.width() / 2 < mouse.x())) || + (qobject_cast<QMenu*>(d->causedPopup.widget) && pos.x() + size.width() / 2 < d->causedPopup.widget->x())) hGuess = QEffects::LeftScroll; } #ifndef QT_NO_MENUBAR - if ((snapToMouse && (pos.y() + size.height()/2 < mouse.y())) || + if ((snapToMouse && (pos.y() + size.height() / 2 < mouse.y())) || (qobject_cast<QMenuBar*>(d->causedPopup.widget) && - pos.y() + size.width()/2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y())) + pos.y() + size.width() / 2 < d->causedPopup.widget->mapToGlobal(d->causedPopup.widget->pos()).y())) vGuess = QEffects::UpScroll; #endif if (QApplication::isEffectEnabled(Qt::UI_AnimateMenu)) { diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index ef9fac3..2734fba 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -944,8 +944,8 @@ void QPlainTextEditPrivate::_q_adjustScrollbars() int vSliderLength = 0; if (!centerOnScroll && q->isVisible()) { QTextBlock block = doc->lastBlock(); - const int visible = static_cast<int>(viewport->rect().height() - margin - 1); - int y = 0; + const qreal visible = viewport->rect().height() - margin - 1; + qreal y = 0; int visibleFromBottom = 0; while (block.isValid()) { @@ -953,7 +953,7 @@ void QPlainTextEditPrivate::_q_adjustScrollbars() block = block.previous(); continue; } - y += int(documentLayout->blockBoundingRect(block).height()); + y += documentLayout->blockBoundingRect(block).height(); QTextLayout *layout = block.layout(); int layoutLineCount = layout->lineCount(); @@ -962,7 +962,7 @@ void QPlainTextEditPrivate::_q_adjustScrollbars() while (lineNumber < layoutLineCount) { QTextLine line = layout->lineAt(lineNumber); const QRectF lr = line.naturalTextRect(); - if (int(lr.top()) >= y - visible) + if (lr.top() >= y - visible) break; ++lineNumber; } |