From f0c21f86cdc9341b7dda2b4b2bca085954a79ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Mon, 30 Mar 2009 14:42:48 +0200 Subject: Mac: check for valid -arch arguments in configure. Allow x86 x86_64 ppc ppc64, exit with an error message if something else is passed? Reviewed-by: nrc --- configure | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/configure b/configure index 269d88c..f0b7f90 100755 --- a/configure +++ b/configure @@ -2692,6 +2692,18 @@ if [ "$QT_CROSS_COMPILE" = "yes" ]; then fi fi +# check -arch arguments for validity. +if [ "$PLATFORM_MAC" = "yes" ]; then + ALLOWED="x86 ppc x86_64 ppc64" + for i in $CFG_MAC_ARCHS + do + if echo "$ALLOWED" | grep -w -v "$i" > /dev/null 2>&1; then + echo "Unknown architecture: \"$i\". Supported architechtures: x86 ppc x86_64 ppc64"; + exit 2; + fi + done +fi + # find the default framework value if [ "$PLATFORM_MAC" = "yes" ] && [ "$PLATFORM" != "macx-xlc" ]; then if [ "$CFG_FRAMEWORK" = "auto" ]; then -- cgit v0.12 From 13d2c268b732ce07c249f341a6e1b9e1ff63e71d Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 30 Mar 2009 13:21:22 +0200 Subject: Adjust the opacity value for popups Seems that things are a little less transparent in 10.5 (and have a blur). Getting the blur in is going to be difficult, but adjusting the opacity will get us closer than we are now. Task-number: 249364 Reviewed-by: Jens Bache-Wiig --- src/gui/styles/qmacstyle_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index d598807..398e11d 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -2189,7 +2189,7 @@ void QMacStyle::polish(QWidget* w) } if (qobject_cast(w) || qobject_cast(w)) { - w->setWindowOpacity(0.94); + w->setWindowOpacity(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 ? 0.985 : 0.94); if (!w->testAttribute(Qt::WA_SetPalette)) { QPixmap px(64, 64); HIThemeMenuDrawInfo mtinfo; -- cgit v0.12 From 93a69b9cec71ca7e0140f83aeb4e31537eb9753e Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 30 Mar 2009 15:26:05 +0200 Subject: Don't send QFileOpenEvents for items on the command-line Cocoa actually has a nice feature that if you pass arguments on the command-line, Cocoa will pass those along as Open events later. This is probably how we should have handled things inside of Qt as it would have unified the file opening code. Unfortunately, we can't turn back time on this, so we need to prevent it because people probably aren't expecting it (i.e., they expect to do the parsing themselves, and not to get events later). This also means that we can send the event immediately instead of posting it, because the race that we had before no longer exists. We only do this check during launch time because that's the only time we may get bitten by it (people usually only parse the arguments once). Someday, people may actually WANT this functionality though. When that comes along, we should make it an application attribute. Task-number: 249553 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qcocoaapplicationdelegate_mac.mm | 24 ++++++++++++++++++++---- src/gui/kernel/qcocoaapplicationdelegate_mac_p.h | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index 650ebbd..e6bd511 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -107,6 +107,8 @@ static void cleanupCocoaApplicationDelegate() - (id)init { self = [super init]; + if (self) + inLaunch = true; return self; } @@ -198,12 +200,26 @@ static void cleanupCocoaApplicationDelegate() return reply; } +- (void)applicationDidFinishLaunching:(NSNotification *)aNotification +{ + Q_UNUSED(aNotification); + inLaunch = false; +} + - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames { - unsigned int ix; - for( ix = 0; ix < [filenames count]; ix++) { - NSString *fileName = [filenames objectAtIndex:ix]; - qApp->postEvent(qApp, new QFileOpenEvent(QCFString::toQString((CFStringRef)fileName))); + for (NSString *fileName in filenames) { + QString qtFileName = qt_mac_NSStringToQString(fileName); + if (inLaunch) { + // We need to be careful because Cocoa will be nice enough to take + // command line arguments and send them to us as events. Given the history + // of Qt Applications, this will result in behavior people don't want, as + // they might be doing the opening themselves with the command line parsing. + if (qApp->arguments().contains(qtFileName)) + continue; + } + QFileOpenEvent foe(qtFileName); + qt_sendSpontaneousEvent(qAppInstance(), &foe); } if (reflectionDelegate && diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h index c5336f1..fca2a15 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac_p.h @@ -107,6 +107,7 @@ QT_FORWARD_DECLARE_CLASS(QApplicationPrivate); NSMenu *dockMenu; QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *qtMenuLoader; id reflectionDelegate; + bool inLaunch; } + (QT_MANGLE_NAMESPACE(QCocoaApplicationDelegate)*)sharedDelegate; - (void)setDockMenu:(NSMenu *)newMenu; -- cgit v0.12 From 444ce6c3124c183c90d22a7d39756bf943d305a3 Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Mon, 30 Mar 2009 16:08:43 +0200 Subject: Make Qt/Embedded compile with the -no-feature-PICTURE switch. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PRINTER is dependant upon the PICTURE feature in 4.5, since the PDF and PS engines now uses the QAlphaPaintEngine internally. Task-number: 248568 Reviewed-by: Samuel Rødal --- src/corelib/global/qfeatures.txt | 122 +++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index c26c274..40ccb15 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -3,28 +3,28 @@ Feature: PROPERTIES Description: Supports scripting Qt-based applications. Section: Kernel -Requires: +Requires: Name: Properties SeeAlso: ??? Feature: TEXTHTMLPARSER Description: Parser for HTML Section: Kernel -Requires: +Requires: Name: HtmlParser SeeAlso: ??? Feature: TEXTODFWRITER Description: Provides an ODF writer Section: Kernel -Requires: XMLSTREAMWRITER +Requires: XMLSTREAMWRITER Name: OdfWriter SeeAlso: ??? Feature: CSSPARSER Description: Parser for Style Sheets Section: Kernel -Requires: +Requires: Name: CssParser SeeAlso: ??? @@ -52,21 +52,21 @@ SeeAlso: ??? Feature: SESSIONMANAGER Description: Supports session management. Section: Kernel -Requires: +Requires: Name: Session Manager SeeAlso: ??? Feature: SHORTCUT Description: Supports keyboard accelerators and shortcuts. Section: Kernel -Requires: +Requires: Name: QShortcut SeeAlso: ??? Feature: ACTION Description: Supports widget actions. Section: Kernel -Requires: +Requires: Name: QAction SeeAlso: ??? @@ -129,8 +129,8 @@ SeeAlso: ??? Feature: XMLSTREAM Description: Provides a simple streaming API for XML. Section: Kernel -Requires: -Name: +Requires: +Name: SeeAlso: ??? Feature: XMLSTREAMREADER @@ -159,14 +159,14 @@ SeeAlso: ??? Feature: QUUID_STRING Description: Supports convertion between UUID and strings. Section: Data structures -Requires: +Requires: Name: Universally Unique Identifier Convertion SeeAlso: ??? Feature: TEXTDATE Description: Supports month and day names in dates. Section: Data structures -Requires: +Requires: Name: Text Date SeeAlso: ??? @@ -210,7 +210,7 @@ SeeAlso: ??? Feature: SETTINGS Description: Supports persistent application settings. Section: File I/O -Requires: TEXTSTREAM +Requires: TEXTSTREAM Name: QSettings SeeAlso: ??? @@ -229,7 +229,7 @@ Name: QFileSystemModel SeeAlso: ??? Feature: FILESYSTEMWATCHER -Description: Provides an interface for monitoring files and directories +Description: Provides an interface for monitoring files and directories for modications. Section: File I/O Requires: THREAD @@ -239,7 +239,7 @@ SeeAlso: ??? # Widgets Feature: TREEWIDGET -Description: Supports views using tree models. +Description: Supports views using tree models. Section: Widgets Requires: TREEVIEW Name: QTreeWidget @@ -283,7 +283,7 @@ SeeAlso: ??? Feature: SPLASHSCREEN Description: Supports splash screens that can be shown during application startup. Section: Widgets -Requires: +Requires: Name: Splash screen widget SeeAlso: ??? @@ -295,7 +295,7 @@ Name: QSplitter SeeAlso: ??? Feature: LCDNUMBER -Description: Supports LCD-like digits. +Description: Supports LCD-like digits. Section: Widgets Requires: Name: QLCDNumber @@ -381,7 +381,7 @@ SeeAlso: ??? Feature: BUTTONGROUP Description: Supports organizing groups of button widgets. Section: Widgets -Requires: GROUPBOX +Requires: GROUPBOX Name: QButtonGroup SeeAlso: ??? @@ -393,7 +393,7 @@ Name: QMainWindow SeeAlso: ??? Feature: DOCKWIDGET -Description: Supports docking widgets inside a QMainWindow or floated as +Description: Supports docking widgets inside a QMainWindow or floated as a top-level window on the desktop. Section: Widgets Requires: RUBBERBAND MAINWINDOW @@ -401,7 +401,7 @@ Name: QDockwidget SeeAlso: ??? Feature: WORKSPACE -Description: Supports workspace windows, e.g. used in an MDI application. +Description: Supports workspace windows, e.g. used in an MDI application. Section: Widgets Requires: SCROLLBAR RESIZEHANDLER MENU TOOLBUTTON MAINWINDOW TOOLBAR MENUBAR Name: QWorkSpace @@ -457,8 +457,8 @@ Name: QSlider SeeAlso: ??? Feature: SCROLLBAR -Description: Supports scrollbars allowing the user access parts of a -document that is larger than the widget used to display it. +Description: Supports scrollbars allowing the user access parts of a +document that is larger than the widget used to display it. Section: Widgets Requires: SLIDER Name: QScrollBar @@ -500,7 +500,7 @@ Name: QTextEdit SeeAlso: ??? Feature: SYNTAXHIGHLIGHTER -Description: Supports custom syntax highlighting. +Description: Supports custom syntax highlighting. Section: Widgets Requires: TEXTEDIT Name: QSyntaxHighlighter @@ -556,7 +556,7 @@ Name: QSizeGrip SeeAlso: ??? Feature: CALENDARWIDGET -Description: Provides a monthly based calendar widget allowing the user to select +Description: Provides a monthly based calendar widget allowing the user to select a date. Section: Widgets Requires: TABLEVIEW MENU TEXTDATE SPINBOX TOOLBUTTON @@ -567,14 +567,14 @@ Feature: PRINTPREVIEWWIDGET Description: Provides a widget for previewing page layouts for printer output. a date. Section: Widgets -Requires: GRAPHICSVIEW PRINTER PICTURE +Requires: GRAPHICSVIEW PRINTER Name: QPrintPreviewWidget SeeAlso: ??? # Dialogs Feature: MESSAGEBOX -Description: Supports message boxes displaying +Description: Supports message boxes displaying informative messages and simple questions. Section: Dialogs Requires: @@ -589,7 +589,7 @@ Name: QColorDialog SeeAlso: ??? Feature: FILEDIALOG -Description: Supports a dialog widget for selecting files or directories. +Description: Supports a dialog widget for selecting files or directories. Section: Dialogs Requires: DIRMODEL TREEVIEW COMBOBOX TOOLBUTTON BUTTONGROUP TOOLTIP SPLITTER STACKEDWIDGET FILESYSTEMMODEL Name: QFileDialog @@ -654,7 +654,7 @@ SeeAlso: ??? # ItemViews Feature: ITEMVIEWS -Description: Supports the model/view architecture managing the relationship +Description: Supports the model/view architecture managing the relationship between data and the way it is presented to the user. Section: ItemViews Requires: RUBBERBAND SCROLLAREA @@ -683,8 +683,8 @@ Name: QAbstractProxyModel SeeAlso: ??? Feature: SORTFILTERPROXYMODEL -Description: Supports sorting and filtering of data passed between -another model and a view. +Description: Supports sorting and filtering of data passed between +another model and a view. Section: ItemViews Requires: PROXYMODEL Name: QSortFilterProxyModel @@ -705,9 +705,9 @@ Name: QListView SeeAlso: ??? Feature: TABLEVIEW -Description: Supports a default model/view implementation of a table view. +Description: Supports a default model/view implementation of a table view. Section: ItemViews -Requires: ITEMVIEWS +Requires: ITEMVIEWS Name: QTableView SeeAlso: ??? @@ -735,21 +735,21 @@ SeeAlso: ??? # Styles Feature: STYLE_WINDOWS -Description: Supports a Microsoft Windows-like look and feel. +Description: Supports a Microsoft Windows-like look and feel. Section: Styles Requires: Name: QWindowsStyle SeeAlso: ??? Feature: STYLE_MOTIF -Description: Supports a Motif look and feel. +Description: Supports a Motif look and feel. Section: Styles Requires: Name: QMotifStyle SeeAlso: ??? Feature: STYLE_CDE -Description: Supports a CDE look and feel. +Description: Supports a CDE look and feel. Section: Styles Requires: STYLE_MOTIF Name: QCDEStyle @@ -798,7 +798,7 @@ Name: QWindowsMobileStyle SeeAlso: ??? Feature: STYLE_STYLESHEET -Description: +Description: Section: Styles Requires: STYLE_WINDOWS PROPERTIES CSSPARSER Name: QStyleSheetStyle @@ -809,14 +809,14 @@ SeeAlso: ??? Feature: IMAGEFORMATPLUGIN Description: Supports writing an image format plugin. Section: Images -Requires: +Requires: Name: QImageIOPlugin SeeAlso: ??? Feature: ICON Description: Supports scalable icons in different modes and states. Section: Images -Requires: +Requires: Name: QIcon SeeAlso: ??? @@ -837,14 +837,14 @@ SeeAlso: ??? Feature: IMAGEFORMAT_PPM Description: Supports the Portable Pixmap image file format. Section: Images -Requires: +Requires: Name: PPM Image Format SeeAlso: ??? Feature: IMAGEFORMAT_XBM Description: Supports the X11 Bitmap image file format. Section: Images -Requires: +Requires: Name: XBM Image Format SeeAlso: ??? @@ -858,14 +858,14 @@ SeeAlso: ??? Feature: IMAGEFORMAT_PNG Description: Supports the Portable Network Graphics image file format. Section: Images -Requires: +Requires: Name: PNG Image Format SeeAlso: ??? Feature: IMAGEFORMAT_JPEG Description: Supports the Joint Photographic Experts Group image file format. Section: Images -Requires: +Requires: Name: JPEG Image Format SeeAlso: ??? @@ -895,7 +895,7 @@ SeeAlso: ??? Feature: PICTURE Description: Supports recording and replaying QPainter commands. Section: Painting -Requires: +Requires: Name: QPicture SeeAlso: ??? @@ -908,9 +908,9 @@ Name: Color Names SeeAlso: ??? Feature: PRINTER -Description: Supports printing +Description: Supports printing Section: Painting -Requires: TEXTSTREAM +Requires: TEXTSTREAM PICTURE Name: QPrinter SeeAlso: ??? @@ -952,7 +952,7 @@ Name: Freetype Font Engine SeeAlso: ??? Feature: QWS_QPF -Description: Supports Qt's pre-rendered fonts, a light-weight non-scalable font format +Description: Supports Qt's pre-rendered fonts, a light-weight non-scalable font format specific to Qt for Embedded Linux. Section: Fonts Requires: @@ -960,7 +960,7 @@ Name: Qt Prerendered Font Format SeeAlso: ??? Feature: QWS_QPF2 -Description: Supports Qt's second generation of pre-rendered fonts, a light-weight +Description: Supports Qt's second generation of pre-rendered fonts, a light-weight non-scalable font format specific to Qt for Embedded Linux. Section: Fonts Requires: @@ -987,7 +987,7 @@ Feature: TRANSLATION_UTF8 Description: Supports translations using QObject::trUtf8(). Section: Internationalization Requires: TRANSLATION TEXTCODEC -Name: Translation (UTF-8 representation) +Name: Translation (UTF-8 representation) SeeAlso: ??? Feature: TEXTCODEC @@ -1007,14 +1007,14 @@ SeeAlso: ??? Feature: BIG_CODECS Description: Supports big codecs, e.g. CJK. Section: Internationalization -Requires: +Requires: Name: Big Codecs SeeAlso: ??? Feature: QWS_INPUTMETHODS Description: Supports international input methods. Section: Internationalization -Requires: +Requires: Name: QWSInputMethod SeeAlso: ??? @@ -1023,14 +1023,14 @@ SeeAlso: ??? Feature: URLINFO Description: Supports storage of URL information. Section: Networking -Requires: +Requires: Name: QUrlInfo SeeAlso: ??? Feature: HOSTINFO Description: Supports host name lookups. Section: Networking -Requires: TEXTSTREAM +Requires: TEXTSTREAM Name: QHostInfo SeeAlso: ??? @@ -1051,14 +1051,14 @@ SeeAlso: ??? Feature: UDPSOCKET Description: Supports User Datagram Protocol sockets. Section: Networking -Requires: +Requires: Name: QUdpSocket SeeAlso: ??? Feature: NETWORKPROXY Description: Supports configuring network layer proxy support to the Qt network classes. Section: Networking -Requires: +Requires: Name: QNetworkProxy SeeAlso: ??? @@ -1123,7 +1123,7 @@ Name: QUndoStack SeeAlso: ??? Feature: UNDOGROUP -Description: +Description: Section: Utilities Requires: UNDOCOMMAND UNDOSTACK Name: QUndoGroup @@ -1181,7 +1181,7 @@ Name: QSvgRenderer SeeAlso: ??? Feature: SVGWIDGET -Description: Provides a widget that is used to display the contents of SVG files. +Description: Provides a widget that is used to display the contents of SVG files. Section: SVG Requires: SVGRENDERER Name: QSvgWidget @@ -1233,21 +1233,21 @@ Name: Manager SeeAlso: ??? Feature: QWS_DECORATION_DEFAULT -Description: Supports default decoration of the top level windows. +Description: Supports default decoration of the top level windows. Section: Qt for Embedded Linux -Requires: +Requires: Name: Decoration SeeAlso: ??? Feature: QWS_DECORATION_WINDOWS -Description: Supports a "Windows" style decoration of the top level windows. +Description: Supports a "Windows" style decoration of the top level windows. Section: Qt for Embedded Linux Requires: QWS_DECORATION_DEFAULT Name: Decoration (Windows Style) SeeAlso: ??? Feature: QWS_DECORATION_STYLED -Description: Supports styled decoration of the top level windows. +Description: Supports styled decoration of the top level windows. Section: Qt for Embedded Linux Requires: QWS_DECORATION_DEFAULT Name: Decoration (Styled) @@ -1395,13 +1395,13 @@ SeeAlso: ??? Feature: PHONON_MEDIACONTROLLER Description: Support for the MediaController class Section: Phonon -Requires: +Requires: Name: Phonon::MediaController SeeAlso: ??? Feature: PHONON_ABSTRACTMEDIASTREAM Description: Support for streaming of raw data (QIODevice...) Section: Phonon -Requires: +Requires: Name: Phonon::AbstractMediaStream SeeAlso: ??? -- cgit v0.12 From 637b8aa2361fea8c0ea6579a6308ae594e6d8633 Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Mon, 30 Mar 2009 16:15:15 +0200 Subject: Fix threaded QImage text drawing under Windows. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qt_win_display() will always trigger an assert and should not be used in the src/painting directory. Task-number: 248266 Reviewed-by: Samuel Rødal --- src/gui/image/qnativeimage.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp index 6b74323..33e565c 100644 --- a/src/gui/image/qnativeimage.cpp +++ b/src/gui/image/qnativeimage.cpp @@ -100,7 +100,9 @@ QNativeImage::QNativeImage(int width, int height, QImage::Format format, bool is bmi.blueMask = 0; } - hdc = CreateCompatibleDC(qt_win_display_dc()); + HDC display_dc = GetDC(0); + hdc = CreateCompatibleDC(display_dc); + ReleaseDC(0, display_dc); Q_ASSERT(hdc); uchar *bits = 0; -- cgit v0.12 From 34059fba55816496d2570b3306ac2b631b12a5c6 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Fri, 27 Mar 2009 10:58:37 -0700 Subject: Work around raster engine not ignoring the pad byte in RGB32 DirectFB sets the alpha byte to 0 in RGB32 for all drawing operations. The raster paint engine needs this padding byte to be 0xFF as it shares some code paths with RGBA8888_Premultiplied. So, always fall back to raster engine for draw operations. This is really due to a bug in the raster paint engine (Tracked by task 184073), which should ignore the extra byte. Once this task is fixed, this patch can probably be reverted. Reviewed-by: Tom Cooksey --- .../gfxdrivers/directfb/qdirectfbpaintdevice.h | 7 ++- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 67 +++++++++++++--------- .../gfxdrivers/directfb/qdirectfbpixmap.cpp | 59 +++++++++++-------- 3 files changed, 78 insertions(+), 55 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index 23fa5d6..7096124 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -61,25 +61,28 @@ public: void lockDirectFB(); void unlockDirectFB(); + inline bool forceRasterPrimitives() const { return forceRaster; } + // Reimplemented from QCustomRasterPaintDevice: void* memory() const; QImage::Format format() const; int bytesPerLine() const; QSize size() const; int metric(QPaintDevice::PaintDeviceMetric metric) const; - protected: // Shouldn't create QDirectFBPaintDevice by itself but only sub-class it: QDirectFBPaintDevice(QDirectFBScreen *scr = QDirectFBScreen::instance()) : QCustomRasterPaintDevice(0), dfbSurface(0), lockedImage(0), - screen(scr) {} + screen(scr), + forceRaster(false) {} IDirectFBSurface *dfbSurface; QImage *lockedImage; QDirectFBScreen *screen; int bpl; + bool forceRaster; private: Q_DISABLE_COPY(QDirectFBPaintDevice) }; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 84a92d8..28386e5 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -195,6 +195,7 @@ public: QBrush brush; bool antialiased; + bool forceRasterPrimitives; bool simplePen; bool simpleBrush; @@ -265,7 +266,7 @@ private: }; QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) - : surface(0), antialiased(false), simplePen(false), + : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false), simpleBrush(false), matrixRotShear(false), matrixScale(false), fbWidth(-1), fbHeight(-1), opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), dirtyFlags(false), dirtyClip(true), dfbHandledClip(false), dfbDevice(0), q(p) @@ -345,6 +346,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", device->devType()); } + forceRasterPrimitives = dfbDevice->forceRasterPrimitives(); surface->GetSize(surface, &fbWidth, &fbHeight); @@ -945,7 +947,8 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush || !d->simplePen) { + if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush + || !d->simplePen || d->forceRasterPrimitives) { d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); return; @@ -969,7 +972,8 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush || !d->simplePen) { + if (!d->dfbCanHandleClip() || d->matrixRotShear || !d->simpleBrush + || !d->simplePen || d->forceRasterPrimitives) { d->lock(); QRasterPaintEngine::drawRects(rects, rectCount); return; @@ -993,7 +997,7 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->simplePen || !d->dfbCanHandleClip()) { + if (!d->simplePen || !d->dfbCanHandleClip() || d->forceRasterPrimitives) { d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); return; @@ -1011,7 +1015,7 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->simplePen || !d->dfbCanHandleClip()) { + if (!d->simplePen || !d->dfbCanHandleClip() || d->forceRasterPrimitives) { d->lock(); QRasterPaintEngine::drawLines(lines, lineCount); return; @@ -1181,6 +1185,8 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (d->dfbCanHandleClip(rect) && !d->matrixRotShear) { switch (brush.style()) { case Qt::SolidPattern: { + if (d->forceRasterPrimitives) + break; d->unlock(); d->updateFlags(); d->setDFBColor(brush.color()); @@ -1209,7 +1215,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) { Q_D(QDirectFBPaintEngine); d->updateClip(); - if (!d->dfbCanHandleClip() || d->matrixRotShear) { + if (!d->dfbCanHandleClip() || d->matrixRotShear || d->forceRasterPrimitives) { d->lock(); QRasterPaintEngine::fillRect(rect, color); } else { @@ -1226,31 +1232,36 @@ void QDirectFBPaintEngine::drawColorSpans(const QSpan *spans, int count, uint color) { Q_D(QDirectFBPaintEngine); - color = INV_PREMUL(color); - - QVarLengthArray lines(count); - int j = 0; - for (int i = 0; i < count; ++i) { - if (spans[i].coverage == 255) { - lines[j].x1 = spans[i].x; - lines[j].y1 = spans[i].y; - lines[j].x2 = spans[i].x + spans[i].len - 1; - lines[j].y2 = spans[i].y; - ++j; - } else { - DFBSpan span = { spans[i].x, spans[i].len }; - uint c = BYTE_MUL(color, spans[i].coverage); + if (d->forceRasterPrimitives) { + d->lock(); + QRasterPaintEngine::drawColorSpans(spans, count, color); + } else { + color = INV_PREMUL(color); + + QVarLengthArray lines(count); + int j = 0; + for (int i = 0; i < count; ++i) { + if (spans[i].coverage == 255) { + lines[j].x1 = spans[i].x; + lines[j].y1 = spans[i].y; + lines[j].x2 = spans[i].x + spans[i].len - 1; + lines[j].y2 = spans[i].y; + ++j; + } else { + DFBSpan span = { spans[i].x, spans[i].len }; + uint c = BYTE_MUL(color, spans[i].coverage); + d->surface->SetColor(d->surface, + qRed(c), qGreen(c), qBlue(c), qAlpha(c)); + d->surface->FillSpans(d->surface, spans[i].y, &span, 1); + } + } + if (j > 0) { d->surface->SetColor(d->surface, - qRed(c), qGreen(c), qBlue(c), qAlpha(c)); - d->surface->FillSpans(d->surface, spans[i].y, &span, 1); + qRed(color), qGreen(color), qBlue(color), + qAlpha(color)); + d->surface->DrawLines(d->surface, lines.data(), j); } } - if (j > 0) { - d->surface->SetColor(d->surface, - qRed(color), qGreen(color), qBlue(color), - qAlpha(color)); - d->surface->DrawLines(d->surface, lines.data(), j); - } } void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize, diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 6d942a4..3099205 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -71,15 +71,10 @@ void QDirectFBPixmapData::resize(int width, int height) return; } - DFBSurfaceDescription description; - description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH - | DSDESC_HEIGHT - | DSDESC_PIXELFORMAT); - QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, screen->pixelFormat()); - description.width = width; - description.height = height; - - dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); + dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height), + screen->pixelFormat(), + QDirectFBScreen::TrackSurface); + forceRaster = (screen->pixelFormat() == QImage::Format_RGB32); if (!dfbSurface) { setSerialNumber(0); qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface"); @@ -92,10 +87,12 @@ void QDirectFBPixmapData::resize(int width, int height) void QDirectFBPixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags) { - dfbSurface = screen->copyToDFBSurface(img, - img.hasAlphaChannel() ? screen->alphaPixmapFormat() - : screen->pixelFormat(), - QDirectFBScreen::TrackSurface); + const QImage::Format format = img.hasAlphaChannel() ? + screen->alphaPixmapFormat() + : screen->pixelFormat(); + dfbSurface = screen->copyToDFBSurface(img, format, + QDirectFBScreen::TrackSurface); + forceRaster = (format == QImage::Format_RGB32); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage()"); setSerialNumber(0); @@ -112,22 +109,18 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) } IDirectFBSurface *src = static_cast(data)->directFbSurface(); + const QImage::Format format = (data->hasAlphaChannel() + ? QDirectFBScreen::instance()->alphaPixmapFormat() + : QDirectFBScreen::instance()->pixelFormat()); - DFBSurfaceDescription description; - description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | - DSDESC_HEIGHT | - DSDESC_PIXELFORMAT); - description.width = rect.width(); - description.height = rect.height(); - src->GetPixelFormat(src, &description.pixelformat); - src->GetCapabilities(src, &description.caps); - - dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); + dfbSurface = screen->createDFBSurface(rect.size(), format, + QDirectFBScreen::TrackSurface); if (!dfbSurface) { qWarning("QDirectFBPixmapData::copy()"); setSerialNumber(0); return; } + forceRaster = (format == QImage::Format_RGB32); dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); const DFBRectangle blitRect = { rect.x(), rect.y(), @@ -160,6 +153,7 @@ void QDirectFBPixmapData::fill(const QColor &color) screen->releaseDFBSurface(dfbSurface); // release old surface dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); + forceRaster = false; setSerialNumber(++global_ser_no); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fill()"); @@ -168,8 +162,23 @@ void QDirectFBPixmapData::fill(const QColor &color) } } - dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(), - color.alpha()); + if (forceRaster) { + // in DSPF_RGB32 all dfb drawing causes the Alpha byte to be + // set to 0. This causes issues for the raster engine. + char *mem; + int bpl; + const int h = QPixmapData::height(); + dfbSurface->Lock(dfbSurface, DSLF_WRITE, (void**)&mem, &bpl); + const int c = color.rgba(); + for (int i = 0; i < h; ++i) { + memset(mem, c, bpl); + mem += bpl; + } + dfbSurface->Unlock(dfbSurface); + } else { + dfbSurface->Clear(dfbSurface, color.red(), color.green(), color.blue(), + color.alpha()); + } } bool QDirectFBPixmapData::hasAlphaChannel() const -- cgit v0.12 From 097b3b3323ab6641c17318057e100543b60bca77 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 30 Mar 2009 16:09:23 +0200 Subject: Fix backslashes in string propeerty in property browser Inside DesignerEditorFactory::createTextEditor() we first do setText() and afterwards we do setTextPropertyValidationMode(). setTextPropertyValidationMode() didn't update the cached text. Below patch fixes it. Reviewed-by: Friedemann Kleint Task-number: 245503 --- tools/designer/src/lib/shared/textpropertyeditor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/designer/src/lib/shared/textpropertyeditor.cpp b/tools/designer/src/lib/shared/textpropertyeditor.cpp index cf12842..95a9f85 100644 --- a/tools/designer/src/lib/shared/textpropertyeditor.cpp +++ b/tools/designer/src/lib/shared/textpropertyeditor.cpp @@ -293,6 +293,7 @@ namespace qdesigner_internal { } setFocusProxy(m_lineEdit); + setText(m_cachedText); markIntermediateState(); } -- cgit v0.12 From 469b9a0f2ddf4bd1d2719619f3e4e52afbc7731f Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 16:44:55 +0200 Subject: Doc: Synchronized the QTransform constructor arguments with the class documentation and updated a diagram. Task-number: 228201 Reviewed-by: TrustMe --- doc/src/diagrams/qtransform-representation.sk | 103 ++++++++++++++++++++++++++ src/gui/painting/qtransform.cpp | 19 +++-- 2 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 doc/src/diagrams/qtransform-representation.sk diff --git a/doc/src/diagrams/qtransform-representation.sk b/doc/src/diagrams/qtransform-representation.sk new file mode 100644 index 0000000..17dcbfe --- /dev/null +++ b/doc/src/diagrams/qtransform-representation.sk @@ -0,0 +1,103 @@ +##Sketch 1 2 +document() +layout('A4',0) +layer('Layer 1',1,1,0,0,(0,0,0)) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,190,760) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,190,695) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,190,630) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,320,760) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,320,695) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,320,630) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,255,760) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,255,695) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,255,630) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m33',(329.16,589.968)) +G() +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('dy',(274.828,577.768)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m32',(264.16,602.768)) +G_() +G() +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m31',(199.16,602.768)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('dx',(209.828,577.8)) +G_() +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m11',(199.16,719.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m12',(264.16,719.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m13',(329.16,719.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m21',(199.16,654.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m22',(264.16,654.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m23',(329.16,654.968)) +guidelayer('Guide Lines',1,0,0,1,(0,0,1)) +grid((0,0,5,5),1,(0,0,1),'Grid') diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index da8c428..c70208c 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -168,10 +168,10 @@ QT_BEGIN_NAMESPACE \image qtransform-representation.png - A QTransform object contains a 3 x 3 matrix. The \c dx and \c dy - elements specify horizontal and vertical translation. The \c m11 - and \c m22 elements specify horizontal and vertical scaling. The - \c m21 and \c m12 elements specify horizontal and vertical \e shearing. + A QTransform object contains a 3 x 3 matrix. The \c m31 (\c dx) and + \c m32 (\c dy) elements specify horizontal and vertical translation. + The \c m11 and \c m22 elements specify horizontal and vertical scaling. + The \c m21 and \c m12 elements specify horizontal and vertical \e shearing. And finally, the \c m13 and \c m23 elements specify horizontal and vertical projection, with \c m33 as an additional projection factor. @@ -246,8 +246,10 @@ QTransform::QTransform() } /*! - Constructs a matrix with the elements, \a h11, \a h12, \a h13, - \a h21, \a h22, \a h23, \a h31, \a h32, \a h33. + \fn QTransform::QTransform(qreal m11, qreal m12, qreal m13, qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33) + + Constructs a matrix with the elements, \a m11, \a m12, \a m13, + \a m21, \a m22, \a m23, \a m31, \a m32, \a m33. \sa setMatrix() */ @@ -263,8 +265,9 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13, } /*! - Constructs a matrix with the elements, \a h11, \a h12, \a h21, \a - h22, \a dx and \a dy. + \fn QTransform::QTransform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy) + + Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a m22, \a dx and \a dy. \sa setMatrix() */ -- cgit v0.12 From 7ce9e9160ce04e6ab7e4219af9de6c24a9d2889c Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 16:48:26 +0200 Subject: Doc: Synchronized the QTransform constructor arguments with the class documentation and updated a diagram. Task-number: 228201 Reviewed-by: TrustMe --- doc/src/images/qtransform-representation.png | Bin 17892 -> 17385 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/src/images/qtransform-representation.png b/doc/src/images/qtransform-representation.png index 2608872..883d5dc 100644 Binary files a/doc/src/images/qtransform-representation.png and b/doc/src/images/qtransform-representation.png differ -- cgit v0.12 From 259175c6d55d7add0b25fd552b9dadc256e45def Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 17:03:01 +0200 Subject: Doc: Fixed typo. Reviewed-by: TrustMe --- src/corelib/kernel/qmetatype.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 4d7d309..ce10bae 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1255,7 +1255,7 @@ void QMetaType::destroy(int type, void *data) \relates QMetaType \threadsafe - Registers the type name \a typeName to the type \c{T}. Returns + Registers the type name \a typeName for the type \c{T}. Returns the internal ID used by QMetaType. Any class or struct that has a public default constructor, a public copy constructor and a public destructor can be registered. -- cgit v0.12 From 51a59f48f5b92e1c55dae5da0ffa9fbb492abc6b Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 30 Mar 2009 17:19:21 +0200 Subject: Explicitely mentioned in the doc that the format string for qDebug, qWarning and qFatal should be in Latin1. Reviewed-by: Thiago --- src/corelib/global/qglobal.cpp | 11 +++++++---- src/corelib/tools/qstring.cpp | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 90020f7..08ecf3c 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2022,7 +2022,8 @@ void qt_message_output(QtMsgType msgType, const char *buf) during compilation. If you pass the function a format string and a list of arguments, - it works in similar way to the C printf() function. + it works in similar way to the C printf() function. The format + should be a Latin-1 string. Example: @@ -2068,7 +2069,8 @@ void qDebug(const char *msg, ...) QT_FATAL_WARNINGS is defined. This function takes a format string and a list of arguments, - similar to the C printf() function. + similar to the C printf() function. The format should be a Latin-1 + string. Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26 @@ -2106,8 +2108,9 @@ void qWarning(const char *msg, ...) message handler has been installed, the message is printed to stderr. Under Windows, the message is sent to the debugger. - This function takes a format string and a list of arguments, similar - to the C printf() function. + This function takes a format string and a list of arguments, + similar to the C printf() function. The format should be a Latin-1 + string. Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28 diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 1b29adc..9c637ac 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4864,7 +4864,8 @@ QString QString::toUpper() const a pointer to a zero-terminated array of unicode characters of type ushort (as returned by QString::utf16()). - \note This function expects a UTF-8 string for %s. + \note This function expects a UTF-8 string for %s and Latin-1 for + the format string. The format string supports most of the conversion specifiers provided by printf() in the standard C++ library. It doesn't -- cgit v0.12 From a9ffdee9c0e8ba092bb20759300157c1e45bc407 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 08:30:23 -0700 Subject: Rename function Everything else capitalizes both the F and the B. s/Fb/FB/g Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 6 +++--- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index 8dbad53..5e71640 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -50,7 +50,7 @@ QDirectFBPaintDevice::~QDirectFBPaintDevice() } -IDirectFBSurface *QDirectFBPaintDevice::directFbSurface() const +IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const { return dfbSurface; } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index 7096124..89a3087 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -56,7 +56,7 @@ class QDirectFBPaintDevice : public QCustomRasterPaintDevice public: ~QDirectFBPaintDevice(); - IDirectFBSurface *directFbSurface() const; + IDirectFBSurface *directFBSurface() const; void lockDirectFB(); void unlockDirectFB(); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 28386e5..da4f367 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -340,7 +340,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) } if (dfbDevice) - surface = dfbDevice->directFbSurface(); + surface = dfbDevice->directFBSurface(); if (!surface) { qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", @@ -641,7 +641,7 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); - IDirectFBSurface *s = dfbData->directFbSurface(); + IDirectFBSurface *s = dfbData->directFBSurface(); const QRect sr = src.toRect(); const QRect dr = ::mapRect(transform, dest); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; @@ -674,7 +674,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); - IDirectFBSurface *s = dfbData->directFbSurface(); + IDirectFBSurface *s = dfbData->directFBSurface(); const QRect dr = ::mapRect(transform, dest); DFBResult result = DFB_OK; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 3099205..9f5c055 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -108,7 +108,7 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) return; } - IDirectFBSurface *src = static_cast(data)->directFbSurface(); + IDirectFBSurface *src = static_cast(data)->directFBSurface(); const QImage::Format format = (data->hasAlphaChannel() ? QDirectFBScreen::instance()->alphaPixmapFormat() : QDirectFBScreen::instance()->pixelFormat()); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index db9672a..87a5910 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1033,7 +1033,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) if (surface->key() == QLatin1String("directfb")) { QDirectFBSurface *s = static_cast(surface); - blit(s->directFbSurface(), offset, r); + blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); } @@ -1082,7 +1082,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) if (surface->key() == QLatin1String("directfb")) { QDirectFBSurface *s = static_cast(surface); - blit(s->directFbSurface(), offset, r); + blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); } -- cgit v0.12 From 6a303f13616fe1f54086092952b0d740534ca52a Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 17:40:53 +0200 Subject: Doc: Exclude the internal Phonon classes from the Assistant documentation. Task-number: 247060 Reviewed-by: TrustMe --- tools/qdoc3/test/qt-api-only.qdocconf | 2 +- tools/qdoc3/test/qt-build-docs.qdocconf | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/qdoc3/test/qt-api-only.qdocconf b/tools/qdoc3/test/qt-api-only.qdocconf index 2e91ba2..bc5656b 100644 --- a/tools/qdoc3/test/qt-api-only.qdocconf +++ b/tools/qdoc3/test/qt-api-only.qdocconf @@ -9,7 +9,7 @@ url = ./ # Ensures that the documentation for the tools is not included in the generated # .qhp file. -qhp.Qt.excluded = $QT_SOURCE_TREE/doc/src/assistant-manual.qdoc \ +qhp.Qt.excluded += $QT_SOURCE_TREE/doc/src/assistant-manual.qdoc \ $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc \ $QT_SOURCE_TREE/doc/src/designer-manual.qdoc \ $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \ diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index a085768..25cdc5a 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -92,7 +92,11 @@ excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \ $QT_SOURCE_TREE/src/3rdparty/webkit/WebCore \ $QT_SOURCE_TREE/src/3rdparty/wintab \ $QT_SOURCE_TREE/src/3rdparty/zlib \ - $QT_SOURCE_TREE/doc/src/snippets + $QT_SOURCE_TREE/doc/src/snippets \ + $QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer \ + $QT_SOURCE_TREE/src/3rdparty/phonon/ds9 \ + $QT_SOURCE_TREE/src/3rdparty/phonon/qt7 \ + $QT_SOURCE_TREE/src/3rdparty/phonon/waveout sources.fileextensions = "*.cpp *.qdoc *.mm" examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp" -- cgit v0.12 From 2cb93d0c1f80c572c5cfa5074a6cfae81a3b28d2 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Thu, 5 Mar 2009 17:34:21 -0500 Subject: Improvements to follow the behavior of web servers and other browsers, specifically match the behavior of Firefox which servers test against. - When updating the cache metadata don't update content-* headers - Don't lowercase headers names when updating them - Fixed a typo in QNETWORKACCESSHTTPBACKEND_DEBUG code Originally seen on http://www.bibelbund.de/htm/99-4-306.htm where on refresh the 304 will set the content type of text/plain. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 4b41aa7..227a578 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -951,6 +951,7 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo QList newHeaders = rawHeaderList(); foreach (QByteArray header, newHeaders) { + QByteArray originalHeader = header; header = header.toLower(); bool hop_by_hop = (header == "connection" @@ -974,19 +975,32 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo continue; } + it = cacheHeaders.findRawHeader(header); + if (it != cacheHeaders.rawHeaders.constEnd()) { + // Match the behavior of Firefox and assume Cache-Control: "no-transform" + if (header == "content-encoding" + || header == "content-range" + || header == "content-type") + continue; + + // For MS servers that send "Content-Length: 0" on 304 responses + // ignore this too + if (header == "content-length") + continue; + } + #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) QByteArray n = rawHeader(header); QByteArray o; - it = cacheHeaders.findRawHeader(header); if (it != cacheHeaders.rawHeaders.constEnd()) o = (*it).second; - if (n != o && header != "Date") { + if (n != o && header != "date") { qDebug() << "replacing" << header; qDebug() << "new" << n; qDebug() << "old" << o; } #endif - cacheHeaders.setRawHeader(header, rawHeader(header)); + cacheHeaders.setRawHeader(originalHeader, rawHeader(header)); } metaData.setRawHeaders(cacheHeaders.rawHeaders); -- cgit v0.12 From ca7651e37599e0743ea37036dd3c7f891565fed8 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Fri, 20 Mar 2009 15:11:06 -0400 Subject: When loading a url straight from cache call finished so the QNetworkReply::finished() signal is emited. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 227a578..b09e9a6 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -527,8 +527,10 @@ void QNetworkAccessHttpBackend::postRequest() foreach (const QByteArray &header, headers) httpRequest.setHeaderField(header, request().rawHeader(header)); - if (loadedFromCache) + if (loadedFromCache) { + QNetworkAccessBackend::finished(); return; // no need to send the request! :) + } httpReply = http->sendRequest(httpRequest); httpReply->setParent(this); -- cgit v0.12 From fe6f08387f726d45536c13c00604b8290237af51 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Thu, 19 Feb 2009 13:16:41 -0500 Subject: Check for a redirection after setting the headers. If there is a redirection the location header will be used to determine where to go. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index b09e9a6..401dc71 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -888,8 +888,6 @@ bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &m if (status < 100) status = 200; // fake it - checkForRedirect(status); - setAttribute(QNetworkRequest::HttpStatusCodeAttribute, status); setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute)); setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true); @@ -900,6 +898,8 @@ bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &m for ( ; it != end; ++it) setRawHeader(it->first, it->second); + checkForRedirect(status); + writeDownstreamData(contents); #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) qDebug() << "Successfully sent cache:" << url() << contents->size() << "bytes"; -- cgit v0.12 From 79f02e7dbd28f3a60deeb083afb3c74a14430a88 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Mon, 16 Mar 2009 14:05:22 -0400 Subject: When parsing a cookie string the ',' character is special because it is used in the date and to differentiate between multiple cookies. When there are multiple set-cookie headers rather then combining them with ', ' use '\n' like Firefox because we are 100% sure that we have multiple cookies and using , can result in cases where the , is interpreted as as part of the date such as the following set-cookie:a=b; expires=2009 mar 10 set-cookie:c=d Combined the old way they result in the second cookie being ignored a=b; expires=2009 mar 10, c=d Using '\n' moves our cookie parser closer to Firefox's algorithm which will result in more behavior and bug for bug compatibility. Attempting to be smarter about the , will result in incompatibility with Firefox's implementation (as my first attempt at fixing this bug resulted). Also when parsing multiple cookies when we have an error don't return an empty list of cookies, but return the list of cookies we were able to parse successfully so far. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 8 ++++++-- src/network/access/qnetworkcookie.cpp | 10 +++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 401dc71..a52b5a0 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -769,8 +769,12 @@ void QNetworkAccessHttpBackend::replyHeaderChanged() for (; it != end; ++it) { QByteArray value = rawHeader(it->first); - if (!value.isEmpty()) - value += ", "; + if (!value.isEmpty()) { + if (it->first.toLower() == "set-cookie") + value += "\n"; + else + value += ", "; + } value += it->second; setRawHeader(it->first, value); } diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 1235960..5c28ff3 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -543,11 +543,17 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin while (position < length) { QNetworkCookie cookie; + // When there are multiple SetCookie headers they are join with a new line + // \n will always be the start of a new cookie + int endOfSetCookie = cookieString.indexOf('\n'); + if (endOfSetCookie == -1) + endOfSetCookie = length; + // The first part is always the "NAME=VALUE" part QPair field = nextField(cookieString, position); if (field.first.isEmpty() || field.second.isNull()) // parsing error - return QList(); + break; cookie.setName(field.first); cookie.setValue(field.second); @@ -664,6 +670,8 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin } position = nextNonWhitespace(cookieString, position); + if (position > endOfSetCookie) + endOfCookie = true; } result += cookie; -- cgit v0.12 From b790584708a8090211c1897e85f8b3d6df7afa29 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 12:59:56 +0100 Subject: Fix bug introduced by last patch. Make sure that we can handle two Set-Cookie headers. Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 5c28ff3..a327bc0 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -559,7 +559,7 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin position = nextNonWhitespace(cookieString, position); bool endOfCookie = false; - while (!endOfCookie && position < length) + while (!endOfCookie && position < endOfSetCookie) switch (cookieString.at(position++)) { case ',': // end of the cookie -- cgit v0.12 From 0fe33578f03a0966c42f9fc44d80a49495f87878 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Thu, 26 Feb 2009 12:21:37 -0500 Subject: Change cookie expiration reading to match the behavior of Firefox. Rather then only allowing the three date formats that are in the rfc allow a much wider set of date strings. Because many browsers support this many websites send dates strings that are not in the rfc format. See documentation in parseDateString for more details about the implementation. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 437 +++++++++++++++++++++++++++++----- 1 file changed, 384 insertions(+), 53 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index a327bc0..b127f18 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -49,6 +49,7 @@ #include "QtCore/qlist.h" #include "QtCore/qlocale.h" #include "QtCore/qstring.h" +#include "QtCore/qstringlist.h" #include "QtCore/qurl.h" #include "private/qobject_p.h" @@ -513,6 +514,385 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const return result; } +static const char zones[] = + "pst\0" // -8 + "pdt\0" + "mst\0" // -7 + "mdt\0" + "cst\0" // -6 + "cdt\0" + "est\0" // -5 + "edt\0" + "ast\0" // -4 + "nst\0" // -3 + "gmt\0" // 0 + "utc\0" + "bst\0" + "met\0" // 1 + "eet\0" // 2 + "jst\0" // 9 + "\0"; +static int zoneOffsets[] = {-8, -8, -7, -7, -6, -6, -5, -5, -4, -3, 0, 0, 0, 1, 2, 9 }; + +static const char months[] = + "jan\0" + "feb\0" + "mar\0" + "apr\0" + "may\0" + "jun\0" + "jul\0" + "aug\0" + "sep\0" + "oct\0" + "nov\0" + "dec\0" + "\0"; + +static inline bool isNumber(char s) { return s >= '0' && s <= '9'; } +static inline bool isTerminator (char c) { return c == '\n' || c == '\r'; } +static inline bool isValueSeparator (char c) { return isTerminator(c) || c == ';'; } +static inline bool isWhitespace (char c) { return c == ' ' || c == '\t'; } + +static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, size_t size) { + if (dateString[at] < 'a' || dateString[at] > 'z') + return false; + if (val == -1 && dateString.length() >= at + 3) { + int j = 0; + size_t i = 0; + while (i <= size) { + const char *str(array + i); + if (str[0] == dateString[at] + && str[1] == dateString[at + 1] + && str[2] == dateString[at + 2]) { + val = j; + return true; + } + i += strlen(str) + 1; + ++j; + } + } + return false; +} + +//#define PARSEDATESTRINGDEBUG + +#define ADAY 1 +#define AMONTH 2 +#define AYEAR 4 + +/* + Parse all the date formats that Firefox can. + + The official format is: + expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT + + But browsers have been supporting a very wide range of date + strings. To work on many sites we need to support more then + just the official date format. + + For reference see Firefox's PR_ParseTimeStringToExplodedTime in + prtime.c. The Firefox date parser is coded in a very complex way + and is slightly over ~700 lines long. While this implementation + will be slightly slower for the non standard dates it is smaller, + more readable, and maintainable. + + Or in their own words: + "} // else what the hell is this." +*/ +static QDateTime parseDateString(const QByteArray &dateString) +{ + QTime time; + // placeholders for values when we are not sure it is a year, month or day + int unknown[3] = {-1, -1, -1}; + int month = -1; + int day = -1; + int year = -1; + int zoneOffset = -1; + + // hour:minute:second.ms pm + QRegExp timeRx(QLatin1String("(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})|)(\\.(\\d{1,3})|)((\\s{0,}(am|pm))|)")); + + int at = 0; + while (at < dateString.length()) { +#ifdef PARSEDATESTRINGDEBUG + qDebug() << dateString.mid(at); +#endif + bool isNum = isNumber(dateString[at]); + + // Month + if (!isNum + && checkStaticArray(month, dateString, at, months, sizeof(months)- 1)) { + ++month; +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Month:" << month; +#endif + at += 3; + continue; + } + // Zone + if (!isNum + && zoneOffset == -1 + && checkStaticArray(zoneOffset, dateString, at, zones, sizeof(zones)- 1)) { + int sign = (at >= 0 && dateString[at - 1] == '-') ? -1 : 1; + zoneOffset = sign * zoneOffsets[zoneOffset] * 60 * 60; +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Zone:" << month; +#endif + at += 3; + continue; + } + // Zone offset + if (!isNum + && (zoneOffset == -1 || zoneOffset == 0) // Can only go after gmt + && (dateString[at] == '+' || dateString[at] == '-') + && (at == 0 + || isWhitespace(dateString[at - 1]) + || dateString[at - 1] == ',' + || (dateString[at - 1] == 't'))) { + + int end = 1; + while (dateString[at + end] >= '0' && dateString[at + end] <= '9' + && end < 5) + ++end; + int minutes = 0; + int hours = 0; + switch (end - 1) { + case 4: + minutes = atoi(dateString.mid(at + 3, 2).constData()); + // fall through + case 2: + hours = atoi(dateString.mid(at + 1, 2).constData()); + break; + case 1: + hours = atoi(dateString.mid(at + 1, 1).constData()); + break; + default: + at += end; + continue; + } + if (end != 1) { + int sign = dateString[at] == '-' ? -1 : 1; + zoneOffset = sign * ((minutes * 60) + (hours * 60 * 60)); +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Zone offset:" << zoneOffset << hours << minutes; +#endif + at += end; + continue; + } + } + + // Time + if (isNum && time.isNull() + && dateString.length() >= at + 3 + && (dateString[at + 2] == ':' || dateString[at + 1] == ':')) { + // While the date can be found all over the string the format + // for the time is set and a nice regexp can be used. + int pos = timeRx.indexIn(QLatin1String(dateString), at); + if (pos != -1) { + QStringList list = timeRx.capturedTexts(); + int h = atoi(list.at(1).toLatin1().constData()); + int m = atoi(list.at(2).toLatin1().constData()); + int s = atoi(list.at(4).toLatin1().constData()); + int ms = atoi(list.at(6).toLatin1().constData()); + if (h < 12 && !list.at(9).isEmpty()) + if (list.at(9) == QLatin1String("pm")) + h += 12; + time = QTime(h, m, s, ms); +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Time:" << list << timeRx.matchedLength(); +#endif + at += timeRx.matchedLength(); + continue; + } + } + + // 4 digit Year + if (isNum + && year == -1 + && dateString.length() >= at + 3) { + if (isNumber(dateString[at + 1]) + && isNumber(dateString[at + 2]) + && isNumber(dateString[at + 3])) { + year = atoi(dateString.mid(at, 4).constData()); + at += 4; +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Year:" << year; +#endif + continue; + } + } + + // a one or two digit number + // Could be month, day or year + if (isNum) { + int length = 1; + if (dateString.length() >= at + 1 + && isNumber(dateString[at + 1])) + ++length; + int x = atoi(dateString.mid(at, length).constData()); + if (year == -1 && (x > 31 || x == 0)) { + year = x; + } else { + if (unknown[0] == -1) unknown[0] = x; + else if (unknown[1] == -1) unknown[1] = x; + else if (unknown[2] == -1) unknown[2] = x; + } + at += length; +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Saving" << x; +#endif + continue; + } + + // Unknown character, typically a weekday such as 'Mon' + ++at; + } + + // Once we are done parsing the string take the digits in unknown + // and determine which is the unknown year/month/day + + int couldBe[3] = { 0, 0, 0 }; + int unknownCount = 3; + for (int i = 0; i < unknownCount; ++i) { + if (unknown[i] == -1) { + couldBe[i] = ADAY | AYEAR | AMONTH; + unknownCount = i; + continue; + } + + if (unknown[i] >= 1) + couldBe[i] = ADAY; + + if (month == -1 && unknown[i] >= 1 && unknown[i] <= 12) + couldBe[i] |= AMONTH; + + if (year == -1) + couldBe[i] |= AYEAR; + } + + // For any possible day make sure one of the values that could be a month + // can contain that day. + // For any possible month make sure one of the values that can be a + // day that month can have. + // Example: 31 11 06 + // 31 can't be a day because 11 and 6 don't have 31 days + for (int i = 0; i < unknownCount; ++i) { + int currentValue = unknown[i]; + bool findMatchingMonth = couldBe[i] & ADAY && currentValue >= 29; + bool findMatchingDay = couldBe[i] & AMONTH; + if (!findMatchingMonth || !findMatchingDay) + continue; + for (int j = 0; j < 3; ++j) { + if (j == i) + continue; + for (int k = 0; k < 2; ++k) { + if (k == 0 && !(findMatchingMonth && (couldBe[j] & AMONTH))) + continue; + else if (k == 1 && !(findMatchingDay && (couldBe[j] & ADAY))) + continue; + int m = currentValue; + int d = unknown[j]; + if (k == 0) + qSwap(m, d); + if (m == -1) m = month; + bool found = true; + switch(m) { + case 2: + // When we get 29 and the year ends up having only 28 + // See date.isValid below + // Example: 29 23 Feb + if (d <= 29) + found = false; + break; + case 4: case 6: case 9: case 11: + if (d <= 30) + found = false; + break; + default: + if (d > 0 && d <= 31) + found = false; + } + if (k == 0) findMatchingMonth = found; + else if (k == 1) findMatchingDay = found; + } + } + if (findMatchingMonth) + couldBe[i] &= ~ADAY; + if (findMatchingDay) + couldBe[i] &= ~AMONTH; + } + + // First set the year/month/day that have been deduced + // and reduce the set as we go along to deduce more + for (int i = 0; i < unknownCount; ++i) { + int unset = 0; + for (int j = 0; j < 3; ++j) { + if (couldBe[j] == ADAY && day == -1) { + day = unknown[j]; + unset |= ADAY; + } else if (couldBe[j] == AMONTH && month == -1) { + month = unknown[j]; + unset |= AMONTH; + } else if (couldBe[j] == AYEAR && year == -1) { + year = unknown[j]; + unset |= AYEAR; + } else { + // common case + break; + } + couldBe[j] &= ~unset; + } + } + + // Now fallback to a standardized order to fill in the rest with + for (int i = 0; i < unknownCount; ++i) { + if (couldBe[i] & AMONTH && month == -1) month = unknown[i]; + else if (couldBe[i] & ADAY && day == -1) day = unknown[i]; + else if (couldBe[i] & AYEAR && year == -1) year = unknown[i]; + } +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Final set" << year << month << day; +#endif + + if (year == -1 || month == -1 || day == -1) { +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Parser failure" << year << month << day; +#endif + return QDateTime(); + } + + // Y2k behavior + int y2k = 0; + if (year < 70) + y2k = 2000; + else if (year < 100) + y2k = 1900; + + QDate date(year + y2k, month, day); + + // When we were given a bad cookie that when parsed + // set the day to 29 and the year to one that doesn't + // have the 29th of Feb rather then adding the extra + // complicated checking earlier just swap here. + // Example: 29 23 Feb + if (!date.isValid()) + date = QDate(day + y2k, month, year); + + QDateTime dateTime; + + if (zoneOffset == -1) { + dateTime = QDateTime(date, time); + dateTime = dateTime.toTimeSpec(Qt::UTC); + } else { + dateTime = QDateTime(date, time, Qt::UTC); + dateTime = dateTime.addSecs(zoneOffset); + } + if (!dateTime.isValid()) + return QDateTime(); + return dateTime; +} + /*! Parses the cookie string \a cookieString as received from a server response in the "Set-Cookie:" header. If there's a parsing error, @@ -572,64 +952,15 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin field.first = field.first.toLower(); // everything but the NAME=VALUE is case-insensitive if (field.first == "expires") { - static const char dateFormats[] = - "d-MMM-yyyy hh:mm:ss\0" - "d MMM yyyy hh:mm:ss\0" - "d-MMM-yy hh:mm:ss\0" - "\0"; - - // expires is a special case because it contains a naked comma - // and naked spaces. The format is: - // expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT - // but we also accept standard HTTP dates - - // make sure we're at the comma - if (position >= length || cookieString.at(position) != ',') - // invalid cookie string - return QList(); - - ++position; + position -= field.second.length(); int end; for (end = position; end < length; ++end) - if (cookieString.at(end) == ',' || cookieString.at(end) == ';') + if (isValueSeparator(cookieString.at(end))) break; - QByteArray datestring = cookieString.mid(position, end - position).trimmed(); + QByteArray dateString = cookieString.mid(position, end - position).trimmed(); position = end; - if (datestring.endsWith(" GMT") || datestring.endsWith(" UTC")) - datestring.chop(4); - else if (datestring.endsWith(" +0000")) - datestring.chop(6); - - size_t i = 0; - int j = 0; - QLocale cLocale = QLocale::c(); - QDateTime dt; - do { - QLatin1String df(dateFormats + i); - i += strlen(dateFormats + i) + 1; - -#ifndef QT_NO_DATESTRING - dt = cLocale.toDateTime(QString::fromLatin1(datestring), df); - - // some cookies are set with a two-digit year - // (although this is not allowed); this is interpreted as a year - // in the 20th century by QDateTime. - // Work around this case here (assuming 00-69 is 21st century, - // 70-99 is 20th century) - QDate date = dt.date(); - if (j == 2 && date.year() >= 1900 && date.year() < 1970) - dt = dt.addYears(100); - if (date.year() >= 0 && date.year() < 100) - dt = dt.addYears(1900); -#endif - j++; - } while (!dt.isValid() && i <= sizeof dateFormats - 1); - if (!dt.isValid()) - // invalid cookie string - return QList(); - - dt.setTimeSpec(Qt::UTC); + QDateTime dt = parseDateString(dateString.toLower()); cookie.setExpirationDate(dt); } else if (field.first == "domain") { QByteArray rawDomain = field.second; -- cgit v0.12 From 83dc49feaf56bdf469388174972fa6fc815b844b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 14:52:03 +0100 Subject: Fix a few issues introduced by Ben's last patch. Test if we're not past the end of the array before we attempt to read it. Dates without timezone information are taken to be UTC, so merge the code. If the date parsing failed, don't add a malformed cookie. Better to have no cookie than to have it for past its expiration date. Also update the autotests, since we now can cope with some of the invalid cookies seen on the net. Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 39 +++++++++++++++--------- tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp | 11 +++---- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index b127f18..56cb539 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -549,17 +549,25 @@ static const char months[] = "dec\0" "\0"; -static inline bool isNumber(char s) { return s >= '0' && s <= '9'; } -static inline bool isTerminator (char c) { return c == '\n' || c == '\r'; } -static inline bool isValueSeparator (char c) { return isTerminator(c) || c == ';'; } -static inline bool isWhitespace (char c) { return c == ' ' || c == '\t'; } +static inline bool isNumber(char s) +{ return s >= '0' && s <= '9'; } -static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, size_t size) { +static inline bool isTerminator(char c) +{ return c == '\n' || c == '\r'; } + +static inline bool isValueSeparator(char c) +{ return isTerminator(c) || c == ';'; } + +static inline bool isWhitespace(char c) +{ return c == ' ' || c == '\t'; } + +static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, int size) +{ if (dateString[at] < 'a' || dateString[at] > 'z') return false; if (val == -1 && dateString.length() >= at + 3) { int j = 0; - size_t i = 0; + int i = 0; while (i <= size) { const char *str(array + i); if (str[0] == dateString[at] @@ -652,8 +660,7 @@ static QDateTime parseDateString(const QByteArray &dateString) || (dateString[at - 1] == 't'))) { int end = 1; - while (dateString[at + end] >= '0' && dateString[at + end] <= '9' - && end < 5) + while (end < 5 && dateString[at + end] >= '0' && dateString[at + end] <= '9') ++end; int minutes = 0; int hours = 0; @@ -879,13 +886,9 @@ static QDateTime parseDateString(const QByteArray &dateString) if (!date.isValid()) date = QDate(day + y2k, month, year); - QDateTime dateTime; + QDateTime dateTime(date, time, Qt::UTC); - if (zoneOffset == -1) { - dateTime = QDateTime(date, time); - dateTime = dateTime.toTimeSpec(Qt::UTC); - } else { - dateTime = QDateTime(date, time, Qt::UTC); + if (zoneOffset != -1) { dateTime = dateTime.addSecs(zoneOffset); } if (!dateTime.isValid()) @@ -961,6 +964,11 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin QByteArray dateString = cookieString.mid(position, end - position).trimmed(); position = end; QDateTime dt = parseDateString(dateString.toLower()); + if (!dt.isValid()) { + cookie = QNetworkCookie(); + endOfCookie = true; + continue; + } cookie.setExpirationDate(dt); } else if (field.first == "domain") { QByteArray rawDomain = field.second; @@ -1005,7 +1013,8 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin endOfCookie = true; } - result += cookie; + if (!cookie.name().isEmpty()) + result += cookie; } return result; diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index 9010db4..4da17d9 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -315,6 +315,9 @@ void tst_QNetworkCookie::parseSingleCookie_data() cookie.setExpirationDate(QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59), Qt::UTC)); QTest::newRow("network2") << "__siteid=1; expires=Fri, 31-Dec-9999 23:59:59 GMT; path=/" << cookie; + cookie = QNetworkCookie("YM.LC", "v=2&m=9993_262838_159_1558_1063_0_5649_4012_3776161073,9426_260205_549_1295_1336_0_5141_4738_3922731647,6733_258196_952_1364_643_0_3560_-1_0,3677_237633_1294_1294_19267_0_3244_29483_4102206176,1315_235149_1693_1541_941_0_3224_1691_1861378060,1858_214311_2100_1298_19538_0_2873_30900_716411652,6258_212007_2506_1285_1017_0_2868_3606_4288540264,3743_207884_2895_1362_2759_0_2545_7114_3388520216,2654_205253_3257_1297_1332_0_2504_4682_3048534803,1891_184881_3660_1291_19079_0_978_29178_2592538685&f=1&n=20&s=date&o=down&e=1196548712&b=Inbox&u=removed"); + cookie.setPath("/"); + cookie.setDomain("mail.yahoo.com"); QTest::newRow("network3") << "YM.LC=v=2&m=9993_262838_159_1558_1063_0_5649_4012_3776161073,9426_260205_549_1295_1336_0_5141_4738_3922731647,6733_258196_952_1364_643_0_3560_-1_0,3677_237633_1294_1294_19267_0_3244_29483_4102206176,1315_235149_1693_1541_941_0_3224_1691_1861378060,1858_214311_2100_1298_19538_0_2873_30900_716411652,6258_212007_2506_1285_1017_0_2868_3606_4288540264,3743_207884_2895_1362_2759_0_2545_7114_3388520216,2654_205253_3257_1297_1332_0_2504_4682_3048534803,1891_184881_3660_1291_19079_0_978_29178_2592538685&f=1&n=20&s=date&o=down&e=1196548712&b=Inbox&u=removed; path=/; domain=mail.yahoo.com" << cookie; cookie = QNetworkCookie("__ac", "c2hhdXNtYW46U2FTYW80Wm8%3D"); @@ -330,9 +333,9 @@ void tst_QNetworkCookie::parseSingleCookie() QList result = QNetworkCookie::parseCookies(cookieString.toLatin1()); - QEXPECT_FAIL("network2", "QDateTime parsing problem: the date is beyond year 8000", Abort); - QEXPECT_FAIL("network3", "Cookie value contains commas, violating the HTTP spec", Abort); + //QEXPECT_FAIL("network2", "QDateTime parsing problem: the date is beyond year 8000", Abort); QCOMPARE(result.count(), 1); + QEXPECT_FAIL("network3", "Cookie value contains commas, violating the HTTP spec", Abort); QCOMPARE(result.at(0), expectedCookie); result = QNetworkCookie::parseCookies(result.at(0).toRawForm()); @@ -358,9 +361,7 @@ void tst_QNetworkCookie::parseMultipleCookies_data() // reason: malformed NAME=VALUE pair QTest::newRow("invalid-05") << "foo" << list; QTest::newRow("invalid-06") << "=b" << list; - QTest::newRow("invalid-08") << "a=b,foo" << list; QTest::newRow("invalid-09") << "foo,a=b" << list; - QTest::newRow("invalid-10") << "a=b,=b" << list; QTest::newRow("invalid-11") << ";path=/" << list; // reason: malformed expiration date string @@ -369,8 +370,6 @@ void tst_QNetworkCookie::parseMultipleCookies_data() QTest::newRow("invalid-14") << "a=b;expires=foobar, abc" << list; QTest::newRow("invalid-15") << "a=b;expires=foobar, dd-mmm-yyyy hh:mm:ss GMT; path=/" << list; QTest::newRow("invalid-16") << "a=b;expires=foobar, 32-Caz-1999 24:01:60 GMT; path=/" << list; - QTest::newRow("invalid-17") << "a=b,c=d;expires=" << list; - QTest::newRow("invalid-18") << "a=b, c=d; expires=foobar, 32-Caz-1999 24:01:60 GMT; path=/" << list; QNetworkCookie cookie; cookie.setName("a"); -- cgit v0.12 From 36b7256f87f97a84f1a1331c68d5ef7783aef9ab Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 15:47:04 +0100 Subject: When doing date comparisons, force to the same timezone. It's the logical time that matters, not the exact date representation. Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 56cb539..852fcd6 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -164,7 +164,7 @@ bool QNetworkCookie::operator==(const QNetworkCookie &other) const return true; return d->name == other.d->name && d->value == other.d->value && - d->expirationDate == other.d->expirationDate && + d->expirationDate.toUTC() == other.d->expirationDate.toUTC() && d->domain == other.d->domain && d->path == other.d->path && d->secure == other.d->secure && -- cgit v0.12 From fde8457213eaa3da881d1afa8f9f2294acdc4877 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 15:47:59 +0100 Subject: Fix parsing of dates: if the month is followed by a dash, it's not the negative sign. I don't know why, but this only triggers for the month of October Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 852fcd6..286c5f6 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -636,6 +636,8 @@ static QDateTime parseDateString(const QByteArray &dateString) qDebug() << "Month:" << month; #endif at += 3; + if (at < dateString.length() && dateString[at] == '-') + ++at; continue; } // Zone -- cgit v0.12 From 9cc1b5573affdfcf1862369afe387c8fdf8474e6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 15:48:18 +0100 Subject: Fix accesses past-the-end of the byte array Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 286c5f6..4846618 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -662,7 +662,8 @@ static QDateTime parseDateString(const QByteArray &dateString) || (dateString[at - 1] == 't'))) { int end = 1; - while (end < 5 && dateString[at + end] >= '0' && dateString[at + end] <= '9') + while (end < 5 && dateString.length() > at+end + && dateString[at + end] >= '0' && dateString[at + end] <= '9') ++end; int minutes = 0; int hours = 0; @@ -736,7 +737,7 @@ static QDateTime parseDateString(const QByteArray &dateString) // Could be month, day or year if (isNum) { int length = 1; - if (dateString.length() >= at + 1 + if (dateString.length() > at + 1 && isNumber(dateString[at + 1])) ++length; int x = atoi(dateString.mid(at, length).constData()); -- cgit v0.12 From ece28c5e497c5a7ce1f7671094c5ff3e58d176c5 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Thu, 26 Mar 2009 15:53:09 +0100 Subject: Autotest: more date-time parsing tests for QNetworkCookie Signoff-by: Thiago Macieira Signed-off-by: Peter Hartmann --- tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp | 264 +++++++++++++++++++++++ 1 file changed, 264 insertions(+) diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index 4da17d9..2187b61 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -286,8 +286,263 @@ void tst_QNetworkCookie::parseSingleCookie_data() QTest::newRow("expiration3") << "a=b; expires=Wednesday, 09-Nov-1999 23:12:40 GMT " << cookie; QTest::newRow("expiration-utc") << "a=b;expires=Wednesday, 09-Nov-1999 23:12:40 UTC" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 0, 0), Qt::UTC)); + QTest::newRow("time-0") << "a=b;expires=14 Apr 89 03:20" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 12, 0), Qt::UTC)); + QTest::newRow("time-1") << "a=b;expires=14 Apr 89 03:20:12" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-2") << "a=b;expires=14 Apr 89 03:20:12.88" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-3") << "a=b;expires=14 Apr 89 03:20:12.88am" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(15, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-4") << "a=b;expires=14 Apr 89 03:20:12.88pm" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-5") << "a=b;expires=14 Apr 89 03:20:12.88 Am" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(15, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-6") << "a=b;expires=14 Apr 89 03:20:12.88 PM" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(15, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-7") << "a=b;expires=14 Apr 89 3:20:12.88 PM" << cookie; + + // normal months + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-1") << "a=b;expires=Jan 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 2, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-2") << "a=b;expires=Feb 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 3, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-3") << "a=b;expires=mar 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-4") << "a=b;expires=Apr 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 5, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-5") << "a=b;expires=May 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 6, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-6") << "a=b;expires=Jun 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 7, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-7") << "a=b;expires=Jul 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 8, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-8") << "a=b;expires=Aug 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 9, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-9") << "a=b;expires=Sep 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 10, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-10") << "a=b;expires=Oct 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 11, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-11") << "a=b;expires=Nov 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 12, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-12") << "a=b;expires=Dec 1 89 1:1" << cookie; + + // extra months + cookie.setExpirationDate(QDateTime(QDate(1989, 12, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-13") << "a=b;expires=December 1 89 1:1" << cookie; + QTest::newRow("months-14") << "a=b;expires=1 89 1:1 Dec" << cookie; + //cookie.setExpirationDate(QDateTime()); + //QTest::newRow("months-15") << "a=b;expires=1 89 1:1 De" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2024, 2, 29), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-16") << "a=b;expires=2024 29 Feb 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2024, 2, 29), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-17") << "a=b;expires=Fri, 29-Feb-2024 01:01:00 GMT" << cookie; + QTest::newRow("months-18") << "a=b;expires=2024 29 Feb 1:1 GMT" << cookie; + + // normal offsets + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-0") << "a=b;expires=Jan 1 89 8:0 PST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-1") << "a=b;expires=Jan 1 89 8:0 PDT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-2") << "a=b;expires=Jan 1 89 7:0 MST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-3") << "a=b;expires=Jan 1 89 7:0 MDT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-4") << "a=b;expires=Jan 1 89 6:0 CST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-5") << "a=b;expires=Jan 1 89 6:0 CDT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-6") << "a=b;expires=Jan 1 89 5:0 EST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-7") << "a=b;expires=Jan 1 89 5:0 EDT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-8") << "a=b;expires=Jan 1 89 4:0 AST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-9") << "a=b;expires=Jan 1 89 3:0 NST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-10") << "a=b;expires=Jan 1 89 0:0 GMT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-11") << "a=b;expires=Jan 1 89 0:0 BST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-12") << "a=b;expires=Jan 1 89 23:0 MET" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-13") << "a=b;expires=Jan 1 89 22:0 EET" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-14") << "a=b;expires=Jan 1 89 15:0 JST" << cookie; + + // extra offsets + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-14") << "a=b;expires=Jan 1 89 15:0 JST+1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); + QTest::newRow("zoneoffset-15") << "a=b;expires=Jan 1 89 0:0 GMT+1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-15b") << "a=b;expires=Jan 1 89 1:0 GMT-1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); + QTest::newRow("zoneoffset-16") << "a=b;expires=Jan 1 89 0:0 GMT+01" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 5), Qt::UTC)); + QTest::newRow("zoneoffset-17") << "a=b;expires=Jan 1 89 0:0 GMT+0105" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-18") << "a=b;expires=Jan 1 89 0:0 GMT+015" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-19") << "a=b;expires=Jan 1 89 0:0 GM" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-19b") << "a=b;expires=Jan 1 89 0:0 GMT" << cookie; + + // offsets from gmt + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); + QTest::newRow("zoneoffset-20") << "a=b;expires=Jan 1 89 0:0 +1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); + QTest::newRow("zoneoffset-21") << "a=b;expires=Jan 1 89 0:0 +01" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("zoneoffset-22") << "a=b;expires=Jan 1 89 0:0 +0101" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-23") << "a=b;expires=Jan 1 89 1:0 -1" << cookie; + + // Y2k + cookie.setExpirationDate(QDateTime(QDate(2000, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("year-0") << "a=b;expires=Jan 1 00 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("year-1") << "a=b;expires=Jan 1 70 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1971, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("year-2") << "a=b;expires=Jan 1 71 0:0" << cookie; + + // Day, month, year + cookie.setExpirationDate(QDateTime(QDate(2013, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("date-0") << "a=b;expires=Jan 2 13 0:0" << cookie; + QTest::newRow("date-1") << "a=b;expires=1-2-13 0:0" << cookie; + QTest::newRow("date-2") << "a=b;expires=1/2/13 0:0" << cookie; + QTest::newRow("date-3") << "a=b;expires=Jan 2 13 0:0" << cookie; + QTest::newRow("date-4") << "a=b;expires=Jan 2, 13 0:0" << cookie; + QTest::newRow("date-5") << "a=b;expires=1-2-13 0:0" << cookie; + QTest::newRow("date-6") << "a=b;expires=1/2/13 0:0" << cookie; + + // Known Year, determine month and day + cookie.setExpirationDate(QDateTime(QDate(1995, 1, 13), QTime(0, 0), Qt::UTC)); + QTest::newRow("knownyear-0") << "a=b;expires=13/1/95 0:0" << cookie; + QTest::newRow("knownyear-1") << "a=b;expires=95/13/1 0:0" << cookie; + QTest::newRow("knownyear-2") << "a=b;expires=1995/1/13 0:0" << cookie; + QTest::newRow("knownyear-3") << "a=b;expires=1995/13/1 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1995, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("knownyear-4") << "a=b;expires=1/2/95 0:0" << cookie; + QTest::newRow("knownyear-5") << "a=b;expires=95/1/2 0:0" << cookie; + + // Known Year, Known day, determining month + cookie.setExpirationDate(QDateTime(QDate(1995, 1, 13), QTime(0, 0), Qt::UTC)); + QTest::newRow("knownYD-0") << "a=b;expires=13/1/95 0:0" << cookie; + QTest::newRow("knownYD-1") << "a=b;expires=1/13/95 0:0" << cookie; + QTest::newRow("knownYD-2") << "a=b;expires=95/13/1 0:0" << cookie; + QTest::newRow("knownYD-3") << "a=b;expires=95/1/13 0:0" << cookie; + + // Month comes before Year + cookie.setExpirationDate(QDateTime(QDate(2021, 03, 26), QTime(0, 0), Qt::UTC)); + QTest::newRow("month-0") << "a=b;expires=26/03/21 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2015, 12, 30), QTime(16, 25, 0, 0), Qt::UTC)); + QTest::newRow("month-1") << "a=b;expires=wed 16:25pm December 2015 30" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2031, 11, 11), QTime(16, 25, 0, 0), Qt::UTC)); + QTest::newRow("month-2") << "a=b;expires=16:25 11 31 11" << cookie; + + // The very ambiguous cases + // Matching Firefox's behavior of guessing month, day, year in those cases + cookie.setExpirationDate(QDateTime(QDate(2013, 10, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-0") << "a=b;expires=10/2/13 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2013, 2, 10), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-1") << "a=b;expires=2/10/13 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2010, 2, 3), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-2") << "a=b;expires=2/3/10 0:0" << cookie; + + // FYI If you try these in Firefox it wont set a cookie for the following two string + // because 03 is turned into the year at which point it is expired + cookie.setExpirationDate(QDateTime(QDate(2003, 2, 10), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-3") << "a=b;expires=2/10/3 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2003, 10, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-4") << "a=b;expires=10/2/3 0:0" << cookie; + + // These are the cookies that firefox's source says it can parse + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 0, 0), Qt::UTC)); + QTest::newRow("firefox-0") << "a=b;expires=14 Apr 89 03:20" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 0, 0), Qt::UTC)); + QTest::newRow("firefox-1") << "a=b;expires=14 Apr 89 03:20 GMT" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 3, 17), QTime(4, 1, 33, 0), Qt::UTC)); + QTest::newRow("firefox-2") << "a=b;expires=Fri, 17 Mar 89 4:01:33" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 3, 17), QTime(4, 1, 0, 0), Qt::UTC)); + QTest::newRow("firefox-3") << "a=b;expires=Fri, 17 Mar 89 4:01 GMT" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 16), QTime(16-8, 12, 0, 0), Qt::UTC)); + QTest::newRow("firefox-4") << "a=b;expires=Mon Jan 16 16:12 PDT 1989" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 16), QTime(17, 42, 0, 0), Qt::UTC)); + QTest::newRow("firefox-5") << "a=b;expires=Mon Jan 16 16:12 +0130 1989" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1992, 5, 6), QTime(16-9, 41, 0, 0), Qt::UTC)); + QTest::newRow("firefox-6") << "a=b;expires=6 May 1992 16:41-JST (Wednesday)" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1993, 8, 22), QTime(10, 59, 12, 82), Qt::UTC)); + QTest::newRow("firefox-7") << "a=b;expires=22-AUG-1993 10:59:12.82" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1993, 8, 22), QTime(22, 59, 0, 0), Qt::UTC)); + QTest::newRow("firefox-8") << "a=b;expires=22-AUG-1993 10:59pm" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1993, 8, 22), QTime(12, 59, 0, 0), Qt::UTC)); + QTest::newRow("firefox-9") << "a=b;expires=22-AUG-1993 12:59am" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1993, 8, 22), QTime(12, 59, 0, 0), Qt::UTC)); + QTest::newRow("firefox-10") << "a=b;expires=22-AUG-1993 12:59 PM" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1995, 8, 4), QTime(15, 54, 0, 0), Qt::UTC)); + QTest::newRow("firefox-11") << "a=b;expires=Friday, August 04, 1995 3:54 PM" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1995, 6, 21), QTime(16, 24, 34, 0), Qt::UTC)); + QTest::newRow("firefox-12") << "a=b;expires=06/21/95 04:24:34 PM" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1995, 6, 20), QTime(21, 7, 0, 0), Qt::UTC)); + QTest::newRow("firefox-13") << "a=b;expires=20/06/95 21:07" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1995, 6, 8), QTime(19-5, 32, 48, 0), Qt::UTC)); + QTest::newRow("firefox-14") << "a=b;expires=95-06-08 19:32:48 EDT" << cookie; + + // Edge cases caught by fuzzing + // These are about the default cause creates dates that don't exits + cookie.setExpirationDate(QDateTime(QDate(2030, 2, 25), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-0") << "a=b; expires=30 -000002 1:1 25;" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(2031, 11, 20), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-1") << "a=b; expires=31 11 20 1:1;" << cookie; + + // April only has 30 days + cookie.setExpirationDate(QDateTime(QDate(2031, 4, 30), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-2") << "a=b; expires=31 30 4 1:1" << cookie; + + // 9 must be the month so 31 can't be the day + cookie.setExpirationDate(QDateTime(QDate(2031, 9, 21), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-3") << "a=b; expires=31 21 9 1:1" << cookie; + + // Year is known, then fallback to defaults of filling in month and day + cookie.setExpirationDate(QDateTime(QDate(2031, 11, 1), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-4") << "a=b; expires=31 11 01 1:1" << cookie; + + // 2 must be the month so 30 can't be the day + cookie.setExpirationDate(QDateTime(QDate(2030, 2, 20), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-5") << "a=b; expires=30 02 20 1:1" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(2021, 12, 22), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-6") << "a=b; expires=2021 12 22 1:1" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(2029, 2, 23), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-7") << "a=b; expires=29 23 Feb 1:1" << cookie; + + // 11 and 6 don't have 31 days + cookie.setExpirationDate(QDateTime(QDate(2031, 11, 06), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-8") << "a=b; expires=31 11 06 1:1" << cookie; + // two-digit years: // from 70 until 99, we assume 20th century + cookie.setExpirationDate(QDateTime(QDate(1999, 11, 9), QTime(23, 12, 40), Qt::UTC)); QTest::newRow("expiration-2digit1") << "a=b; expires=Wednesday, 09-Nov-99 23:12:40 GMT " << cookie; cookie.setExpirationDate(QDateTime(QDate(1970, 1, 1), QTime(23, 12, 40), Qt::UTC)); QTest::newRow("expiration-2digit2") << "a=b; expires=Thursday, 01-Jan-70 23:12:40 GMT " << cookie; @@ -340,6 +595,15 @@ void tst_QNetworkCookie::parseSingleCookie() result = QNetworkCookie::parseCookies(result.at(0).toRawForm()); QCOMPARE(result.count(), 1); + + // Drop any millisecond information, if there's any + QDateTime dt = expectedCookie.expirationDate(); + if (dt.isValid()) { + QTime t = dt.time(); + dt.setTime(t.addMSecs(-t.msec())); + expectedCookie.setExpirationDate(dt); + } + QCOMPARE(result.at(0), expectedCookie); } -- cgit v0.12 From 37b61133eed38dbb8a7b87fce18b6ea016469fdc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 16:00:53 +0100 Subject: Fix parsing of multiple cookies that are separated by a newline Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 2 +- tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 4846618..fed0afc 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -931,7 +931,7 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin // When there are multiple SetCookie headers they are join with a new line // \n will always be the start of a new cookie - int endOfSetCookie = cookieString.indexOf('\n'); + int endOfSetCookie = cookieString.indexOf('\n', position); if (endOfSetCookie == -1) endOfSetCookie = length; diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index 2187b61..36a4b45 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -680,6 +680,26 @@ void tst_QNetworkCookie::parseMultipleCookies_data() list << cookie; QTest::newRow("network1") << "id=51706646077999719 bb=\"K14144t\"_AAQ\"ototrK_A_ttot44AQ4KwoRQtoto| adv=; Domain=.bluestreak.com; expires=Tuesday 05-Dec-2017 09:11:07 GMT; path=/;" << list; + QNetworkCookie cookieA; + cookieA.setName("a"); + cookieA.setValue("b"); + + QNetworkCookie cookieB; + cookieB.setName("c"); + cookieB.setValue("d"); + + // NewLine + cookieA.setExpirationDate(QDateTime(QDate(2009, 3, 10), QTime(7, 0, 0, 0), Qt::UTC)); + cookieB.setExpirationDate(QDateTime(QDate(2009, 3, 20), QTime(7, 0, 0, 0), Qt::UTC)); + list = QList() << cookieA << cookieB; + QTest::newRow("real-0") << "a=b; expires=Tue Mar 10 07:00:00 2009 GMT\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; + QTest::newRow("real-1") << "a=b; expires=Tue Mar 10 07:00:00 2009 GMT\n\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; + QTest::newRow("real-2") << "a=b; expires=Mar 10 07:00:00 2009 GMT, Tue\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; + + // Match firefox's behavior + cookieA.setPath("/foo"); + list = QList() << cookieA << cookieB; + QTest::newRow("real-3") << "a=b; expires=Mar 10 07:00:00 2009 GMT, Tue; path=/foo\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; } void tst_QNetworkCookie::parseMultipleCookies() -- cgit v0.12 From 1e7d1500e9351d8fc0cd7d3bc017e974aa45b035 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 08:58:40 -0700 Subject: Compile with QT_NO_DIRECTFB_WM s/QDirectFBSurface/QDirectFBScreen/g Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index 00d1781..4ba1102 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -154,7 +154,7 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) description.width = rect.width(); description.height = rect.height(); QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, - QDirectFBSurface::instance()->pixelFormat()); + QDirectFBScreen::instance()->pixelFormat()); dfbSurface = QDirectFBScreen::instance()->createDFBSurface(&description, false); } else { Q_ASSERT(dfbSurface); -- cgit v0.12 From 9340b75300d90d055056cdd68d10725de7829bdd Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 09:00:49 -0700 Subject: Compile with QT_NO_DIRECTFB_PREALLOCATED Use the right surface for locking/unlocking. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 87a5910..3a6b3a2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -161,13 +161,13 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCr if (surface) { char *mem; int bpl; - surface->Lock(dfbSurface, DSLF_WRITE, (void**)&mem, &bpl); + surface->Lock(surface, DSLF_WRITE, (void**)&mem, &bpl); const int h = img.height(); for (int i = 0; i < h; ++i) { memcpy(mem, img.scanLine(i), bpl); mem += bpl; } - surface->Unlock(ret); + surface->Unlock(surface); } #endif #ifndef QT_NO_DIRECTFB_PALETTE -- cgit v0.12 From b91da630b8b1d043bd8ebe52df6fd9c562564d89 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Mon, 30 Mar 2009 18:08:37 +0200 Subject: Doc: Swapping \a with \c to fix a qdoc warning --- src/corelib/io/qtextstream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 512332e..ed9d0aa 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -1370,7 +1370,7 @@ QTextStream::FieldAlignment QTextStream::fieldAlignment() const \snippet doc/src/snippets/code/src_corelib_io_qtextstream.cpp 5 - The string \a s contains: + The string \c s contains: \snippet doc/src/snippets/code/src_corelib_io_qtextstream.cpp 6 -- cgit v0.12 From e475c68f22732553caad350608f2539db7694979 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 18:11:04 +0200 Subject: Doc: Added a code snippet to illustrate the opening of local files. Task-number: 223087 Reviewed-by: TrustMe --- doc/src/snippets/code/src_gui_util_qdesktopservices.cpp | 5 ++++- src/gui/util/qdesktopservices.cpp | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp b/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp index a9c630b..5001984 100644 --- a/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp +++ b/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp @@ -11,7 +11,10 @@ public slots: QDesktopServices::setUrlHandler("help", helpInstance, "showHelp"); //! [0] - //! [1] mailto:user@foo.com?subject=Test&body=Just a test //! [1] + +//! [2] +QDesktopServices::openUrl(QUrl("file:///C:/Documents and Settings/All Users/Desktop", QUrl::TolerantMode)); +//! [2] diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index 0fe1d69..84aa16e 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -157,6 +157,11 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler) If the URL is a reference to a local file (i.e., the URL scheme is "file") then it will be opened with a suitable application instead of a Web browser. + The following example opens a file on the Windows file system residing on a path + that contains spaces: + + \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 2 + If a \c mailto URL is specified, the user's e-mail client will be used to open a composer window containing the options specified in the URL, similar to the way \c mailto links are handled by a Web browser. -- cgit v0.12