From 467b23fcff9f25a14abf051edfb2373c36172fc9 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 7 Apr 2009 12:14:22 +0200 Subject: Fixes missing hover on QListView in Vista We did not enable hover on list view item views. This is inconsistent with how QTreeView works as well as different from how native icon views behave. Reviewed-by: Prasanth Ullattil Task number: 242519 --- src/gui/styles/qwindowsvistastyle.cpp | 3 +++ src/gui/styles/qwindowsvistastyle_p.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index b14b8b3..013ca1e 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -2396,6 +2396,9 @@ void QWindowsVistaStyle::polish(QWidget *widget) else if (QTreeView *tree = qobject_cast (widget)) { tree->viewport()->setAttribute(Qt::WA_Hover); } + else if (QListView *list = qobject_cast (widget)) { + list->viewport()->setAttribute(Qt::WA_Hover); + } } /*! diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/gui/styles/qwindowsvistastyle_p.h index 877bc50..cef2b71 100644 --- a/src/gui/styles/qwindowsvistastyle_p.h +++ b/src/gui/styles/qwindowsvistastyle_p.h @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include -- cgit v0.12 From c1c30037292711f0fb05677e77ed2eb2112eca78 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 7 Apr 2009 12:50:32 +0200 Subject: Fixes: WDestructiveClose flag and the new WindowCancelButtonHint have the same value -> crash on SetTitle() Task: 242484 RevBy: mauricek AutoTest: Details: Since we do not respect binary compatibility on Windows CE we just change the enum --- src/corelib/global/qnamespace.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index fb7fa0c..a519f4a 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -280,9 +280,7 @@ public: WindowStaysOnTopHint = 0x00040000, // reserved for Qt3Support: // WMouseNoMask = 0x00080000, - WindowOkButtonHint = 0x00080000, // WDestructiveClose = 0x00100000, - WindowCancelButtonHint = 0x00100000, // WStaticContents = 0x00200000, // WGroupLeader = 0x00400000, // WShowModal = 0x00800000, @@ -291,7 +289,9 @@ public: WindowStaysOnBottomHint = 0x04000000, WindowCloseButtonHint = 0x08000000, MacWindowToolBarButtonHint = 0x10000000, - BypassGraphicsProxyWidget = 0x20000000 + BypassGraphicsProxyWidget = 0x20000000, + WindowOkButtonHint = 0x00080000, + WindowCancelButtonHint = 0x00100000 #ifdef QT3_SUPPORT , -- cgit v0.12 From a6ab4f638a63755a601b61141fa7730d5ac6e793 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Apr 2009 13:16:28 +0200 Subject: Adjust comments Someone messed up the whitespace on this comment. --- src/gui/widgets/qcocoamenu_mac.mm | 67 ++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index c92dfc0..64da141 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -1,41 +1,41 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) + ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ + ** No Commercial Usage + ** This file contains pre-release code and may not be distributed. + ** You may use this file in accordance with the terms and conditions + ** contained in the either Technology Preview License Agreement or the + ** Beta Release License Agreement. + ** + ** GNU Lesser General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU Lesser + ** General Public License version 2.1 as published by the Free Software + ** Foundation and appearing in the file LICENSE.LGPL included in the + ** packaging of this file. Please review the following information to + ** ensure the GNU Lesser General Public License version 2.1 requirements + ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + ** + ** In addition, as a special exception, Nokia gives you certain + ** additional rights. These rights are described in the Nokia Qt LGPL + ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this + ** package. + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License version 3.0 as published by the Free Software + ** Foundation and appearing in the file LICENSE.GPL included in the + ** packaging of this file. Please review the following information to + ** ensure the GNU General Public License version 3.0 requirements will be + ** met: http://www.gnu.org/copyleft/gpl.html. + ** + ** If you are unsure which license is appropriate for your use, please + ** contact the sales department at qt-sales@nokia.com. + ** $QT_END_LICENSE$ ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -134,8 +134,9 @@ QT_END_NAMESPACE // If it does, then we will first send the key sequence to the QWidget that has focus // since (in Qt's eyes) it needs to a chance at the key event first. If the widget // accepts the key event, we then return YES, but set the target and action to be nil, - // which means that the action should not be triggered. In every other case we return - // NO, which means that Cocoa can do as it pleases (i.e., fire the menu action). + // which means that the action should not be triggered, and instead dispatch the event ourselves. + // In every other case we return NO, which means that Cocoa can do as it pleases + // (i.e., fire the menu action). NSMenuItem *whichItem; if ([self hasShortcut:menu forKey:[event characters] -- cgit v0.12 From acff913a6287ad50b0ac782d817d51072ccb479c Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Apr 2009 13:17:05 +0200 Subject: BT: Send the keyevent after we send the shortcutoverride in menu In our Cocoa menu we check if we need to send the key event to the qwidget before the menu has a chance at it, because logically in Qt, the key event should go to the widget and not the menubar first (a bit different than what happens on the mac). The way to determine this is to send a shortcut override event and see if it accepts it. If it does, that means we should just send it the key event. Previously we were sending the shortcut override, but not following through on the key event because we thought (however foolishly). That returning "YES" but not setting an action would somehow forward the event (it doesn't). There still seems to be some problems if you have a Dvorak-QWERTY+CWD layout, but this probably needs to be dealt with at the key mapper level. Reviewed-by: Prasanth Ullattil --- src/gui/widgets/qcocoamenu_mac.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index 64da141..bae270a 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -161,6 +161,7 @@ QT_END_NAMESPACE if (accel_ev.isAccepted()) { *target = nil; *action = nil; + [qt_mac_nativeview_for(widget) keyDown:event]; return YES; } } -- cgit v0.12 From 179fafcc370c907a6070c7150695d446255e68d1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 7 Apr 2009 13:19:11 +0200 Subject: BT: QFileDialog: A folder with a name containing diacritic is disabled on Mac OS X - cocoa The filename as NSString that we get from Cocoa does not have the correct file system encoding. This means that certain characters are implemented differently than what e.g. QFile::encoded returns. This fix normalizes the string from cocoa before using it. Task-number: 249928 Reviewed-by: Trenton Schulz --- src/gui/dialogs/qfiledialog_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm index 4c13d01..90af9fc 100644 --- a/src/gui/dialogs/qfiledialog_mac.mm +++ b/src/gui/dialogs/qfiledialog_mac.mm @@ -278,7 +278,7 @@ QT_USE_NAMESPACE { Q_UNUSED(sender); QString qtFileName = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(filename); - QFileInfo info(qtFileName); + QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C))); QString path = info.absolutePath(); if (path != *mLastFilterCheckPath){ *mLastFilterCheckPath = path; -- cgit v0.12 From ca2d62f97f991d042a781d9d7bd0dbda910e1d04 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 7 Apr 2009 10:59:41 +0200 Subject: Drag cursor is not updated when modifier keys are pressed/released in the Cocoa Builds. The drag move events were compressed based only on the position of the cursor. It has to be based on both position and the "drag operation" in native event. Reviewed-by: nrc --- src/gui/kernel/qcocoaview_mac.mm | 6 ++++-- src/gui/kernel/qt_mac_p.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 19367d1..9b581c5 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -300,11 +300,13 @@ extern "C" { NSPoint windowPoint = [sender draggingLocation]; NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint]; NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; + NSDragOperation nsActions = [sender draggingSourceOperationMask]; QPoint posDrag(localPoint.x, localPoint.y); - if (qt_mac_mouse_inside_answer_rect(posDrag)) + if (qt_mac_mouse_inside_answer_rect(posDrag) + && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions) return QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction)); // send drag move event to the widget - NSDragOperation nsActions = [sender draggingSourceOperationMask]; + QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions; Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions); QMimeData *mimeData = dropData; if (QDragManager::self()->source()) diff --git a/src/gui/kernel/qt_mac_p.h b/src/gui/kernel/qt_mac_p.h index e65492d..ca995dc 100644 --- a/src/gui/kernel/qt_mac_p.h +++ b/src/gui/kernel/qt_mac_p.h @@ -250,11 +250,13 @@ struct QMacDndAnswerRecord { Qt::KeyboardModifiers modifiers; Qt::MouseButtons buttons; Qt::DropAction lastAction; + unsigned int lastOperation; void clear() { rect = QRect(); modifiers = Qt::NoModifier; buttons = Qt::NoButton; lastAction = Qt::IgnoreAction; + lastOperation = 0; } }; extern QMacDndAnswerRecord qt_mac_dnd_answer_rec; -- cgit v0.12 From c5b0197611ebb3279b3426aca275458477edb42d Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 7 Apr 2009 14:15:39 +0200 Subject: My changelog for 4.5.1 --- dist/changes-4.5.1 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 1d2286e..de4eef7 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -33,9 +33,25 @@ Third party components * Library * **************************************************************************** +- QAbstractSocket + * [192037] Emit disconnected only if we were connected before + +- QAuthenticator + * [237979] fix implemenation of md5-sess + +- QFileInfo + * [205244] return valid file info also for relative UNC paths + +- QHttp + * [208445] cancel request upon receiving unknown authentication method + - QSharedPointer * [246843] Fixed a crash caused by using QSharedPointer in global statics +- QSSlSocket + * [245668] set also protocol, verifyMode and verifyDepth in + setSslConfiguration() + **************************************************************************** * Database Drivers * **************************************************************************** -- cgit v0.12 From 0ea43e7d28815c133e8029f3d966871a10fef8e0 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 7 Apr 2009 14:55:04 +0200 Subject: Fixes: mediaobject autotest for windows ce (waveout) RevBy: Joerg AutoTest: mediaobject Details: Since our wave files on Windows CE are very short (memory) we actually land up in the PausedState when playback is finished --- tests/auto/mediaobject/tst_mediaobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/mediaobject/tst_mediaobject.cpp b/tests/auto/mediaobject/tst_mediaobject.cpp index 96589b7..e0275de 100644 --- a/tests/auto/mediaobject/tst_mediaobject.cpp +++ b/tests/auto/mediaobject/tst_mediaobject.cpp @@ -787,7 +787,7 @@ void tst_MediaObject::setMediaAndPlay() QSignalSpy totalTimeChangedSignalSpy(m_media, SIGNAL(totalTimeChanged(qint64))); QVERIFY(m_media->currentSource().type() != MediaSource::Invalid); Phonon::State state = m_media->state(); - QVERIFY(state == Phonon::StoppedState || state == Phonon::PlayingState); + QVERIFY(state == Phonon::StoppedState || state == Phonon::PlayingState || Phonon::PausedState); m_media->setCurrentSource(m_url); // before calling play() we better make sure that if play() finishes very fast that we don't get // called again -- cgit v0.12 From 9904f77b26d3b75f8ed53e82c14ff8e9baf710dc Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 7 Apr 2009 15:04:31 +0200 Subject: BT: compilefix for Qt in namespace RevBy: mauricek Details: using prefix qt_ instead of ::global namespace --- src/gui/graphicsview/qgraphicsitem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 9d320b7..b520a3f 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3707,7 +3707,7 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyCl dirtyChildren = 1; } -static inline bool allChildrenCombineOpacity(QGraphicsItem *parent) +static inline bool qt_allChildrenCombineOpacity(QGraphicsItem *parent) { Q_ASSERT(parent); if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren) @@ -3726,11 +3726,11 @@ void QGraphicsItemPrivate::updateEffectiveOpacity() Q_Q(QGraphicsItem); if (parent) { resolveEffectiveOpacity(parent->effectiveOpacity()); - parent->d_ptr->allChildrenCombineOpacity = ::allChildrenCombineOpacity(parent); + parent->d_ptr->allChildrenCombineOpacity = qt_allChildrenCombineOpacity(parent); } else { resolveEffectiveOpacity(1.0); } - allChildrenCombineOpacity = ::allChildrenCombineOpacity(q); + allChildrenCombineOpacity = qt_allChildrenCombineOpacity(q); } /*! -- cgit v0.12 From de007bd2a20a141aefe901408512c806879a2387 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 7 Apr 2009 15:03:11 +0200 Subject: fix tap-and-hold checkbox problem for Windows CE Symptom: checkboxes didn't get checked if you press, hold for some seconds and then release the mouse or stylus. In QAbstractButton we reacted on the contextMenuEvent that gets sent if the system recognizes the context menu gesture (tap and hold) and did call setDown(false). This change has been done because buttons in tool bars stayed in the down state when displaying the context menu with this gesture. I've now moved the handling of this to qtoolbar.cpp. Task-number: 246619 Reviewed-by: thartman --- src/gui/widgets/qabstractbutton.cpp | 9 --------- src/gui/widgets/qabstractbutton.h | 3 --- src/gui/widgets/qtoolbar.cpp | 11 +++++++++++ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp index 330a7f8..61ed0ea 100644 --- a/src/gui/widgets/qabstractbutton.cpp +++ b/src/gui/widgets/qabstractbutton.cpp @@ -1248,15 +1248,6 @@ void QAbstractButton::timerEvent(QTimerEvent *e) } } -#if defined(Q_OS_WINCE) && !defined(QT_NO_CONTEXTMENU) -/*! \reimp */ -void QAbstractButton::contextMenuEvent(QContextMenuEvent *e) -{ - e->ignore(); - setDown(false); -} -#endif - /*! \reimp */ void QAbstractButton::focusInEvent(QFocusEvent *e) { diff --git a/src/gui/widgets/qabstractbutton.h b/src/gui/widgets/qabstractbutton.h index 6503a56..f0cbb05 100644 --- a/src/gui/widgets/qabstractbutton.h +++ b/src/gui/widgets/qabstractbutton.h @@ -143,9 +143,6 @@ protected: void focusOutEvent(QFocusEvent *e); void changeEvent(QEvent *e); void timerEvent(QTimerEvent *e); -#ifdef Q_OS_WINCE - void contextMenuEvent(QContextMenuEvent *e); -#endif #ifdef QT3_SUPPORT public: diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 85d6ea2..1babb6d 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -1153,6 +1153,17 @@ bool QToolBar::event(QEvent *event) if (d->mouseMoveEvent(static_cast(event))) return true; break; +#ifdef Q_OS_WINCE + case QEvent::ContextMenu: + { + QContextMenuEvent* contextMenuEvent = static_cast(event); + QWidget* child = childAt(contextMenuEvent->pos()); + QAbstractButton* button = qobject_cast(child); + if (button) + button->setDown(false); + } + break; +#endif case QEvent::Leave: if (d->state != 0 && d->state->dragging) { #ifdef Q_OS_WIN -- cgit v0.12 From 773c4d326c24f8db12ab58e379bd223ce1126d72 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Apr 2009 15:30:12 +0200 Subject: BT: Prevent a crash in Designer when quiting when in the filter edit. Gah, my original change (f5ef0eb1a6543abdd29e07c23de7fa1128f6d623) had its heart in the right place, but it seems that it can cause crashes on closing where we refuse to give up the first responder and we end up with a dangling pointer. This lets that case happen (when we have no focus widget and are setting a nil first responder, there's no reason to stop that, but it refuses to do that when we do have a focus widget. Hopefully we don't get in a situation where our focus widget gets out of sync. Reviewed-by: Prasanth Ullattil --- src/gui/kernel/qcocoapanel_mac.mm | 5 +++-- src/gui/kernel/qcocoawindow_mac.mm | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index c17b30c..95e20af 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -157,10 +157,11 @@ QT_USE_NAMESPACE [self release]; } - - (BOOL)makeFirstResponder:(NSResponder *)responder { - if (responder == nil) + // For some reason Cocoa wants to flip the first responder + // when Qt doesn't want to, sorry, but "No" :-) + if (responder == nil && qApp->focusWidget()) return NO; return [super makeFirstResponder:responder]; } diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index ba121cd..e7b76a7 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -182,7 +182,9 @@ extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview. - (BOOL)makeFirstResponder:(NSResponder *)responder { - if (responder == nil) + // For some reason Cocoa wants to flip the first responder + // when Qt doesn't want to, sorry, but "No" :-) + if (responder == nil && qApp->focusWidget()) return NO; return [super makeFirstResponder:responder]; } -- cgit v0.12 From 35c26d696cbff269d551c012a212c09692dd6f6b Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 7 Apr 2009 16:37:08 +0200 Subject: Bt: Fix regression in the Embedded dialogs example We had to revert an earlier fix since it obviously did not work correctly. However since we do not really need to propagate the palette on the viewContainer _before_ it is created, we can simply avoid the issue alltogether as it would happen because we implicitly added a child widget during the polish of the combo box. Reviewed-by: nrc --- demos/embeddeddialogs/customproxy.cpp | 11 +++++++++-- src/gui/widgets/qcombobox.cpp | 24 +++++++++++++----------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/demos/embeddeddialogs/customproxy.cpp b/demos/embeddeddialogs/customproxy.cpp index 56a0548..ed2fc76 100644 --- a/demos/embeddeddialogs/customproxy.cpp +++ b/demos/embeddeddialogs/customproxy.cpp @@ -111,8 +111,15 @@ bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event) QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value) { - if (change == ItemChildRemovedChange) - removeSceneEventFilter(this); + if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { + QGraphicsItem *item = qVariantValue(value); + if (change == ItemChildAddedChange) { + item->setCacheMode(ItemCoordinateCache); + item->installSceneEventFilter(this); + } else { + item->removeSceneEventFilter(this); + } + } return QGraphicsProxyWidget::itemChange(change, value); } diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 09a51fe..b9dbc62 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -2572,19 +2572,21 @@ void QComboBox::changeEvent(QEvent *e) hidePopup(); break; case QEvent::PaletteChange: { - QStyleOptionComboBox opt; - initStyleOption(&opt); + if (d->container) { + QStyleOptionComboBox opt; + initStyleOption(&opt); #ifndef QT_NO_MENU - if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { - QMenu menu; - menu.ensurePolished(); - d->viewContainer()->setPalette(menu.palette()); - d->viewContainer()->setWindowOpacity(menu.windowOpacity()); - } else + if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { + QMenu menu; + menu.ensurePolished(); + d->viewContainer()->setPalette(menu.palette()); + d->viewContainer()->setWindowOpacity(menu.windowOpacity()); + } else #endif - { - d->viewContainer()->setPalette(palette()); - d->viewContainer()->setWindowOpacity(1.0); + { + d->viewContainer()->setPalette(palette()); + d->viewContainer()->setWindowOpacity(1.0); + } } break; } -- cgit v0.12 From 76608a9c51f4cd5309a5fec1af40c4d80089adf5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 7 Apr 2009 17:05:45 +0200 Subject: Fix compilation if SSL is not enabled. Using #ifndef QT_NO_OPENSSL without first #include'ing something will never work. Which means we always include qsslsocket.h. The problem is: if OpenSSL isn't enabled, then that file is a no-op and we never include qabstractsocket.h. Reviewed-by: Markus Goetz --- src/network/access/qhttpnetworkreply_p.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 21f4116..c17c65c 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -66,12 +66,10 @@ static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header #define CHUNK 16384 #endif -#ifndef QT_NO_OPENSSL -# include -# include -#else -# include -#endif +#include +// it's safe to include these even if SSL support is not enabled +#include +#include #include #include -- cgit v0.12 From 18af4dfaabb4c3281abf2c2da575ced8dda672f1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 7 Apr 2009 17:19:47 +0200 Subject: Fixes: Support for OpenGL ES 2.0 in configure.exe (Windows CE) RevBy: Joerg Details: -opengl-es-2 option for configure.exe --- tools/configure/configureapp.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 8c0dc39..df583a6 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -675,6 +675,9 @@ void Configure::parseCmdLine() } else if ( configCmdLine.at(i) == "-opengl-es-cl" ) { dictionary[ "OPENGL" ] = "yes"; dictionary[ "OPENGL_ES_CL" ] = "yes"; + } else if ( configCmdLine.at(i) == "-opengl-es-2" ) { + dictionary[ "OPENGL" ] = "yes"; + dictionary[ "OPENGL_ES_2" ] = "yes"; } // Databases ------------------------------------------------ else if( configCmdLine.at(i) == "-qt-sql-mysql" ) @@ -1632,6 +1635,7 @@ bool Configure::displayHelp() desc( "-signature ", "Use file for signing the target project"); desc("OPENGL_ES_CM", "no", "-opengl-es-cm", "Enable support for OpenGL ES Common"); desc("OPENGL_ES_CL", "no", "-opengl-es-cl", "Enable support for OpenGL ES Common Lite"); + desc("OPENGL_ES_2", "no", "-opengl-es-2", "Enable support for OpenGL ES 2.0"); desc("DIRECTSHOW", "no", "-phonon-wince-ds9", "Enable Phonon Direct Show 9 backend for Windows CE"); return true; @@ -1785,6 +1789,8 @@ bool Configure::checkAvailability(const QString &part) available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "OPENGL_ES_CL") available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); + else if (part == "OPENGL_ES_2") + available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "DIRECTSHOW") available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "SSE2") @@ -2264,6 +2270,10 @@ void Configure::generateOutputVars() qtConfig += "opengles1"; } + if ( dictionary["OPENGL_ES_2"] == "yes" ) { + qtConfig += "opengles2"; + } + if ( dictionary["OPENGL_ES_CL"] == "yes" ) { qtConfig += "opengles1cl"; } @@ -2664,9 +2674,11 @@ void Configure::generateConfigfiles() if(dictionary["SCRIPTTOOLS"] == "no") qconfigList += "QT_NO_SCRIPTTOOLS"; if(dictionary["OPENGL_ES_CM"] == "yes" || - dictionary["OPENGL_ES_CL"] == "yes") qconfigList += "QT_OPENGL_ES"; + dictionary["OPENGL_ES_CL"] == "yes" || + dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES"; if(dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1"; + if(dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2"; if(dictionary["OPENGL_ES_CL"] == "yes") qconfigList += "QT_OPENGL_ES_1_CL"; if(dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL"; -- cgit v0.12 From 5d6b7757eebc76018eedd2fdfb5135df7b5cb460 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 7 Apr 2009 08:19:52 -0700 Subject: Make sure to clear surface in toImage It seems DirectFB doesn't preserve alpha value of a blit unless BLEND is specified and if it is we need to Clear to transparent first. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 35ab859..a20b66a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -250,7 +250,12 @@ QImage QDirectFBPixmapData::toImage() const #ifndef QT_NO_DIRECTFB_PREALLOCATED QImage ret(size(), QDirectFBScreen::getImageFormat(dfbSurface)); if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) { - imgSurface->SetBlittingFlags(imgSurface, hasAlphaChannel() ? DSBLIT_BLEND_ALPHACHANNEL : DSBLIT_NOFX); + if (hasAlphaChannel()) { + imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL); + imgSurface->Clear(imgSurface, 0, 0, 0, 0); + } else { + imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX); + } imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0); imgSurface->ReleaseSource(imgSurface); imgSurface->Release(imgSurface); -- cgit v0.12 From 3568aeef72bec8333650eb2200b12eba8fac1b71 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 7 Apr 2009 16:59:01 +0200 Subject: compile with aCC --- tools/linguist/shared/translatormessage.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/translatormessage.h b/tools/linguist/shared/translatormessage.h index 7d31925..9f847b0 100644 --- a/tools/linguist/shared/translatormessage.h +++ b/tools/linguist/shared/translatormessage.h @@ -195,12 +195,12 @@ struct TranslatorMessagePtr { Q_DECLARE_TYPEINFO(TranslatorMessagePtr, Q_MOVABLE_TYPE); -static inline int qHash(TranslatorMessagePtr tmp) +inline int qHash(TranslatorMessagePtr tmp) { return qHash(*tmp.ptr); } -static inline bool operator==(TranslatorMessagePtr tmp1, TranslatorMessagePtr tmp2) +inline bool operator==(TranslatorMessagePtr tmp1, TranslatorMessagePtr tmp2) { return *tmp1.ptr == *tmp2.ptr; } -- cgit v0.12 From 2553bde1b24091ef4076d0512709b6657750000e Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 7 Apr 2009 12:47:04 -0700 Subject: Make flipflags work a little better. Make it more flexible. This patch allows people to use DFB without DSFLIP_BLIT. Also, before this patch the flip= options weren't really used for anything. Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 20 ++++++----- .../gfxdrivers/directfb/qdirectfbsurface.cpp | 40 ++++++++++++++-------- src/plugins/gfxdrivers/directfb/qdirectfbsurface.h | 5 +-- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 4ae64f7..a62c846 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -85,7 +85,7 @@ public: }; QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen) - : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_BLIT) + : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_NONE) #ifndef QT_NO_DIRECTFB_LAYER , dfbLayer(0) #endif @@ -710,7 +710,7 @@ int QDirectFBScreen::depth(DFBSurfacePixelFormat format) void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args) { - QRegExp flipRegexp(QLatin1String("^flip=([\\w,]+)$")); + QRegExp flipRegexp(QLatin1String("^flip=([\\w,]*)$")); int index = args.indexOf(flipRegexp); if (index >= 0) { const QStringList flips = flipRegexp.cap(1).split(QLatin1Char(','), @@ -729,6 +729,8 @@ void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args) qWarning("QDirectFBScreen: Unknown flip argument: %s", qPrintable(flip)); } + } else { + flipFlags = DFBSurfaceFlipFlags(DSFLIP_BLIT); } } @@ -994,19 +996,21 @@ void QDirectFBScreen::blank(bool on) QWSWindowSurface* QDirectFBScreen::createSurface(QWidget *widget) const { #ifdef QT_NO_DIRECTFB_WM - if (QApplication::type() == QApplication::GuiServer) - return new QDirectFBSurface(const_cast(this), widget); - else + if (QApplication::type() == QApplication::GuiServer) { + return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this), widget); + } else { return QScreen::createSurface(widget); + } #else - return new QDirectFBSurface(const_cast(this), widget); + return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this), widget); #endif } QWSWindowSurface* QDirectFBScreen::createSurface(const QString &key) const { - if (key == QLatin1String("directfb")) - return new QDirectFBSurface(const_cast(this)); + if (key == QLatin1String("directfb")) { + return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this)); + } return QScreen::createSurface(key); } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index 4b8fe0a..f5626c8 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -50,12 +50,13 @@ //#define QT_DIRECTFB_DEBUG_SURFACES 1 -QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr) +QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen* scr) : QDirectFBPaintDevice(scr) #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) #endif , engine(0) + , flipFlags(flip) { setSurfaceFlags(Opaque | Buffered); #ifdef QT_DIRECTFB_TIMING @@ -64,12 +65,13 @@ QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr) #endif } -QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr, QWidget *widget) +QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) : QWSWindowSurface(widget), QDirectFBPaintDevice(scr) #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) #endif , engine(0) + , flipFlags(flip) { onscreen = widget->testAttribute(Qt::WA_PaintOnScreen); if (onscreen) @@ -244,7 +246,7 @@ void QDirectFBSurface::setPermanentState(const QByteArray &state) bool QDirectFBSurface::scroll(const QRegion ®ion, int dx, int dy) { - if (!dfbSurface) + if (!dfbSurface || !(flipFlags & DSFLIP_BLIT)) return false; const QVector rects = region.rects(); @@ -362,21 +364,31 @@ void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, } #endif #ifndef QT_NO_DIRECTFB_WM - if (region.numRects() > 1) { - const QVector rects = region.rects(); - for (int i=0; iFlip(dfbSurface, 0, DFBSurfaceFlipFlags(flipFlags)); + } else { + if (region.numRects() > 1) { + const QVector rects = region.rects(); + DFBSurfaceFlipFlags tmpFlags = flipFlags; + if (flipFlags & DSFLIP_WAIT) + tmpFlags = DFBSurfaceFlipFlags(flipFlags & ~DSFLIP_WAIT); + for (int i=0; iFlip(dfbSurface, &dfbReg, + i + 1 < rects.size() + ? tmpFlags + : flipFlags); + } + } else { + const QRect r = region.boundingRect(); const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), r.x() + r.width() + offset.x(), r.y() + r.height() + offset.y() }; - dfbSurface->Flip(dfbSurface, &dfbReg, DSFLIP_ONSYNC); + dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); } - } else { - const QRect r = region.boundingRect(); - const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), - r.x() + r.width() + offset.x(), - r.y() + r.height() + offset.y() }; - dfbSurface->Flip(dfbSurface, &dfbReg, DSFLIP_ONSYNC); } #endif #ifdef QT_DIRECTFB_TIMING diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h index 9e2791c..ab4145d 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h @@ -61,8 +61,8 @@ QT_MODULE(Gui) class QDirectFBSurface: public QWSWindowSurface, public QDirectFBPaintDevice { public: - QDirectFBSurface(QDirectFBScreen* scr); - QDirectFBSurface(QDirectFBScreen* scr, QWidget *widget); + QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); + QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); ~QDirectFBSurface(); bool isValid() const; @@ -99,6 +99,7 @@ private: bool onscreen; QList bufferImages; + DFBSurfaceFlipFlags flipFlags; #ifdef QT_DIRECTFB_TIMING int frames; QTime timer; -- cgit v0.12 From b818bf2d67e4e5f3f3a01eeb0c0de37a4cd33b50 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 7 Apr 2009 15:01:46 -0700 Subject: Work around RGB32 issue in solidFill Drawing operations with DirectFB in RGB32 changes the alpha byte to 0. This doesn't play well with QRasterEngine. See 5fb7752ff93b31635e64fa321917749744cc9db6 and 34059fba55816496d2570b3306ac2b631b12a5c6 Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 37 +++++++++++++--------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index a62c846..bf9864a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1182,21 +1182,29 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) if (region.isEmpty()) return; - const QVector rects = region.rects(); - QVarLengthArray dfbRects(rects.size()); - for (int i = 0; i < rects.size(); ++i) { - const QRect r = rects.at(i); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); + if (QDirectFBScreen::getImageFormat(d_ptr->dfbSurface) == QImage::Format_RGB32) { + uchar *mem; + int bpl; + d_ptr->dfbSurface->Lock(d_ptr->dfbSurface, DSLF_WRITE, (void**)&mem, &bpl); + QImage img(mem, w, h, bpl, QImage::Format_RGB32); + QPainter p(&img); + p.setBrush(color); + p.setPen(Qt::NoPen); + const QVector rects = region.rects(); + p.drawRects(rects.constData(), rects.size()); + p.end(); + d_ptr->dfbSurface->Unlock(d_ptr->dfbSurface); + } else { + d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface, + color.red(), color.green(), color.blue(), + color.alpha()); + const QVector rects = region.rects(); + for (int i=0; idfbSurface->FillRectangle(d_ptr->dfbSurface, + r.x(), r.y(), r.width(), r.height()); + } } - - d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface, - color.red(), color.green(), color.blue(), - color.alpha()); - d_ptr->dfbSurface->FillRectangles(d_ptr->dfbSurface, dfbRects.data(), - dfbRects.size()); } QImage::Format QDirectFBScreen::alphaPixmapFormat() const @@ -1204,7 +1212,6 @@ QImage::Format QDirectFBScreen::alphaPixmapFormat() const return d_ptr->alphaPixmapFormat; } - bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format) { -- cgit v0.12 From 06c19716bd9c5974743775de7aa702271b3ab435 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Apr 2009 09:53:53 +1000 Subject: Fixes: Memory leak in DB2 driver Looks like they were using the old QPtrVector in qt3, and didn't quite handle the porting correctly. Reviewed-by: Lincoln Ramsay --- src/sql/drivers/db2/qsql_db2.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 69383f7..a6be435 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -87,8 +87,19 @@ public: {} ~QDB2ResultPrivate() { - for (int i = 0; i < valueCache.count(); ++i) + emptyValueCache(); + } + void clearValueCache() + { + for (int i = 0; i < valueCache.count(); ++i) { delete valueCache[i]; + valueCache[i] = NULL; + } + } + void emptyValueCache() + { + clearValueCache(); + valueCache.clear(); } const QDB2DriverPrivate* dp; @@ -544,7 +555,7 @@ bool QDB2Result::reset (const QString& query) SQLRETURN r; d->recInf.clear(); - d->valueCache.clear(); + d->emptyValueCache(); if (!qMakeStatement(d, isForwardOnly())) return false; @@ -567,7 +578,7 @@ bool QDB2Result::reset (const QString& query) } else { setSelect(false); } - d->valueCache.resize(count); + d->valueCache.resize(count, NULL); setActive(true); return true; } @@ -579,7 +590,7 @@ bool QDB2Result::prepare(const QString& query) SQLRETURN r; d->recInf.clear(); - d->valueCache.clear(); + d->emptyValueCache(); if (!qMakeStatement(d, isForwardOnly())) return false; @@ -607,7 +618,7 @@ bool QDB2Result::exec() SQLRETURN r; d->recInf.clear(); - d->valueCache.clear(); + d->emptyValueCache(); if (!qMakeStatement(d, isForwardOnly(), false)) return false; @@ -810,7 +821,7 @@ bool QDB2Result::exec() setSelect(false); } setActive(true); - d->valueCache.resize(count); + d->valueCache.resize(count, NULL); //get out parameters if (!hasOutValues()) @@ -858,7 +869,7 @@ bool QDB2Result::fetch(int i) return false; if (i == at()) return true; - d->valueCache.fill(0); + d->clearValueCache(); int actualIdx = i + 1; if (actualIdx <= 0) { setAt(QSql::BeforeFirstRow); @@ -887,7 +898,7 @@ bool QDB2Result::fetch(int i) bool QDB2Result::fetchNext() { SQLRETURN r; - d->valueCache.fill(0); + d->clearValueCache(); r = SQLFetchScroll(d->hStmt, SQL_FETCH_NEXT, 0); @@ -907,7 +918,7 @@ bool QDB2Result::fetchFirst() return false; if (isForwardOnly()) return fetchNext(); - d->valueCache.fill(0); + d->clearValueCache(); SQLRETURN r; r = SQLFetchScroll(d->hStmt, SQL_FETCH_FIRST, @@ -923,7 +934,7 @@ bool QDB2Result::fetchFirst() bool QDB2Result::fetchLast() { - d->valueCache.fill(0); + d->clearValueCache(); int i = at(); if (i == QSql::AfterLastRow) { @@ -1101,7 +1112,7 @@ bool QDB2Result::nextResult() setActive(false); setAt(QSql::BeforeFirstRow); d->recInf.clear(); - d->valueCache.clear(); + d->emptyValueCache(); setSelect(false); SQLRETURN r = SQLMoreResults(d->hStmt); @@ -1119,7 +1130,7 @@ bool QDB2Result::nextResult() for (int i = 0; i < fieldCount; ++i) d->recInf.append(qMakeFieldInfo(d, i)); - d->valueCache.resize(fieldCount); + d->valueCache.resize(fieldCount, NULL); setActive(true); return true; -- cgit v0.12 From 25b8d04ad9f2d5b89e81f56212b4dbfaeff1304d Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Apr 2009 14:55:00 +1000 Subject: Missed these changes from the last commit. Last of the changes to include behaviour from QPtrVector --- src/sql/drivers/db2/qsql_db2.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index a6be435..5d221b8 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #ifndef UNICODE #define UNICODE @@ -578,7 +579,8 @@ bool QDB2Result::reset (const QString& query) } else { setSelect(false); } - d->valueCache.resize(count, NULL); + d->valueCache.resize(count); + d->valueCache.fill(NULL); setActive(true); return true; } @@ -821,7 +823,8 @@ bool QDB2Result::exec() setSelect(false); } setActive(true); - d->valueCache.resize(count, NULL); + d->valueCache.resize(count); + d->valueCache.fill(NULL); //get out parameters if (!hasOutValues()) @@ -1130,7 +1133,8 @@ bool QDB2Result::nextResult() for (int i = 0; i < fieldCount; ++i) d->recInf.append(qMakeFieldInfo(d, i)); - d->valueCache.resize(fieldCount, NULL); + d->valueCache.resize(fieldCount); + d->valueCache.fill(NULL); setActive(true); return true; -- cgit v0.12 From 9565e3420bdc214c389aa513748da11ff16b1fca Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Apr 2009 15:40:24 +1000 Subject: DB2 driver returning double field as empty The high precision code path was getting an empty string on the second call to getstringdata, which was causing it to return empty for the field. Really only needed to call it once anyway, so use the original call. Reviewed-by: Justin McPherson --- src/sql/drivers/db2/qsql_db2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 5d221b8..2786dbb 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -1058,7 +1058,7 @@ QVariant QDB2Result::data(int field) case QSql::HighPrecision: default: // length + 1 for the comma - v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull)); + v = new QVariant(value); ok = true; break; } -- cgit v0.12 From a4252201f631d65553846c6af65df905a0cf4048 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 08:05:44 +0200 Subject: Enable test for WinCE While we integrate into native menubar on Windows Mobile, we can still test WinCE itself. --- tests/auto/qmenubar/tst_qmenubar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index e0a9f42..6d069c6 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -1429,7 +1429,7 @@ void tst_QMenuBar::check_menuPosition() #ifdef Q_WS_MAC QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); #endif -#ifdef Q_OS_WINCE +#ifdef Q_OS_WINCE_WM QSKIP("Qt/CE uses native menubar", SkipAll); #endif QMenu menu; -- cgit v0.12 From 64858dcac58621295c419903efe58ce9a8d0e5b7 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 08:06:40 +0200 Subject: add deployment for WinCE --- tests/auto/qtextcodec/test/test.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qtextcodec/test/test.pro b/tests/auto/qtextcodec/test/test.pro index ed2ade3..e52bb7a 100644 --- a/tests/auto/qtextcodec/test/test.pro +++ b/tests/auto/qtextcodec/test/test.pro @@ -5,6 +5,7 @@ wince*: { addFiles.sources = ../*.txt addFiles.path = . DEPLOYMENT += addFiles + DEPLOYMENT_PLUGIN += qcncodecs qjpcodecs qkrcodecs qtwcodecs } -- cgit v0.12 From 7332065a28577444e7c97617fb03d0f14c706b5b Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 8 Apr 2009 08:18:55 +0200 Subject: Don't check license for internal configurations A Nokia build doesn't require a license. Reviewed-by: mauricek BT: yes --- tools/configure/configureapp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index df583a6..5e77606 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3511,7 +3511,8 @@ void Configure::readLicense() } #else } else { - Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); + if (dictionary[ "BUILDNOKIA" ] != "yes") + Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); if (dictionary["DONE"] != "error") { // give the user some feedback, and prompt for license acceptance cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl; -- cgit v0.12 From f0239a4983dd84b0e23c1e6f796c5c44dfde26b2 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 8 Apr 2009 08:25:05 +0200 Subject: New binary for Windows configure Reviewed-by: mauricek BT: yes --- configure.exe | Bin 1134592 -> 851968 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 13ca0e5..891e928 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From ccaf16278f4fd422458d01b80579952846e6cf38 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 8 Apr 2009 08:57:16 +0200 Subject: BT: Revert "Fixes: Remove warnings in the embeddeddialogs demo." This reverts commit 7d24c0af8e52687b4e5735950495bb25947ca9f0. This change removed the accidental recursion leading to console warnings on Mac OS X by changing the way the scene event filter is registered for popups. But it also broke the behavior of the demo with regards to popup handling, in that the custom proxy no longer can detect popups that close, so dialogs stay zoomed in after the cursor has left. So before, the demo worked but printed warnings to the console on Mac OS X, and after, the warnings were gone but the demo behavior broke on all platforms... The change also accidentally removed the cache mode from the popup; I don't think this was intentional. Reviewed-by: Alexis --- demos/embeddeddialogs/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/demos/embeddeddialogs/main.cpp b/demos/embeddeddialogs/main.cpp index 4cf7325..cfb31c4 100644 --- a/demos/embeddeddialogs/main.cpp +++ b/demos/embeddeddialogs/main.cpp @@ -68,7 +68,6 @@ int main(int argc, char *argv[]) proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache); scene.addItem(proxy); - proxy->installSceneEventFilter(proxy); } } scene.setSceneRect(scene.itemsBoundingRect()); -- cgit v0.12 From e2360b31d93e856945f030ea9526c5936ab62a8c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 09:05:42 +0200 Subject: remove senseless testfunctions Reviewed-by: joerg Some of the testfunctions use key/mouse events, which doesn't work on Windows Mobile due to native menubar integration. Basically the same situation like on Mac. In addition there are still two test functions failing, waiting for input on those. --- tests/auto/qmenubar/tst_qmenubar.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 6d069c6..538e443 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -457,8 +457,8 @@ void tst_QMenuBar::accel() void tst_QMenuBar::accel_noQt3() { -#ifdef Q_WS_MAC - QSKIP("On Mac, native key events are needed to test menu action activation", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("On Mac/WinCE, native key events are needed to test menu action activation", SkipAll); #endif // create a popup menu with menu items set the accelerators later... initSimpleMenubar_noQt3(); @@ -486,8 +486,8 @@ void tst_QMenuBar::activatedCount() void tst_QMenuBar::activatedCount_noQt3() { -#ifdef Q_WS_MAC - QSKIP("On Mac, native key events are needed to test menu action activation", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("On Mac/WinCE, native key events are needed to test menu action activation", SkipAll); #endif // create a popup menu with menu items set the accelerators later... initSimpleMenubar_noQt3(); @@ -888,8 +888,8 @@ void tst_QMenuBar::insertItem_QString_QObject_noQt3() void tst_QMenuBar::check_accelKeys() { -#ifdef Q_WS_MAC - QSKIP("On Mac, native key events are needed to test menu action activation", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("On Mac/WinCE, native key events are needed to test menu action activation", SkipAll); #endif #ifdef QT3_SUPPORT initComplexMenubar(); @@ -961,8 +961,8 @@ void tst_QMenuBar::check_accelKeys() void tst_QMenuBar::check_cursorKeys1() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif #ifdef QT3_SUPPORT @@ -996,8 +996,8 @@ void tst_QMenuBar::check_cursorKeys1() void tst_QMenuBar::check_cursorKeys2() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif #ifdef QT3_SUPPORT @@ -1030,8 +1030,8 @@ void tst_QMenuBar::check_cursorKeys2() */ void tst_QMenuBar::check_cursorKeys3() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif #ifdef QT3_SUPPORT @@ -1186,8 +1186,8 @@ void tst_QMenuBar::check_escKey() void tst_QMenuBar::check_escKey_noQt3() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif initComplexMenubar_noQt3(); @@ -1329,7 +1329,7 @@ void tst_QMenuBar::check_escKey_noQt3() void tst_QMenuBar::allowActiveAndDisabled() { -#ifndef Q_WS_MAC +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE_WM) mb->hide(); mb->clear(); @@ -1393,8 +1393,8 @@ void tst_QMenuBar::check_altPress() void tst_QMenuBar::check_shortcutPress() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif #ifdef QT3_SUPPORT -- cgit v0.12 From f13c24438b5baec0c11220a5d783fc6830d47aa3 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 10:20:14 +0200 Subject: fix assert Reviewed-by: thartman - in case we explicitly use double as testdata, one cannot push float to it. - fuzzyCompare is not fuzzy enough, thus adopt the epsilon check of other testfunctions. --- tests/auto/qline/tst_qline.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/qline/tst_qline.cpp b/tests/auto/qline/tst_qline.cpp index 932ec8e..ab0bd9b 100644 --- a/tests/auto/qline/tst_qline.cpp +++ b/tests/auto/qline/tst_qline.cpp @@ -201,8 +201,8 @@ void tst_QLine::testIntersection_data() b = b.translated(1, 1); QTest::newRow(qPrintable(QString::fromLatin1("rotation-%0").arg(i))) - << a.x1() << a.y1() << a.x2() << a.y2() - << b.x1() << b.y1() << b.x2() << b.y2() + << (double)a.x1() << (double)a.y1() << (double)a.x2() << (double)a.y2() + << (double)b.x1() << (double)b.y1() << (double)b.x2() << (double)b.y2() << int(QLineF::BoundedIntersection) << 1.0 << 1.0; @@ -232,8 +232,8 @@ void tst_QLine::testIntersection() QCOMPARE(int(itype), type); if (type != QLineF::NoIntersection) { - QCOMPARE(ip.x(), qreal(ix)); - QCOMPARE(ip.y(), qreal(iy)); + QVERIFY(qAbs(ip.x() - ix) < epsilon); + QVERIFY(qAbs(ip.y() - iy) < epsilon); } } -- cgit v0.12 From df461a4a1bc7492729f701d38c81916b1be386b0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 8 Apr 2009 10:30:50 +0200 Subject: Autotest: Cisco changed their DNS setup; update our test. Reviewed-by: TrustMe --- tests/auto/qhostinfo/tst_qhostinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qhostinfo/tst_qhostinfo.cpp b/tests/auto/qhostinfo/tst_qhostinfo.cpp index 3a7698b..0c5bc59 100644 --- a/tests/auto/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/qhostinfo/tst_qhostinfo.cpp @@ -305,7 +305,7 @@ void tst_QHostInfo::reverseLookup_data() // ### Use internal DNS instead. Discussed with Andreas. //QTest::newRow("classical.hexago.com") << QString("2001:5c0:0:2::24") << QStringList(QString("classical.hexago.com")) << 0; - QTest::newRow("www.cisco.com") << QString("198.133.219.25") << QStringList(QString("www.cisco.com")) << 0; + QTest::newRow("www.cisco.com") << QString("198.133.219.25") << QStringList(QString("origin-www.cisco.com")) << 0; QTest::newRow("bogusexample.doenstexist.org") << QString("1::2::3::4") << QStringList() << 1; } -- cgit v0.12 From 3f3d09cf1511dde99797671a7bc848cdabc8d7fa Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 8 Apr 2009 10:25:06 +0200 Subject: Revert "Bt: Fix regression in the Embedded dialogs example" This reverts commit 35c26d696cbff269d551c012a212c09692dd6f6b. The change to QComboBox introduces a behavior change; whereas before the view container would always get its palette set as a response to QEvent::PaletteChange, it would now miss this event and rely on regular palette propagation to get the right contens. The difference in behavior is that QWidget::setPalette() also resolves the palette mask, and after 35c26d69 this would no longer happen. The bug in the embedded dialogs demo is caused by the embedded dialogs demo. See upcoming commit. Reviewed-by: Alexis Reviewed-by: Jens Bache-Wiig --- demos/embeddeddialogs/customproxy.cpp | 11 ++--------- src/gui/widgets/qcombobox.cpp | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/demos/embeddeddialogs/customproxy.cpp b/demos/embeddeddialogs/customproxy.cpp index ed2fc76..56a0548 100644 --- a/demos/embeddeddialogs/customproxy.cpp +++ b/demos/embeddeddialogs/customproxy.cpp @@ -111,15 +111,8 @@ bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event) QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value) { - if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { - QGraphicsItem *item = qVariantValue(value); - if (change == ItemChildAddedChange) { - item->setCacheMode(ItemCoordinateCache); - item->installSceneEventFilter(this); - } else { - item->removeSceneEventFilter(this); - } - } + if (change == ItemChildRemovedChange) + removeSceneEventFilter(this); return QGraphicsProxyWidget::itemChange(change, value); } diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index b9dbc62..09a51fe 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -2572,21 +2572,19 @@ void QComboBox::changeEvent(QEvent *e) hidePopup(); break; case QEvent::PaletteChange: { - if (d->container) { - QStyleOptionComboBox opt; - initStyleOption(&opt); + QStyleOptionComboBox opt; + initStyleOption(&opt); #ifndef QT_NO_MENU - if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { - QMenu menu; - menu.ensurePolished(); - d->viewContainer()->setPalette(menu.palette()); - d->viewContainer()->setWindowOpacity(menu.windowOpacity()); - } else + if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { + QMenu menu; + menu.ensurePolished(); + d->viewContainer()->setPalette(menu.palette()); + d->viewContainer()->setWindowOpacity(menu.windowOpacity()); + } else #endif - { - d->viewContainer()->setPalette(palette()); - d->viewContainer()->setWindowOpacity(1.0); - } + { + d->viewContainer()->setPalette(palette()); + d->viewContainer()->setWindowOpacity(1.0); } break; } -- cgit v0.12 From 510ce6fa8a3a30063744eaaf004850679610060e Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 8 Apr 2009 10:27:28 +0200 Subject: BT: Fix the embedded dialogs demo on Mac OS X and Motif style The CustomProxy class installs an event filter on its child to detect whether it is shadowed by a popup or not. The problem is it does this regardless of whether it currently has a scene assigned or not. Styles that assign palettes, or otherwise cause side effects when assigned to a QGraphicsProxyWidget, will cause the demo to print warnings to the console and fail to install the event filter. The reason for the failure to install the filter is that QGraphicsItem only allows scene event filters to be installed between items that are in the same scene. So, depending on the style, you either get an ItemSceneHasChanged or an ItemChildAddedChange first. The demo must account for this, and install its filter only when the items are guaranteed to be in the scene already. Reviewed-by: Alexis --- demos/embeddeddialogs/customproxy.cpp | 17 ++++++++++++++--- demos/embeddeddialogs/customproxy.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/demos/embeddeddialogs/customproxy.cpp b/demos/embeddeddialogs/customproxy.cpp index 56a0548..dd8766f 100644 --- a/demos/embeddeddialogs/customproxy.cpp +++ b/demos/embeddeddialogs/customproxy.cpp @@ -44,7 +44,7 @@ #include CustomProxy::CustomProxy(QGraphicsItem *parent, Qt::WindowFlags wFlags) - : QGraphicsProxyWidget(parent, wFlags), popupShown(false) + : QGraphicsProxyWidget(parent, wFlags), popupShown(false), currentPopup(0) { timeLine = new QTimeLine(250, this); connect(timeLine, SIGNAL(valueChanged(qreal)), @@ -111,8 +111,19 @@ bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event) QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value) { - if (change == ItemChildRemovedChange) - removeSceneEventFilter(this); + if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { + if (change == ItemChildAddedChange) { + currentPopup = qVariantValue(value); + currentPopup->setCacheMode(ItemCoordinateCache); + if (scene()) + currentPopup->installSceneEventFilter(this); + } else if (scene()) { + currentPopup->removeSceneEventFilter(this); + currentPopup = 0; + } + } else if (currentPopup && change == ItemSceneHasChanged) { + currentPopup->installSceneEventFilter(this); + } return QGraphicsProxyWidget::itemChange(change, value); } diff --git a/demos/embeddeddialogs/customproxy.h b/demos/embeddeddialogs/customproxy.h index 0a5fbaf..d324426 100644 --- a/demos/embeddeddialogs/customproxy.h +++ b/demos/embeddeddialogs/customproxy.h @@ -70,6 +70,7 @@ private slots: private: QTimeLine *timeLine; bool popupShown; + QGraphicsItem *currentPopup; }; #endif -- cgit v0.12 From c131208e59f5b2dd517b00c4539458760b8fd8aa Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Apr 2009 10:45:41 +0200 Subject: BT: Fix infinite recursion potential from change acff913a6287ad50b0ac782 It seems there is a potential for recursion because calling keyDown: can bubble up to the window which will start the process all over again. keyDown: will actually call qt_dispatchKeyEvent(), we may as well short it out here. All the previous cases I tried continue to work and we don't crash Creator if you are really impatient hitting keys. --- src/gui/widgets/qcocoamenu_mac.mm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index bae270a..bd62a00 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -159,10 +159,11 @@ QT_END_NAMESPACE accel_ev.ignore(); qt_sendSpontaneousEvent(widget, &accel_ev); if (accel_ev.isAccepted()) { - *target = nil; - *action = nil; - [qt_mac_nativeview_for(widget) keyDown:event]; - return YES; + if (qt_dispatchKeyEvent(event, widget)) { + *target = nil; + *action = nil; + return YES; + } } } } -- cgit v0.12 From 74f092408d1a870e2c1e2a49182c8e09f952055d Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 8 Apr 2009 11:07:33 +0200 Subject: Javascript: When there is javascript running then it will spin the CPU at 100% Zero timers on Windows would continue to fire even after being stopped as long as a new timer was started that reused the pointer address of the zero timer. Fix this by only re-firing zero timers if the zero timer hadn't been stopped (we can check this by looking at the inTimerEvent flag, which is set to false by registerTimer()). Task-number: 247401 Reviewed-by: Denis Dzyubenko Reviewed-by: Prasanth Ullattil --- dist/changes-4.5.1 | 4 ++ src/corelib/kernel/qeventdispatcher_win.cpp | 15 +++++-- tests/auto/qtimer/tst_qtimer.cpp | 65 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index de4eef7..eb8ec5f 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -68,6 +68,10 @@ Qt for Linux/X11 Qt for Windows -------------- +- QCoreApplication + * [247401] Fixed a bug that would cause a restarted timer to fire + too early, causing Javascript in QtWebKit to consume 100% CPU on + Windows. Qt for Mac OS X --------------- diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 880e95c..c4061f4 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -1059,11 +1059,20 @@ bool QEventDispatcherWin32::event(QEvent *e) QZeroTimerEvent *zte = static_cast(e); WinTimerInfo *t = d->timerDict.value(zte->timerId()); if (t) { + t->inTimerEvent = true; + QTimerEvent te(zte->timerId()); QCoreApplication::sendEvent(t->obj, &te); - WinTimerInfo *tn = d->timerDict.value(zte->timerId()); - if (tn && t == tn) - QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId())); + + t = d->timerDict.value(zte->timerId()); + if (t) { + if (t->interval == 0 && t->inTimerEvent) { + // post the next zero timer event as long as the timer was not restarted + QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId())); + } + + t->inTimerEvent = false; + } } return true; } else if (e->type() == QEvent::Timer) { diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index 527628c..bffb4f2 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -83,6 +83,7 @@ private slots: void recurringTimer(); void deleteLaterOnQTimer(); // long name, don't want to shadow QObject::deleteLater() void moveToThread(); + void restartedTimerFiresTooSoon(); }; class TimerHelper : public QObject @@ -416,5 +417,69 @@ void tst_QTimer::moveToThread() QVERIFY((ti3.timerId() & 0xffffff) != (ti1.timerId() & 0xffffff)); } +class RestartedTimerFiresTooSoonObject : public QObject +{ + Q_OBJECT + +public: + QBasicTimer m_timer; + + int m_interval; + QTime m_startedTime; + QEventLoop eventLoop; + + inline RestartedTimerFiresTooSoonObject() + : QObject(), m_interval(0) + { } + + void timerFired() + { + static int interval = 1000; + + m_interval = interval; + m_startedTime.start(); + m_timer.start(interval, this); + + // alternate between single-shot and 1 sec + interval = interval ? 0 : 1000; + } + + void timerEvent(QTimerEvent* ev) + { + if (ev->timerId() != m_timer.timerId()) + return; + + m_timer.stop(); + + QTime now = QTime::currentTime(); + int elapsed = m_startedTime.elapsed(); + + if (elapsed < m_interval / 2) { + // severely too early! + m_timer.stop(); + eventLoop.exit(-1); + return; + } + + timerFired(); + + // don't do this forever + static int count = 0; + if (count++ > 20) { + m_timer.stop(); + eventLoop.quit(); + return; + } + } +}; + +void tst_QTimer::restartedTimerFiresTooSoon() +{ + RestartedTimerFiresTooSoonObject object; + object.timerFired(); + QVERIFY(object.eventLoop.exec() == 0); +} + QTEST_MAIN(tst_QTimer) #include "tst_qtimer.moc" +\ -- cgit v0.12 From be3b8acbd311b9cbeaa7c87b4f34b2e33b4a7fa3 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Apr 2009 11:45:50 +0200 Subject: BT: Fix up comments in new Cocoa files. It seems that Vim or Xcode or whatever I was using to paste these in messed up and added an extra space. Now we should be consistent with the .cpp files and I found a file that we missed too. --- src/gui/kernel/qcocoaapplication_mac.mm | 22 +++---- src/gui/kernel/qcocoaapplicationdelegate_mac.mm | 22 +++---- src/gui/kernel/qcocoamenuloader_mac.mm | 22 +++---- src/gui/kernel/qcocoawindow_mac.mm | 22 +++---- src/gui/kernel/qcocoawindowdelegate_mac.mm | 22 +++---- src/gui/widgets/qcocoamenu_mac.mm | 84 ++++++++++++------------- src/gui/widgets/qmaccocoaviewcontainer_mac.mm | 22 +++---- src/gui/widgets/qmacnativewidget_mac.mm | 22 +++---- src/gui/widgets/qmainwindowlayout_mac.mm | 44 +++++++++++++ 9 files changed, 163 insertions(+), 119 deletions(-) diff --git a/src/gui/kernel/qcocoaapplication_mac.mm b/src/gui/kernel/qcocoaapplication_mac.mm index f95f004f..a3cc2c1 100644 --- a/src/gui/kernel/qcocoaapplication_mac.mm +++ b/src/gui/kernel/qcocoaapplication_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ /**************************************************************************** ** diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index e6bd511..6571068 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ /**************************************************************************** ** diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 7ecb765..e836286 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #include "qmacdefines_mac.h" #ifdef QT_MAC_USE_COCOA diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index e7b76a7..972e477 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #include "qmacdefines_mac.h" #ifdef QT_MAC_USE_COCOA diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index 8480179..03b2fce 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #import "private/qcocoawindowdelegate_mac_p.h" #ifdef QT_MAC_USE_COCOA diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index bd62a00..c5fee66 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -1,46 +1,46 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** No Commercial Usage - ** This file contains pre-release code and may not be distributed. - ** You may use this file in accordance with the terms and conditions - ** contained in the either Technology Preview License Agreement or the - ** Beta Release License Agreement. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 2.1 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 2.1 requirements - ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - ** - ** In addition, as a special exception, Nokia gives you certain - ** additional rights. These rights are described in the Nokia Qt LGPL - ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this - ** package. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 3.0 as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU General Public License version 3.0 requirements will be - ** met: http://www.gnu.org/copyleft/gpl.html. - ** - ** If you are unsure which license is appropriate for your use, please - ** contact the sales department at qt-sales@nokia.com. - ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #include "qmacdefines_mac.h" #include "qapplication.h" diff --git a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm b/src/gui/widgets/qmaccocoaviewcontainer_mac.mm index 710af6a..380e983 100644 --- a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm +++ b/src/gui/widgets/qmaccocoaviewcontainer_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #import #include diff --git a/src/gui/widgets/qmacnativewidget_mac.mm b/src/gui/widgets/qmacnativewidget_mac.mm index 1bc0430..0f4edf9 100644 --- a/src/gui/widgets/qmacnativewidget_mac.mm +++ b/src/gui/widgets/qmacnativewidget_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #import #import diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 950f758..c807afb 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -1,3 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + #include #include #include -- cgit v0.12 From 3b5f04843c9ab5e0ccce7f4aa8a73d45c9021c35 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 12:47:47 +0200 Subject: update/fix configure Reviewed-by: Thiago - display the nokia internal usage text like on configure - instead of skipping the license check we need to actually call it to set QT_EDITION and friends properly. Otherwise the build gets broken. --- tools/configure/configureapp.cpp | 8 +++++--- tools/configure/tools.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 5e77606..bcbf557 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -474,6 +474,9 @@ void Configure::parseCmdLine() else if( configCmdLine.at(i) == "-developer-build" ) dictionary[ "BUILDDEV" ] = "yes"; else if( configCmdLine.at(i) == "-nokia-developer" ) { + cout << "Detected -nokia-developer option" << endl; + cout << "Nokia employees and agents are allowed to use this software under" << endl; + cout << "the authority of Nokia Corporation and/or its subsidiary(-ies)" << endl; dictionary[ "BUILDNOKIA" ] = "yes"; dictionary[ "BUILDDEV" ] = "yes"; dictionary["LICENSE_CONFIRMED"] = "yes"; @@ -3511,9 +3514,8 @@ void Configure::readLicense() } #else } else { - if (dictionary[ "BUILDNOKIA" ] != "yes") - Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); - if (dictionary["DONE"] != "error") { + Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); + if (dictionary["DONE"] != "error" && dictionary["BUILDNOKIA"] != "yes") { // give the user some feedback, and prompt for license acceptance cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl; if (!showLicense(dictionary["LICENSE FILE"])) { diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index 760c101..2649d44 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -58,6 +58,13 @@ using namespace std; void Tools::checkLicense(QMap &dictionary, QMap &licenseInfo, const QString &path) { + if (dictionary[ "BUILDNOKIA" ] == "yes") { + dictionary["EDITION"] = "NokiaInternalBuild"; + dictionary["LICENSE_FILE"] = ""; // No License for nokia developers + dictionary["QT_EDITION"] = "QT_EDITION_OPENSOURCE"; + return; // No license key checking in internal builds + } + QString tpLicense = dictionary["QT_SOURCE_TREE"] + "/LICENSE.PREVIEW.OPENSOURCE"; if (QFile::exists(tpLicense)) { dictionary["EDITION"] = "Preview"; -- cgit v0.12 From a08d7a675a4e7f61b80a8a92114cda6f8dbacd96 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 8 Apr 2009 12:56:08 +0200 Subject: Added some changes for 4.5.1 --- dist/changes-4.5.1 | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index eb8ec5f..17e32d4 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -52,6 +52,10 @@ Third party components * [245668] set also protocol, verifyMode and verifyDepth in setSslConfiguration() +- QStyleSheetStyle + * Improved support for setting background and foreground roles in styles + such as the text color in a combo box popup on Mac and Cleanlooks. + **************************************************************************** * Database Drivers * **************************************************************************** @@ -64,6 +68,27 @@ Third party components Qt for Linux/X11 ---------------- +- Phonon/GStreamer + * [244259] Fixed a problem where the backend would fail to indicate an + error when streaming fails. + * [233188] Fixed a problem where the seek slider would reset to 0 while + being dragged. + * [246189] Fixed a problem where the backend would fail to correctly + escape certain file names so that playback would not start + * [246097] Added support for the MediaController interface to allow audio + CD playback. + +- QGtkStyle + * The system palette is no longer strictly forced. Also behavior related + to system theme changes have been improved. + * [249363] QFrame is now styled as a GtkScrolledWindow. + * [247653] Fixed a compilation issue on solaris. + * Fixed palette and styling issues with the background color of + combo box popups. + * [239829] Disabled alt-key navigation for QGtkStyle to follow + GTK+ behavior. + * [238196] Allow middle click to set scrollbar position to follow + GTK+ behavior. Qt for Windows -------------- @@ -72,6 +97,9 @@ Qt for Windows * [247401] Fixed a bug that would cause a restarted timer to fire too early, causing Javascript in QtWebKit to consume 100% CPU on Windows. +- QWindowsXPStyle + * [248036] Fixed an issue where tool buttons would incorrectly + hover when disabled. Qt for Mac OS X --------------- @@ -122,7 +150,6 @@ Qt for Windows CE - moc - - uic * [244998] Fixed include file generation for phonon widgets. * [248070] Fixed code generation for QStringList-type properties to use -- cgit v0.12 From f034683be4d84bacd874b24a846d1833f4d4f4df Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 8 Apr 2009 14:00:23 +0200 Subject: Fixes: No navigation with alt for the native menubar (Windows CE) RevBy: Mauricek AutoTest: tst_QMenuBar::check_altPress() Details: We do not allow alt navigation with the windows mobile style --- src/gui/styles/qwindowsmobilestyle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index c52c700..1c03b9e 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -3401,6 +3401,9 @@ int QWindowsMobileStyle::styleHint(StyleHint hint, const QStyleOption *opt, cons case SH_ScrollBar_ContextMenu: ret = false; break; + case SH_MenuBar_AltKeyNavigation: + ret = false; + break; default: ret = QWindowsStyle::styleHint(hint, opt, widget, returnData); break; -- cgit v0.12 From 27c1edac6769f863549f0940d35cf3f82e778a46 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Apr 2009 14:04:26 +0200 Subject: My changes. --- dist/changes-4.5.1 | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 17e32d4..5584c11 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -45,6 +45,13 @@ Third party components - QHttp * [208445] cancel request upon receiving unknown authentication method +- QMacStyle + * [248769] Fix regression where QMacStyle would only draw tabs when passed a QStyleOptionTabV3. + * Adjust the opacity value for popups. + +- QMainWindow + * [248048] Fix a regression that would cause tooltips to disappear when using the unified toolbar. + - QSharedPointer * [246843] Fixed a crash caused by using QSharedPointer in global statics @@ -104,6 +111,35 @@ Qt for Windows Qt for Mac OS X --------------- +- Cocoa port + * Fixed a bug where actions in the native menubar weren't properly disabled. + * Make shortcuts work properly when using the Dvorak-QWERTY+CMD keyboard layout. + * Fixed a bug where dialogs would be positioned in the wrong place on the screen. + * [244369] Window flags on Cocoa windows should match have a similar look as the Carbon ones. + * The build-key for Cocoa was changed in the unlikely case that a plugin may make + assumptions on how Qt was built. All Cocoa plugins built against 4.5.0 WILL NOT WORK + with 4.5.1, we don't foresee changing this again. + * Fixed a bug where some windows would not get activation when they normally should. + * Key events sent to popups do not get propagated onwards. + * [249296] Fix a bug where lineedits on a second page of a stack widget wourd not get key events + * QFileOpenEvents are no longer sent for items passed on the command line. + * Various fixes for determining metrics of text and the ability to disable kerning. + * [248918] Fixed color matching for themed text items. + * Modify the colliding mice example to work better with coalesced updates. + +- Fix a crash when showing a widget that is window modal but has no parent. +- [248803] Showing two dialogs at the same time don't get shared activation. +- Added QSysInfo::MV_10_6 as an enum to test against. +- Various compile fixes for Snow Leopard (preliminary support). + + +- The uninstall-qt.py script included in the binary package no longer complains about removing itself multiple times. + +- Document a bit clearer how qt_mac_set_dock_menu() works. + +- QTestLib + * Activate the test application when launched from the command line. + Qt for Embedded Linux --------------------- @@ -161,6 +197,7 @@ Qt for Windows CE - qmake + * [248806] Ensure that the Xcode generator includes the right path to frameworks. - configure -- cgit v0.12 From f2edb497ac2c3ff6f8c004046e216b8bdf7c4347 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 8 Apr 2009 14:34:18 +0200 Subject: BT: Fix a painting glitch in gtk combo box This improves the look of combo box with gtk style which is somewhat a regression from 4.5.0 since we did not style this part before. Reviewed-by: nrc --- src/gui/styles/qgtkstyle.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index b569b5c..519fed7 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2507,6 +2507,10 @@ void QGtkStyle::drawControl(ControlElement element, if (selected) { QRect rect = option->rect.adjusted(0, 0, -1, -1); +#ifndef QT_NO_COMBOBOX + if (qobject_cast(widget)) + rect = option->rect; +#endif gtkPainter.paintBox( gtkMenuItem, "menuitem", rect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style); } -- cgit v0.12 From b273cd322345c54d5cbd6f178791d1ccfcc08e05 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 8 Apr 2009 15:47:42 +0200 Subject: BT: Compilefix for Windows CE and namespaces RevBy: Mauricek Details: functions needs to be declared outside of the namespace --- src/gui/inputmethod/qwininputcontext_win.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp index 720f0b8..e3e8aa4 100644 --- a/src/gui/inputmethod/qwininputcontext_win.cpp +++ b/src/gui/inputmethod/qwininputcontext_win.cpp @@ -57,15 +57,17 @@ #ifdef Q_IME_DEBUG #include "qdebug.h" -#endif - -QT_BEGIN_NAMESPACE +#endif -extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); #if defined(Q_OS_WINCE) extern void qt_wince_show_SIP(bool show); // defined in qguifunctions_wince.cpp #endif +QT_BEGIN_NAMESPACE + +extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); + + DEFINE_GUID(IID_IActiveIMMApp, 0x08c0e040, 0x62d1, 0x11d1, 0x93, 0x26, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e); -- cgit v0.12 From 91081c68b7899c95a998b03ee581927d62bd6880 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 12:24:58 -0700 Subject: Don't convert unsupported images for dfb Fall back to raster engine for formats not supported by dfb rather than converting the image to a supported format. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index a93bbf7..452ee48 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -694,16 +694,10 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, } void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, - const QImage &srcImage, + const QImage &image, const QRectF &src) { - QImage image = srcImage; - if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) { - image = image.convertToFormat(image.hasAlphaChannel() - ? QDirectFBScreen::instance()->alphaPixmapFormat() - : QDirectFBScreen::instance()->pixelFormat()); - } - + Q_ASSERT(QDirectFBScreen::getSurfacePixelFormat(image.format()) != DSPF_UNKNOWN); CachedImage *img = imageCache[image.cacheKey()]; IDirectFBSurface *imgSurface = 0; bool doRelease = false; @@ -1017,7 +1011,8 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, #ifndef QT_NO_DIRECTFB_PREALLOCATED d->updateClip(); - if (!d->dfbCanHandleClip(r) || d->matrixRotShear) + if (!d->dfbCanHandleClip(r) || d->matrixRotShear + || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) #endif { d->lock(); -- cgit v0.12 From d554a4b6218885e683c98b7c538fb5feee618067 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 13:59:51 -0700 Subject: Fix up drawing/blitting/porterduff situation This was rather broken previously. For example, porterduff mode does not play well with alpha values and blends. Also, setting the flags to the existing value is a noop in DirectFB (checked the code) so bool dirty approach buys us nothing. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 212 ++++++++------------- 1 file changed, 77 insertions(+), 135 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 452ee48..f72b0da 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -196,10 +196,10 @@ public: void setPen(const QPen &pen); void setBrush(const QBrush &brush); void setCompositionMode(QPainter::CompositionMode mode); - void setOpacity(const qreal value); + void setOpacity(quint8 value); void setRenderHints(QPainter::RenderHints hints); - inline void setDFBColor(const QColor &color) const; + inline void setDFBColor(const QColor &color); inline void lock(); inline void unlock(); @@ -222,14 +222,14 @@ public: void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap); void drawImage(const QRectF &dest, const QImage &image, const QRectF &src); - void updateClip(); - void updateFlags(); + inline void updateClip(); inline void setClipDirty(); void systemStateChanged(); //Needed to be notified when system clip changes void begin(QPaintDevice *device); void end(); + void prepareForBlit(bool alpha); SurfaceCache *surfaceCache; QTransform transform; int lastLockedHeight; @@ -244,10 +244,9 @@ private: quint8 opacity; - quint32 drawFlags; - quint32 blitFlags; - quint32 duffFlags; - bool dirtyFlags; + quint32 drawFlagsFromCompositionMode, blitFlagsFromCompositionMode; + DFBSurfacePorterDuffRule porterDuffRule; + bool dirtyClip; bool dfbHandledClip; QDirectFBPaintDevice *dfbDevice; @@ -258,8 +257,9 @@ private: QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false), simpleBrush(false), matrixRotShear(false), matrixScale(false), lastLockedHeight(-1), - fbWidth(-1), fbHeight(-1), opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), - dirtyFlags(false), dirtyClip(true), dfbHandledClip(false), dfbDevice(0), q(p) + fbWidth(-1), fbHeight(-1), opacity(255), drawFlagsFromCompositionMode(0), + blitFlagsFromCompositionMode(0), porterDuffRule(DSPD_SRC_OVER), dirtyClip(true), + dfbHandledClip(false), dfbDevice(0), q(p) { fb = QDirectFBScreen::instance()->dfb(); surfaceCache = new SurfaceCache; @@ -295,7 +295,6 @@ void QDirectFBPaintEnginePrivate::setClipDirty() dirtyClip = true; } - void QDirectFBPaintEnginePrivate::lock() { // We will potentially get a new pointer to the buffer after a @@ -345,11 +344,8 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) setTransform(QTransform()); antialiased = false; - drawFlags = DSDRAW_BLEND; - blitFlags = DSBLIT_BLEND_ALPHACHANNEL; - duffFlags = DSPD_SRC_OVER; opacity = 255; - dirtyFlags = true; + setCompositionMode(q->state()->compositionMode()); dirtyClip = true; setPen(q->state()->pen); setDFBColor(pen.color()); @@ -382,91 +378,72 @@ void QDirectFBPaintEnginePrivate::setBrush(const QBrush &b) void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode) { - drawFlags &= ~(DSDRAW_XOR); - blitFlags &= ~(DSBLIT_XOR); - - // TODO: check these mappings!!!! - quint32 duff = DSPD_NONE; - quint32 blit = blitFlags; + blitFlagsFromCompositionMode = DSBLIT_NOFX; + drawFlagsFromCompositionMode = DSDRAW_NOFX; + bool blend = true; switch (mode) { case QPainter::CompositionMode_SourceOver: - duff = DSPD_SRC_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_OVER; break; case QPainter::CompositionMode_DestinationOver: - duff = DSPD_DST_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_DST_OVER; break; case QPainter::CompositionMode_Clear: - duff = DSPD_CLEAR; - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_CLEAR; + blend = false; break; case QPainter::CompositionMode_Source: - duff = DSPD_SRC; - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC; + blend = false; break; case QPainter::CompositionMode_Destination: - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_NONE; // ### need to double check this + blend = false; return; case QPainter::CompositionMode_SourceIn: - duff = DSPD_SRC_IN; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_IN; break; case QPainter::CompositionMode_DestinationIn: - duff = DSPD_DST_IN; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_DST_IN; break; case QPainter::CompositionMode_SourceOut: - duff = DSPD_SRC_OUT; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_OUT; break; case QPainter::CompositionMode_DestinationOut: - duff = DSPD_DST_OUT; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - break; - case QPainter::CompositionMode_SourceAtop: - duff = DSPD_SRC_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - break; - case QPainter::CompositionMode_DestinationAtop: - duff = DSPD_DST_OVER; + porterDuffRule = DSPD_DST_OUT; break; case QPainter::CompositionMode_Xor: - duff = DSPD_NONE; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - drawFlags |= DSDRAW_XOR; - blit |= DSBLIT_XOR; - dirtyFlags = true; + porterDuffRule = DSPD_XOR; + blitFlagsFromCompositionMode |= DSBLIT_XOR; + drawFlagsFromCompositionMode |= DSDRAW_XOR; break; +// case QPainter::CompositionMode_Plus: // ??? +// porterDuffRule = DSPD_ADD; +// break; default: qWarning("QDirectFBPaintEnginePrivate::setCompositionMode(): " "mode %d not implemented", mode); - break; + return; } - - if (duff != duffFlags || blit != blitFlags) { - duffFlags = duff; - blitFlags = blit; - dirtyFlags = true; + // intentially not comparing with current porterDuffRule. surface might have changed. + if (blend) { + blitFlagsFromCompositionMode |= DSBLIT_BLEND_ALPHACHANNEL; + drawFlagsFromCompositionMode |= DSDRAW_BLEND; + } + if (opacity != 255) { + setOpacity(opacity); } } -void QDirectFBPaintEnginePrivate::setOpacity(const qreal value) +void QDirectFBPaintEnginePrivate::setOpacity(quint8 opacity) { - const bool wasOpaque = (opacity == 255); - opacity = quint8(value * 255); - const bool opaque = (opacity == 255); - - if (opaque == wasOpaque) - return; - - if (opaque) - blitFlags &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); - else - blitFlags |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); - - dirtyFlags = true; + if (opacity == 255) { + // ### need to check this stuff + blitFlagsFromCompositionMode &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); + } else { + blitFlagsFromCompositionMode |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); + } } void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) @@ -478,22 +455,33 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) } } -void QDirectFBPaintEnginePrivate::updateFlags() +void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) { - if (!dirtyFlags) - return; - surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawFlags)); - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); - surface->SetPorterDuff(surface, DFBSurfacePorterDuffRule(duffFlags)); - dirtyFlags = false; + quint32 blittingFlags = blitFlagsFromCompositionMode; + if (!alpha) { + blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL; + surface->SetPorterDuff(surface, DSPD_NONE); + } else { + surface->SetPorterDuff(surface, porterDuffRule); + } + surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); + surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); } -void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) const +void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) { + Q_ASSERT(surface); const quint8 alpha = (opacity == 255 ? color.alpha() : ALPHA_MUL(color.alpha(), opacity)); surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha); + quint32 drawingFlags = drawFlagsFromCompositionMode; + if (alpha == 255) { + drawingFlags &= ~DSDRAW_BLEND; + } + surface->SetPorterDuff(surface, DSPD_NONE); + // PorterDuff messes up alpha values for primitives + surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawingFlags)); } void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) const @@ -601,15 +589,7 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, const QPixmap &pixmap, const QRectF &src) { - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !pixmap.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } - + prepareForBlit(pixmap.hasAlphaChannel()); QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); @@ -627,22 +607,12 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, } if (result != DFB_OK) DirectFBError("QDirectFBPaintEngine::drawPixmap()", result); - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); } void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap) { - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !pixmap.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } - + prepareForBlit(pixmap.hasAlphaChannel()); QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); @@ -688,9 +658,6 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, if (result != DFB_OK) DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result); - - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); } void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, @@ -739,14 +706,7 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, const QRect dr = transform.mapRect(dest).toRect(); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !image.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } + prepareForBlit(image.hasAlphaChannel()); if (dr.size() == sr.size()) { surface->Blit(surface, imgSurface, &sRect, dr.x(), dr.y()); } else { @@ -754,8 +714,6 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, dr.width(), dr.height() }; surface->StretchBlit(surface, imgSurface, &sRect, &dRect); } - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); if (doRelease) { surface->ReleaseSource(surface); imgSurface->Release(imgSurface); @@ -850,8 +808,7 @@ void QDirectFBPaintEngine::brushChanged() void QDirectFBPaintEngine::opacityChanged() { Q_D(QDirectFBPaintEngine); - d->setOpacity(state()->opacity); - + d->setOpacity(quint8(state()->opacity * 255)); QRasterPaintEngine::opacityChanged(); } @@ -859,7 +816,6 @@ void QDirectFBPaintEngine::compositionModeChanged() { Q_D(QDirectFBPaintEngine); d->setCompositionMode(state()->compositionMode()); - QRasterPaintEngine::compositionModeChanged(); } @@ -888,7 +844,7 @@ void QDirectFBPaintEngine::setState(QPainterState *s) d->setClipDirty(); d->setPen(state()->pen); d->setBrush(state()->brush); - d->setOpacity(state()->opacity); + d->setOpacity(quint8(state()->opacity * 255)); d->setCompositionMode(state()->compositionMode()); d->setTransform(state()->transform()); } @@ -930,12 +886,10 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) d->unlock(); if (d->brush != Qt::NoBrush) { - d->updateFlags(); d->setDFBColor(d->brush.color()); d->fillRects(rects, rectCount); } if (d->pen != Qt::NoPen) { - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawRects(rects, rectCount); } @@ -955,12 +909,10 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) d->unlock(); if (d->brush != Qt::NoBrush) { - d->updateFlags(); d->setDFBColor(d->brush.color()); d->fillRects(rects, rectCount); } if (d->pen != Qt::NoPen) { - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawRects(rects, rectCount); } @@ -978,7 +930,6 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) if (d->pen != Qt::NoPen) { d->unlock(); - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawLines(lines, lineCount); } @@ -996,7 +947,6 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) if (d->pen != Qt::NoPen) { d->unlock(); - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawLines(lines, lineCount); } @@ -1022,7 +972,6 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, #ifndef QT_NO_DIRECTFB_PREALLOCATED d->unlock(); - d->updateFlags(); d->drawImage(r, image, sr); #endif } @@ -1041,15 +990,12 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { d->lock(); QRasterPaintEngine::drawPixmap(r, pixmap, sr); - } - else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) { + } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) { const QImage *img = static_cast(pixmap.pixmapData())->buffer(); d->lock(); QRasterPaintEngine::drawImage(r, *img, sr); - } - else { + } else { d->unlock(); - d->updateFlags(); d->drawPixmap(r, pixmap, sr); } } @@ -1068,18 +1014,15 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp); - } - else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { + } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { const QImage *img = static_cast(pixmap.pixmapData())->buffer(); d->lock(); QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType); data->fromImage(*img, Qt::AutoColor); const QPixmap pix(data); QRasterPaintEngine::drawTiledPixmap(r, pix, sp); - } - else { + } else { d->unlock(); - d->updateFlags(); d->drawTiledPixmap(r, pixmap); } } @@ -1162,7 +1105,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (d->forceRasterPrimitives) break; d->unlock(); - d->updateFlags(); d->setDFBColor(brush.color()); const QRect r = d->transform.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), @@ -1172,7 +1114,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (state()->brushOrigin == QPointF() && brush.transform().isIdentity()) { //could handle certain types of brush.transform() E.g. scale d->unlock(); - d->updateFlags(); d->drawTiledPixmap(rect, brush.texture()); return; } @@ -1194,7 +1135,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) QRasterPaintEngine::fillRect(rect, color); } else { d->unlock(); - d->updateFlags(); d->setDFBColor(color); const QRect r = d->transform.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), @@ -1224,6 +1164,7 @@ void QDirectFBPaintEngine::drawColorSpans(const QSpan *spans, int count, } else { DFBSpan span = { spans[i].x, spans[i].len }; uint c = BYTE_MUL(color, spans[i].coverage); + // ### how does this play with setDFBColor d->surface->SetColor(d->surface, qRed(c), qGreen(c), qBlue(c), qAlpha(c)); d->surface->FillSpans(d->surface, spans[i].y, &span, 1); @@ -1244,6 +1185,7 @@ void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize, { Q_D(QDirectFBPaintEngine); IDirectFBSurface *src = d->surfaceCache->getSurface(buffer, bufsize); + // ### how does this play with setDFBColor src->SetColor(src, 0, 0, 0, const_alpha); const DFBRectangle rect = { 0, 0, length, 1 }; d->surface->Blit(d->surface, src, &rect, x, y); -- cgit v0.12 From 2cf88ffef18622b5c08cd48d4cb0b5624c59a713 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 16:07:04 -0700 Subject: Diagnostic info when failing to create surface Only enabled in debug builds since it could something that should be ignored. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index bf9864a..04d2f57 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -233,6 +233,16 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY); } result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &voDesc, &newSurface); +#ifndef QT_NO_DEBUG + if (result != DFB_OK) { + qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n" + " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s", + desc->flags, desc->caps, desc->width, desc->height, + desc->pixelformat, DFB_PIXELFORMAT_INDEX(desc->pixelformat), + desc->preallocated[0].data, desc->preallocated[0].pitch, + DirectFBErrorString(result)); + } +#endif } if (!newSurface) -- cgit v0.12 From d8dda2706408e0c9558966e74376834d290dc6e3 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 15:08:24 -0700 Subject: Make flipping and paintOnScreen work better Make the paintOnScreen case paint directly on the primary surface if the size of the window surface == size of primary surface. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbsurface.cpp | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index f5626c8..8ed308c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -139,28 +139,32 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) dfbWindow = 0; } #endif - if (dfbSurface) { + if (dfbSurface && dfbSurface != screen->dfbSurface()) { dfbSurface->Release(dfbSurface); dfbSurface = 0; } } else if (rect != geometry()) { - const bool isResize = rect.size() != geometry().size(); DFBResult result = DFB_OK; // If we're in a resize, the surface shouldn't be locked - Q_ASSERT( (lockedImage == 0) || (isResize == false)); + Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size())); if (onscreen) { - if (dfbSurface) - dfbSurface->Release(dfbSurface); - - DFBRectangle r = { rect.x(), rect.y(), - rect.width(), rect.height() }; IDirectFBSurface *primarySurface = screen->dfbSurface(); Q_ASSERT(primarySurface); - result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); + if (dfbSurface && dfbSurface != primarySurface) + dfbSurface->Release(dfbSurface); + + if (rect == screen->region().boundingRect()) { + dfbSurface = primarySurface; + } else { + const DFBRectangle r = { rect.x(), rect.y(), + rect.width(), rect.height() }; + result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); + } forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); } else { + const bool isResize = rect.size() != geometry().size(); #ifdef QT_NO_DIRECTFB_WM if (isResize) { if (dfbSurface) @@ -362,10 +366,8 @@ void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, if (winOpacity != opacity) dfbWindow->SetOpacity(dfbWindow, winOpacity); } -#endif -#ifndef QT_NO_DIRECTFB_WM if (!(flipFlags & DSFLIP_BLIT)) { - dfbSurface->Flip(dfbSurface, 0, DFBSurfaceFlipFlags(flipFlags)); + dfbSurface->Flip(dfbSurface, 0, flipFlags); } else { if (region.numRects() > 1) { const QVector rects = region.rects(); -- cgit v0.12 From 6b494c48efa21f4ed3e2367f8bed8e138fd58190 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 16:49:08 -0700 Subject: Be smarter about alpha formats Try harder to prevent blends by explicitly checking for alpha pixels in the source image (unless asked not to). Can be defined out by #defining QT_NO_DIRECTFB_OPAQUE_DETECTION Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/directfb.pro | 1 + .../gfxdrivers/directfb/qdirectfbpixmap.cpp | 161 +++++++++++++++++---- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h | 3 + 3 files changed, 133 insertions(+), 32 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro index 399044e..89a289c 100644 --- a/src/plugins/gfxdrivers/directfb/directfb.pro +++ b/src/plugins/gfxdrivers/directfb/directfb.pro @@ -13,6 +13,7 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers #DEFINES += QT_NO_DIRECTFB_MOUSE #DEFINES += QT_NO_DIRECTFB_KEYBOARD #DEFINES += QT_DIRECTFB_TIMING +#DEFINES += QT_NO_DIRECTFB_OPAQUE_DETECTION target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers INSTALLS += target diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index a20b66a..a4e235b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -51,7 +51,7 @@ static int global_ser_no = 0; QDirectFBPixmapData::QDirectFBPixmapData(PixelType pixelType) : QPixmapData(pixelType, DirectFBClass), - engine(0) + engine(0), format(QImage::Format_Invalid), alpha(false) { setSerialNumber(0); } @@ -67,16 +67,18 @@ QDirectFBPixmapData::~QDirectFBPixmapData() void QDirectFBPixmapData::resize(int width, int height) { if (width <= 0 || height <= 0) { - setSerialNumber(0); + invalidate(); return; } - dfbSurface = screen->createDFBSurface(QSize(width, height), - screen->pixelFormat(), - QDirectFBScreen::TrackSurface); - forceRaster = (screen->pixelFormat() == QImage::Format_RGB32); + format = screen->pixelFormat(); + dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height), + format, + QDirectFBScreen::TrackSurface); + alpha = false; + forceRaster = (format == QImage::Format_RGB32); if (!dfbSurface) { - setSerialNumber(0); + invalidate(); qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface"); return; } @@ -84,18 +86,98 @@ void QDirectFBPixmapData::resize(int width, int height) setSerialNumber(++global_ser_no); } + +// mostly duplicated from qimage.cpp (QImageData::checkForAlphaPixels) +static bool checkForAlphaPixels(const QImage &img) +{ + const uchar *bits = img.bits(); + const int bytes_per_line = img.bytesPerLine(); + const uchar *end_bits = bits + bytes_per_line; + const int width = img.width(); + const int height = img.height(); + switch (img.format()) { + case QImage::Format_Indexed8: + return img.hasAlphaChannel(); + case QImage::Format_ARGB32: + case QImage::Format_ARGB32_Premultiplied: + for (int y=0; yalphaPixmapFormat() - : screen->pixelFormat(); + Q_ASSERT(img.depth() != 1); // these should be handled by QRasterPixmapData + if (img.hasAlphaChannel() +#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION + && (flags & Qt::NoOpaqueDetection || ::checkForAlphaPixels(img)) +#endif + ) { + alpha = true; + format = screen->alphaPixmapFormat(); + } else { + alpha = false; + format = screen->pixelFormat(); + } dfbSurface = screen->copyToDFBSurface(img, format, QDirectFBScreen::TrackSurface); forceRaster = (format == QImage::Format_RGB32); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage()"); - setSerialNumber(0); + invalidate(); return; } setSerialNumber(++global_ser_no); @@ -110,15 +192,15 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) IDirectFBSurface *src = static_cast(data)->directFBSurface(); const bool hasAlpha = data->hasAlphaChannel(); - const QImage::Format format = (hasAlpha - ? screen->alphaPixmapFormat() - : screen->pixelFormat()); + format = (hasAlpha + ? QDirectFBScreen::instance()->alphaPixmapFormat() + : QDirectFBScreen::instance()->pixelFormat()); dfbSurface = screen->createDFBSurface(rect.size(), format, QDirectFBScreen::TrackSurface); if (!dfbSurface) { qWarning("QDirectFBPixmapData::copy()"); - setSerialNumber(0); + invalidate(); return; } forceRaster = (format == QImage::Format_RGB32); @@ -135,13 +217,28 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) dfbSurface->ReleaseSource(dfbSurface); if (result != DFB_OK) { DirectFBError("QDirectFBPixmapData::copy()", result); - setSerialNumber(0); + invalidate(); return; } setSerialNumber(++global_ser_no); } +static inline bool isOpaqueFormat(QImage::Format format) +{ + switch (format) { + case QImage::Format_RGB32: + case QImage::Format_RGB16: + case QImage::Format_RGB666: + case QImage::Format_RGB555: + case QImage::Format_RGB888: + case QImage::Format_RGB444: + return true; + default: + break; + } + return false; +} void QDirectFBPixmapData::fill(const QColor &color) { @@ -150,17 +247,19 @@ void QDirectFBPixmapData::fill(const QColor &color) Q_ASSERT(dfbSurface); - if (color.alpha() < 255 && !hasAlphaChannel()) { + alpha = (color.alpha() < 255); + if (alpha && ::isOpaqueFormat(format)) { QSize size; dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight()); screen->releaseDFBSurface(dfbSurface); + format = screen->alphaPixmapFormat(); dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface); forceRaster = false; setSerialNumber(++global_ser_no); if (!dfbSurface) { - qWarning("QDirectFBPixmapData::fill()"); - setSerialNumber(0); + qWarning("QDirecttFBPixmapData::fill()"); + invalidate(); return; } } @@ -186,15 +285,7 @@ void QDirectFBPixmapData::fill(const QColor &color) bool QDirectFBPixmapData::hasAlphaChannel() const { - if (!serialNumber()) - return false; - DFBSurfacePixelFormat format; - dfbSurface->GetPixelFormat(dfbSurface, &format); - return QDirectFBScreen::hasAlpha(format); - - // We don't need to ask DFB for this really. Can just keep track - // of what image format this has. It should always have either - // QDirectFBScreen::alphaPixmapFormat() or QScreen::pixelFormat() + return alpha; } QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, @@ -221,11 +312,10 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, return QPixmap(); QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType); - QImage::Format format = screen->pixelFormat(); DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; - if (hasAlphaChannel()) { + data->alpha = alpha; + if (alpha) { flags = DSBLIT_BLEND_ALPHACHANNEL; - format = screen->alphaPixmapFormat(); } data->dfbSurface = screen->createDFBSurface(size, format, @@ -285,3 +375,10 @@ QImage* QDirectFBPixmapData::buffer() lockDirectFB(); return lockedImage; } + +void QDirectFBPixmapData::invalidate() +{ + setSerialNumber(0); + alpha = false; + format = QImage::Format_Invalid; +} diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index 32676f8..7aa6df8 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -75,7 +75,10 @@ public: int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} private: + void invalidate(); QDirectFBPaintEngine *engine; + QImage::Format format; + bool alpha; }; QT_END_HEADER -- cgit v0.12 From 743fc72ff7fd64ad5a0857f9103b68074a8c8103 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 9 Apr 2009 07:41:07 +0200 Subject: Revert "New binary for Windows configure" This reverts commit f0239a4983dd84b0e23c1e6f796c5c44dfde26b2. The old change did not write out QT_EDITION etc. to qconfig.h causing the build to break. --- configure.exe | Bin 851968 -> 1134592 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 891e928..13ca0e5 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From f1152c539845b4a52f22c8f2c978c684b442f4be Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 01:30:24 -0700 Subject: Make sure to update the member opacity variable Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index f72b0da..24d77bf 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -436,8 +436,9 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m } } -void QDirectFBPaintEnginePrivate::setOpacity(quint8 opacity) +void QDirectFBPaintEnginePrivate::setOpacity(quint8 op) { + opacity = op; if (opacity == 255) { // ### need to check this stuff blitFlagsFromCompositionMode &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); -- cgit v0.12 From 405f78f8e1ef68ebce2abd790820438c9e420755 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 09:32:57 -0700 Subject: Inline hasAlphaChannel and add pixelFormat getter Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 5 ----- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index a4e235b..0a1696a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -283,11 +283,6 @@ void QDirectFBPixmapData::fill(const QColor &color) } } -bool QDirectFBPixmapData::hasAlphaChannel() const -{ - return alpha; -} - QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, Qt::TransformationMode mode) const { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index 7aa6df8..6cfafcd 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -64,7 +64,7 @@ public: void fromImage(const QImage &image, Qt::ImageConversionFlags flags); void copy(const QPixmapData *data, const QRect &rect); void fill(const QColor &color); - bool hasAlphaChannel() const; + inline bool hasAlphaChannel() const { return alpha; } QPixmap transformed(const QTransform &matrix, Qt::TransformationMode mode) const; QImage toImage() const; @@ -73,7 +73,7 @@ public: // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} - + inline QImage::Format pixelFormat() const { return format; } private: void invalidate(); QDirectFBPaintEngine *engine; -- cgit v0.12 From b106ddb649ec0260486755ff7a87bbdc719785d1 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 09:34:14 -0700 Subject: Fix setOpacity Opacity doesn't play well with PorterDuff so we need to disable the porter duff when opacity is set. Also the DSBLIT_SRC_PREMULTCOLOR flag is not the right thing for us. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 24d77bf..a8fdff8 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -440,10 +440,9 @@ void QDirectFBPaintEnginePrivate::setOpacity(quint8 op) { opacity = op; if (opacity == 255) { - // ### need to check this stuff - blitFlagsFromCompositionMode &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); + blitFlagsFromCompositionMode &= ~DSBLIT_BLEND_COLORALPHA; } else { - blitFlagsFromCompositionMode |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); + blitFlagsFromCompositionMode |= DSBLIT_BLEND_COLORALPHA; } } @@ -459,11 +458,14 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) { quint32 blittingFlags = blitFlagsFromCompositionMode; - if (!alpha) { + if (alpha) { + surface->SetPorterDuff(surface, + (blittingFlags & DSBLIT_BLEND_COLORALPHA) + ? DSPD_NONE + : porterDuffRule); + } else { blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL; surface->SetPorterDuff(surface, DSPD_NONE); - } else { - surface->SetPorterDuff(surface, porterDuffRule); } surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); -- cgit v0.12 From cde39f381afe9cb255076a49b7859af54ae391d2 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 09:53:10 -0700 Subject: Clean up code a little and get rid extra memcpys The QVarLengthArray approach makes no sense with DirectFB. Draw.*s is a regular function call and the receiving function even memcpy's the data on arrival anyway. Just call the Draw.* functions one by one Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 51 ++-------------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index a8fdff8..d9346fd 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -224,7 +224,7 @@ public: inline void updateClip(); inline void setClipDirty(); - void systemStateChanged(); //Needed to be notified when system clip changes + void systemStateChanged(); void begin(QPaintDevice *device); void end(); @@ -234,9 +234,6 @@ public: QTransform transform; int lastLockedHeight; private: -// QRegion rectsToClippedRegion(const QRect *rects, int n) const; -// QRegion rectsToClippedRegion(const QRectF *rects, int n) const; - IDirectFB *fb; DFBSurfaceDescription fbDescription; int fbWidth; @@ -489,61 +486,19 @@ void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) const { - QVarLengthArray regions(n); - for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]); - - regions[i].x1 = l.x1(); - regions[i].y1 = l.y1(); - regions[i].x2 = l.x2(); - regions[i].y2 = l.y2(); + surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); } - surface->DrawLines(surface, regions.data(), n); } void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) const { - QVarLengthArray regions(n); - for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]).toLine(); - - regions[i].x1 = l.x1(); - regions[i].y1 = l.y1(); - regions[i].x2 = l.x2(); - regions[i].y2 = l.y2(); + surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); } - surface->DrawLines(surface, regions.data(), n); -} - -/* ### Commented out until it can be implemented properly using raster's QClipData -QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRect *rects, - int n) const -{ - QRegion region; - - for (int i = 0; i < n; ++i) { - const QRect r = transform.mapRect(rects[i]); - region += clip & r; - } - - return region; -} - -QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRectF *rects, - int n) const -{ - QRegion region; - - for (int i = 0; i < n; ++i) { - const QRect r = transform.mapRect(rects[i]).toRect(); - region += clip & r; - } - - return region; } -*/ void QDirectFBPaintEnginePrivate::fillRegion(const QRegion ®ion) const { -- cgit v0.12 From d4f23b414c337654d65ba54937e40d46b8510c0a Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 13:37:59 -0700 Subject: Add a change description about DirectFB Reviewed-by: TrustMe --- dist/changes-4.5.1 | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 5584c11..87f808d 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -144,6 +144,7 @@ Qt for Mac OS X Qt for Embedded Linux --------------------- +- Various improvements to the Qt DirectFB plugin. Qt for Windows CE ----------------- -- cgit v0.12 From b52e3da01bd43da12587654f6d4e3f3ececed0cf Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 15:50:05 -0700 Subject: Better warnings when primary is not in videomem If connect options are set to include videoonly and creating the primary surface in video memory fails warn even in release mode. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 04d2f57..8e57bb2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -233,8 +233,11 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY); } result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &voDesc, &newSurface); -#ifndef QT_NO_DEBUG - if (result != DFB_OK) { + if (result != DFB_OK +#ifdef QT_NO_DEBUG + && (desc->flags & DSDESC_CAPS) && (desc->caps & DSCAPS_PRIMARY) +#endif + ) { qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n" " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s", desc->flags, desc->caps, desc->width, desc->height, @@ -242,7 +245,6 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription desc->preallocated[0].data, desc->preallocated[0].pitch, DirectFBErrorString(result)); } -#endif } if (!newSurface) -- cgit v0.12 From 0634fb1f6d8a4bef7ed82784b5b6deb117765df2 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 15:56:24 -0700 Subject: Take out the DSCAPS_TRIPLE when not blitting When this code was written there was never a case when we would not blit our flips and hence the entire if (!(flipFlags & DSFLIP_BLIT)) business seems not to have been tested anyway. Since I don't see the point of this I am taking it out. Might enable us to actually create the primary surface in video memory more often. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 8e57bb2..a230bf9 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -826,13 +826,6 @@ bool QDirectFBScreen::connect(const QString &displaySpec) | DSCAPS_PREMULTIPLIED); } - if (!(d_ptr->flipFlags & DSFLIP_BLIT)) { - description.caps = DFBSurfaceCapabilities(description.caps - | DSCAPS_DOUBLE - | DSCAPS_TRIPLE); - } - - // We don't track the primary surface as it's released in disconnect d_ptr->dfbSurface = createDFBSurface(&description, DontTrackSurface); if (!d_ptr->dfbSurface) { -- cgit v0.12 From 5c36257e21d00106e36f5b68eea78507efc3f39c Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 16:55:48 -0700 Subject: Beautify displayArgs parsing Also add support for setting the width and height of the primary surface using display arguments (which can be good when debugging performace issues). Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index a230bf9..041d522 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -772,6 +772,18 @@ static void printDirectFBInfo(IDirectFB *fb) dev.blitting_flags, dev.drawing_flags, dev.video_memory); } +static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value) +{ + Q_ASSERT(value); + QRegExp rx(QString("%1=?(\\d+)").arg(variable)); + rx.setCaseSensitivity(Qt::CaseInsensitive); + if (arguments.indexOf(rx) != -1) { + *value = rx.cap(1).toInt(); + return true; + } + return false; +} + bool QDirectFBScreen::connect(const QString &displaySpec) { DFBResult result = DFB_OK; @@ -817,6 +829,10 @@ bool QDirectFBScreen::connect(const QString &displaySpec) DFBSurfaceDescription description; description.flags = DFBSurfaceDescriptionFlags(DSDESC_CAPS); + if (::setIntOption(displayArgs, QLatin1String("width"), &description.width)) + description.flags = DFBSurfaceDescriptionFlags(description.flags | DSDESC_WIDTH); + if (::setIntOption(displayArgs, QLatin1String("height"), &description.height)) + description.flags = DFBSurfaceDescriptionFlags(description.flags | DSDESC_HEIGHT); description.caps = DFBSurfaceCapabilities(DSCAPS_PRIMARY | DSCAPS_DOUBLE | DSCAPS_STATIC_ALLOC); @@ -882,18 +898,8 @@ bool QDirectFBScreen::connect(const QString &displaySpec) setPixelFormat(getImageFormat(d_ptr->dfbSurface)); physWidth = physHeight = -1; - QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)")); - int dimIdxW = displayArgs.indexOf(mmWidthRx); - if (dimIdxW >= 0) { - mmWidthRx.exactMatch(displayArgs.at(dimIdxW)); - physWidth = mmWidthRx.cap(1).toInt(); - } - QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)")); - int dimIdxH = displayArgs.indexOf(mmHeightRx); - if (dimIdxH >= 0) { - mmHeightRx.exactMatch(displayArgs.at(dimIdxH)); - physHeight = mmHeightRx.cap(1).toInt(); - } + ::setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth); + ::setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight); const int dpi = 72; if (physWidth < 0) physWidth = qRound(dw * 25.4 / dpi); -- cgit v0.12 From 6e5774d84e7e3b68736f95fae09a084bd5b9ac7a Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 9 Apr 2009 13:50:38 +1000 Subject: Fixes compile of WebKit with MinGW when using any `-j' option to build in parallel. On Windows, when a project has a lot of INCLUDEPATHs, some extra logic takes place to work around an issue of large command lines. Instead of passing all the paths directly to moc.exe, the paths are written to mocinclude.tmp which is then read from by moc.exe. Prior to this change, every moc rule tries to write to mocinclude.tmp. When running make with -j, this will happen in parallel, causing this error message: "The process cannot access the file because it is being used by another process" Change the logic so mocinclude.tmp is generated by its own rule. Reviewed-by: Lincoln Ramsay --- mkspecs/features/moc.prf | 62 ++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index f18d462..975867e 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -8,31 +8,45 @@ isEmpty(MOC_DIR):MOC_DIR = . isEmpty(QMAKE_H_MOD_MOC):QMAKE_H_MOD_MOC = moc_ isEmpty(QMAKE_EXT_CPP_MOC):QMAKE_EXT_CPP_MOC = .moc -# This function on Windows puts the includes into a .inc file which moc will read, if the project -# has more than 30 includes. We do this to overcome a command-line limit on Win < XP -# Otherwise the function simply returns the normal command-line for moc -defineReplace(mocCmd) { - win32:count($$list($$INCPATH), 40, >) { - EOC = $$escape_expand(\n\t) +# On Windows, put the includes into a .inc file which moc will read, if the project +# has too many includes. We do this to overcome a command-line limit on Win < XP +INCLUDETEMP= +win32:count($$list($$INCPATH), 40, >) { + INCLUDETEMP = mocinclude.tmp + + # Remove any existing mocinclude.tmp when qmake runs + WIN_OUT_PWD=$$OUT_PWD + WIN_OUT_PWD~=s,/,\,g + system($$QMAKE_DEL_FILE $$WIN_OUT_PWD\\$$INCLUDETEMP > NUL 2>&1) + + EOC = $$escape_expand(\n\t) + + if(contains(TEMPLATE, "vc.*")|contains(TEMPLATE_PREFIX, "vc")) { + # the VCPROJ generator will replace the \r\h with the coded \r\n: + # No other generator understands the \h + if(win32-msvc.net|win32-msvc2*|wince*msvc*): EOC = $$escape_expand(\r\h) + else: EOC = $$escape_expand(\\)$$escape_expand(\n\t) + } - if(contains(TEMPLATE, "vc.*")|contains(TEMPLATE_PREFIX, "vc")) { - # the VCPROJ generator will replace the \r\h with the coded \r\n: - # No other generator understands the \h - if(win32-msvc.net|win32-msvc2*|wince*msvc*): EOC = $$escape_expand(\r\h) - else: EOC = $$escape_expand(\\)$$escape_expand(\n\t) - } + unset(INCFILELIST) + RET = + for(incfile, $$list($$INCPATH)) { + INCFILELIST = -I$$incfile + isEmpty(RET): RET += @echo $$INCFILELIST> $$INCLUDETEMP $$EOC + else: RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC + } + !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC - INCLUDETEMP = mocinclude.tmp - unset(INCFILELIST) - RET = - for(incfile, $$list($$INCPATH)) { - INCFILELIST = -I$$incfile - isEmpty(RET): RET += @echo $$INCFILELIST> $$INCLUDETEMP $$EOC - else: RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC - } - !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC - RET += $$QMAKE_MOC $(DEFINES) @$$INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2 - return($$RET) + build_pass|isEmpty(BUILDS) { + mocinclude.target = $$INCLUDETEMP + mocinclude.commands = $$RET + QMAKE_EXTRA_TARGETS += mocinclude + } +} + +defineReplace(mocCmd) { + !isEmpty(INCLUDETEMP) { + return($$QMAKE_MOC $(DEFINES) @$$INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) } return($$QMAKE_MOC $(DEFINES) $(INCPATH) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) } @@ -45,6 +59,7 @@ moc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAK moc_header.input = HEADERS moc_header.variable_out = SOURCES moc_header.name = MOC ${QMAKE_FILE_IN} +!isEmpty(INCLUDETEMP):moc_header.depends += $$INCLUDETEMP silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands QMAKE_EXTRA_COMPILERS += moc_header INCREDIBUILD_XGE += moc_header @@ -56,6 +71,7 @@ moc_source.commands = ${QMAKE_FUNC_mocCmd} moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC} moc_source.input = SOURCES OBJECTIVE_SOURCES moc_source.name = MOC ${QMAKE_FILE_IN} +!isEmpty(INCLUDETEMP):moc_source.depends += $$INCLUDETEMP silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands QMAKE_EXTRA_COMPILERS += moc_source INCREDIBUILD_XGE += moc_source -- cgit v0.12 From 02f4f244f585868dc1cca208f0caa6f02d734d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 14 Apr 2009 09:16:55 +0200 Subject: Fix spelling error Reviewed-by: TrustMe --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 7e66a98..6d67dee 100755 --- a/configure +++ b/configure @@ -2698,7 +2698,7 @@ if [ "$PLATFORM_MAC" = "yes" ]; then 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"; + echo "Unknown architecture: \"$i\". Supported architectures: x86 ppc x86_64 ppc64"; exit 2; fi done -- cgit v0.12 From 1c4f8069dea405cc80e87548e1e3609611a7bab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 14 Apr 2009 09:30:15 +0200 Subject: Allow "i386" as an alias for x86 for Mac universal builds GCC uses i386, but configure has always used x86, which can lead to confusion. Reviewed-by: nrc --- configure | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 6d67dee..adb08a8 100755 --- a/configure +++ b/configure @@ -2694,14 +2694,17 @@ fi # check -arch arguments for validity. if [ "$PLATFORM_MAC" = "yes" ]; then - ALLOWED="x86 ppc x86_64 ppc64" + ALLOWED="x86 ppc x86_64 ppc64 i386" for i in $CFG_MAC_ARCHS do if echo "$ALLOWED" | grep -w -v "$i" > /dev/null 2>&1; then - echo "Unknown architecture: \"$i\". Supported architectures: x86 ppc x86_64 ppc64"; + echo "Unknown architecture: \"$i\". Supported architectures: x86[i386] ppc x86_64 ppc64"; exit 2; fi done + +# replace "i386" with "x86" to support configuring with -arch i386 as an alias for x86. + CFG_MAC_ARCHS="${CFG_MAC_ARCHS/i386/x86}" fi # find the default framework value -- cgit v0.12 From 91e4f13001a2969ea6311171fb5e7ec0164a3165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 14 Apr 2009 09:40:47 +0200 Subject: Fix typo. Reviewed-by: nrc --- tools/macdeployqt/macdeployqt/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/macdeployqt/macdeployqt/main.cpp b/tools/macdeployqt/macdeployqt/main.cpp index d6f7e5f..0026c40 100644 --- a/tools/macdeployqt/macdeployqt/main.cpp +++ b/tools/macdeployqt/macdeployqt/main.cpp @@ -63,7 +63,7 @@ int main(int argc, char **argv) qDebug() << "framework. The accessibilty, image formats, and text codec"; qDebug() << "plugins are always copied, unless \"-no-plugins\" is specified."; qDebug() << ""; - qDebug() << "See the \"Deploying an Application on Qt/Mac\" typic in the"; + qDebug() << "See the \"Deploying an Application on Qt/Mac\" topic in the"; qDebug() << "documentation for more information about deployment on Mac OS X."; return 0; -- cgit v0.12 From 69414e5afeb87df2f7a371962f092c2d277aaf6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 14 Apr 2009 09:44:23 +0200 Subject: Remove duplicate defines in the mac accessibility module. This was causing compile warnings. Reviewed-by: nrc --- src/gui/accessible/qaccessible_mac.mm | 122 ---------------------------------- 1 file changed, 122 deletions(-) diff --git a/src/gui/accessible/qaccessible_mac.mm b/src/gui/accessible/qaccessible_mac.mm index b6412c2..68efb8f 100644 --- a/src/gui/accessible/qaccessible_mac.mm +++ b/src/gui/accessible/qaccessible_mac.mm @@ -72,55 +72,36 @@ typedef NSString * const QAXRoleType; #define QAXApplicationRole NSAccessibilityApplicationRole #define QAXButtonRole NSAccessibilityButtonRole #define QAXCancelAction NSAccessibilityCancelAction -#define QAXCancelAction NSAccessibilityCancelAction #define QAXCheckBoxRole NSAccessibilityCheckBoxRole #define QAXChildrenAttribute NSAccessibilityChildrenAttribute -#define QAXChildrenAttribute NSAccessibilityChildrenAttribute -#define QAXChildrenAttribute NSAccessibilityChildrenAttribute #define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute #define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute #define QAXColumnRole NSAccessibilityColumnRole #define QAXConfirmAction NSAccessibilityConfirmAction -#define QAXConfirmAction NSAccessibilityConfirmAction #define QAXContentsAttribute NSAccessibilityContentsAttribute -#define QAXContentsAttribute NSAccessibilityContentsAttribute -#define QAXDecrementAction NSAccessibilityDecrementAction #define QAXDecrementAction NSAccessibilityDecrementAction #define QAXDecrementArrowSubrole NSAccessibilityDecrementArrowSubrole #define QAXDecrementPageSubrole NSAccessibilityDecrementPageSubrole #define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute -#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute -#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute -#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute -#define QAXEnabledAttribute NSAccessibilityEnabledAttribute #define QAXEnabledAttribute NSAccessibilityEnabledAttribute #define QAXExpandedAttribute NSAccessibilityExpandedAttribute #define QAXFocusedAttribute NSAccessibilityFocusedAttribute -#define QAXFocusedAttribute NSAccessibilityFocusedAttribute -#define QAXFocusedAttribute NSAccessibilityFocusedAttribute #define QAXFocusedUIElementChangedNotification NSAccessibilityFocusedUIElementChangedNotification #define QAXFocusedWindowChangedNotification NSAccessibilityFocusedWindowChangedNotification #define QAXGroupRole NSAccessibilityGroupRole #define QAXGrowAreaAttribute NSAccessibilityGrowAreaAttribute -#define QAXGrowAreaAttribute NSAccessibilityGrowAreaAttribute #define QAXGrowAreaRole NSAccessibilityGrowAreaRole #define QAXHelpAttribute NSAccessibilityHelpAttribute -#define QAXHelpAttribute NSAccessibilityHelpAttribute -#define QAXHelpAttribute NSAccessibilityHelpAttribute #define QAXHorizontalOrientationValue NSAccessibilityHorizontalOrientationValue #define QAXHorizontalScrollBarAttribute NSAccessibilityHorizontalScrollBarAttribute -#define QAXHorizontalScrollBarAttribute NSAccessibilityHorizontalScrollBarAttribute -#define QAXIncrementAction NSAccessibilityIncrementAction #define QAXIncrementAction NSAccessibilityIncrementAction #define QAXIncrementArrowSubrole NSAccessibilityIncrementArrowSubrole #define QAXIncrementPageSubrole NSAccessibilityIncrementPageSubrole #define QAXIncrementorRole NSAccessibilityIncrementorRole #define QAXLinkedUIElementsAttribute NSAccessibilityLinkedUIElementsAttribute -#define QAXLinkedUIElementsAttribute NSAccessibilityLinkedUIElementsAttribute #define QAXListRole NSAccessibilityListRole #define QAXMainAttribute NSAccessibilityMainAttribute #define QAXMaxValueAttribute NSAccessibilityMaxValueAttribute -#define QAXMaxValueAttribute NSAccessibilityMaxValueAttribute #define QAXMenuBarRole NSAccessibilityMenuBarRole #define QAXMenuButtonRole NSAccessibilityMenuButtonRole #define QAXMenuClosedNotification NSAccessibilityMenuClosedNotification @@ -128,151 +109,90 @@ typedef NSString * const QAXRoleType; #define QAXMenuOpenedNotification NSAccessibilityMenuOpenedNotification #define QAXMenuRole NSAccessibilityMenuRole #define QAXMinValueAttribute NSAccessibilityMinValueAttribute -#define QAXMinValueAttribute NSAccessibilityMinValueAttribute #define QAXMinimizeButtonAttribute NSAccessibilityMinimizeButtonAttribute -#define QAXMinimizeButtonAttribute NSAccessibilityMinimizeButtonAttribute -#define QAXMinimizedAttribute NSAccessibilityMinimizedAttribute #define QAXMinimizedAttribute NSAccessibilityMinimizedAttribute #define QAXNextContentsAttribute NSAccessibilityNextContentsAttribute -#define QAXNextContentsAttribute NSAccessibilityNextContentsAttribute -#define QAXOrientationAttribute NSAccessibilityOrientationAttribute -#define QAXOrientationAttribute NSAccessibilityOrientationAttribute #define QAXOrientationAttribute NSAccessibilityOrientationAttribute #define QAXParentAttribute NSAccessibilityParentAttribute #define QAXPickAction NSAccessibilityPickAction -#define QAXPickAction NSAccessibilityPickAction #define QAXPopUpButtonRole NSAccessibilityPopUpButtonRole #define QAXPositionAttribute NSAccessibilityPositionAttribute -#define QAXPositionAttribute NSAccessibilityPositionAttribute -#define QAXPressAction NSAccessibilityPressAction #define QAXPressAction NSAccessibilityPressAction #define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute -#define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute -#define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute #define QAXProgressIndicatorRole NSAccessibilityProgressIndicatorRole #define QAXRadioButtonRole NSAccessibilityRadioButtonRole #define QAXRoleAttribute NSAccessibilityRoleAttribute -#define QAXRoleAttribute NSAccessibilityRoleAttribute #define QAXRoleDescriptionAttribute NSAccessibilityRoleDescriptionAttribute #define QAXRowRole NSAccessibilityRowRole #define QAXRowsAttribute NSAccessibilityRowsAttribute -#define QAXRowsAttribute NSAccessibilityRowsAttribute -#define QAXScrollAreaRole NSAccessibilityScrollAreaRole -#define QAXScrollAreaRole NSAccessibilityScrollAreaRole #define QAXScrollAreaRole NSAccessibilityScrollAreaRole #define QAXScrollBarRole NSAccessibilityScrollBarRole #define QAXSelectedAttribute NSAccessibilitySelectedAttribute #define QAXSelectedChildrenAttribute NSAccessibilitySelectedChildrenAttribute #define QAXSelectedRowsAttribute NSAccessibilitySelectedRowsAttribute -#define QAXSelectedRowsAttribute NSAccessibilitySelectedRowsAttribute -#define QAXSizeAttribute NSAccessibilitySizeAttribute #define QAXSizeAttribute NSAccessibilitySizeAttribute #define QAXSliderRole NSAccessibilitySliderRole #define QAXSplitGroupRole NSAccessibilitySplitGroupRole #define QAXSplitterRole NSAccessibilitySplitterRole -#define QAXSplitterRole NSAccessibilitySplitterRole -#define QAXSplitterRole NSAccessibilitySplitterRole -#define QAXSplittersAttribute NSAccessibilitySplittersAttribute #define QAXSplittersAttribute NSAccessibilitySplittersAttribute #define QAXStaticTextRole NSAccessibilityStaticTextRole -#define QAXStaticTextRole NSAccessibilityStaticTextRole -#define QAXSubroleAttribute NSAccessibilitySubroleAttribute #define QAXSubroleAttribute NSAccessibilitySubroleAttribute #define QAXSubroleAttribute NSAccessibilitySubroleAttribute #define QAXTabGroupRole NSAccessibilityTabGroupRole -#define QAXTabGroupRole NSAccessibilityTabGroupRole #define QAXTableRole NSAccessibilityTableRole #define QAXTabsAttribute NSAccessibilityTabsAttribute -#define QAXTabsAttribute NSAccessibilityTabsAttribute #define QAXTextFieldRole NSAccessibilityTextFieldRole -#define QAXTextFieldRole NSAccessibilityTextFieldRole -#define QAXTitleAttribute NSAccessibilityTitleAttribute -#define QAXTitleAttribute NSAccessibilityTitleAttribute #define QAXTitleAttribute NSAccessibilityTitleAttribute -#define QAXTitleAttribute NSAccessibilityTitleAttribute -#define QAXTitleUIElementAttribute NSAccessibilityTitleUIElementAttribute #define QAXTitleUIElementAttribute NSAccessibilityTitleUIElementAttribute #define QAXToolbarButtonAttribute NSAccessibilityToolbarButtonAttribute -#define QAXToolbarButtonAttribute NSAccessibilityToolbarButtonAttribute #define QAXToolbarRole NSAccessibilityToolbarRole #define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute -#define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute -#define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute -#define QAXUnknownRole NSAccessibilityUnknownRole #define QAXUnknownRole NSAccessibilityUnknownRole #define QAXValueAttribute NSAccessibilityValueAttribute -#define QAXValueAttribute NSAccessibilityValueAttribute -#define QAXValueAttribute NSAccessibilityValueAttribute -#define QAXValueAttribute NSAccessibilityValueAttribute #define QAXValueChangedNotification NSAccessibilityValueChangedNotification #define QAXValueIndicatorRole NSAccessibilityValueIndicatorRole #define QAXVerticalOrientationValue NSAccessibilityVerticalOrientationValue #define QAXVerticalScrollBarAttribute NSAccessibilityVerticalScrollBarAttribute -#define QAXVerticalScrollBarAttribute NSAccessibilityVerticalScrollBarAttribute #define QAXVisibleRowsAttribute NSAccessibilityVisibleRowsAttribute -#define QAXVisibleRowsAttribute NSAccessibilityVisibleRowsAttribute -#define QAXWindowAttribute NSAccessibilityWindowAttribute -#define QAXWindowAttribute NSAccessibilityWindowAttribute #define QAXWindowAttribute NSAccessibilityWindowAttribute #define QAXWindowCreatedNotification NSAccessibilityWindowCreatedNotification #define QAXWindowMovedNotification NSAccessibilityWindowMovedNotification #define QAXWindowRole NSAccessibilityWindowRole #define QAXZoomButtonAttribute NSAccessibilityZoomButtonAttribute -#define QAXZoomButtonAttribute NSAccessibilityZoomButtonAttribute #else typedef CFStringRef const QAXRoleType; #define QAXApplicationRole kAXApplicationRole #define QAXButtonRole kAXButtonRole #define QAXCancelAction kAXCancelAction -#define QAXCancelAction kAXCancelAction #define QAXCheckBoxRole kAXCheckBoxRole #define QAXChildrenAttribute kAXChildrenAttribute -#define QAXChildrenAttribute kAXChildrenAttribute -#define QAXChildrenAttribute kAXChildrenAttribute -#define QAXCloseButtonAttribute kAXCloseButtonAttribute #define QAXCloseButtonAttribute kAXCloseButtonAttribute #define QAXColumnRole kAXColumnRole #define QAXConfirmAction kAXConfirmAction -#define QAXConfirmAction kAXConfirmAction #define QAXContentsAttribute kAXContentsAttribute -#define QAXContentsAttribute kAXContentsAttribute -#define QAXDecrementAction kAXDecrementAction #define QAXDecrementAction kAXDecrementAction #define QAXDecrementArrowSubrole kAXDecrementArrowSubrole #define QAXDecrementPageSubrole kAXDecrementPageSubrole #define QAXDescriptionAttribute kAXDescriptionAttribute -#define QAXDescriptionAttribute kAXDescriptionAttribute -#define QAXDescriptionAttribute kAXDescriptionAttribute -#define QAXDescriptionAttribute kAXDescriptionAttribute -#define QAXEnabledAttribute kAXEnabledAttribute #define QAXEnabledAttribute kAXEnabledAttribute #define QAXExpandedAttribute kAXExpandedAttribute #define QAXFocusedAttribute kAXFocusedAttribute -#define QAXFocusedAttribute kAXFocusedAttribute -#define QAXFocusedAttribute kAXFocusedAttribute #define QAXFocusedUIElementChangedNotification kAXFocusedUIElementChangedNotification #define QAXFocusedWindowChangedNotification kAXFocusedWindowChangedNotification #define QAXGroupRole kAXGroupRole #define QAXGrowAreaAttribute kAXGrowAreaAttribute -#define QAXGrowAreaAttribute kAXGrowAreaAttribute #define QAXGrowAreaRole kAXGrowAreaRole #define QAXHelpAttribute kAXHelpAttribute -#define QAXHelpAttribute kAXHelpAttribute -#define QAXHelpAttribute kAXHelpAttribute #define QAXHorizontalOrientationValue kAXHorizontalOrientationValue #define QAXHorizontalScrollBarAttribute kAXHorizontalScrollBarAttribute -#define QAXHorizontalScrollBarAttribute kAXHorizontalScrollBarAttribute -#define QAXIncrementAction kAXIncrementAction #define QAXIncrementAction kAXIncrementAction #define QAXIncrementArrowSubrole kAXIncrementArrowSubrole #define QAXIncrementPageSubrole kAXIncrementPageSubrole #define QAXIncrementorRole kAXIncrementorRole #define QAXLinkedUIElementsAttribute kAXLinkedUIElementsAttribute -#define QAXLinkedUIElementsAttribute kAXLinkedUIElementsAttribute #define QAXListRole kAXListRole #define QAXMainAttribute kAXMainAttribute #define QAXMaxValueAttribute kAXMaxValueAttribute -#define QAXMaxValueAttribute kAXMaxValueAttribute #define QAXMenuBarRole kAXMenuBarRole #define QAXMenuButtonRole kAXMenuButtonRole #define QAXMenuClosedNotification kAXMenuClosedNotification @@ -280,97 +200,55 @@ typedef CFStringRef const QAXRoleType; #define QAXMenuOpenedNotification kAXMenuOpenedNotification #define QAXMenuRole kAXMenuRole #define QAXMinValueAttribute kAXMinValueAttribute -#define QAXMinValueAttribute kAXMinValueAttribute #define QAXMinimizeButtonAttribute kAXMinimizeButtonAttribute -#define QAXMinimizeButtonAttribute kAXMinimizeButtonAttribute -#define QAXMinimizedAttribute kAXMinimizedAttribute #define QAXMinimizedAttribute kAXMinimizedAttribute #define QAXNextContentsAttribute kAXNextContentsAttribute -#define QAXNextContentsAttribute kAXNextContentsAttribute -#define QAXOrientationAttribute kAXOrientationAttribute -#define QAXOrientationAttribute kAXOrientationAttribute #define QAXOrientationAttribute kAXOrientationAttribute #define QAXParentAttribute kAXParentAttribute #define QAXPickAction kAXPickAction -#define QAXPickAction kAXPickAction #define QAXPopUpButtonRole kAXPopUpButtonRole #define QAXPositionAttribute kAXPositionAttribute -#define QAXPositionAttribute kAXPositionAttribute -#define QAXPressAction kAXPressAction #define QAXPressAction kAXPressAction #define QAXPreviousContentsAttribute kAXPreviousContentsAttribute -#define QAXPreviousContentsAttribute kAXPreviousContentsAttribute -#define QAXPreviousContentsAttribute kAXPreviousContentsAttribute #define QAXProgressIndicatorRole kAXProgressIndicatorRole #define QAXRadioButtonRole kAXRadioButtonRole #define QAXRoleAttribute kAXRoleAttribute -#define QAXRoleAttribute kAXRoleAttribute #define QAXRoleDescriptionAttribute kAXRoleDescriptionAttribute #define QAXRowRole kAXRowRole #define QAXRowsAttribute kAXRowsAttribute -#define QAXRowsAttribute kAXRowsAttribute -#define QAXScrollAreaRole kAXScrollAreaRole -#define QAXScrollAreaRole kAXScrollAreaRole #define QAXScrollAreaRole kAXScrollAreaRole #define QAXScrollBarRole kAXScrollBarRole #define QAXSelectedAttribute kAXSelectedAttribute #define QAXSelectedChildrenAttribute kAXSelectedChildrenAttribute #define QAXSelectedRowsAttribute kAXSelectedRowsAttribute -#define QAXSelectedRowsAttribute kAXSelectedRowsAttribute -#define QAXSizeAttribute kAXSizeAttribute #define QAXSizeAttribute kAXSizeAttribute #define QAXSliderRole kAXSliderRole #define QAXSplitGroupRole kAXSplitGroupRole #define QAXSplitterRole kAXSplitterRole -#define QAXSplitterRole kAXSplitterRole -#define QAXSplitterRole kAXSplitterRole -#define QAXSplittersAttribute kAXSplittersAttribute #define QAXSplittersAttribute kAXSplittersAttribute #define QAXStaticTextRole kAXStaticTextRole -#define QAXStaticTextRole kAXStaticTextRole -#define QAXSubroleAttribute kAXSubroleAttribute #define QAXSubroleAttribute kAXSubroleAttribute -#define QAXSubroleAttribute kAXSubroleAttribute -#define QAXTabGroupRole kAXTabGroupRole #define QAXTabGroupRole kAXTabGroupRole #define QAXTableRole kAXTableRole #define QAXTabsAttribute kAXTabsAttribute -#define QAXTabsAttribute kAXTabsAttribute -#define QAXTextFieldRole kAXTextFieldRole #define QAXTextFieldRole kAXTextFieldRole #define QAXTitleAttribute kAXTitleAttribute -#define QAXTitleAttribute kAXTitleAttribute -#define QAXTitleAttribute kAXTitleAttribute -#define QAXTitleAttribute kAXTitleAttribute #define QAXTitleUIElementAttribute kAXTitleUIElementAttribute -#define QAXTitleUIElementAttribute kAXTitleUIElementAttribute -#define QAXToolbarButtonAttribute kAXToolbarButtonAttribute #define QAXToolbarButtonAttribute kAXToolbarButtonAttribute #define QAXToolbarRole kAXToolbarRole #define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute -#define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute -#define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute #define QAXUnknownRole kAXUnknownRole -#define QAXUnknownRole kAXUnknownRole -#define QAXValueAttribute kAXValueAttribute -#define QAXValueAttribute kAXValueAttribute -#define QAXValueAttribute kAXValueAttribute #define QAXValueAttribute kAXValueAttribute #define QAXValueChangedNotification kAXValueChangedNotification #define QAXValueIndicatorRole kAXValueIndicatorRole #define QAXVerticalOrientationValue kAXVerticalOrientationValue #define QAXVerticalScrollBarAttribute kAXVerticalScrollBarAttribute -#define QAXVerticalScrollBarAttribute kAXVerticalScrollBarAttribute -#define QAXVisibleRowsAttribute kAXVisibleRowsAttribute #define QAXVisibleRowsAttribute kAXVisibleRowsAttribute #define QAXWindowAttribute kAXWindowAttribute -#define QAXWindowAttribute kAXWindowAttribute -#define QAXWindowAttribute kAXWindowAttribute #define QAXWindowCreatedNotification kAXWindowCreatedNotification #define QAXWindowMovedNotification kAXWindowMovedNotification #define QAXWindowRole kAXWindowRole #define QAXZoomButtonAttribute kAXZoomButtonAttribute -#define QAXZoomButtonAttribute kAXZoomButtonAttribute #endif -- cgit v0.12 From d5a99cff5235ff72f68f57ab0772274d332b118b Mon Sep 17 00:00:00 2001 From: jasplin Date: Tue, 14 Apr 2009 10:14:03 +0200 Subject: My changes. --- dist/changes-4.5.1 | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 87f808d..f0ab546 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -39,6 +39,13 @@ Third party components - QAuthenticator * [237979] fix implemenation of md5-sess +- QColorDialog + * [247349] Fixed bug causing the wrong alpha value to be returned. + +- QCompleter + * [250064] Fixed focus policy propagation regression. + * [246056] Fixed assertion failure in setCompletionPrefix(). + - QFileInfo * [205244] return valid file info also for relative UNC paths @@ -63,6 +70,10 @@ Third party components * Improved support for setting background and foreground roles in styles such as the text color in a combo box popup on Mac and Cleanlooks. +- QWizard + * [248107] Fixed bug on Vista causing Back button to connect twice to the back() signal. + + **************************************************************************** * Database Drivers * **************************************************************************** -- cgit v0.12 From 52f87de53328c661049acf09d5fedc1850aa9bfa Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 8 Apr 2009 10:35:18 +0200 Subject: Fix docs of QPainter::initFrom. --- src/gui/painting/qpainter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 2beb8c2..18993e1 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1465,8 +1465,8 @@ bool QPainter::isActive() const /*! Initializes the painters pen, background and font to the same as - the given \a widget. Call this function after begin() while the - painter is active. + the given \a widget. This function is automatically when the + painter is opened on a QWidget. \sa begin(), {QPainter#Settings}{Settings} */ -- cgit v0.12 From 4d82197292815c718a569a953de8082e64fc7e46 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 14 Apr 2009 11:05:51 +0200 Subject: Don't crash in XP style if the painter is inactive. --- src/gui/styles/qwindowsxpstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 9d735a7..2f4254e 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -607,7 +607,7 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) QPainter *painter = themeData.painter; Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter"); - if (!painter) + if (!painter || !painter->isActive()) return; painter->save(); @@ -2834,7 +2834,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo bflags |= State_MouseOver; } } - + QStyleOption tool(0); tool.palette = toolbutton->palette; if (toolbutton->subControls & SC_ToolButton) { -- cgit v0.12 From afc51dc4cf5254f6cfb552bc09dd443a8fe0762b Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 14 Apr 2009 12:59:26 +0200 Subject: Updated changelog for 4.5.1 --- dist/changes-4.5.1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index f0ab546..38651a9 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -119,6 +119,11 @@ Qt for Windows * [248036] Fixed an issue where tool buttons would incorrectly hover when disabled. +- [249576] Fixed a crash when using a combobox with Qt::NoFocus. +- [244875] System menu will now be shown for a fullscreen window. +- [240891] Corrected the focus behavior of native file dialogs, when application has multiple toplevels. +- [245330] Fixed a bug which causes mouse inputs to be ignored on modal dialogs, when shown from an ActieQt control. + Qt for Mac OS X --------------- @@ -132,11 +137,13 @@ Qt for Mac OS X with 4.5.1, we don't foresee changing this again. * Fixed a bug where some windows would not get activation when they normally should. * Key events sent to popups do not get propagated onwards. - * [249296] Fix a bug where lineedits on a second page of a stack widget wourd not get key events + * [249296] Fix a bug where lineedits on a second page of a stack widget would not get key events * QFileOpenEvents are no longer sent for items passed on the command line. * Various fixes for determining metrics of text and the ability to disable kerning. * [248918] Fixed color matching for themed text items. * Modify the colliding mice example to work better with coalesced updates. + * Fixed a bug where the drag cursor was not updated when modifier keys are used. + * [247947] Fixed a crash in drag and drop. - Fix a crash when showing a widget that is window modal but has no parent. - [248803] Showing two dialogs at the same time don't get shared activation. -- cgit v0.12 From 67344b0e7617fde78722440346a779aee0bf1286 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 14 Apr 2009 13:38:47 +0200 Subject: Cocoa: dialogs are sometimes not shown if triggered from outside the app NSPanels are set to hide when the application becomes inactive by default. This is not what we wan't for normal dialogs in Qt. This patch makes this setting explicit, in case the window we're about to create is a dialog. Task-number: 250869 Reviewed-by: Trenton Schulz --- src/gui/kernel/qwidget_mac.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 5432c55..e7dfde5 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2172,7 +2172,10 @@ void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWin if ((popup || type == Qt::Tool || type == Qt::ToolTip) && !q->isModal()) { [windowRef setHidesOnDeactivate:YES]; [windowRef setHasShadow:YES]; + } else { + [windowRef setHidesOnDeactivate:NO]; } + Q_UNUSED(parentWidget); Q_UNUSED(dialog); -- cgit v0.12 From c28cb85841fb5be154c2460efdc82dde012407b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 14 Apr 2009 13:13:29 +0200 Subject: Remove scale applied to cosmetic pens when antialiasing is enabled (X11). The pen width should not be scaled for cosmetic pens. Task-number: 247083 Reviewed-by: Trond BT: yes --- src/gui/painting/qpaintengine_x11.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index d931f55..39ce59f 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1760,7 +1760,10 @@ void QX11PaintEngine::drawPath(const QPainterPath &path) QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height()); // necessary to get aliased alphablended primitives to be drawn correctly if (d->cpen.isCosmetic() || d->has_scaling_xform) { - stroker.setWidth(width == 0 ? 1 : width * d->xform_scale); + if (d->cpen.isCosmetic()) + stroker.setWidth(width == 0 ? 1 : width); + else + stroker.setWidth(width * d->xform_scale); stroker.d_ptr->stroker.setClipRect(deviceRect); stroke = stroker.createStroke(path * d->matrix); if (stroke.isEmpty()) -- cgit v0.12 From 4db6f873386e7b21e23efb4a5ca31eb09f3dd94e Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Tue, 14 Apr 2009 14:05:23 +0200 Subject: Adding note about setting properties to QPrinter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting properties on an invalid printer is not supported. Use isValid() to check if it valid. Rev-by: Trond KjernÃ¥sen Rev-by: Geir Vattekar --- src/gui/painting/qprinter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp index 6c309c7..4f3e71c 100644 --- a/src/gui/painting/qprinter.cpp +++ b/src/gui/painting/qprinter.cpp @@ -284,6 +284,10 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke to send PostScript or PDF output to the printer. As an alternative, the printProgram() function can be used to specify the command or utility to use instead of the system default. + + Note that setting parameters like paper size and resolution on an + invalid printer is undefined. You can use QPrinter::isValid() to + verify this before changing any parameters. QPrinter supports a number of parameters, most of which can be changed by the end user through a \l{QPrintDialog}{print dialog}. In -- cgit v0.12 From eb87a7003153b190d8b635563868717b58ce2faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Tue, 14 Apr 2009 14:02:36 +0200 Subject: Update docs regarding sibling widgets ontop of QGLWidgets when Qt is built with Cocoa support on Mac. The Cocoa API doesn't have a concept of Z-ordering of widgets, and it's implemented by reordering the widget hierarchy for normal widgets. This does unfortunately not work for GL widgets, and it's not supported by Apple. This apparently work with the Carbon AGL API though. Task-number: 244890 Reviewed-by: Gunnar Sletta BT: yes --- src/opengl/qgl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 2d90342..6d75d02 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2615,6 +2615,10 @@ const QGLContext* QGLContext::currentContext() QGLWidget. This will side-step the issue altogether, and is what we recommend for users that need this kind of functionality. + On Mac OS X, when Qt is built with Cocoa support, a QGLWidget + can't have any sibling widgets placed ontop of itself. This is due + to limitations in the Cocoa API and is not supported by Apple. + \section1 Overlays The QGLWidget creates a GL overlay context in addition to the -- cgit v0.12 From e1a9014cc92091e8371f9a888ff94c694f562df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 14 Apr 2009 14:13:54 +0200 Subject: My updates to 4.5.1 changelog. --- dist/changes-4.5.1 | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 38651a9..7bd7aa4 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -59,6 +59,22 @@ Third party components - QMainWindow * [248048] Fix a regression that would cause tooltips to disappear when using the unified toolbar. +- QPainter + * [247492] Fix rendering bug in raster paint engine causing one-pixel + offset when drawing premultiplied ARGB32 images on RGB16 images. + * [249490] Fix one-pixel offset between stroke and fills of ellipses in + X11 paint engine. + * [246573] Fix very slow stroking of paths in X11 paint engine. + * [247083] Fix scale applied to antialiased cosmetic pens in X11 paint + engine. + * [247505] Fix missing fills of rectangles with negative width/height in + raster paint engine. + * [249628] Fix crash in OpenGL paint engine when filling using Qt::NoBrush. + +- QPixmap + * [249175] Fix QPixmap::fromImage() of monochrome images to result in + black/white pixels and not transparent/white pixels. + - QSharedPointer * [246843] Fixed a crash caused by using QSharedPointer in global statics @@ -108,6 +124,17 @@ Qt for Linux/X11 * [238196] Allow middle click to set scrollbar position to follow GTK+ behavior. +- Font rendering + * Improve performance of subpixel antialiased text rendering by using a mask + in the calls to XRender's text compositing function. + * [248387] Better respect the font config LCD filter settings for subpixel + antialiased text rendering when Freetype's native subpixel rendering is + disabled. + * [248498] Fix garbled rendering of subpixel antialiased text when using + Freetype's native subpixel rendering for vertical subpixel layouts. + * [248644] Fall back to Qt's subpixel rendering if Freetype's subpixel + rendering is available at compile-time but not at run-time. + Qt for Windows -------------- -- cgit v0.12 From 91aeceb7132f4afae0996443a162a5783d8f17aa Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 10:02:42 +0200 Subject: Fix crash in QTreeView Discovered in Kopete trunk BT: yes Reviewed-by: Thierry --- src/gui/itemviews/qtreeview.cpp | 1 + tests/auto/qtreeview/tst_qtreeview.cpp | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 0117db2..62c1277 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2019,6 +2019,7 @@ int QTreeView::verticalOffset() const // If we are scrolling per item and have non-uniform row heights, // finding the vertical offset in pixels is going to be relatively slow. // ### find a faster way to do this + d->executePostedLayout(); int offset = 0; for (int i = 0; i < d->viewItems.count(); ++i) { if (i == verticalScrollBar()->value()) diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index e1d405d..dfccd9e 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -209,6 +209,8 @@ private slots: void indexRowSizeHint(); void addRowsWhileSectionsAreHidden(); + void filterProxyModelCrash(); + // task-specific tests: void task174627_moveLeftToRoot(); void task171902_expandWith1stColHidden(); @@ -2829,6 +2831,29 @@ void tst_QTreeView::indexRowSizeHint() QCOMPARE(view.indexRowSizeHint(index), w->sizeHint().height()); } +void tst_QTreeView::filterProxyModelCrash() +{ + QStandardItemModel model; + QList items; + for (int i = 0; i < 100; i++) + items << new QStandardItem(QString::fromLatin1("item %1").arg(i)); + model.appendColumn(items); + + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + + QTreeView view; + view.setModel(&proxy); + view.show(); + QTest::qWait(30); + proxy.invalidate(); + view.verticalScrollBar()->setValue(15); + QTest::qWait(20); + + proxy.invalidate(); + view.repaint(); //used to crash +} + class task174627_TreeView : public QTreeView { Q_OBJECT @@ -3254,6 +3279,5 @@ void tst_QTreeView::task246536_scrollbarsNotWorking() QVERIFY(o.count > 0); } - QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v0.12 From b15ec327df81f8b0d4934ee2f52a7ccc6a8281c2 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 11:44:56 +0200 Subject: Fixes: QTreeView font change regression if there is an application stylesheet The way font propagation work has changed since 4.4: When there is a stylesheet enabled, font does not propagate. So when settings a font to the QAbstractItemView, the viewport font will not change, and hence no QEvent::FontChange on it. So catch the QEvent::FontChange in QAbstractItemView::event in addition to QAbstractItemView::viewportEvent. (we seems to use the view's font everywhere anyway) Task-number: 250754 Reviewed-by: Jens Bache-Wiig --- src/gui/itemviews/qabstractitemview.cpp | 3 ++ .../qabstractitemview/tst_qabstractitemview.cpp | 43 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 7bd6207..55b3a03 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -1400,6 +1400,9 @@ bool QAbstractItemView::event(QEvent *event) case QEvent::FocusOut: d->checkPersistentEditorFocus(); break; + case QEvent::FontChange: + d->doDelayedItemsLayout(); // the size of the items will change + break; default: break; } diff --git a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp index 3337a49..086c551 100644 --- a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include "../../shared/util.h" //TESTED_CLASS= @@ -209,6 +211,7 @@ private slots: void setCurrentIndex(); void task221955_selectedEditor(); + void task250754_fontChange(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -1179,8 +1182,46 @@ void tst_QAbstractItemView::task221955_selectedEditor() button->setFocus(); QTest::qWait(50); QVERIFY(tree.selectionModel()->selectedIndexes().isEmpty()); +} + +void tst_QAbstractItemView::task250754_fontChange() +{ + QString app_css = qApp->styleSheet(); + qApp->setStyleSheet("/* */"); + + QWidget w; + QTreeView tree(&w); + QVBoxLayout *vLayout = new QVBoxLayout(&w); + vLayout->addWidget(&tree); + + QStandardItemModel *m = new QStandardItemModel(this); + for (int i=0; i<5; ++i) { + QStandardItem *item = new QStandardItem(QString("Item number %1").arg(i)); + for (int j=0; j<5; ++j) { + QStandardItem *child = new QStandardItem(QString("Child Item number %1").arg(j)); + item->setChild(j, 0, child); + } + m->setItem(i, 0, item); + } + tree.setModel(m); + + w.show(); + w.resize(150,150); + QTest::qWait(30); + QFont font = tree.font(); + font.setPointSize(5); + tree.setFont(font); + QTest::qWait(30); + + QVERIFY(!tree.verticalScrollBar()->isVisible()); + + font.setPointSize(45); + tree.setFont(font); + QTest::qWait(30); + //now with the huge items, the scrollbar must be visible + QVERIFY(tree.verticalScrollBar()->isVisible()); - + qApp->setStyleSheet(app_css); } QTEST_MAIN(tst_QAbstractItemView) -- cgit v0.12 From e2fa120510584327b7e46ff2a4413aa659a5bd65 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 14 Apr 2009 14:52:49 +0200 Subject: fix deployment rules add additional file to deployment. --- tests/auto/qtranslator/qtranslator.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qtranslator/qtranslator.pro b/tests/auto/qtranslator/qtranslator.pro index e4ad22a..0d67f70 100644 --- a/tests/auto/qtranslator/qtranslator.pro +++ b/tests/auto/qtranslator/qtranslator.pro @@ -3,7 +3,7 @@ SOURCES += tst_qtranslator.cpp wince*: { - addFiles.sources = hellotr_la.qm + addFiles.sources = hellotr_la.qm msgfmt_from_po.qm addFiles.path = . DEPLOYMENT += addFiles } -- cgit v0.12 From f0ceef57b178d4ed71e61a6ce2681f3d401d69fe Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 14 Apr 2009 14:59:30 +0200 Subject: fix potential crash Reviewed-by: Thomas Hartmann need to check for valid menuBar, otherwise dereferencing will horribly fail. --- src/gui/widgets/qmainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 46d6471..2abc9e8 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -481,7 +481,7 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar) oldMenuBar->deleteLater(); } #ifdef Q_OS_WINCE - if (menuBar->size().height() > 0) + if (menuBar && menuBar->size().height() > 0) #endif d->layout->setMenuBar(menuBar); } -- cgit v0.12 From 9a41b437be6014c7a671591e2741c5ca7d8c8be8 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 14 Apr 2009 15:16:43 +0200 Subject: increase waiting time slower platforms (like WinCE) need some more time to actually update. --- tests/auto/qcolordialog/tst_qcolordialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qcolordialog/tst_qcolordialog.cpp b/tests/auto/qcolordialog/tst_qcolordialog.cpp index e51dfcc..1b5babb 100644 --- a/tests/auto/qcolordialog/tst_qcolordialog.cpp +++ b/tests/auto/qcolordialog/tst_qcolordialog.cpp @@ -108,7 +108,7 @@ void tst_QColorDialog::native_activeModalWidget() // color dialog when it is executing, even when using a native // dialog: TestNativeDialog d; - QTimer::singleShot(100, &d, SLOT(hide())); + QTimer::singleShot(1000, &d, SLOT(hide())); d.exec(); QVERIFY(&d == d.m_activeModalWidget); } -- cgit v0.12 From 56feb92927d48edffcd09491091ec735b86a820d Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 14 Apr 2009 15:02:34 +0200 Subject: Fix a bug where a widget would not always get the correct Cursor in Cocoa Cocoa has a different way of dealing with cursors than our heavy handed approach that we used in Carbon. We simply need to re-implement the proper function in NSView and set up the rectangles for the cursor correctly. We also need to expose an QCursor2NSCursor type functions since the current QCursor::handle() is useless for doing this and we shouldn't change that. With this change things seem to work much more like the native stuff for both Carbon and Cocoa. --- src/gui/kernel/qcocoaview_mac.mm | 29 +++++++++++++++++++++++++++++ src/gui/kernel/qcursor.h | 2 ++ src/gui/kernel/qcursor_mac.mm | 16 ++++++++++++++++ src/gui/kernel/qwidget_mac.mm | 14 ++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 9b581c5..bcbd1bf 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -181,6 +181,7 @@ QT_FORWARD_DECLARE_CLASS(QAbstractScrollAreaPrivate) QT_FORWARD_DECLARE_CLASS(QPaintEvent) QT_FORWARD_DECLARE_CLASS(QPainter) QT_FORWARD_DECLARE_CLASS(QHoverEvent) +QT_FORWARD_DECLARE_CLASS(QCursor) QT_USE_NAMESPACE extern "C" { extern NSString *NSTextInputReplacementRangeAttributeName; @@ -236,6 +237,34 @@ extern "C" { } } +- (void)resetCursorRects +{ + QWidget *cursorWidget = qwidget; + + if (cursorWidget->testAttribute(Qt::WA_TransparentForMouseEvents)) + cursorWidget = QApplication::widgetAt(qwidget->mapToGlobal(qwidget->rect().center())); + + if (cursorWidget == 0) + return; + + if (!cursorWidget->testAttribute(Qt::WA_SetCursor)) { + [super resetCursorRects]; + return; + } + + QRegion mask = qt_widget_private(cursorWidget)->extra->mask; + NSCursor *nscursor = static_cast(nsCursorForQCursor(cursorWidget->cursor())); + if (mask.isEmpty()) { + [self addCursorRect:[qt_mac_nativeview_for(cursorWidget) visibleRect] cursor:nscursor]; + } else { + const QVector &rects = mask.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect &rect = rects.at(i); + [self addCursorRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()) cursor:nscursor]; + } + } +} + - (void)removeDropData { if (dropData) { diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h index 15b4597..ad1860d 100644 --- a/src/gui/kernel/qcursor.h +++ b/src/gui/kernel/qcursor.h @@ -77,6 +77,7 @@ class QBitmap; class QPixmap; #if defined(Q_WS_MAC) +void *nsCursorForQCursor(const QCursor &c); void qt_mac_set_cursor(const QCursor *c, const QPoint &p); #endif @@ -128,6 +129,7 @@ public: private: QCursorData *d; #if defined(Q_WS_MAC) + friend void *nsCursorForQCursor(const QCursor &c); friend void qt_mac_set_cursor(const QCursor *c, const QPoint &p); #endif }; diff --git a/src/gui/kernel/qcursor_mac.mm b/src/gui/kernel/qcursor_mac.mm index d632eb79..ae98f2e 100644 --- a/src/gui/kernel/qcursor_mac.mm +++ b/src/gui/kernel/qcursor_mac.mm @@ -95,9 +95,19 @@ protected: } }; +void *nsCursorForQCursor(const QCursor &c) +{ + c.d->update(); + return [[static_cast(c.d->curs.cp.nscursor) retain] autorelease]; +} + static QCursorData *currentCursor = 0; //current cursor void qt_mac_set_cursor(const QCursor *c, const QPoint &) { +#ifdef QT_MAC_USE_COCOA + Q_UNUSED(c); + return; +#else if (!c) { currentCursor = 0; return; @@ -128,10 +138,15 @@ void qt_mac_set_cursor(const QCursor *c, const QPoint &) } } currentCursor = c->d; +#endif } void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos) { +#ifdef QT_MAC_USE_COCOA + Q_UNUSED(globalPos); + return; +#else QCursor cursor(Qt::ArrowCursor); if (QApplication::overrideCursor()) { cursor = *QApplication::overrideCursor(); @@ -144,6 +159,7 @@ void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos) } } qt_mac_set_cursor(&cursor, globalPos); +#endif } void qt_mac_update_cursor() diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index e7dfde5..827e098 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2847,12 +2847,26 @@ void QWidgetPrivate::updateSystemBackground() void QWidgetPrivate::setCursor_sys(const QCursor &) { + Q_Q(QWidget); +#ifndef QT_MAC_USE_COCOA qt_mac_update_cursor(); +#else + if (q->testAttribute(Qt::WA_WState_Created)) { + [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)]; + } +#endif } void QWidgetPrivate::unsetCursor_sys() { + Q_Q(QWidget); +#ifndef QT_MAC_USE_COCOA qt_mac_update_cursor(); +#else + if (q->testAttribute(Qt::WA_WState_Created)) { + [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)]; + } +#endif } void QWidgetPrivate::setWindowTitle_sys(const QString &caption) -- cgit v0.12 From 99ed68cda10355dba5c7a3e2466ee45b59dbb555 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 14 Apr 2009 15:19:41 +0200 Subject: Don't remove the cache file if you have successfully added it. This regression probably happened because of the fix to task 244485 (see 8d500381), which made QFile follow a rename. This means that QTemporaryFile removes its target when it is deleted. This fixes a number of caching autotests that are failing. Reviewed-by: Markus Goetz BT: yes --- src/network/access/qnetworkdiskcache.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index fa0fccb..93360c8 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -253,7 +253,8 @@ void QNetworkDiskCachePrivate::storeItem(QCacheItem *cacheItem) // ### use atomic rename rather then remove & rename if (cacheItem->file->rename(fileName)) currentCacheSize += cacheItem->file->size(); - cacheItem->file->setAutoRemove(true); + else + cacheItem->file->setAutoRemove(true); } if (cacheItem->metaData.url() == lastItem.metaData.url()) lastItem.reset(); -- cgit v0.12 From 1657a030b340050f3e813a9a8d34df93e115c7be Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 14 Apr 2009 16:11:55 +0200 Subject: Fix warning: "__LP64__" is not defined" Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qmacdefines_mac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qmacdefines_mac.h b/src/gui/kernel/qmacdefines_mac.h index 97ec544..035b8c5 100644 --- a/src/gui/kernel/qmacdefines_mac.h +++ b/src/gui/kernel/qmacdefines_mac.h @@ -105,7 +105,7 @@ Yes, it is an informative comment ;-) # undef qDebug #endif -#if __LP64__ +#ifdef __LP64__ typedef signed int OSStatus; #else typedef signed long OSStatus; -- cgit v0.12 From 36f4460b3d6cc18e737edd7d4b18e4b2636e6ff9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 16:10:51 +0200 Subject: Changelog: add my changes for 4.5.1 BT: yes --- dist/changes-4.5.1 | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 7bd7aa4..0d9c2a3 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -33,6 +33,13 @@ Third party components * Library * **************************************************************************** +- QAbstractItemModel + * [243195] Clrarified some warning messages printed if the model is invalid. + +- QAbstractEventDispatcher + * [248805] Duplicates timerid could happen when timer are running while + the QObject is moved to another thread, and would stop timers from working. + - QAbstractSocket * [192037] Emit disconnected only if we were connected before @@ -42,6 +49,9 @@ Third party components - QColorDialog * [247349] Fixed bug causing the wrong alpha value to be returned. +- QCombobox + * [248094] Fixed scrollbar appearing while not required. + - QCompleter * [250064] Fixed focus policy propagation regression. * [246056] Fixed assertion failure in setCompletionPrefix(). @@ -75,20 +85,43 @@ Third party components * [249175] Fix QPixmap::fromImage() of monochrome images to result in black/white pixels and not transparent/white pixels. +- QScrollBar + * [247985] Stylesheet: added ability to style scrollbar menus. + - QSharedPointer * [246843] Fixed a crash caused by using QSharedPointer in global statics +- QSortFilterProxyModel + * [247867] Properly sort when calling appendRows() + * [248868] Resort when the model is reset if dynamicSort is enabled. + * [248868] Fixed QSortFilterProxyModel::sort while dynamicSort was disabled. + - QSSlSocket * [245668] set also protocol, verifyMode and verifyDepth in setSslConfiguration() - QStyleSheetStyle * Improved support for setting background and foreground roles in styles - such as the text color in a combo box popup on Mac and Cleanlooks. + such as the text color in a combo box popup on Mac and Cleanlooks, or + the QScrollBar background. + * [188195] fix background of QAbstractScrollArea loosing its color if styled with pseudo-class. + * Fixed crash while styling the title bar of a QMdiArea. + * [246542] Fixed QToolButton::hover{ color:.... } + +- QTreeView + * Fixed crash that may occurs when event are processed just after QSortFilterProxyModel + has been invalidated + * [246025] Fixed auto-expand that occurs while quicly collapsing an item after clicking on a child + * [248805] Calling programatically QTreeView::sortByColumn was not working if manual + sorting is disabled + * [248163] Fixed possible crash in the paintEvent when spans are used. - QWizard * [248107] Fixed bug on Vista causing Back button to connect twice to the back() signal. +- Q3ListView + * [248689] Q3ListView would not update under certain condition. + **************************************************************************** * Database Drivers * @@ -135,6 +168,11 @@ Qt for Linux/X11 * [248644] Fall back to Qt's subpixel rendering if Freetype's subpixel rendering is available at compile-time but not at run-time. +- QEventDispatcherGlib + * Event posted to a thread before it is started are not processed until + others events are posted. + + Qt for Windows -------------- @@ -185,6 +223,7 @@ Qt for Mac OS X - QTestLib * Activate the test application when launched from the command line. +- Fixed the focus frame transparency that would make widget difficult to use with widget stylesheet. Qt for Embedded Linux --------------------- -- cgit v0.12 From e8877160e332d12958cf700a8a607c36e6c426e1 Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Tue, 14 Apr 2009 16:16:49 +0200 Subject: Fixes the composition demo for Mac/Cocoa in GL mode. QGLPixelBuffer::generateDynamicTexture() will bind the texture to the pbuffer regardless. Why this works on Carbon is a mystery, but if we're to follow our own docs, we should NOT bind the texture to the pbuffer by default. An explicit call to ::bindToDynamicTexture() is required for that. Task-number: 250664 Reviewed-by: Samuel BT: yes --- src/opengl/qglpixelbuffer_mac.mm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/opengl/qglpixelbuffer_mac.mm b/src/opengl/qglpixelbuffer_mac.mm index 14941ab..9a679b1 100644 --- a/src/opengl/qglpixelbuffer_mac.mm +++ b/src/opengl/qglpixelbuffer_mac.mm @@ -308,10 +308,6 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - [static_cast(d->share_ctx) - setTextureImageToPixelBuffer:static_cast(d->pbuf) - colorBuffer:GL_FRONT]; - glBindTexture(GL_TEXTURE_2D, texture); // updates texture target glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -322,8 +318,6 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - aglTexImagePBuffer(d->share_ctx, d->pbuf, GL_FRONT); - glBindTexture(GL_TEXTURE_2D, texture); // updates texture target glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); return texture; -- cgit v0.12 From 5dda84c32b38051ca64c3641ffaaa807e2406285 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 14 Apr 2009 17:07:05 +0200 Subject: Update changes file with my WebKit changes as well as from external contributors. Reviewed-by: Trust me --- dist/changes-4.5.1 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 0d9c2a3..6062093 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -122,6 +122,14 @@ Third party components - Q3ListView * [248689] Q3ListView would not update under certain condition. +- QtWebKit + * Fix bug in cookie handling (WebKit Bugzilla 24062, Benjamin Meyer). + * Fixed support for calling from JavaScript into NPAPI plugins on Windows. + * Fixed updating state of WebActions (Erik Bunce) + * Fixed bug in HTML 5 Canvas clearRect() (Dirk Schulze) + * Fixed text field theming with KDE 4 Oxygen style (Zack Rusin) + * Fixed path fill styles (Zack Rusin) + * Fixed pre-edit text handling with input methods. **************************************************************************** * Database Drivers * -- cgit v0.12 From 28d2b22a940174b4e64f6fa2f5548a7832fc07e8 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 14 Apr 2009 16:55:24 +0200 Subject: Fix logic for autodetecting the embedded-linux package The previous version would get confused because the embedded package also contains _x11 files. Reviewed-by: Thiago --- configure | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/configure b/configure index adb08a8..730c84a 100755 --- a/configure +++ b/configure @@ -119,7 +119,13 @@ elif [ -f "$relpath"/src/gui/kernel/qapplication_qws.cpp ]; then # ~ src/gui/base/qapplication_qws.cpp is present # ~ this is the free or commercial edition # ~ this is the internal edition and Qt Embedded is explicitly enabled - PLATFORM_QWS=maybe + if [ -f "$relpath"/src/gui/kernel/qapplication_mac.mm ]; then + # This is a depot build, or an all-platforms package + PLATFORM_QWS=maybe + else + # This must be the embedded package, since the Qt/Mac source files are not present + PLATFORM_QWS=yes + fi fi #----------------------------------------------------------------------------- -- cgit v0.12 From 0f6950e11389a3ddf657116a98ee8f4ec0753eb4 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 14 Apr 2009 18:01:26 +0200 Subject: QGraphicsView: Rubber Band drag mode not updated correctly when scrolling [regression] The problem was that we didn't update the new region when we paint the rubber band and we scroll at the same time BT:yes Task-number: 245766 Reviewed-by: bnilsen Reviewed-by: andreas --- src/gui/graphicsview/qgraphicsview.cpp | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 418638f..b5a1bdf 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -3621,30 +3621,30 @@ void QGraphicsView::scrollContentsBy(int dx, int dy) if (isRightToLeft()) dx = -dx; - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate - && d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) { - for (int i = 0; i < d->dirtyRects.size(); ++i) - d->dirtyRects[i].translate(dx, dy); - for (int i = 0; i < d->dirtyRegions.size(); ++i) - d->dirtyRegions[i].translate(dx, dy); - } - + if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate) { + if (d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) { + for (int i = 0; i < d->dirtyRects.size(); ++i) + d->dirtyRects[i].translate(dx, dy); + for (int i = 0; i < d->dirtyRegions.size(); ++i) + d->dirtyRegions[i].translate(dx, dy); + if (d->accelerateScrolling) { #ifndef QT_NO_RUBBERBAND - // Update old rubberband - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) { - if (d->viewportUpdateMode != FullViewportUpdate) - viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect)); - else - viewport()->update(); - } + // Update new and old rubberband regions + if (!d->rubberBandRect.isEmpty()) { + QRegion rubberBandRegion(d->rubberBandRegion(viewport(), d->rubberBandRect)); + rubberBandRegion += rubberBandRegion.translated(-dx, -dy); + viewport()->update(rubberBandRegion); + } #endif - - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){ - if (d->accelerateScrolling && d->viewportUpdateMode != FullViewportUpdate) - viewport()->scroll(dx, dy); - else + viewport()->scroll(dx, dy); + } else { + viewport()->update(); + } + } else { viewport()->update(); + } } + d->updateLastCenterPoint(); if ((d->cacheMode & CacheBackground) -- cgit v0.12 From 0bb526f8fab33a42df56c8a60c272e2cca4cc792 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 14 Apr 2009 18:05:26 +0200 Subject: QGraphicsItem: When an item is deleted and eventfilters installed The problem here is that we are filling the sceneEventFilters map when we install evenfilter but we never remove the references of an item if it has been removed from the scene or deleted. The deletion can keep stale pointers into the map and a crash can happen. BT:yes Task-number:250272 Reviewed-by: bnilsen Reviewed-by: andreas --- src/gui/graphicsview/qgraphicsscene.cpp | 19 +++++++++++++++++++ tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a5fec69..9881960 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -746,6 +746,15 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) unpolishedItems.removeAll(item); dirtyItems.removeAll(item); + //We remove all references of item from the sceneEventFilter arrays + QMultiMap::iterator iterator = sceneEventFilters.begin(); + while (iterator != sceneEventFilters.end()) { + if (iterator.value() == item || iterator.key() == item) + iterator = sceneEventFilters.erase(iterator); + else + ++iterator; + } + // Remove from scene transform cache int transformIndex = item->d_func()->sceneTransformIndex; if (transformIndex != -1) { @@ -3293,6 +3302,16 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) d->unpolishedItems.removeAll(item); d->dirtyItems.removeAll(item); + //We remove all references of item from the sceneEventFilter arrays + QMultiMap::iterator iterator = d->sceneEventFilters.begin(); + while (iterator != d->sceneEventFilters.end()) { + if (iterator.value() == item || iterator.key() == item) + iterator = d->sceneEventFilters.erase(iterator); + else + ++iterator; + } + + //Ensure dirty flag have the correct default value so the next time it will be added it will receive updates item->d_func()->dirty = 0; item->d_func()->dirtyChildren = 0; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index ad0dc97..5dd7e1e 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4037,6 +4037,25 @@ void tst_QGraphicsItem::sceneEventFilter() QCOMPARE(tester->filteredEventReceivers.at(6), static_cast(text2)); QVERIFY(text2->hasFocus()); + + //Let check if the items are correctly removed from the sceneEventFilters array + //to avoid stale pointers. + QGraphicsView gv; + QGraphicsScene *anotherScene = new QGraphicsScene; + QGraphicsTextItem *ti = anotherScene->addText("This is a test #1"); + ti->moveBy(50, 50); + QGraphicsTextItem *ti2 = anotherScene->addText("This is a test #2"); + QGraphicsTextItem *ti3 = anotherScene->addText("This is a test #3"); + gv.setScene(anotherScene); + gv.show(); + QTest::qWait(250); + ti->installSceneEventFilter(ti2); + ti3->installSceneEventFilter(ti); + delete ti2; + //we souldn't crash + QTest::mouseMove(gv.viewport(), gv.mapFromScene(ti->scenePos())); + QTest::qWait(250); + delete ti; } class GeometryChanger : public QGraphicsItem -- cgit v0.12 From 94a9f77b41c2d924983e92df30e3e4cc7882cb75 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 14 Apr 2009 18:28:19 +0200 Subject: My ChangeLog Reviewed-by: TrustMe --- dist/changes-4.5.1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 6062093..e8595ff 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -56,9 +56,24 @@ Third party components * [250064] Fixed focus policy propagation regression. * [246056] Fixed assertion failure in setCompletionPrefix(). +- QDirIterator + * [247645] Fix a bug that may loose all cached data inside the QFileInfo + - QFileInfo * [205244] return valid file info also for relative UNC paths +- QFileDialog + * [250194] QFileDialog and QSortFilterProxyModel index mapping issue + * [248332] QFileDialog is slow after visiting a large directory + * [221323] QFileDialog programatical file selection bug + +- QGraphicsItem + * [247890] Cached QGraphicsItems are not updated if update() is called when they are hidden + * [250272] When an item is deleted it does not get removed from the sceneeventfilters meaning a crash can occur + +-QGraphicsView + * [245766] Rubber Band drag mode not updated correctly when scrolling + - QHttp * [208445] cancel request upon receiving unknown authentication method -- cgit v0.12 From a94b601866740e483f093233f59f43b022a68735 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 14 Apr 2009 20:56:06 +0200 Subject: Fix auto-test failure since we remove the warning in QColor Reviewed-by: ogoffart --- tests/auto/qcssparser/tst_cssparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qcssparser/tst_cssparser.cpp b/tests/auto/qcssparser/tst_cssparser.cpp index 6e277d3..9a984c8 100644 --- a/tests/auto/qcssparser/tst_cssparser.cpp +++ b/tests/auto/qcssparser/tst_cssparser.cpp @@ -272,7 +272,7 @@ void tst_CssParser::term_data() val.variant = QVariant(QColor("#ffbb00")); QTest::newRow("hexcolor2") << true << "#fb0" << val; - QTest::ignoreMessage(QtWarningMsg, "QColor::setNamedColor: Could not parse color '#cafebabe'"); + QTest::ignoreMessage(QtWarningMsg, "QCssParser::parseHexColor: Unknown color name '#cafebabe'"); QTest::newRow("hexcolor_failure") << false << "#cafebabe" << val; val.type = QCss::Value::Uri; -- cgit v0.12 From bb7bddc47dd0748b45d22180d9e3c8e5209010b3 Mon Sep 17 00:00:00 2001 From: abcd Date: Wed, 15 Apr 2009 10:16:48 +1000 Subject: Fix the behaviour of sql classes regarding quoted identifiers If no quotes around identifiers are provided by the programmer, identifiers are treated identically to how the underlying engine would behave. i.e. some engines uppercase the identifiers others lowercase them. If the programmer wants case sensitivty and/or use whitespaces they will need to quote their identifiers. The previous (incorrect) behaviour always quoted the identifiers. Reviewed-by: Bill King --- src/sql/drivers/db2/qsql_db2.cpp | 70 +++- src/sql/drivers/ibase/qsql_ibase.cpp | 16 +- src/sql/drivers/mysql/qsql_mysql.cpp | 19 +- src/sql/drivers/mysql/qsql_mysql.h | 3 + src/sql/drivers/oci/qsql_oci.cpp | 58 ++- src/sql/drivers/odbc/qsql_odbc.cpp | 129 ++++++ src/sql/drivers/odbc/qsql_odbc.h | 4 + src/sql/drivers/psql/qsql_psql.cpp | 32 +- src/sql/drivers/sqlite/qsql_sqlite.cpp | 16 +- src/sql/drivers/sqlite2/qsql_sqlite2.cpp | 20 +- src/sql/drivers/tds/qsql_tds.cpp | 21 +- src/sql/kernel/qsqldriver.cpp | 131 +++++- src/sql/kernel/qsqldriver.h | 6 + src/sql/models/qsqlrelationaltablemodel.cpp | 73 +++- src/sql/models/qsqltablemodel.cpp | 20 +- tests/auto/qsqldatabase/tst_databases.h | 37 +- tests/auto/qsqldriver/qsqldriver.pro | 16 + tests/auto/qsqldriver/tst_qsqldriver.cpp | 218 ++++++++++ .../tst_qsqlrelationaltablemodel.cpp | 455 +++++++++++++++++++-- tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp | 15 +- 20 files changed, 1218 insertions(+), 141 deletions(-) create mode 100644 tests/auto/qsqldriver/qsqldriver.pro create mode 100644 tests/auto/qsqldriver/tst_qsqldriver.cpp diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 2786dbb..11d0041 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -1182,7 +1182,7 @@ QDB2Driver::~QDB2Driver() delete d; } -bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString&, int, +bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port, const QString& connOpts) { if (isOpen()) @@ -1205,6 +1205,8 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas setOpenError(true); return false; } + + QString protocol; // Set connection attributes const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); for (int i = 0; i < opts.count(); ++i) { @@ -1235,7 +1237,10 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas } else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) { v = val.toUInt(); r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0); - } else { + } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) { + protocol = tmp; + } + else { qWarning("QDB2Driver::open: Unknown connection attribute '%s'", tmp.toLocal8Bit().constData()); } @@ -1244,9 +1249,18 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas "Unable to set connection attribute '%1'").arg(opt), d); } + if (protocol.isEmpty()) + protocol = QLatin1String("PROTOCOL=TCPIP"); + + if (port < 0 ) + port = 50000; + QString connQStr; - connQStr = QLatin1String("DSN=") + db + QLatin1String(";UID=") + user + QLatin1String(";PWD=") - + password; + connQStr = protocol + QLatin1String(";DATABASE=") + db + QLatin1String(";HOSTNAME=") + host + + QLatin1String(";PORT=") + QString::number(port) + QLatin1String(";UID=") + user + + QLatin1String(";PWD=") + password; + + SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH]; SQLSMALLINT cb; @@ -1265,7 +1279,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas return false; } - d->user = user.toUpper(); + d->user = user; setOpen(true); setOpenError(false); return true; @@ -1310,10 +1324,25 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const SQLHANDLE hStmt; QString catalog, schema, table; - qSplitTableQualifier(tableName.toUpper(), &catalog, &schema, &table); + qSplitTableQualifier(tableName, &catalog, &schema, &table); if (schema.isEmpty()) schema = d->user; + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = catalog.toUpper(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toUpper(); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, d->hDbc, &hStmt); @@ -1327,6 +1356,9 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY, SQL_IS_UINTEGER); + + //Aside: szSchemaName and szTableName parameters of SQLColumns + //are case sensitive search patterns, so no escaping is used. r = SQLColumns(hStmt, NULL, 0, @@ -1407,7 +1439,13 @@ QStringList QDB2Driver::tables(QSql::TableType type) const bool isNull; QString fieldVal = qGetStringData(hStmt, 2, -1, isNull); QString userVal = qGetStringData(hStmt, 1, -1, isNull); - if (userVal != d->user) + QString user = d->user; + if ( isIdentifierEscaped(user, QSqlDriver::TableName)) + user = stripDelimiters(user, QSqlDriver::TableName); + else + user = user.toUpper(); + + if (userVal != user) fieldVal = userVal + QLatin1Char('.') + fieldVal; tl.append(fieldVal); r = SQLFetchScroll(hStmt, @@ -1438,7 +1476,23 @@ QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const return index; } QString catalog, schema, table; - qSplitTableQualifier(tablename.toUpper(), &catalog, &schema, &table); + qSplitTableQualifier(tablename, &catalog, &schema, &table); + + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = catalog.toUpper(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toUpper(); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + r = SQLSetStmtAttr(hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index 64f13b5..0705722 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -1552,12 +1552,16 @@ QSqlRecord QIBaseDriver::record(const QString& tablename) const QSqlQuery q(createResult()); q.setForwardOnly(true); - + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); q.exec(QLatin1String("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, " "b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG " "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b " "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE " - "AND a.RDB$RELATION_NAME = '") + tablename.toUpper() + QLatin1String("' " + "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' " "ORDER BY a.RDB$FIELD_POSITION")); while (q.next()) { @@ -1585,12 +1589,18 @@ QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const if (!isOpen()) return index; + QString tablename = table; + if (isIdentifierEscaped(tablename, QSqlDriver::TableName)) + tablename = stripDelimiters(tablename, QSqlDriver::TableName); + else + tablename = tablename.toUpper(); + QSqlQuery q(createResult()); q.setForwardOnly(true); q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE " "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d " "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' " - "AND a.RDB$RELATION_NAME = '") + table.toUpper() + + "AND a.RDB$RELATION_NAME = '") + tablename + QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME " "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME " "AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME " diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 9b57f3c..a84e840 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1314,7 +1314,7 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const QSqlQuery i(createResult()); QString stmt(QLatin1String("show index from %1;")); QSqlRecord fil = record(tablename); - i.exec(stmt.arg(escapeIdentifier(tablename, QSqlDriver::TableName))); + i.exec(stmt.arg(tablename)); while (i.isActive() && i.next()) { if (i.value(2).toString() == QLatin1String("PRIMARY")) { idx.append(fil.field(i.value(4).toString())); @@ -1329,10 +1329,14 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const QSqlRecord QMYSQLDriver::record(const QString& tablename) const { + QString table=tablename; + if(isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlRecord info; if (!isOpen()) return info; - MYSQL_RES* r = mysql_list_fields(d->mysql, tablename.toLocal8Bit().constData(), 0); + MYSQL_RES* r = mysql_list_fields(d->mysql, table.toLocal8Bit().constData(), 0); if (!r) { return info; } @@ -1443,4 +1447,15 @@ QString QMYSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType return res; } +bool QMYSQLDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const +{ + Q_UNUSED(type); + bool isLeftDelimited = (identifier.left(1) == QString(QLatin1Char('`'))); + bool isRightDelimited = (identifier.right(1) == QString(QLatin1Char('`'))); + if( identifier.size() > 2 && isLeftDelimited && isRightDelimited ) + return true; + else + return false; +} + QT_END_NAMESPACE diff --git a/src/sql/drivers/mysql/qsql_mysql.h b/src/sql/drivers/mysql/qsql_mysql.h index 97aa346..31d9dcf 100644 --- a/src/sql/drivers/mysql/qsql_mysql.h +++ b/src/sql/drivers/mysql/qsql_mysql.h @@ -123,6 +123,9 @@ public: QVariant handle() const; QString escapeIdentifier(const QString &identifier, IdentifierType type) const; +protected Q_SLOTS: + bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; + protected: bool beginTransaction(); bool commitTransaction(); diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index 7017d6c..fa9b5f0 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -2098,7 +2098,7 @@ bool QOCIDriver::open(const QString & db, setOpen(true); setOpenError(false); - d->user = user.toUpper(); + d->user = user; return true; } @@ -2200,8 +2200,15 @@ QStringList QOCIDriver::tables(QSql::TableType type) const "and owner != 'WKSYS'" "and owner != 'CTXSYS'" "and owner != 'WMSYS'")); + + QString user = d->user; + if ( isIdentifierEscaped(user, QSqlDriver::TableName)) + user = stripDelimiters(user, QSqlDriver::TableName); + else + user = user.toUpper(); + while (t.next()) { - if (t.value(0).toString() != d->user) + if (t.value(0).toString() != user) tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString()); else tl.append(t.value(1).toString()); @@ -2237,10 +2244,10 @@ void qSplitTableAndOwner(const QString & tname, QString * tbl, { int i = tname.indexOf(QLatin1Char('.')); // prefixed with owner? if (i != -1) { - *tbl = tname.right(tname.length() - i - 1).toUpper(); - *owner = tname.left(i).toUpper(); + *tbl = tname.right(tname.length() - i - 1); + *owner = tname.left(i); } else { - *tbl = tname.toUpper(); + *tbl = tname; } } @@ -2256,7 +2263,7 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const QString stmt(QLatin1String("select column_name, data_type, data_length, " "data_precision, data_scale, nullable, data_default%1" "from all_tab_columns " - "where upper(table_name)=%2")); + "where table_name=%2")); if (d->serverVersion >= 9) stmt = stmt.arg(QLatin1String(", char_length ")); else @@ -2264,11 +2271,23 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const bool buildRecordInfo = false; QString table, owner, tmpStmt; qSplitTableAndOwner(tablename, &table, &owner); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + tmpStmt = stmt.arg(QLatin1Char('\'') + table + QLatin1Char('\'')); if (owner.isEmpty()) { owner = d->user; } - tmpStmt += QLatin1String(" and upper(owner)='") + owner + QLatin1String("'"); + + if (isIdentifierEscaped(owner, QSqlDriver::TableName)) + owner = stripDelimiters(owner, QSqlDriver::TableName); + else + owner = owner.toUpper(); + + tmpStmt += QLatin1String(" and owner='") + owner + QLatin1String("'"); t.setForwardOnly(true); t.exec(tmpStmt); if (!t.next()) { // try and see if the tablename is a synonym @@ -2317,11 +2336,23 @@ QSqlIndex QOCIDriver::primaryIndex(const QString& tablename) const bool buildIndex = false; QString table, owner, tmpStmt; qSplitTableAndOwner(tablename, &table, &owner); - tmpStmt = stmt + QLatin1String(" and upper(a.table_name)='") + table + QLatin1String("'"); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + + tmpStmt = stmt + QLatin1String(" and a.table_name='") + table + QLatin1String("'"); if (owner.isEmpty()) { owner = d->user; } - tmpStmt += QLatin1String(" and upper(a.owner)='") + owner + QLatin1String("'"); + + if (isIdentifierEscaped(owner, QSqlDriver::TableName)) + owner = stripDelimiters(owner, QSqlDriver::TableName); + else + owner = owner.toUpper(); + + tmpStmt += QLatin1String(" and a.owner='") + owner + QLatin1String("'"); t.setForwardOnly(true); t.exec(tmpStmt); @@ -2415,13 +2446,14 @@ QVariant QOCIDriver::handle() const return qVariantFromValue(d->env); } -QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType /* type */) const +QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const { QString res = identifier; - res.replace(QLatin1Char('"'), QLatin1String("\"\"")); - if (identifier.indexOf(QLatin1Char(' ')) != -1) + if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type)) { + res.replace(QLatin1Char('"'), QLatin1String("\"\"")); res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); -// res.replace(QLatin1Char('.'), QLatin1String("\".\"")); + res.replace(QLatin1Char('.'), QLatin1String("\".\"")); + } return res; } diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index f6710db..71b1b2a 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -88,6 +88,7 @@ static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL class QODBCDriverPrivate { public: + enum DefaultCase{Lower, Mixed, Upper, Sensitive}; QODBCDriverPrivate() : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false), isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false) @@ -119,6 +120,9 @@ public: bool setConnectionOptions(const QString& connOpts); void splitTableQualifier(const QString &qualifier, QString &catalog, QString &schema, QString &table); + DefaultCase defaultCase() const; + QString adjustCase(const QString&) const; + QChar quoteChar() const; }; class QODBCPrivate @@ -555,6 +559,29 @@ static int qGetODBCVersion(const QString &connOpts) return SQL_OV_ODBC2; } +QChar QODBCDriverPrivate::quoteChar() const +{ + static bool isQuoteInitialized = false; + static QChar quote = QChar::fromLatin1('"'); + if (!isQuoteInitialized) { + char driverResponse[4]; + SQLUSMALLINT casing; + SQLSMALLINT length; + int r = SQLGetInfo(hDbc, + SQL_IDENTIFIER_QUOTE_CHAR, + &driverResponse, + sizeof(driverResponse), + &length); + if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { + quote = QChar::fromLatin1(driverResponse[0]); + } else { + quote = QChar::fromLatin1('"'); + } + isQuoteInitialized = true; + } + return quote; +} + bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts) { // Set any connection attributes @@ -705,6 +732,65 @@ void QODBCDriverPrivate::splitTableQualifier(const QString & qualifier, QString } } +QODBCDriverPrivate::DefaultCase QODBCDriverPrivate::defaultCase() const +{ + static bool isInitialized = false; + static DefaultCase ret; + + if (!isInitialized) { + SQLUSMALLINT casing; + int r = SQLGetInfo(hDbc, + SQL_IDENTIFIER_CASE, + &casing, + sizeof(casing), + NULL); + if ( r != SQL_SUCCESS) + ret = Lower;//arbitrary case if driver cannot be queried + else { + switch (casing) { + case (SQL_IC_UPPER): + ret = Upper; + break; + case (SQL_IC_LOWER): + ret = Lower; + break; + case (SQL_IC_SENSITIVE): + ret = Sensitive; + break; + case (SQL_IC_MIXED): + ret = Mixed; + break; + default: + ret = Upper; + } + } + isInitialized = true; + } + return ret; +} + +/* + Adjust the casing of an identifier to match what the + database engine would have done to it. +*/ +QString QODBCDriverPrivate::adjustCase(const QString &identifier) const +{ + QString ret = identifier; + switch(defaultCase()) { + case (Lower): + ret = identifier.toLower(); + break; + case (Upper): + ret = identifier.toUpper(); + break; + case(Mixed): + case(Sensitive): + default: + ret = identifier; + } + return ret; +} + //////////////////////////////////////////////////////////////////////////// QODBCResult::QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p) @@ -2084,6 +2170,22 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const } QString catalog, schema, table; d->splitTableQualifier(tablename, catalog, schema, table); + + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = d->adjustCase(catalog); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = d->adjustCase(schema); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = d->adjustCase(table); + r = SQLSetStmtAttr(hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, @@ -2186,6 +2288,22 @@ QSqlRecord QODBCDriver::record(const QString& tablename) const SQLHANDLE hStmt; QString catalog, schema, table; d->splitTableQualifier(tablename, catalog, schema, table); + + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = d->adjustCase(catalog); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = d->adjustCase(schema); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = d->adjustCase(table); + SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, d->hDbc, &hStmt); @@ -2309,4 +2427,15 @@ QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType) return res; } +bool QODBCDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType) const +{ + QString quote = d->quoteChar(); + bool isLeftDelimited = identifier.left(1) == quote; + bool isRightDelimited = identifier.right(1) == quote; + if( identifier.size() > 2 && isLeftDelimited && isRightDelimited ) + return true; + else + return false; +} + QT_END_NAMESPACE diff --git a/src/sql/drivers/odbc/qsql_odbc.h b/src/sql/drivers/odbc/qsql_odbc.h index 4148007..51f53ea 100644 --- a/src/sql/drivers/odbc/qsql_odbc.h +++ b/src/sql/drivers/odbc/qsql_odbc.h @@ -145,10 +145,14 @@ public: QString escapeIdentifier(const QString &identifier, IdentifierType type) const; +protected Q_SLOTS: + bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; + protected: bool beginTransaction(); bool commitTransaction(); bool rollbackTransaction(); + private: void init(); bool endTrans(); diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index afe45fc..16d19f1 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -894,6 +894,16 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const QString schema; qSplitTableName(tbl, schema); + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + tbl = stripDelimiters(tbl, QSqlDriver::TableName); + else + tbl = tbl.toLower(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toLower(); + switch(d->pro) { case QPSQLDriver::Version6: stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname " @@ -926,7 +936,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const "FROM pg_attribute, pg_class " "WHERE %1 pg_class.oid IN " "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN " - " (SELECT oid FROM pg_class WHERE lower(relname) = '%2')) " + " (SELECT oid FROM pg_class WHERE relname = '%2')) " "AND pg_attribute.attrelid = pg_class.oid " "AND pg_attribute.attisdropped = false " "ORDER BY pg_attribute.attnum"); @@ -934,11 +944,11 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND")); else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema.toLower())); + "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema)); break; } - i.exec(stmt.arg(tbl.toLower())); + i.exec(stmt.arg(tbl)); while (i.isActive() && i.next()) { QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt())); idx.append(f); @@ -957,6 +967,16 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const QString schema; qSplitTableName(tbl, schema); + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + tbl = stripDelimiters(tbl, QSqlDriver::TableName); + else + tbl = tbl.toLower(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toLower(); + QString stmt; switch(d->pro) { case QPSQLDriver::Version6: @@ -1001,7 +1021,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "left join pg_attrdef on (pg_attrdef.adrelid = " "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) " "where %1 " - "and lower(pg_class.relname) = '%2' " + "and pg_class.relname = '%2' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid " "and pg_attribute.attisdropped = false " @@ -1010,12 +1030,12 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)")); else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1')").arg(schema.toLower())); + "pg_namespace where pg_namespace.nspname = '%1')").arg(schema)); break; } QSqlQuery query(createResult()); - query.exec(stmt.arg(tbl.toLower())); + query.exec(stmt.arg(tbl)); if (d->pro >= QPSQLDriver::Version71) { while (query.next()) { int len = query.value(3).toInt(); diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 605c4e8..f732077 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -661,9 +661,13 @@ QSqlIndex QSQLiteDriver::primaryIndex(const QString &tblname) const if (!isOpen()) return QSqlIndex(); + QString table = tblname; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlQuery q(createResult()); q.setForwardOnly(true); - return qGetTableInfo(q, tblname, true); + return qGetTableInfo(q, table, true); } QSqlRecord QSQLiteDriver::record(const QString &tbl) const @@ -671,9 +675,13 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const if (!isOpen()) return QSqlRecord(); + QString table = tbl; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlQuery q(createResult()); q.setForwardOnly(true); - return qGetTableInfo(q, tbl); + return qGetTableInfo(q, table); } QVariant QSQLiteDriver::handle() const @@ -681,10 +689,10 @@ QVariant QSQLiteDriver::handle() const return qVariantFromValue(d->access); } -QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType /*type*/) const +QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const { QString res = identifier; - if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) { + if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type) ) { res.replace(QLatin1Char('"'), QLatin1String("\"\"")); res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); res.replace(QLatin1Char('.'), QLatin1String("\".\"")); diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp index ff73caa..d0c6e18 100644 --- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp +++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp @@ -167,7 +167,15 @@ void QSQLite2ResultPrivate::init(const char **cnames, int numCols) for (int i = 0; i < numCols; ++i) { const char* lastDot = strrchr(cnames[i], '.'); const char* fieldName = lastDot ? lastDot + 1 : cnames[i]; - rInf.append(QSqlField(QString::fromAscii(fieldName), + + //remove quotations around the field name if any + QString fieldStr = QString::fromAscii(fieldName); + QString quote = QString::fromLatin1("\""); + if ( fieldStr.length() > 2 && fieldStr.left(1) == quote && fieldStr.right(1) == quote) { + fieldStr = fieldStr.mid(1); + fieldStr.chop(1); + } + rInf.append(QSqlField(fieldStr, nameToType(QString::fromAscii(cnames[i+numCols])))); } } @@ -503,8 +511,11 @@ QSqlIndex QSQLite2Driver::primaryIndex(const QString &tblname) const QSqlQuery q(createResult()); q.setForwardOnly(true); + QString table = tblname; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); // finrst find a UNIQUE INDEX - q.exec(QLatin1String("PRAGMA index_list('") + tblname + QLatin1String("');")); + q.exec(QLatin1String("PRAGMA index_list('") + table + QLatin1String("');")); QString indexname; while(q.next()) { if (q.value(2).toInt()==1) { @@ -517,7 +528,7 @@ QSqlIndex QSQLite2Driver::primaryIndex(const QString &tblname) const q.exec(QLatin1String("PRAGMA index_info('") + indexname + QLatin1String("');")); - QSqlIndex index(tblname, indexname); + QSqlIndex index(table, indexname); while(q.next()) { QString name = q.value(2).toString(); QVariant::Type type = QVariant::Invalid; @@ -532,6 +543,9 @@ QSqlRecord QSQLite2Driver::record(const QString &tbl) const { if (!isOpen()) return QSqlRecord(); + QString table = tbl; + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); QSqlQuery q(createResult()); q.setForwardOnly(true); diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp index 46e4a0b..515f0de 100644 --- a/src/sql/drivers/tds/qsql_tds.cpp +++ b/src/sql/drivers/tds/qsql_tds.cpp @@ -293,6 +293,8 @@ QTDSResult::QTDSResult(const QTDSDriver* db) // insert d in error handler dict errs()->insert(d->dbproc, d); + dbcmd(d->dbproc, "set quoted_identifier on"); + dbsqlexec(d->dbproc); } QTDSResult::~QTDSResult() @@ -367,7 +369,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index) if (qIsNull(d->buffer.at(i * 2 + 1))) values[idx] = QVariant(QVariant::String); else - values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)); + values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed(); break; case QVariant::ByteArray: { if (qIsNull(d->buffer.at(i * 2 + 1))) @@ -698,9 +700,14 @@ QSqlRecord QTDSDriver::record(const QString& tablename) const return info; QSqlQuery t(createResult()); t.setForwardOnly(true); + + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QString stmt (QLatin1String("select name, type, length, prec from syscolumns " "where id = (select id from sysobjects where name = '%1')")); - t.exec(stmt.arg(tablename)); + t.exec(stmt.arg(table)); while (t.next()) { QSqlField f(t.value(0).toString().simplified(), qDecodeTDSType(t.value(1).toInt())); f.setLength(t.value(2).toInt()); @@ -770,13 +777,17 @@ QSqlIndex QTDSDriver::primaryIndex(const QString& tablename) const { QSqlRecord rec = record(tablename); - QSqlIndex idx(tablename); - if ((!isOpen()) || (tablename.isEmpty())) + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + + QSqlIndex idx(table); + if ((!isOpen()) || (table.isEmpty())) return QSqlIndex(); QSqlQuery t(createResult()); t.setForwardOnly(true); - t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(tablename)); + t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table)); if (t.next()) { QStringList fNames = t.value(2).toString().simplified().split(QLatin1Char(',')); QRegExp regx(QLatin1String("\\s*(\\S+)(?:\\s+(DESC|desc))?\\s*")); diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp index a995005..40bc0df 100644 --- a/src/sql/kernel/qsqldriver.cpp +++ b/src/sql/kernel/qsqldriver.cpp @@ -49,6 +49,17 @@ QT_BEGIN_NAMESPACE +static QString prepareIdentifier(const QString &identifier, + QSqlDriver::IdentifierType type, const QSqlDriver *driver) +{ + Q_ASSERT( driver != NULL ); + QString ret = identifier; + if (!driver->isIdentifierEscaped(identifier, type)) { + ret = driver->escapeIdentifier(identifier, type); + } + return ret; +} + class QSqlDriverPrivate : public QObjectPrivate { public: @@ -372,6 +383,7 @@ QSqlRecord QSqlDriver::record(const QString & /* tableName */) const on \a type. The default implementation does nothing. + \sa isIdentifierEscaped() */ QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const { @@ -379,6 +391,55 @@ QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) } /*! + Returns whether \a identifier is escaped according to the database rules. + \a identifier can either be a table name or field name, dependent + on \a type. + + \warning Because of binary compatability constraints, this function is not virtual. + If you want to provide your own implementation in your QSqlDriver subclass, + reimplement the isIdentifierEscapedImplementation() slot in your subclass instead. + The isIdentifierEscapedFunction() will dynamically detect the slot and call it. + + \sa stripDelimiters(), escapeIdentifier() + */ +bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType type) const +{ + bool result; + QMetaObject::invokeMethod(const_cast(this), + "isIdentifierEscapedImplementation", Qt::DirectConnection, + Q_RETURN_ARG(bool, result), + Q_ARG(QString, identifier), + Q_ARG(IdentifierType, type)); + return result; +} + +/*! + Returns the \a identifier with the leading and trailing delimiters removed, + \a identifier can either be a table name or field name, + dependent on \a type. If \a identifier does not have leading + and trailing delimiter characters, \a identifier is returned without + modification. + + \warning Because of binary compatability constraints, this function is not virtual, + If you want to provide your own implementation in your QSqlDriver subclass, + reimplement the stripDelimitersImplementation() slot in your subclass instead. + The stripDelimiters() function will dynamically detect the slot and call it. + + \since 4.5 + \sa isIdentifierEscaped() + */ +QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const +{ + QString result; + QMetaObject::invokeMethod(const_cast(this), + "stripDelimitersImplementation", Qt::DirectConnection, + Q_RETURN_ARG(QString, result), + Q_ARG(QString, identifier), + Q_ARG(IdentifierType, type)); + return result; +} + +/*! Returns a SQL statement of type \a type for the table \a tableName with the values from \a rec. If \a preparedStatement is true, the string will contain placeholders instead of values. @@ -397,17 +458,17 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, case SelectStatement: for (i = 0; i < rec.count(); ++i) { if (rec.isGenerated(i)) - s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", ")); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); } if (s.isEmpty()) return s; s.chop(2); - s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(escapeIdentifier(tableName, TableName)); + s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName); break; case WhereStatement: if (preparedStatement) { for (int i = 0; i < rec.count(); ++i) { - s.append(escapeIdentifier(rec.fieldName(i), FieldName)); + s.append(prepareIdentifier(rec.fieldName(i), FieldName,this)); if (rec.isNull(i)) s.append(QLatin1String(" IS NULL")); else @@ -416,7 +477,7 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, } } else { for (i = 0; i < rec.count(); ++i) { - s.append(escapeIdentifier(rec.fieldName(i), FieldName)); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)); QString val = formatValue(rec.field(i)); if (val == QLatin1String("NULL")) s.append(QLatin1String(" IS NULL")); @@ -431,12 +492,12 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, } break; case UpdateStatement: - s.append(QLatin1String("UPDATE ")).append(escapeIdentifier(tableName, TableName)).append( + s.append(QLatin1String("UPDATE ")).append(tableName).append( QLatin1String(" SET ")); for (i = 0; i < rec.count(); ++i) { if (!rec.isGenerated(i) || !rec.value(i).isValid()) continue; - s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1Char('=')); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1Char('=')); if (preparedStatement) s.append(QLatin1Char('?')); else @@ -449,15 +510,15 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, s.clear(); break; case DeleteStatement: - s.append(QLatin1String("DELETE FROM ")).append(escapeIdentifier(tableName, TableName)); + s.append(QLatin1String("DELETE FROM ")).append(tableName); break; case InsertStatement: { - s.append(QLatin1String("INSERT INTO ")).append(escapeIdentifier(tableName, TableName)).append(QLatin1String(" (")); + s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" (")); QString vals; for (i = 0; i < rec.count(); ++i) { if (!rec.isGenerated(i) || !rec.value(i).isValid()) continue; - s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", ")); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); if (preparedStatement) vals.append(QLatin1String("?")); else @@ -805,4 +866,56 @@ QStringList QSqlDriver::subscribedToNotificationsImplementation() const return QStringList(); } +/*! + This slot returns whether \a identifier is escaped according to the database rules. + \a identifier can either be a table name or field name, dependent + on \a type. + + Because of binary compatability constraints, isIdentifierEscaped() function + (introduced in Qt 4.5) is not virtual. Instead, isIdentifierEscaped() will + dynamically detect and call \e this slot. The default implementation + assumes the escape/delimiter character is a double quote. Reimplement this + slot in your own QSqlDriver if your database engine uses a different + delimiter character. + + \since 4.5 + \sa isIdentifierEscaped() + */ +bool QSqlDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const +{ + Q_UNUSED(type); + bool isLeftDelimited = identifier.left(1) == QString(QLatin1Char('"')); + bool isRightDelimited = identifier.right(1) == QString(QLatin1Char('"')); + if( identifier.size() > 2 && isLeftDelimited && isRightDelimited ) + return true; + else + return false; +} + +/*! + This slot returns \a identifier with the leading and trailing delimiters removed, + \a identifier can either be a tablename or field name, dependent on \a type. + If \a identifier does not have leading and trailing delimiter characters, \a + identifier is returned without modification. + + Because of binary compatability constraints, the stripDelimiters() function + (introduced in Qt 4.5) is not virtual. Instead, stripDelimiters() will + dynamically detect and call \e this slot. It generally unnecessary + to reimplement this slot. + + \since 4.5 + \sa stripDelimiters() + */ +QString QSqlDriver::stripDelimitersImplementation(const QString &identifier, IdentifierType type) const +{ + QString ret; + if (this->isIdentifierEscaped(identifier, type)) { + ret = identifier.mid(1); + ret.chop(1); + } else { + ret = identifier; + } + return ret; +} + QT_END_NAMESPACE diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h index e763719..8ac1471 100644 --- a/src/sql/kernel/qsqldriver.h +++ b/src/sql/kernel/qsqldriver.h @@ -127,6 +127,9 @@ public: bool unsubscribeFromNotification(const QString &name); // ### Qt 5: make virtual QStringList subscribedToNotifications() const; // ### Qt 5: make virtual + bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual + QString stripDelimiters(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual + Q_SIGNALS: void notification(const QString &name); @@ -140,6 +143,9 @@ protected Q_SLOTS: bool unsubscribeFromNotificationImplementation(const QString &name); // ### Qt 5: eliminate, see unsubscribeFromNotification() QStringList subscribedToNotificationsImplementation() const; // ### Qt 5: eliminate, see subscribedNotifications() + bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; // ### Qt 5: eliminate, see isIdentifierEscaped() + QString stripDelimitersImplementation(const QString &identifier, IdentifierType type) const; // ### Qt 5: eliminate, see stripDelimiters() + private: Q_DISABLE_COPY(QSqlDriver) }; diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp index 935466b..12eae84 100644 --- a/src/sql/models/qsqlrelationaltablemodel.cpp +++ b/src/sql/models/qsqlrelationaltablemodel.cpp @@ -182,10 +182,21 @@ void QRelation::populateDictionary() populateModel(); QSqlRecord record; + QString indexColumn; + QString displayColumn; for (int i=0; i < model->rowCount(); ++i) { record = model->record(i); - dictionary[record.field(rel.indexColumn()).value().toString()] = - record.field(rel.displayColumn()).value(); + + indexColumn = rel.indexColumn(); + if (m_parent->database().driver()->isIdentifierEscaped(indexColumn, QSqlDriver::FieldName)) + indexColumn = m_parent->database().driver()->stripDelimiters(indexColumn, QSqlDriver::FieldName); + + displayColumn = rel.displayColumn(); + if (m_parent->database().driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName)) + displayColumn = m_parent->database().driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName); + + dictionary[record.field(indexColumn).value().toString()] = + record.field(displayColumn).value(); } m_dictInitialized = true; } @@ -215,7 +226,7 @@ public: QSqlRelationalTableModelPrivate() : QSqlTableModelPrivate() {} - QString escapedRelationField(const QString &tableName, const QString &fieldName) const; + QString relationField(const QString &tableName, const QString &fieldName) const; int nameToIndex(const QString &name) const; mutable QVector relations; @@ -255,7 +266,10 @@ void QSqlRelationalTableModelPrivate::revertCachedRow(int row) int QSqlRelationalTableModelPrivate::nameToIndex(const QString &name) const { - return baseRec.indexOf(name); + QString fieldname = name; + if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName)) + fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName); + return baseRec.indexOf(fieldname); } void QSqlRelationalTableModelPrivate::clearEditBuffer() @@ -481,14 +495,14 @@ QSqlRelation QSqlRelationalTableModel::relation(int column) const return d->relations.value(column).rel; } -QString QSqlRelationalTableModelPrivate::escapedRelationField(const QString &tableName, +QString QSqlRelationalTableModelPrivate::relationField(const QString &tableName, const QString &fieldName) const { - QString esc; - esc.reserve(tableName.size() + fieldName.size() + 1); - esc.append(tableName).append(QLatin1Char('.')).append(fieldName); + QString ret; + ret.reserve(tableName.size() + fieldName.size() + 1); + ret.append(tableName).append(QLatin1Char('.')).append(fieldName); - return db.driver()->escapeIdentifier(esc, QSqlDriver::FieldName); + return ret; } /*! @@ -514,15 +528,29 @@ QString QSqlRelationalTableModel::selectStatement() const // Count how many times each field name occurs in the record QHash fieldNames; + QStringList fieldList; for (int i = 0; i < rec.count(); ++i) { QSqlRelation relation = d->relations.value(i, nullRelation).rel; QString name; if (relation.isValid()) + { // Count the display column name, not the original foreign key name = relation.displayColumn(); + if (d->db.driver()->isIdentifierEscaped(name, QSqlDriver::FieldName)) + name = d->db.driver()->stripDelimiters(name, QSqlDriver::FieldName); + + QSqlRecord rec = database().record(relation.tableName()); + for (int i = 0; i < rec.count(); ++i) { + if (name.compare(rec.fieldName(i), Qt::CaseInsensitive) == 0) { + name = rec.fieldName(i); + break; + } + } + } else name = rec.fieldName(i); fieldNames.insert(name, fieldNames.value(name, 0) + 1); + fieldList.append(name); } for (int i = 0; i < rec.count(); ++i) { @@ -531,27 +559,30 @@ QString QSqlRelationalTableModel::selectStatement() const QString relTableAlias = QString::fromLatin1("relTblAl_%1").arg(i); if (!fList.isEmpty()) fList.append(QLatin1String(", ")); - fList.append(d->escapedRelationField(relTableAlias, relation.displayColumn())); + fList.append(d->relationField(relTableAlias,relation.displayColumn())); // If there are duplicate field names they must be aliased - if (fieldNames.value(relation.displayColumn()) > 1) { - fList.append(QString::fromLatin1(" AS %1_%2").arg(relation.tableName()).arg(relation.displayColumn())); + if (fieldNames.value(fieldList[i]) > 1) { + QString relTableName = relation.tableName(); + if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName)) + relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName); + QString displayColumn = relation.displayColumn(); + if (d->db.driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName)) + displayColumn = d->db.driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName); + fList.append(QString::fromLatin1(" AS %1_%2").arg(relTableName).arg(displayColumn)); } // this needs fixing!! the below if is borken. - if (!tables.contains(relation.tableName())) - tables.append(d->db.driver()->escapeIdentifier(relation.tableName(),QSqlDriver::TableName) - .append(QLatin1String(" ")) - .append(d->db.driver()->escapeIdentifier(relTableAlias, QSqlDriver::TableName))); + tables.append(relation.tableName().append(QLatin1String(" ")).append(relTableAlias)); if(!where.isEmpty()) where.append(QLatin1String(" AND ")); - where.append(d->escapedRelationField(tableName(), rec.fieldName(i))); + where.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName))); where.append(QLatin1String(" = ")); - where.append(d->escapedRelationField(relTableAlias, relation.indexColumn())); + where.append(d->relationField(relTableAlias, relation.indexColumn())); } else { if (!fList.isEmpty()) fList.append(QLatin1String(", ")); - fList.append(d->escapedRelationField(tableName(), rec.fieldName(i))); + fList.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName))); } } if (!tables.isEmpty()) @@ -560,7 +591,7 @@ QString QSqlRelationalTableModel::selectStatement() const return query; if(!tList.isEmpty()) tList.prepend(QLatin1String(", ")); - tList.prepend(d->db.driver()->escapeIdentifier(tableName(),QSqlDriver::TableName)); + tList.prepend(tableName()); query.append(QLatin1String("SELECT ")); query.append(fList).append(QLatin1String(" FROM ")).append(tList); qAppendWhereClause(query, where, filter()); @@ -690,7 +721,7 @@ QString QSqlRelationalTableModel::orderByClause() const return QSqlTableModel::orderByClause(); QString s = QLatin1String("ORDER BY "); - s.append(d->escapedRelationField(QLatin1String("relTblAl_") + QString::number(d->sortColumn), + s.append(d->relationField(QLatin1String("relTblAl_") + QString::number(d->sortColumn), rel.displayColumn())); s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC"); return s; diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 2fb9b0f..c2442c5 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -98,7 +98,10 @@ bool QSqlTableModelPrivate::setRecord(int row, const QSqlRecord &record) int QSqlTableModelPrivate::nameToIndex(const QString &name) const { - return rec.indexOf(name); + QString fieldname = name; + if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName)) + fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName); + return rec.indexOf(fieldname); } void QSqlTableModelPrivate::initRecordAndPrimaryIndex() @@ -367,10 +370,7 @@ void QSqlTableModel::setTable(const QString &tableName) { Q_D(QSqlTableModel); clear(); - if(d->db.tables().contains(tableName.toUpper())) - d->tableName = tableName.toUpper(); - else - d->tableName = tableName; + d->tableName = tableName; d->initRecordAndPrimaryIndex(); d->initColOffsets(d->rec.count()); @@ -976,7 +976,9 @@ QString QSqlTableModel::orderByClause() const if (!f.isValid()) return s; - QString table = d->db.driver()->escapeIdentifier(d->tableName, QSqlDriver::TableName); + QString table = d->tableName; + //we can safely escape the field because it would have been obtained from the database + //and have the correct case QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName); s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field); s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC"); @@ -1317,8 +1319,12 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) mrow.rec = d->rec; mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row()); } + QString fieldName; for (int i = 0; i < record.count(); ++i) { - int idx = mrow.rec.indexOf(record.fieldName(i)); + fieldName = record.fieldName(i); + if (d->db.driver()->isIdentifierEscaped(fieldName, QSqlDriver::FieldName)) + fieldName = d->db.driver()->stripDelimiters(fieldName, QSqlDriver::FieldName); + int idx = mrow.rec.indexOf(fieldName); if (idx == -1) isOk = false; else diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index 9c19048..611077f 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -105,11 +105,7 @@ inline static QString qTableName( const QString& prefix, QSqlDriver* driver = 0 inline static bool testWhiteSpaceNames( const QString &name ) { -/* return name.startsWith( "QPSQL" ) - || name.startsWith( "QODBC" ) - || name.startsWith( "QSQLITE" ) - || name.startsWith( "QMYSQL" );*/ - return name != QLatin1String("QSQLITE2"); + return name != QLatin1String("QTDS7"); } inline static QString toHex( const QString& binary ) @@ -211,7 +207,7 @@ public: // This requires a local ODBC data source to be configured( pointing to a MySql database ) // addDb( "QODBC", "mysqlodbc", "troll", "trond" ); // addDb( "QODBC", "SqlServer", "troll", "trond" ); -// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead.nokia.troll.no" ); +// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead" ); // addDb( "QODBC", "silencetestdb", "troll", "trond", "silence" ); // addDb( "QODBC", "horseheadtestdb", "troll", "trondk", "horsehead" ); @@ -221,7 +217,7 @@ public: // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux // addDb( "QMYSQL3", "testdb", "troll", "trond", "iceblink.nokia.troll.no" ); // MySQL 5.0.13 Windows // addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql4-nokia.trolltech.com.au" ); // MySQL 4.1.22-2.el4 linux -// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux +// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux // addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no" ); // V7.2 NOT SUPPORTED! // addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte @@ -242,12 +238,15 @@ public: // addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1 // use in-memory database to prevent local files -// addDb("QSQLITE", ":memory:"); - addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); + addDb("QSQLITE", ":memory:"); +// addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); // addDb( "QSQLITE2", QDir::toNativeSeparators(QDir::tempPath()+"/foo2.db") ); // addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.nokia.troll.no\\ICEBLINK", "troll", "trond", "" ); // addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" ); +// addDb( "QODBC", "DRIVER={MySQL ODBC 3.51 Driver};SERVER=mysql5-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" ); + } void open() @@ -313,16 +312,18 @@ public: QSqlQuery q( db ); QStringList dbtables=db.tables(); - foreach(const QString &tableName, tableNames) { + foreach(QString tableName, tableNames) + { wasDropped = true; - foreach(const QString dbtablesName, dbtables) { - if(dbtablesName.toUpper() == tableName.toUpper()) { - dbtables.removeAll(dbtablesName); - wasDropped = q.exec("drop table " + db.driver()->escapeIdentifier( dbtablesName, QSqlDriver::TableName )); - if(!wasDropped) - wasDropped = q.exec("drop table " + dbtablesName); - } - } + QString table=tableName; + if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName)) + table = db.driver()->stripDelimiters(table, QSqlDriver::TableName); + + if ( dbtables.contains( table, Qt::CaseSensitive ) ) + wasDropped = q.exec( "drop table " + tableName); + else if ( dbtables.contains( table, Qt::CaseInsensitive ) ) + wasDropped = q.exec( "drop table " + tableName); + if ( !wasDropped ) qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError().text() << "tables:" << dbtables; } diff --git a/tests/auto/qsqldriver/qsqldriver.pro b/tests/auto/qsqldriver/qsqldriver.pro new file mode 100644 index 0000000..0024841 --- /dev/null +++ b/tests/auto/qsqldriver/qsqldriver.pro @@ -0,0 +1,16 @@ +load(qttest_p4) +SOURCES += tst_qsqldriver.cpp + +QT += sql + +wince*: { + plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.path = . + DEPLOYMENT += plugFiles +} else { + win32-g++ { + LIBS += -lws2_32 + } else:win32 { + LIBS += ws2_32.lib + } +} diff --git a/tests/auto/qsqldriver/tst_qsqldriver.cpp b/tests/auto/qsqldriver/tst_qsqldriver.cpp new file mode 100644 index 0000000..bbd7483 --- /dev/null +++ b/tests/auto/qsqldriver/tst_qsqldriver.cpp @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include + +#include "../qsqldatabase/tst_databases.h" + + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QSqlDriver : public QObject +{ + Q_OBJECT + +public: + void recreateTestTables(QSqlDatabase); + + tst_Databases dbs; + +public slots: + void initTestCase_data(); + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void record(); + void primaryIndex(); +}; + + +void tst_QSqlDriver::initTestCase_data() +{ + dbs.open(); + if (dbs.fillTestTable() == 0) { + qWarning("NO DATABASES"); + QSKIP("No database drivers are available in this Qt configuration", SkipAll); + } +} + +void tst_QSqlDriver::recreateTestTables(QSqlDatabase db) +{ + QSqlQuery q(db); + + QStringList tableNames; + tableNames << qTableName( "relTEST1" ); + tst_Databases::safeDropTables( db, tableNames ); + + QVERIFY_SQL( q, exec("create table " + qTableName("relTEST1") + + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(1, 'harry', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(2, 'trond', 2, 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(3, 'vohi', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(4, 'boris', 2, 2)")); +} + +void tst_QSqlDriver::initTestCase() +{ + foreach (const QString &dbname, dbs.dbNames) + recreateTestTables(QSqlDatabase::database(dbname)); +} + +void tst_QSqlDriver::cleanupTestCase() +{ + QStringList tableNames; + tableNames << qTableName( "relTEST1" ); + foreach (const QString &dbName, dbs.dbNames) { + QSqlDatabase db = QSqlDatabase::database(dbName); + tst_Databases::safeDropTables( db, tableNames ); + } + dbs.close(); +} + +void tst_QSqlDriver::init() +{ +} + +void tst_QSqlDriver::cleanup() +{ +} + +void tst_QSqlDriver::record() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QString tablename = qTableName("relTEST1"); + QStringList fields; + fields << "id" << "name" << "title_key" << "another_title_key"; + + //check we can get records using an unquoted mixed case table name + QSqlRecord rec = db.driver()->record(tablename); + QCOMPARE(rec.count(), 4); + + if (db.driverName().startsWith("QIBASE")|| db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + for(int i = 0; i < fields.count(); ++i) + fields[i] = fields[i].toUpper(); + + for (int i = 0; i < fields.count(); ++i) + QCOMPARE(rec.fieldName(i), fields[i]); + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toUpper(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toLower(); + + //check we can get records using a properly quoted table name + rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); + QCOMPARE(rec.count(), 4); + + for (int i = 0; i < fields.count(); ++i) + QCOMPARE(rec.fieldName(i), fields[i]); + + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toLower(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toUpper(); + + //check that we can't get records using incorrect tablename casing that's been quoted + rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); + if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + QCOMPARE(rec.count(), 4); //mysql, sqlite and tds will match + else + QCOMPARE(rec.count(), 0); + +} + +void tst_QSqlDriver::primaryIndex() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QString tablename = qTableName("relTEST1"); + //check that we can get primary index using unquoted mixed case table name + QSqlIndex index = db.driver()->primaryIndex(tablename); + QCOMPARE(index.count(), 1); + + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); + else + QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); + + + //check that we can get the primary index using a quoted tablename + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toUpper(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toLower(); + + index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); + QCOMPARE(index.count(), 1); + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); + else + QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); + + + + //check that we can not get the primary index using a quoted but incorrect table name casing + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toLower(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toUpper(); + + index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); + if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing + else + QCOMPARE(index.count(), 0); +} + +QTEST_MAIN(tst_QSqlDriver) +#include "tst_qsqldriver.moc" diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 76785c3..bb2cddd 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -82,6 +82,10 @@ private slots: void insertRecordDuplicateFieldNames(); void invalidData(); void relationModel(); + void casing(); + void escapedRelations(); + void escapedTableName(); + void whiteSpaceInIdentifiers(); }; @@ -103,7 +107,9 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) << qTableName( "reltest2" ) << qTableName( "reltest3" ) << qTableName( "reltest4" ) - << qTableName( "reltest5" ); + << qTableName( "reltest5" ) + << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName) + << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName); tst_Databases::safeDropTables( db, tableNames ); QVERIFY_SQL( q, exec("create table " + qTableName("reltest1") + @@ -128,6 +134,19 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) QVERIFY_SQL( q, exec("create table " + qTableName("reltest5") + " (title varchar(20) not null primary key, abbrev varchar(20))")); QVERIFY_SQL( q, exec("insert into " + qTableName("reltest5") + " values('herr', 'Hr')")); QVERIFY_SQL( q, exec("insert into " + qTableName("reltest5") + " values('mister', 'Mr')")); + + if (testWhiteSpaceNames(db.driverName())) { + QString reltest6 = db.driver()->escapeIdentifier(qTableName("rel test6"), QSqlDriver::TableName); + QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName) + + " int, " + db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName) + " int)")); + QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)")); + QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)")); + + QString reltest7 = db.driver()->escapeIdentifier(qTableName("rel test7"), QSqlDriver::TableName); + QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + db.driver()->escapeIdentifier("city id", QSqlDriver::TableName) + " int not null primary key, " + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName) + " varchar(20))")); + QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')")); + QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')")); + } } void tst_QSqlRelationalTableModel::initTestCase() @@ -142,10 +161,14 @@ void tst_QSqlRelationalTableModel::cleanupTestCase() tableNames << qTableName( "reltest1" ) << qTableName( "reltest2" ) << qTableName( "reltest3" ) - << qTableName( "reltest4" ); + << qTableName( "reltest4" ) + << qTableName( "reltest5" ); foreach (const QString &dbName, dbs.dbNames) { QSqlDatabase db = QSqlDatabase::database(dbName); - tst_Databases::safeDropTables( db, tableNames ); + QStringList tables = tableNames; + tables << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName) + << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName); + tst_Databases::safeDropTables( db, tables ); } dbs.close(); } @@ -273,7 +296,12 @@ void tst_QSqlRelationalTableModel::setData() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + //sybase doesn't allow tables with the same alias used twice as col names + //so don't set up an identical relation when using the tds driver + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setEditStrategy(QSqlTableModel::OnManualSubmit); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -284,7 +312,10 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi2")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); QVERIFY_SQL(model, submitAll()); } @@ -299,10 +330,15 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); } //check setting of data when the relational key is a non-integer type @@ -336,7 +372,8 @@ void tst_QSqlRelationalTableModel::multipleRelation() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(2, 0)).toInt(), 3); @@ -344,7 +381,7 @@ void tst_QSqlRelationalTableModel::multipleRelation() QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("Trondheim")); } void tst_QSqlRelationalTableModel::insertRecord() @@ -357,6 +394,7 @@ void tst_QSqlRelationalTableModel::insertRecord() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QSqlRecord rec; @@ -398,6 +436,7 @@ void tst_QSqlRelationalTableModel::setRecord() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QSqlRecord rec; @@ -450,13 +489,18 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); model.insertRows(0, 1); model.setData(model.index(0, 0), 1011); @@ -467,12 +511,20 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1011); QCOMPARE(model.data(model.index(0,1)).toString(), QString("test")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 1); QCOMPARE(model.data(model.index(1,0)).toInt(), 1); QCOMPARE(model.data(model.index(1,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(1,3)).toInt(), 2); + + QVERIFY_SQL(model, submitAll()); @@ -481,9 +533,16 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); - model.setData(model.index(0,3),1); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + + if (!db.driverName().startsWith("QTDS")) { + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + model.setData(model.index(0,3),1); + QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + } else { + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); + model.setData(model.index(0,3),1); + QCOMPARE(model.data(model.index(0,3)).toInt(), 1); + } model.insertRows(0, 2); model.setData(model.index(0, 0), 1012); @@ -499,17 +558,27 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(),1012); QCOMPARE(model.data(model.index(0,1)).toString(), QString("george")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); + QCOMPARE(model.data(model.index(1,0)).toInt(),1013); QCOMPARE(model.data(model.index(1,1)).toString(), QString("kramer")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(1,3)).toInt(), 1); QCOMPARE(model.data(model.index(2,0)).toInt(), 1); QCOMPARE(model.data(model.index(2,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(2,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(2,3)).toInt(), 1); QVERIFY_SQL(model, submitAll()); } @@ -574,7 +643,8 @@ void tst_QSqlRelationalTableModel::sort() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); model.setSort(2, Qt::DescendingOrder); QVERIFY_SQL(model, select()); @@ -589,11 +659,19 @@ void tst_QSqlRelationalTableModel::sort() model.setSort(3, Qt::AscendingOrder); QVERIFY_SQL(model, select()); - QCOMPARE(model.rowCount(), 4); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) { + QCOMPARE(model.rowCount(), 4); + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + } else { + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); + QCOMPARE(model.data(model.index(1, 3)).toInt(), 2); + QCOMPARE(model.data(model.index(2, 3)).toInt(), 2); + QCOMPARE(model.data(model.index(3, 3)).toInt(), 2); + } + } static void testRevert(QSqlRelationalTableModel &model) @@ -663,7 +741,7 @@ void tst_QSqlRelationalTableModel::revert() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); model.setSort(0, Qt::AscendingOrder); @@ -689,7 +767,9 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); model.setSort(1, Qt::AscendingOrder); model.setEditStrategy(QSqlTableModel::OnManualSubmit); @@ -698,7 +778,10 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(3, 0)).toInt(), 3); QCOMPARE(model.data(model.index(3, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(3, 3)).toInt(), 2 ); model.insertRow(model.rowCount()); QVERIFY(model.setData(model.index(4, 0), 5, Qt::EditRole)); @@ -710,11 +793,18 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(0, 0)).toInt(), 5); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("anders")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); + QCOMPARE(model.data(model.index(4, 0)).toInt(), 3); QCOMPARE(model.data(model.index(4, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(4, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(4, 3)).toInt(), 2); } // For task 140782 and 176374: If the main table and the the related tables uses the same @@ -729,27 +819,38 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames() QSqlRelationalTableModel model(0, db); model.setTable(qTableName("reltest3")); model.setEditStrategy(QSqlTableModel::OnManualSubmit); + model.setSort(0, Qt::AscendingOrder); // Duplication of "name", used in both reltest3 and reltest4. model.setRelation(2, QSqlRelation(qTableName("reltest4"), "id", "name")); QVERIFY_SQL(model, select()); - QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name"))).toString(), + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name")).toUpper()).toString(), + QString("Trondheim")); + } else { + QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name"))).toString(), QString("Trondheim")); + } QSqlRecord rec = model.record(); rec.setValue(0, 3); rec.setValue(1, "Berge"); rec.setValue(2, 1); // Must insert the key value - QCOMPARE(rec.fieldName(0), QLatin1String("id")); - QCOMPARE(rec.fieldName(1), QLatin1String("name")); // This comes from main table + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + QCOMPARE(rec.fieldName(0), QLatin1String("ID")); + QCOMPARE(rec.fieldName(1), QLatin1String("NAME")); // This comes from main table + } else { + QCOMPARE(rec.fieldName(0), QLatin1String("id")); + QCOMPARE(rec.fieldName(1), QLatin1String("name")); + } // The duplicate field names is aliased because it's comes from the relation's display column. - if(!db.driverName().startsWith("QIBASE")) - QCOMPARE(rec.fieldName(2), qTableName("reltest4").append(QLatin1String("_name"))); - else + if(db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) QCOMPARE(rec.fieldName(2), (qTableName("reltest4").append(QLatin1String("_name"))).toUpper()); + else + QCOMPARE(rec.fieldName(2), qTableName("reltest4").append(QLatin1String("_name"))); QVERIFY(model.insertRecord(-1, rec)); QCOMPARE(model.data(model.index(2, 2)).toString(), QString("Oslo")); @@ -793,7 +894,7 @@ void tst_QSqlRelationalTableModel::relationModel() QVERIFY(model.relationModel(3) == NULL); QVERIFY(model.relationModel(4) == NULL); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); QVERIFY_SQL(model, select()); QVERIFY(model.relationModel(0) == NULL); @@ -806,5 +907,285 @@ void tst_QSqlRelationalTableModel::relationModel() QCOMPARE(rel_model->data(rel_model->index(0,1)).toString(), QString("herr")); } +void tst_QSqlRelationalTableModel::casing() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + if (db.driverName().startsWith("QSQLITE")) + QSKIP("The casing test for SQLITE is irrelevant since SQLITE is case insensitive", SkipAll); + + QStringList tableNames; + tableNames << qTableName("CASETEST1", db.driver()).toUpper(); + tableNames << qTableName("casetest1", db.driver()); + tst_Databases::safeDropTables(db, tableNames); + + QSqlQuery q(db); + QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() + + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(1, 'harry', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(2, 'trond', 2, 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(3, 'vohi', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(4, 'boris', 2, 2)")); + + QVERIFY_SQL( q, exec("create table " + qTableName("casetest1", db.driver()) + + " (ident int not null primary key, name varchar(20), title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(1, 'jerry', 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(2, 'george', 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(4, 'kramer', 2)")); + + if (db.driverName().startsWith("QOCI")) { + //try an owner that doesn't exist + QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 0); + + //try an owner that does exist + rec = db.driver()->record(db.userName() + "." + qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 4); + } + QSqlRecord rec = db.driver()->record(qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 4); + + rec = db.driver()->record(qTableName("casetest1", db.driver())); + QCOMPARE( rec.count(), 3); + + QSqlTableModel upperCaseModel(0, db); + upperCaseModel.setTable(qTableName("CASETEST1", db.driver()).toUpper()); + + QCOMPARE(upperCaseModel.tableName(),qTableName("CASETEST1",db.driver()).toUpper()); + + QVERIFY_SQL(upperCaseModel, select()); + + QCOMPARE(upperCaseModel.rowCount(), 4); + + QSqlTableModel lowerCaseModel(0, db); + lowerCaseModel.setTable(qTableName("casetest1", db.driver())); + QCOMPARE(lowerCaseModel.tableName(), qTableName("casetest1",db.driver())); + QVERIFY_SQL(lowerCaseModel, select()); + + QCOMPARE(lowerCaseModel.rowCount(), 3); + + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("CASETEST1", db.driver()).toUpper()); + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + tst_Databases::safeDropTables(db, tableNames); +} + +void tst_QSqlRelationalTableModel::escapedRelations() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + recreateTestTables(db); + + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("reltest1")); + + //try with relation table name quoted + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(qTableName("reltest2").toUpper(),QSqlDriver::TableName), + "tid", + "title")); + } else { + model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(qTableName("reltest2"),QSqlDriver::TableName), + "tid", + "title")); + + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with index column quoted + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName).toUpper(), + "title")); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName), + "title")); + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with display column quoted + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); + } + + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with tablename and index and display columns quoted in the relation + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); +} + +void tst_QSqlRelationalTableModel::escapedTableName() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + // set the values using OnRowChange Strategy with an escaped tablename + { + QSqlRelationalTableModel model(0, db); + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setTable(db.driver()->escapeIdentifier(qTableName("reltest1").toUpper(), QSqlDriver::TableName)); + } else { + model.setTable(db.driver()->escapeIdentifier(qTableName("reltest1"), QSqlDriver::TableName)); + } + model.setSort(0, Qt::AscendingOrder); + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + + QVERIFY(model.setData(model.index(0, 1), QString("harry2"))); + QVERIFY(model.setData(model.index(0, 2), 2)); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); + + model.submit(); + + QVERIFY(model.setData(model.index(3,1), QString("boris2"))); + QVERIFY(model.setData(model.index(3, 2), 1)); + + QCOMPARE(model.data(model.index(3,1)).toString(), QString("boris2")); + QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); + + model.submit(); + } + { //verify values + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("reltest1")); + model.setSort(0, Qt::AscendingOrder); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 2); + QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); + QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); + + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); + + } +} + +void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers() { + + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + if (!testWhiteSpaceNames(db.driverName())) + QSKIP("White space test irrelevant for driver", SkipAll); + QSqlRelationalTableModel model(0, db); + model.setTable(db.driver()->escapeIdentifier(qTableName("rel test6"), QSqlDriver::TableName)); + model.setSort(0, Qt::DescendingOrder); + model.setRelation(1, QSqlRelation(db.driver()->escapeIdentifier(qTableName("rel test7"), QSqlDriver::TableName), + db.driver()->escapeIdentifier("city id", QSqlDriver::FieldName), + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName))); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0,1)).toString(), QString("Washington")); + QCOMPARE(model.data(model.index(1,1)).toString(), QString("New York")); + + QSqlRecord rec; + QSqlField f1("id", QVariant::Int); + QSqlField f2(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int); + QSqlField f3(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int); + + f1.setValue(3); + f2.setValue(2); + f3.setValue(7); + + f1.setGenerated(true); + f2.setGenerated(true); + f3.setGenerated(true); + + rec.append(f1); + rec.append(f2); + rec.append(f3); + + QVERIFY_SQL(model, insertRecord(-1, rec)); + model.submitAll(); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 3); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Washington")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 7); + + //TODO: For some reson setting a record using manual submit fails + //model.setEditStrategy(QSqlTableModel::OnManualSubmit); + + QSqlRecord recNew; + QSqlField f1New("id", QVariant::Int); + QSqlField f2New(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int); + QSqlField f3New(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int); + + f1New.setValue(4); + f2New.setValue(1); + f3New.setValue(6); + + f1New.setGenerated(true); + f2New.setGenerated(true); + f3New.setGenerated(true); + + recNew.append(f1New); + recNew.append(f2New); + recNew.append(f3New); + + QVERIFY_SQL(model, setRecord(0, recNew)); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 4); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 6); + + QVERIFY_SQL(model, submitAll()); + QCOMPARE(model.data(model.index(0, 0)).toInt(), 4); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 6); +} + QTEST_MAIN(tst_QSqlRelationalTableModel) #include "tst_qsqlrelationaltablemodel.moc" diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index d4affe4..0e7355e 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -145,7 +145,7 @@ void tst_QSqlTableModel::dropTestTables() << qTableName("bigtable") << qTableName("foo"); if (testWhiteSpaceNames(db.driverName())) - tableNames << qTableName("qtestw hitespace"); + tableNames << qTableName("qtestw hitespace", db.driver()); tst_Databases::safeDropTables(db, tableNames); @@ -277,6 +277,7 @@ void tst_QSqlTableModel::setRecord() QList policies = QList() << QSqlTableModel::OnFieldChange << QSqlTableModel::OnRowChange << QSqlTableModel::OnManualSubmit; + QString Xsuffix; foreach( QSqlTableModel::EditStrategy submitpolicy, policies) { QSqlTableModel model(0, db); @@ -295,6 +296,8 @@ void tst_QSqlTableModel::setRecord() if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnManualSubmit) QVERIFY(model.submitAll()); + else if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1) + model.submit(); else { // dataChanged() is not emitted when submitAll() is called QCOMPARE(spy.count(), 2); @@ -304,10 +307,12 @@ void tst_QSqlTableModel::setRecord() } } - QCOMPARE(model.data(model.index(0, 1)).toString(), QString("fooX")); - QCOMPARE(model.data(model.index(0, 2)).toString(), QString("barX")); - QCOMPARE(model.data(model.index(1, 1)).toString(), QString("bazX")); - QCOMPARE(model.data(model.index(1, 2)).toString(), QString("joeX")); + Xsuffix.append('X'); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("foo").append(Xsuffix)); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("bar").append(Xsuffix)); + QCOMPARE(model.data(model.index(1, 1)).toString(), QString("baz").append(Xsuffix)); + QCOMPARE(model.data(model.index(1, 2)).toString(), QString("joe").append(Xsuffix)); } } -- cgit v0.12 From 014af3e99616f9ee13ca365566828f7daf77a7f6 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 15 Apr 2009 10:36:40 +1000 Subject: Fixes WebKit still occasionally failing to compile with MinGW when passing any `-j' to make. Change 6e5774d84e7e3b68736f95fae09a084bd5b9ac7a made the problem much less likely to occur, but in a debug_and_release build, debug and release would share the same mocinclude.tmp. Therefore, if exceptionally unlucky, the bug could still arise. Put mocinclude.tmp under MOC_DIR so each exclusive build has its own. Reviewed-by: Lincoln Ramsay --- mkspecs/features/moc.prf | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 975867e..7c4ff28 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -11,13 +11,14 @@ isEmpty(QMAKE_EXT_CPP_MOC):QMAKE_EXT_CPP_MOC = .moc # On Windows, put the includes into a .inc file which moc will read, if the project # has too many includes. We do this to overcome a command-line limit on Win < XP INCLUDETEMP= +WIN_INCLUDETEMP= win32:count($$list($$INCPATH), 40, >) { - INCLUDETEMP = mocinclude.tmp + INCLUDETEMP = $$MOC_DIR/mocinclude.tmp # Remove any existing mocinclude.tmp when qmake runs - WIN_OUT_PWD=$$OUT_PWD - WIN_OUT_PWD~=s,/,\,g - system($$QMAKE_DEL_FILE $$WIN_OUT_PWD\\$$INCLUDETEMP > NUL 2>&1) + WIN_INCLUDETEMP=$$INCLUDETEMP + WIN_INCLUDETEMP~=s,/,\,g + system($$QMAKE_DEL_FILE $$WIN_INCLUDETEMP > NUL 2>&1) EOC = $$escape_expand(\n\t) @@ -32,10 +33,10 @@ win32:count($$list($$INCPATH), 40, >) { RET = for(incfile, $$list($$INCPATH)) { INCFILELIST = -I$$incfile - isEmpty(RET): RET += @echo $$INCFILELIST> $$INCLUDETEMP $$EOC - else: RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC + isEmpty(RET): RET += @echo $$INCFILELIST> $$WIN_INCLUDETEMP $$EOC + else: RET += @echo $$INCFILELIST>> $$WIN_INCLUDETEMP $$EOC } - !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC + !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$WIN_INCLUDETEMP $$EOC build_pass|isEmpty(BUILDS) { mocinclude.target = $$INCLUDETEMP @@ -45,8 +46,8 @@ win32:count($$list($$INCPATH), 40, >) { } defineReplace(mocCmd) { - !isEmpty(INCLUDETEMP) { - return($$QMAKE_MOC $(DEFINES) @$$INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) + !isEmpty(WIN_INCLUDETEMP) { + return($$QMAKE_MOC $(DEFINES) @$$WIN_INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) } return($$QMAKE_MOC $(DEFINES) $(INCPATH) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) } -- cgit v0.12 From e3462ae7868c679bc88dc01de85ca39454651ff7 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 15 Apr 2009 11:21:13 +1000 Subject: Fix typo in documentation. Error was introduced in change 52f87de53328c661049acf09d5fedc1850aa9bfa. Reviewed-by: Trust Me --- src/gui/painting/qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 18993e1..2fa6a56 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1465,7 +1465,7 @@ bool QPainter::isActive() const /*! Initializes the painters pen, background and font to the same as - the given \a widget. This function is automatically when the + the given \a widget. This function is called automatically when the painter is opened on a QWidget. \sa begin(), {QPainter#Settings}{Settings} -- cgit v0.12 From 3eb4aacf07c77876c6ce68e9746906424934433b Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 15 Apr 2009 13:22:48 +1000 Subject: Fixes an issue with FreeTDS and quoting. Microsofts SQL Server odbc driver calls SET QUOTED_IDENTIFIER_ON, but freetds doesn't, so any quoting fails. This fixes that issue. Reviewed-by: abcd --- src/sql/drivers/odbc/qsql_odbc.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 71b1b2a..d6423ae 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -55,6 +55,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -1800,6 +1801,10 @@ bool QODBCDriver::open(const QString & db, d->checkHasMultiResults(); setOpen(true); setOpenError(false); + if(d->isMSSqlServer) { + QSqlQuery i(createResult()); + i.exec(QLatin1String("SET QUOTED_IDENTIFIER ON")); + } return true; } -- cgit v0.12 From 6c4b9cb575292f5f81afc772d993c1a53eb96ea5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Apr 2009 08:18:30 +0200 Subject: Display QAction keyboard shortcuts in action editor correctly. Use PropertySheetKeySequenceValue instead of plain strings. --- tools/designer/src/lib/shared/actioneditor.cpp | 8 ++++---- tools/designer/src/lib/shared/actionrepository.cpp | 17 +++++++++++------ tools/designer/src/lib/shared/actionrepository_p.h | 7 +++++++ tools/designer/src/lib/shared/newactiondialog.cpp | 4 ++-- tools/designer/src/lib/shared/newactiondialog_p.h | 2 +- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tools/designer/src/lib/shared/actioneditor.cpp b/tools/designer/src/lib/shared/actioneditor.cpp index 6a66442..7f96a15 100644 --- a/tools/designer/src/lib/shared/actioneditor.cpp +++ b/tools/designer/src/lib/shared/actioneditor.cpp @@ -456,7 +456,7 @@ void ActionEditor::slotNewAction() if (actionData.checkable) setInitialProperty(sheet, QLatin1String(checkablePropertyC), QVariant(true)); - if (!actionData.keysequence.isEmpty()) + if (!actionData.keysequence.value().isEmpty()) setInitialProperty(sheet, QLatin1String(shortcutPropertyC), qVariantFromValue(actionData.keysequence)); sheet->setProperty(sheet->indexOf(QLatin1String(iconPropertyC)), qVariantFromValue(actionData.icon)); @@ -491,10 +491,10 @@ static QDesignerFormWindowCommand *setIconPropertyCommand(const PropertySheetIco // return a FormWindow command to apply a QKeySequence or a reset command // in case it is empty. -static QDesignerFormWindowCommand *setKeySequencePropertyCommand(const QKeySequence &ks, QAction *action, QDesignerFormWindowInterface *fw) +static QDesignerFormWindowCommand *setKeySequencePropertyCommand(const PropertySheetKeySequenceValue &ks, QAction *action, QDesignerFormWindowInterface *fw) { const QString shortcutProperty = QLatin1String(shortcutPropertyC); - if (ks.isEmpty()) { + if (ks.value().isEmpty()) { ResetPropertyCommand *cmd = new ResetPropertyCommand(fw); cmd->init(action, shortcutProperty); return cmd; @@ -544,7 +544,7 @@ void ActionEditor::editAction(QAction *action) oldActionData.text = action->text(); oldActionData.toolTip = textPropertyValue(sheet, QLatin1String(toolTipPropertyC)); oldActionData.icon = qVariantValue(sheet->property(sheet->indexOf(QLatin1String(iconPropertyC)))); - oldActionData.keysequence = qVariantValue(sheet->property(sheet->indexOf(QLatin1String(shortcutPropertyC)))); + oldActionData.keysequence = ActionModel::actionShortCut(sheet); oldActionData.checkable = action->isCheckable(); dlg.setActionData(oldActionData); diff --git a/tools/designer/src/lib/shared/actionrepository.cpp b/tools/designer/src/lib/shared/actionrepository.cpp index 941a9ba..1b638c3 100644 --- a/tools/designer/src/lib/shared/actionrepository.cpp +++ b/tools/designer/src/lib/shared/actionrepository.cpp @@ -42,6 +42,7 @@ #include "actionrepository_p.h" #include "qtresourceview_p.h" #include "iconloader_p.h" +#include "qdesigner_utils_p.h" #include #include @@ -168,16 +169,20 @@ QWidgetList ActionModel::associatedWidgets(const QAction *action) } // shortcut is a fake property, need to retrieve it via property sheet. -static QString actionShortCut(QDesignerFormEditorInterface *core, QAction *action) +PropertySheetKeySequenceValue ActionModel::actionShortCut(QDesignerFormEditorInterface *core, QAction *action) { QDesignerPropertySheetExtension *sheet = qt_extension(core->extensionManager(), action); if (!sheet) - return QString(); + return PropertySheetKeySequenceValue(); + return actionShortCut(sheet); +} + +PropertySheetKeySequenceValue ActionModel::actionShortCut(const QDesignerPropertySheetExtension *sheet) +{ const int index = sheet->indexOf(QLatin1String("shortcut")); if (index == -1) - return QString(); - const QKeySequence keysequence = qvariant_cast(sheet->property(index)); - return keysequence.toString(); + return PropertySheetKeySequenceValue(); + return qvariant_cast(sheet->property(index)); } void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, QStandardItemList &sl) @@ -221,7 +226,7 @@ void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, item->setText(action->text()); item->setToolTip(action->text()); // shortcut - const QString shortcut = actionShortCut(core, action); + const QString shortcut = actionShortCut(core, action).value().toString(); item = sl[ShortCutColumn]; item->setText(shortcut); item->setToolTip(shortcut); diff --git a/tools/designer/src/lib/shared/actionrepository_p.h b/tools/designer/src/lib/shared/actionrepository_p.h index 9d1af5a..66d77ce 100644 --- a/tools/designer/src/lib/shared/actionrepository_p.h +++ b/tools/designer/src/lib/shared/actionrepository_p.h @@ -65,9 +65,12 @@ QT_BEGIN_NAMESPACE class QPixmap; class QDesignerFormEditorInterface; +class QDesignerPropertySheetExtension; namespace qdesigner_internal { +class PropertySheetKeySequenceValue; + // Shared model of actions, to be used for several views (detailed/icon view). class QDESIGNER_SHARED_EXPORT ActionModel: public QStandardItemModel { @@ -99,6 +102,10 @@ public: // Find the associated menus and toolbars, ignore toolbuttons static QWidgetList associatedWidgets(const QAction *action); + // Retrieve shortcut via property sheet as it is a fake property + static PropertySheetKeySequenceValue actionShortCut(QDesignerFormEditorInterface *core, QAction *action); + static PropertySheetKeySequenceValue actionShortCut(const QDesignerPropertySheetExtension *ps); + signals: void resourceImageDropped(const QString &path, QAction *action); diff --git a/tools/designer/src/lib/shared/newactiondialog.cpp b/tools/designer/src/lib/shared/newactiondialog.cpp index 53aec4b..bb163d6 100644 --- a/tools/designer/src/lib/shared/newactiondialog.cpp +++ b/tools/designer/src/lib/shared/newactiondialog.cpp @@ -134,7 +134,7 @@ ActionData NewActionDialog::actionData() const rc.toolTip = m_ui->tooltipEditor->text(); rc.icon = m_ui->iconSelector->icon(); rc.checkable = m_ui->checkableCheckBox->checkState() == Qt::Checked; - rc.keysequence = m_ui->keySequenceEdit->keySequence(); + rc.keysequence = PropertySheetKeySequenceValue(m_ui->keySequenceEdit->keySequence()); return rc; } @@ -144,7 +144,7 @@ void NewActionDialog::setActionData(const ActionData &d) m_ui->editObjectName->setText(d.name); m_ui->iconSelector->setIcon(d.icon); m_ui->tooltipEditor->setText(d.toolTip); - m_ui->keySequenceEdit->setKeySequence(d.keysequence); + m_ui->keySequenceEdit->setKeySequence(d.keysequence.value()); m_ui->checkableCheckBox->setCheckState(d.checkable ? Qt::Checked : Qt::Unchecked); m_auto_update_object_name = false; diff --git a/tools/designer/src/lib/shared/newactiondialog_p.h b/tools/designer/src/lib/shared/newactiondialog_p.h index c8bd34c..d4e9b5b 100644 --- a/tools/designer/src/lib/shared/newactiondialog_p.h +++ b/tools/designer/src/lib/shared/newactiondialog_p.h @@ -84,7 +84,7 @@ struct ActionData { QString toolTip; PropertySheetIconValue icon; bool checkable; - QKeySequence keysequence; + PropertySheetKeySequenceValue keysequence; }; inline bool operator==(const ActionData &a1, const ActionData &a2) { return a1.compare(a2) == 0u; } -- cgit v0.12 From b33ebce3de3efd98a45c8ca0a349f78aac09c875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 15 Apr 2009 10:12:34 +0200 Subject: Don't crash or loop infinitely when we retrieving the accessible accel. qt_accHotKey() was pretty buggy; it could both crash or spin forever in some cases. Task-number: 221731 Reviewed-by: alexis --- src/gui/accessible/qaccessiblewidget.cpp | 13 ++++-- tests/auto/qaccessibility/tst_qaccessibility.cpp | 52 +++++++++++++++++++++--- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/gui/accessible/qaccessiblewidget.cpp b/src/gui/accessible/qaccessiblewidget.cpp index 4b2b2ab..753ac57 100644 --- a/src/gui/accessible/qaccessiblewidget.cpp +++ b/src/gui/accessible/qaccessiblewidget.cpp @@ -131,9 +131,16 @@ QString Q_GUI_EXPORT qt_accHotKey(const QString &text) int fa = 0; QChar ac; while ((fa = text.indexOf(QLatin1Char('&'), fa)) != -1) { - if (fa == text.length() - 1 || text.at(fa+1) != QLatin1Char('&')) { - ac = text.at(fa+1); - break; + ++fa; + if (fa < text.length()) { + // ignore "&&" + if (text.at(fa) == QLatin1Char('&')) { + ++fa; + continue; + } else { + ac = text.at(fa); + break; + } } } if (ac.isNull()) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index d023557..1aca624 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -275,6 +275,7 @@ private slots: void accessibleName(); void treeWidgetTest(); void labelTest(); + void accelerators(); private: QWidget *createGUI(); @@ -2592,8 +2593,8 @@ void tst_QAccessibility::menuTest() QTestAccessibility::clearEvents(); mw.hide(); - - + + // Do not crash if the menu don't have a parent QMenu *menu = new QMenu; menu->addAction(QLatin1String("one")); @@ -2607,7 +2608,7 @@ void tst_QAccessibility::menuTest() delete iface2; delete iface; delete menu; - + } QTestAccessibility::clearEvents(); #else @@ -3988,13 +3989,13 @@ void tst_QAccessibility::treeWidgetTest() QCOMPARE(entry, 0); QCOMPARE(accTreeItem2->text(QAccessible::Name, 0), QLatin1String("row: 1")); - - // test selected/focused state + + // test selected/focused state QItemSelectionModel *selModel = tree->selectionModel(); QVERIFY(selModel); selModel->select(QItemSelection(tree->model()->index(0, 0), tree->model()->index(3, 0)), QItemSelectionModel::Select); selModel->setCurrentIndex(tree->model()->index(1, 0), QItemSelectionModel::Current); - + for (int i = 1; i < 10 ; ++i) { QAccessible::State expected; if (i <= 5 && i >= 2) @@ -4046,6 +4047,45 @@ void tst_QAccessibility::labelTest() #endif } +void tst_QAccessibility::accelerators() +{ +#ifdef QTEST_ACCESSIBILITY + QWidget *window = new QWidget; + QHBoxLayout *lay = new QHBoxLayout(window); + QLabel *label = new QLabel(tr("&Line edit"), window); + QLineEdit *le = new QLineEdit(window); + lay->addWidget(label); + lay->addWidget(le); + label->setBuddy(le); + + window->show(); + + QAccessibleInterface *accLineEdit = QAccessible::queryAccessibleInterface(le); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString(QKeySequence(Qt::ALT) + QLatin1String("L"))); + label->setText(tr("Q &")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + label->setText(tr("Q &&")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + label->setText(tr("Q && A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + label->setText(tr("Q &&&A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString(QKeySequence(Qt::ALT) + QLatin1String("A"))); + label->setText(tr("Q &&A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + label->setText(tr("Q &A&B")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString(QKeySequence(Qt::ALT) + QLatin1String("A"))); + +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(window); +#endif + QTest::qWait(100); + delete window; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + QTEST_MAIN(tst_QAccessibility) -- cgit v0.12 From 7a0f9ae94ca7a47dc285431d31f6839c07870194 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 15 Apr 2009 10:23:08 +0200 Subject: BT: Fix a regression to 4.4 in Graphics View's handling of child clippers Regression caused by optimizations in QGraphicsItem and QGraphicsScene. The changes in QGraphicsItem fix bugs in QGraphicsItem::mapToParent functions, which did the translation before applying the transformation, instead of the other way (transform, then translate). This bug caused almost all mapToParent and mapRectToParent functions to behave wrongly. Unfortunately the new helper functions in QGraphicsScene for discovering items made use of these functions, which introduced a regression. Fixing these functions also fixes item discovery. The other part of this change fixes a regression caused by c1909321, which luckily happened after 4.5.0 and never saw the light of day. The fix is to also invalidate the cached clip path even if there is no scene, which is necessary if you build your scene graph outside the scene, and finish off by adding the root item to the scene. Task-number: 250680 Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsitem.cpp | 30 +++++---- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 83 ++++++++++++++++++++++++ tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 26 ++++++++ 3 files changed, 125 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b520a3f..e6bcaa6 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4223,9 +4223,9 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect */ QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const { - if (!d_ptr->hasTransform) - return QPolygonF(rect.translated(d_ptr->pos)); - return transform().map(rect.translated(d_ptr->pos)); + QPolygonF p = !d_ptr->hasTransform ? rect : transform().map(rect); + p.translate(d_ptr->pos); + return p; } /*! @@ -4292,8 +4292,8 @@ QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rec */ QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const { - QRectF r = rect.translated(d_ptr->pos.x(), d_ptr->pos.y()); - return !d_ptr->hasTransform ? r : transform().mapRect(r); + QRectF r = !d_ptr->hasTransform ? rect : transform().mapRect(rect); + return r.translated(d_ptr->pos); } /*! @@ -4424,9 +4424,9 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &p */ QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const { - QPolygonF p = polygon; + QPolygonF p = !d_ptr->hasTransform ? polygon : transform().map(polygon); p.translate(d_ptr->pos); - return d_ptr->hasTransform ? transform().map(p) : p; + return p; } /*! @@ -4468,7 +4468,10 @@ QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterP */ QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const { - return d_ptr->parent ? itemTransform(d_ptr->parent).map(path) : mapToScene(path); + QTransform x = QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y()); + if (d_ptr->hasTransform) + x = transform() * x; + return x.map(path); } /*! @@ -5697,12 +5700,11 @@ void QGraphicsItem::removeFromIndex() */ void QGraphicsItem::prepareGeometryChange() { - if (!d_ptr->scene) - return; - - d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); - QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); - scenePrivate->removeFromIndex(this); + if (d_ptr->scene) { + d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); + QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); + scenePrivate->removeFromIndex(this); + } if (d_ptr->inSetPosHelper) return; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 5dd7e1e..2d1be37 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -162,6 +162,8 @@ private slots: void mapFromToParent(); void mapFromToScene(); void mapFromToItem(); + void mapRectFromToParent_data(); + void mapRectFromToParent(); void isAncestorOf(); void commonAncestorItem(); void data(); @@ -2515,6 +2517,87 @@ void tst_QGraphicsItem::mapFromToItem() delete item4; } +void tst_QGraphicsItem::mapRectFromToParent_data() +{ + QTest::addColumn("parent"); + QTest::addColumn("parentPos"); + QTest::addColumn("parentTransform"); + QTest::addColumn("pos"); + QTest::addColumn("transform"); + QTest::addColumn("inputRect"); + QTest::addColumn("outputRect"); + + QTest::newRow("nil") << false << QPointF() << QTransform() << QPointF() << QTransform() << QRectF() << QRectF(); + QTest::newRow("simple") << false << QPointF() << QTransform() << QPointF() << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10); + QTest::newRow("simple w/parent") << true + << QPointF() << QTransform() + << QPointF() << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10); + QTest::newRow("simple w/parent parentPos") << true + << QPointF(50, 50) << QTransform() + << QPointF() << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10); + QTest::newRow("simple w/parent parentPos parentRotation") << true + << QPointF(50, 50) << QTransform().rotate(45) + << QPointF() << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10); + QTest::newRow("pos w/parent") << true + << QPointF() << QTransform() + << QPointF(50, 50) << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(50, 50, 10, 10); + QTest::newRow("rotation w/parent") << true + << QPointF() << QTransform() + << QPointF() << QTransform().rotate(90) + << QRectF(0, 0, 10, 10) << QRectF(-10, 0, 10, 10); + QTest::newRow("pos rotation w/parent") << true + << QPointF() << QTransform() + << QPointF(50, 50) << QTransform().rotate(90) + << QRectF(0, 0, 10, 10) << QRectF(40, 50, 10, 10); + QTest::newRow("pos rotation w/parent parentPos parentRotation") << true + << QPointF(-170, -190) << QTransform().rotate(90) + << QPointF(50, 50) << QTransform().rotate(90) + << QRectF(0, 0, 10, 10) << QRectF(40, 50, 10, 10); +} + +void tst_QGraphicsItem::mapRectFromToParent() +{ + QFETCH(bool, parent); + QFETCH(QPointF, parentPos); + QFETCH(QTransform, parentTransform); + QFETCH(QPointF, pos); + QFETCH(QTransform, transform); + QFETCH(QRectF, inputRect); + QFETCH(QRectF, outputRect); + + QGraphicsRectItem *rect = new QGraphicsRectItem; + rect->setPos(pos); + rect->setTransform(transform); + + if (parent) { + QGraphicsRectItem *rectParent = new QGraphicsRectItem; + rect->setParentItem(rectParent); + rectParent->setPos(parentPos); + rectParent->setTransform(parentTransform); + } + + // Make sure we use non-destructive transform operations (e.g., 90 degree + // rotations). + QCOMPARE(rect->mapRectToParent(inputRect), outputRect); + QCOMPARE(rect->mapRectFromParent(outputRect), inputRect); + QCOMPARE(rect->itemTransform(rect->parentItem()).mapRect(inputRect), outputRect); + QCOMPARE(rect->mapToParent(inputRect).boundingRect(), outputRect); + QCOMPARE(rect->mapToParent(QPolygonF(inputRect)).boundingRect(), outputRect); + QCOMPARE(rect->mapFromParent(outputRect).boundingRect(), inputRect); + QCOMPARE(rect->mapFromParent(QPolygonF(outputRect)).boundingRect(), inputRect); + QPainterPath inputPath; + inputPath.addRect(inputRect); + QPainterPath outputPath; + outputPath.addRect(outputRect); + QCOMPARE(rect->mapToParent(inputPath).boundingRect(), outputPath.boundingRect()); + QCOMPARE(rect->mapFromParent(outputPath).boundingRect(), inputPath.boundingRect()); +} + void tst_QGraphicsItem::isAncestorOf() { QGraphicsItem *grandPa = new QGraphicsRectItem; diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 91ed851..354d81a 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -245,6 +245,7 @@ private slots: void task139782_containsItemBoundingRect(); void task176178_itemIndexMethodBreaksSceneRect(); void task160653_selectionChanged(); + void task250680_childClip(); }; void tst_QGraphicsScene::initTestCase() @@ -3384,6 +3385,31 @@ void tst_QGraphicsScene::task160653_selectionChanged() QCOMPARE(spy.count(), 1); } +void tst_QGraphicsScene::task250680_childClip() +{ + QGraphicsRectItem *clipper = new QGraphicsRectItem; + clipper->setFlag(QGraphicsItem::ItemClipsChildrenToShape); + clipper->setPen(QPen(Qt::green)); + clipper->setRect(200, 200, 640, 480); + + QGraphicsRectItem *rect = new QGraphicsRectItem(clipper); + rect->setPen(QPen(Qt::red)); + rect->setBrush(QBrush(QColor(255, 0, 0, 75))); + rect->setPos(320, 240); + rect->setRect(-25, -25, 50, 50); + + QGraphicsScene scene; + scene.addItem(clipper); + + QPainterPath path; + path.addRect(-25, -25, 50, 50); + QCOMPARE(rect->clipPath(), path); + + QCOMPARE(scene.items(QRectF(320, 240, 5, 5)).size(), 2); + rect->rotate(45); + QCOMPARE(scene.items(QRectF(320, 240, 5, 5)).size(), 2); +} + void tst_QGraphicsScene::sorting_data() { QTest::addColumn("cache"); -- cgit v0.12 From a59488d4799f6ac9ea034c0a88a468e73a64d517 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 15 Apr 2009 10:47:29 +0200 Subject: Compile with namespace Reviewed-by: hjk --- src/corelib/tools/qvector.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 6bea03b..3fd52ee 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -98,6 +98,8 @@ struct QVectorTypedData T array[1]; }; +class QRegion; + template class QVector { -- cgit v0.12 From afb3848e0abe0cd2355e7ee7319fd904288e4636 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 15 Apr 2009 10:30:17 +0200 Subject: Fix regression in QString::replace(int, int, QChar) when string is empty When QString::replace was optimized, this specific overload missed out on sanity checking of the arguments. Task-number: 249517 Reviewed-by: Joao Reviewed-by: hjk BT: yes --- src/corelib/tools/qstring.cpp | 34 ++++++++++++++++------------------ tests/auto/qstring/tst_qstring.cpp | 4 ++++ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 9c637ac..375d672 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -579,7 +579,7 @@ const QString::Null QString::null = { }; '\\0' character for a null string (\e not a null pointer), and QString() compares equal to QString(""). We recommend that you always use the isEmpty() function and avoid isNull(). - + \section1 Argument Formats In member functions where an argument \e format can be specified @@ -1433,7 +1433,7 @@ QString &QString::append(QChar ch) truncated at the specified \a position. \snippet doc/src/snippets/qstring/main.cpp 37 - + \sa insert(), replace() */ QString &QString::remove(int pos, int len) @@ -1552,7 +1552,7 @@ QString &QString::replace(int pos, int len, const QChar *unicode, int size) return *this; if (pos + len > d->size) len = d->size - pos; - + uint index = pos; replace_helper(&index, 1, len, unicode, size); return *this; @@ -1561,15 +1561,13 @@ QString &QString::replace(int pos, int len, const QChar *unicode, int size) /*! \fn QString &QString::replace(int position, int n, QChar after) \overload replace() - + Replaces \a n characters beginning at index \a position with the character \a after and returns a reference to this string. */ QString &QString::replace(int pos, int len, QChar after) { - uint index = pos; - replace_helper(&index, 1, len, &after, 1); - return *this; + return replace(pos, len, &after, 1); } /*! @@ -1602,7 +1600,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar { if (blen == alen) { detach(); - for (int i = 0; i < nIndices; ++i) + for (int i = 0; i < nIndices; ++i) memcpy(d->data + indices[i], after, alen * sizeof(QChar)); } else if (alen < blen) { detach(); @@ -1633,7 +1631,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar int newLen = d->size + adjust; int moveend = d->size; resize(newLen); - + while (nIndices) { --nIndices; int movestart = indices[nIndices] + blen; @@ -1685,7 +1683,7 @@ QString &QString::replace(const QChar *before, int blen, memcpy(copy, before, blen*sizeof(QChar)); b = copy; } - + QStringMatcher matcher(b, blen, cs); int index = 0; @@ -1712,7 +1710,7 @@ QString &QString::replace(const QChar *before, int blen, // index has to be adjusted in case we get back into the loop above. index += pos*(alen-blen); } - + if (a != after) ::free((QChar *)a); if (b != before) @@ -2250,7 +2248,7 @@ int QString::indexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) QVarLengthArray s(len); for (int i = 0; i < len; ++i) s[i] = str.latin1()[i]; - + return qFindString(unicode(), length(), from, (const QChar *)s.data(), len, cs); } @@ -2346,7 +2344,7 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee /* See indexOf() for explanations. */ - + const ushort *end = haystack; haystack += from; const int sl_minus_1 = sl-1; @@ -2408,7 +2406,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c const int sl = str.d->size; if (sl == 1) return lastIndexOf(QChar(str.d->data[0]), from, cs); - + const int l = d->size; if (from < 0) from += l; @@ -2446,7 +2444,7 @@ int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity const int sl = qstrlen(str.latin1()); if (sl == 1) return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs); - + const int l = d->size; if (from < 0) from += l; @@ -5995,7 +5993,7 @@ QString QString::normalized(QString::NormalizationForm mode, QChar::UnicodeVersi } if (simple) return *this; - + QString s = *this; if (version != CURRENT_VERSION) { for (int i = 0; i < NumNormalizationCorrections; ++i) { @@ -6207,7 +6205,7 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f /*! Returns a copy of this string with the lowest numbered place marker replaced by string \a a, i.e., \c %1, \c %2, ..., \c %99. - + \a fieldWidth specifies the minimum amount of space that argument \a a shall occupy. If \a a requires less space than \a fieldWidth, it is padded to \a fieldWidth with character \a fillChar. A positive @@ -6819,7 +6817,7 @@ void QString::updateProperties() const Appends the given \a ch character onto the end of this string. */ -/*! +/*! \fn std::string QString::toStdString() const Returns a std::string object with the data contained in this diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index f786965..1263a41 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -432,6 +432,10 @@ void tst_QString::replace_uint_uint_data() QTest::newRow( "rep09" ) << QString("ACABCAB") << 4 << 2 << QString("XX") << QString("ACABXXB"); QTest::newRow( "rep10" ) << QString("ACABCAB") << 5 << 2 << QString("XX") << QString("ACABCXX"); QTest::newRow( "rep10" ) << QString("ACABCAB") << 6 << 2 << QString("XX") << QString("ACABCAXX"); + QTest::newRow( "rep12" ) << QString() << 0 << 10 << QString("X") << QString("X"); + QTest::newRow( "rep13" ) << QString("short") << 0 << 10 << QString("X") << QString("X"); + QTest::newRow( "rep14" ) << QString() << 0 << 10 << QString("XX") << QString("XX"); + QTest::newRow( "rep15" ) << QString("short") << 0 << 10 << QString("XX") << QString("XX"); } void tst_QString::replace_string_data() -- cgit v0.12 From 4626232ff040ce0e66e8cdf5ceb7d725c04a4823 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 18:16:15 +0200 Subject: Fixes warning about potential use of uninitialized value Reviewed-by: bnilsen --- src/gui/painting/qtransform.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index fa808d0..39e429d 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1715,13 +1715,12 @@ QRect QTransform::mapRect(const QRect &rect) const return QRect(x, y, w, h); } else if (t < TxProject) { // see mapToPolygon for explanations of the algorithm. - qreal x0 = 0, y0 = 0; - qreal x, y; - MAP(rect.left(), rect.top(), x0, y0); - qreal xmin = x0; - qreal ymin = y0; - qreal xmax = x0; - qreal ymax = y0; + qreal x = 0, y = 0; + MAP(rect.left(), rect.top(), x, y); + qreal xmin = x; + qreal ymin = y; + qreal xmax = x; + qreal ymax = y; MAP(rect.right() + 1, rect.top(), x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); @@ -1782,13 +1781,12 @@ QRectF QTransform::mapRect(const QRectF &rect) const } return QRectF(x, y, w, h); } else if (t < TxProject) { - qreal x0 = 0, y0 = 0; - qreal x, y; - MAP(rect.x(), rect.y(), x0, y0); - qreal xmin = x0; - qreal ymin = y0; - qreal xmax = x0; - qreal ymax = y0; + qreal x = 0, y = 0; + MAP(rect.x(), rect.y(), x, y); + qreal xmin = x; + qreal ymin = y; + qreal xmax = x; + qreal ymax = y; MAP(rect.x() + rect.width(), rect.y(), x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); -- cgit v0.12 From fd5f83e612729cebc5395c992bd98628bb9ea25f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 18:48:02 +0200 Subject: Fixes QSortFilterProxyModel not reporting child if the model need to fetchMore QSortFilterProxyModel::hasChildren need to construct the mapping. And when it tries to construct the mapping, it needs to fetch the childs, so there is none. Task-number: 250023 Reviewed-by: Marius Bugge Monsen --- src/gui/itemviews/qsortfilterproxymodel.cpp | 3 + .../tst_qsortfilterproxymodel.cpp | 87 ++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index 10bcb9a..b0137d2 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -274,6 +274,9 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping( Mapping *m = new Mapping; + if (model->canFetchMore(source_parent)) + model->fetchMore(source_parent); + int source_rows = model->rowCount(source_parent); for (int i = 0; i < source_rows; ++i) { if (q->filterAcceptsRow(i, source_parent)) diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 0a48066..ee9daef 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -131,6 +131,7 @@ private slots: void task247867_insertRowsSort(); void task248868_staticSorting(); void task248868_dynamicSorting(); + void task250023_fetchMore(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -2590,6 +2591,92 @@ void tst_QSortFilterProxyModel::task248868_dynamicSorting() } } +class QtTestModel: public QAbstractItemModel +{ + public: + QtTestModel(int _rows, int _cols, QObject *parent = 0): QAbstractItemModel(parent), + rows(_rows), cols(_cols), wrongIndex(false) { } + + bool canFetchMore(const QModelIndex &idx) const { + return !fetched.contains(idx); + } + + void fetchMore(const QModelIndex &idx) { + fetched.insert(idx); + } + + bool hasChildren(const QModelIndex & = QModelIndex()) const { + return true; + } + + int rowCount(const QModelIndex& parent = QModelIndex()) const { + return fetched.contains(parent) ? rows : 0; + } + int columnCount(const QModelIndex& parent = QModelIndex()) const { + return fetched.contains(parent) ? cols : 0; + } + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const + { + if (row < 0 || column < 0 || column >= cols || row >= rows) { + return QModelIndex(); + } + QModelIndex i = createIndex(row, column, int(parent.internalId() + 1)); + parentHash[i] = parent; + return i; + } + + QModelIndex parent(const QModelIndex &index) const + { + if (!parentHash.contains(index)) + return QModelIndex(); + return parentHash[index]; + } + + QVariant data(const QModelIndex &idx, int role) const + { + if (!idx.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) { + if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) { + wrongIndex = true; + qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(), + idx.internalPointer()); + } + return QString("[%1,%2]").arg(idx.row()).arg(idx.column()); + } + return QVariant(); + } + + QSet fetched; + int rows, cols; + mutable bool wrongIndex; + mutable QMap parentHash; +}; + +void tst_QSortFilterProxyModel::task250023_fetchMore() +{ + QtTestModel model(10,10); + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + QVERIFY(proxy.canFetchMore(QModelIndex())); + QVERIFY(proxy.hasChildren()); + while (proxy.canFetchMore(QModelIndex())) + proxy.fetchMore(QModelIndex()); + QCOMPARE(proxy.rowCount(), 10); + QCOMPARE(proxy.columnCount(), 10); + + QModelIndex idx = proxy.index(1,1); + QVERIFY(idx.isValid()); + QVERIFY(proxy.canFetchMore(idx)); + QVERIFY(proxy.hasChildren(idx)); + while (proxy.canFetchMore(idx)) + proxy.fetchMore(idx); + QCOMPARE(proxy.rowCount(idx), 10); + QCOMPARE(proxy.columnCount(idx), 10); +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" -- cgit v0.12 From 4e78de5a4281bd1c27a984b13887975798573aae Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 15 Apr 2009 09:39:55 +0200 Subject: Stabilize test for QItemDelegate --- tests/auto/qitemdelegate/tst_qitemdelegate.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp index befe0eb..27741e0 100644 --- a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp @@ -777,6 +777,7 @@ void tst_QItemDelegate::dateTimeEditor() QCOMPARE(timeEditor->time(), time); widget.clearFocus(); + qApp->setActiveWindow(&widget); widget.setFocus(); widget.editItem(item2); -- cgit v0.12