From 63a4d6652aa8d84282083e49217120c97bb0bfc8 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 27 Apr 2009 11:36:12 +0200 Subject: Document what QWidget::winId() returns on Mac OS X. There are different types depending on Carbon and Cocoa, and it is probably helpful to point that out. Task-number: 251001 Reviewed-by: Kavindra --- src/gui/kernel/qwidget.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e9fd28b..eb2e9f7 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -2132,6 +2132,10 @@ QWidget *QWidget::find(WId id) If a widget is non-native (alien) and winId() is invoked on it, that widget will be provided a native handle. + On Mac OS X, the type returned depends on which framework Qt was linked + against. If Qt is using Carbon, the {WId} is actually an HIViewRef. If Qt + is using Cocoa, {WId} is a pointer to an NSView. + \note We recommend that you do not store this value as it is likely to change at run-time. -- cgit v0.12 From 96a27e24eec9356e45f1a6b6ff641a9afab24a39 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 27 Apr 2009 14:22:14 +0200 Subject: Make dark color schemes look better in property editor (especially schemes which have a grey color for text) Task: 252251 RevBy: Markus Goetz --- tools/designer/src/components/propertyeditor/propertyeditor.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.cpp b/tools/designer/src/components/propertyeditor/propertyeditor.cpp index 63b57d8..806e1dd 100644 --- a/tools/designer/src/components/propertyeditor/propertyeditor.cpp +++ b/tools/designer/src/components/propertyeditor/propertyeditor.cpp @@ -205,14 +205,15 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare colors.push_back(QColor(234, 191, 255)); colors.push_back(QColor(255, 191, 239)); m_colors.reserve(colors.count()); + const int darknessFactor = 250; for (int i = 0; i < colors.count(); i++) { QColor c = colors.at(i); - m_colors.push_back(qMakePair(c, c.darker(150))); + m_colors.push_back(qMakePair(c, c.darker(darknessFactor))); } QColor dynamicColor(191, 207, 255); QColor layoutColor(255, 191, 191); - m_dynamicColor = qMakePair(dynamicColor, dynamicColor.darker(150)); - m_layoutColor = qMakePair(layoutColor, layoutColor.darker(150)); + m_dynamicColor = qMakePair(dynamicColor, dynamicColor.darker(darknessFactor)); + m_layoutColor = qMakePair(layoutColor, layoutColor.darker(darknessFactor)); updateForegroundBrightness(); -- cgit v0.12 From c1ba5146a5ce2919df1529aa1202f6f3687071a0 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 27 Apr 2009 15:01:28 +0200 Subject: Ensure that QFontDialog::getFont() works on Mac OS X. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It seems that running the font dialog modal means that the "fontChanged" action is not fired. Which means our font is never changed. Thankfully, since it's an app modal case, we can re-sync when the OK button is clicked. Task-number: 252000 Reviewed-by: Morten Sørvig --- src/gui/dialogs/qfontdialog_mac.mm | 67 +++++++++++++++----------------------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 42be3be..50917a1 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -87,7 +87,6 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin NSButton *mOkButton; NSButton *mCancelButton; QFontDialogPrivate *mPriv; - NSFont *mCocoaFont; QFont *mQtFont; BOOL mPanelHackedWithButtons; CGFloat mDialogExtraWidth; @@ -119,6 +118,29 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin - (void)cleanUpAfterMyself; @end +static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) +{ + QFont newFont; + if (cocoaFont) { + int pSize = qRound([cocoaFont pointSize]); + QString family(QCFString::toQString(reinterpret_cast([cocoaFont familyName]))); + QString typeface(QCFString::toQString(reinterpret_cast([cocoaFont fontName]))); +// qDebug() << "original family" << family << "typeface" << typeface << "psize" << pSize; + int hyphenPos = typeface.indexOf(QLatin1Char('-')); + if (hyphenPos != -1) { + typeface.remove(0, hyphenPos + 1); + } else { + typeface = QLatin1String("Normal"); + } +// qDebug() << " massaged family" << family << "typeface" << typeface << "psize" << pSize; + newFont = QFontDatabase().font(family, typeface, pSize); + newFont.setUnderline(resolveFont.underline()); + newFont.setStrikeOut(resolveFont.strikeOut()); + + } + return newFont; +} + @implementation QCocoaFontPanelDelegate - (id)initWithFontPanel:(NSFontPanel *)panel stolenContentView:(NSView *)stolenContentView @@ -134,7 +156,6 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin mOkButton = okButton; mCancelButton = cancelButton; mPriv = priv; - mCocoaFont = 0; mPanelHackedWithButtons = (okButton != 0); mDialogExtraWidth = extraWidth; mDialogExtraHeight = extraHeight; @@ -155,42 +176,14 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin - (void)dealloc { - if (mCocoaFont) - [mCocoaFont release]; delete mQtFont; [super dealloc]; } - (void)changeFont:(id)sender { - Q_UNUSED(sender); - - QFont newFont; - - if (mCocoaFont) - [mCocoaFont autorelease]; NSFont *dummyFont = [NSFont userFontOfSize:12.0]; - mCocoaFont = [sender convertFont:dummyFont]; - if (mCocoaFont) { - [mCocoaFont retain]; - - int pSize = qRound([mCocoaFont pointSize]); - QString family(QCFString::toQString(reinterpret_cast([mCocoaFont familyName]))); - QString typeface(QCFString::toQString(reinterpret_cast([mCocoaFont fontName]))); -// qDebug() << "original family" << family << "typeface" << typeface << "psize" << pSize; - int hyphenPos = typeface.indexOf(QLatin1Char('-')); - if (hyphenPos != -1) { - typeface.remove(0, hyphenPos + 1); - } else { - typeface = QLatin1String("Normal"); - } -// qDebug() << " massaged family" << family << "typeface" << typeface << "psize" << pSize; - newFont = QFontDatabase().font(family, typeface, pSize); - newFont.setUnderline(mQtFont->underline()); - newFont.setStrikeOut(mQtFont->strikeOut()); - } - - [self setQtFont:newFont]; + [self setQtFont:qfontForCocoaFont([sender convertFont:dummyFont], *mQtFont)]; if (mPriv) mPriv->updateSampleFont(*mQtFont); } @@ -317,6 +310,9 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin - (void)onOkClicked { Q_ASSERT(mPanelHackedWithButtons); + NSFontManager *fontManager = [NSFontManager sharedFontManager]; + [self setQtFont:qfontForCocoaFont([fontManager convertFont:[fontManager selectedFont]], + *mQtFont)]; [[mStolenContentView window] close]; [self finishOffWithCode:NSOKButton]; } @@ -374,16 +370,7 @@ const int StyleMask = NSTitledWindowMask | NSClosableWindowMask | NSResizableWin mModalSession = 0; } - // temporary hack to work around bug in deleteLater() in Qt/Mac Cocoa -#if 1 - bool deleteDialog = mPriv->fontDialog()->testAttribute(Qt::WA_DeleteOnClose); - mPriv->fontDialog()->setAttribute(Qt::WA_DeleteOnClose, false); -#endif mPriv->done((code == NSOKButton) ? QDialog::Accepted : QDialog::Rejected); -#if 1 - if (deleteDialog) - delete mPriv->fontDialog(); -#endif } else { [NSApp stopModalWithCode:code]; } -- cgit v0.12 From e7fdaf47dfdf5e2f6056aa5d5b4644e74a05492a Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Mon, 27 Apr 2009 16:11:21 +0200 Subject: Doc - cleaning up some documentation for QFileDialog and obsolete documentation. getOpenFileNames() and getExistingDirectory() mentioned that the dir parameter was ignored. This is no longer the case. This bit was reviewed by nrc, the other fixes were just cleanups. Task-number: 252223 Reviewed-by: nrc --- src/gui/dialogs/qfiledialog.cpp | 263 ++++++++++++++++++++-------------------- 1 file changed, 129 insertions(+), 134 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index d786f3e..073c25b 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -1538,52 +1538,51 @@ extern QString qt_win_get_existing_directory(const QFileDialogArgs &args); #endif /*! - This is a convenience static function that returns an existing file - selected by the user. If the user presses Cancel, it returns a null - string. + This is a convenience static function that returns an existing file + selected by the user. If the user presses Cancel, it returns a null string. - \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 8 + \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 8 - The function creates a modal file dialog with the given \a parent widget. - If the parent is not 0, the dialog will be shown centered over the - parent widget. + The function creates a modal file dialog with the given \a parent widget. + If \a parent is not 0, the dialog will be shown centered over the parent + widget. - The file dialog's working directory will be set to \a dir. If \a - dir includes a file name, the file will be selected. Only files - that match the given \a filter are shown. The filter selected is - set to \a selectedFilter. The parameters \a dir, \a - selectedFilter, and \a filter may be empty strings. If you want - multiple filters, separate them with ';;', for example: + The file dialog's working directory will be set to \a dir. If \a dir + includes a file name, the file will be selected. Only files that match the + given \a filter are shown. The filter selected is set to \a selectedFilter. + The parameters \a dir, \a selectedFilter, and \a filter may be empty + strings. If you want multiple filters, separate them with ';;', for + example: - \code + \code "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" - \endcode + \endcode - The \a options argument holds various - options about how to run the dialog, see the QFileDialog::Option enum for - more information on the flags you can pass. + The \a options argument holds various options about how to run the dialog, + see the QFileDialog::Option enum for more information on the flags you can + pass. - The dialog's caption is set to \a caption. If \a caption is not - specified then a default caption will be used. + The dialog's caption is set to \a caption. If \a caption is not specified + then a default caption will be used. - Under Windows and Mac OS X, this static function will use the native - file dialog and not a QFileDialog. + On Windows and Mac OS X, this static function will use the native file + dialog and not a QFileDialog. - Note that on Windows the dialog will spin a blocking modal event loop - that will not dispatch any QTimers, and if parent is not 0 then it will - position the dialog just under the parent's title bar. + On Windows the dialog will spin a blocking modal event loop that will not + dispatch any QTimers, and if \a parent is not 0 then it will position the + dialog just below the parent's title bar. - Under Unix/X11, the normal behavior of the file dialog is to resolve - and follow symlinks. For example, if \c{/usr/tmp} is a symlink to - \c{/var/tmp}, the file dialog will change to \c{/var/tmp} after - entering \c{/usr/tmp}. If \a options includes DontResolveSymlinks, - the file dialog will treat symlinks as regular directories. + On Unix/X11, the normal behavior of the file dialog is to resolve and + follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp}, + the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If + \a options includes DontResolveSymlinks, the file dialog will treat + symlinks as regular directories. - \warning Do not delete \a parent during the execution of the dialog. - If you want to do this, you should create the dialog - yourself using one of the QFileDialog constructors. + \warning Do not delete \a parent during the execution of the dialog. If you + want to do this, you should create the dialog yourself using one of the + QFileDialog constructors. - \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory() + \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory() */ QString QFileDialog::getOpenFileName(QWidget *parent, const QString &caption, @@ -1626,54 +1625,53 @@ QString QFileDialog::getOpenFileName(QWidget *parent, } /*! - This is a convenience static function that will return one or more - existing files selected by the user. + This is a convenience static function that will return one or more existing + files selected by the user. - \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 9 + \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 9 - This function creates a modal file dialog with the given \a parent - widget. If the parent is not 0, the dialog will be shown centered - over the parent widget. + This function creates a modal file dialog with the given \a parent widget. + If \a parent is not 0, the dialog will be shown centered over the parent + widget. - The file dialog's working directory will be set to \a dir. If \a - dir includes a file name, the file will be selected. The filter - is set to \a filter so that only those files which match the filter - are shown. The filter selected is set to \a selectedFilter. The parameters - \a dir, \a selectedFilter and \a filter may be empty strings. If you - need multiple filters, separate them with ';;', for instance: + The file dialog's working directory will be set to \a dir. If \a dir + includes a file name, the file will be selected. The filter is set to + \a filter so that only those files which match the filter are shown. The + filter selected is set to \a selectedFilter. The parameters \a dir, + \a selectedFilter and \a filter may be empty strings. If you need multiple + filters, separate them with ';;', for instance: - \code + \code "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" - \endcode + \endcode - The dialog's caption is set to \a caption. If \a caption is not - specified then a default caption will be used. + The dialog's caption is set to \a caption. If \a caption is not specified + then a default caption will be used. - Under Windows and Mac OS X, this static function will use the native - file dialog and not a QFileDialog. On Mac OS X, the \a dir argument - is ignored, the native dialog always displays the last visited directory. + On Windows and Mac OS X, this static function will use the native file + dialog and not a QFileDialog. - Note that on Windows the dialog will spin a blocking modal event loop - that will not dispatch any QTimers, and if parent is not 0 then it will - position the dialog just under the parent's title bar. + On Windows the dialog will spin a blocking modal event loop that will not + dispatch any QTimers, and if \a parent is not 0 then it will position the + dialog just below the parent's title bar. - Under Unix/X11, the normal behavior of the file dialog is to resolve - and follow symlinks. For example, if \c{/usr/tmp} is a symlink to - \c{/var/tmp}, the file dialog will change to \c{/var/tmp} after - entering \c{/usr/tmp}. The \a options argument holds various - options about how to run the dialog, see the QFileDialog::Option enum for - more information on the flags you can pass. + On Unix/X11, the normal behavior of the file dialog is to resolve and + follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp}, + the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. + The \a options argument holds various options about how to run the dialog, + see the QFileDialog::Option enum for more information on the flags you can + pass. - Note that if you want to iterate over the list of files, you should - iterate over a copy. For example: + \note If you want to iterate over the list of files, you should iterate + over a copy. For example: \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 10 - \warning Do not delete \a parent during the execution of the dialog. - If you want to do this, you should create the dialog - yourself using one of the QFileDialog constructors. + \warning Do not delete \a parent during the execution of the dialog. If you + want to do this, you should create the dialog yourself using one of the + QFileDialog constructors. - \sa getOpenFileName(), getSaveFileName(), getExistingDirectory() + \sa getOpenFileName(), getSaveFileName(), getExistingDirectory() */ QStringList QFileDialog::getOpenFileNames(QWidget *parent, const QString &caption, @@ -1717,54 +1715,54 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, } /*! - This is a convenience static function that will return a file name - selected by the user. The file does not have to exist. + This is a convenience static function that will return a file name selected + by the user. The file does not have to exist. - It creates a modal file dialog with the given \a parent widget. If the - parent is not 0, the dialog will be shown centered over the parent - widget. + It creates a modal file dialog with the given \a parent widget. If + \a parent is not 0, the dialog will be shown centered over the parent + widget. - \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 11 + \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 11 - The file dialog's working directory will be set to \a dir. If \a - dir includes a file name, the file will be selected. Only files that - match the \a filter are shown. The filter selected is set to - \a selectedFilter. The parameters \a dir, \a selectedFilter, and - \a filter may be empty strings. Multiple filters are separated with ';;'. - For instance: + The file dialog's working directory will be set to \a dir. If \a dir + includes a file name, the file will be selected. Only files that match the + \a filter are shown. The filter selected is set to \a selectedFilter. The + parameters \a dir, \a selectedFilter, and \a filter may be empty strings. + Multiple filters are separated with ';;'. For instance: - \code + \code "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" - \endcode + \endcode - The \a options argument holds various - options about how to run the dialog, see the QFileDialog::Option enum for - more information on the flags you can pass. + The \a options argument holds various options about how to run the dialog, + see the QFileDialog::Option enum for more information on the flags you can + pass. - The default filter can be chosen by setting \a selectedFilter to the desired value. + The default filter can be chosen by setting \a selectedFilter to the + desired value. - The dialog's caption is set to \a caption. If \a caption is not - specified then a default caption will be used. + The dialog's caption is set to \a caption. If \a caption is not specified, + a default caption will be used. - Under Windows and Mac OS X, this static function will use the native - file dialog and not a QFileDialog. + On Windows and Mac OS X, this static function will use the native file + dialog and not a QFileDialog. - Note that on Windows the dialog will spin a blocking modal event loop - that will not dispatch any QTimers, and if parent is not 0 then it will - position the dialog just under the parent's title bar. - On Mac OS X, the filter argument is ignored. + On Windows the dialog will spin a blocking modal event loop that will not + dispatch any QTimers, and if \a parent is not 0 then it will position the + dialog just below the parent's title bar. On Mac OS X, with its native file + dialog, the filter argument is ignored. - Under Unix/X11, the normal behavior of the file dialog is to resolve - and follow symlinks. For example, if \c{/usr/tmp} is a symlink to - \c{/var/tmp}, the file dialog will change to \c{/var/tmp} after - entering \c{/usr/tmp}. If \a options includes DontResolveSymlinks, - the file dialog will treat symlinks as regular directories. + On Unix/X11, the normal behavior of the file dialog is to resolve and + follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp}, + the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If + \a options includes DontResolveSymlinks the file dialog will treat symlinks + as regular directories. - \warning Do not delete \a parent during the execution of the dialog. - If you want to do this, you should create the dialog - yourself using one of the QFileDialog constructors. + \warning Do not delete \a parent during the execution of the dialog. If you + want to do this, you should create the dialog yourself using one of the + QFileDialog constructors. - \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory() + \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory() */ QString QFileDialog::getSaveFileName(QWidget *parent, const QString &caption, @@ -1810,46 +1808,43 @@ QString QFileDialog::getSaveFileName(QWidget *parent, } /*! - This is a convenience static function that will return an existing - directory selected by the user. + This is a convenience static function that will return an existing + directory selected by the user. - \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 12 + \snippet doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp 12 - This function creates a modal file dialog with the given \a parent - widget. If the parent is not 0, the dialog will be shown centered over - the parent widget. + This function creates a modal file dialog with the given \a parent widget. + If \a parent is not 0, the dialog will be shown centered over the parent + widget. - The dialog's working directory is set to \a dir, and the caption is - set to \a caption. Either of these may be an empty string in which case - the current directory and a default caption will be used - respectively. + The dialog's working directory is set to \a dir, and the caption is set to + \a caption. Either of these may be an empty string in which case the + current directory and a default caption will be used respectively. - The \a options argument holds various - options about how to run the dialog, see the QFileDialog::Option enum for - more information on the flags you can pass. Note that \l{QFileDialog::}{ShowDirsOnly} - must be set to ensure a native file dialog. + The \a options argument holds various options about how to run the dialog, + see the QFileDialog::Option enum for more information on the flags you can + pass. To ensure a native file dialog, \l{QFileDialog::}{ShowDirsOnly} must + be set. - Under Windows and Mac OS X, this static function will use the native - file dialog and not a QFileDialog. On Mac OS X, the \a dir argument - is ignored, the native dialog always displays the last visited directory. - On Windows CE, if the device has no native file dialog, a QFileDialog - will be used. + On Windows and Mac OS X, this static function will use the native file + dialog and not a QFileDialog. On Windows CE, if the device has no native + file dialog, a QFileDialog will be used. - Under Unix/X11, the normal behavior of the file dialog is to resolve - and follow symlinks. For example, if \c{/usr/tmp} is a symlink to - \c{/var/tmp}, the file dialog will change to \c{/var/tmp} after - entering \c{/usr/tmp}. If \a options includes DontResolveSymlinks, - the file dialog will treat symlinks as regular directories. + On Unix/X11, the normal behavior of the file dialog is to resolve and + follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp}, + the file dialog will change to \c{/var/tmp} after entering \c{/usr/tmp}. If + \a options includes DontResolveSymlinks, the file dialog will treat + symlinks as regular directories. - Note that on Windows the dialog will spin a blocking modal event loop - that will not dispatch any QTimers, and if parent is not 0 then it will - position the dialog just under the parent's title bar. + On Windows the dialog will spin a blocking modal event loop that will not + dispatch any QTimers, and if \a parent is not 0 then it will position the + dialog just below the parent's title bar. - \warning Do not delete \a parent during the execution of the dialog. - If you want to do this, you should create the dialog - yourself using one of the QFileDialog constructors. + \warning Do not delete \a parent during the execution of the dialog. If you + want to do this, you should create the dialog yourself using one of the + QFileDialog constructors. - \sa getOpenFileName(), getOpenFileNames(), getSaveFileName() + \sa getOpenFileName(), getOpenFileNames(), getSaveFileName() */ QString QFileDialog::getExistingDirectory(QWidget *parent, const QString &caption, -- cgit v0.12 From ae949b9d21470a9b9bf200774c246a0b86a69ff6 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 27 Apr 2009 16:31:58 +0200 Subject: QPixmapCache:Remove the old pixmap if you insert one with the same key. If you insert a new pixmap in the cache with a key that was already in the cache then we remove the old pixmap and add the new one. This avoid to fill the memory with garbage even if the cache has a protection to avoid running out of memory. This was discovered with QraphicsView and its cache. We don't need to keep old cached pixmaps for an item. Task-number: KDE Reviewed-by: Trond --- src/gui/image/qpixmapcache.cpp | 5 +++++ tests/auto/qpixmapcache/tst_qpixmapcache.cpp | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index eedb6a3..458d6b9 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -187,6 +187,11 @@ bool QPMCache::insert(const QString& key, const QPixmap &pixmap, int cost) cacheKeys.insert(key, cacheKey); return true; } + qint64 oldCacheKey = cacheKeys.value(key, -1); + //If for the same key we add already a pixmap we should delete it + if (oldCacheKey != -1) + QCache::remove(oldCacheKey); + bool success = QCache::insert(cacheKey, new QDetachedPixmap(pixmap), cost); if (success) { cacheKeys.insert(key, cacheKey); diff --git a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp index c163b52..1f515ff 100644 --- a/tests/auto/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/qpixmapcache/tst_qpixmapcache.cpp @@ -166,6 +166,16 @@ void tst_QPixmapCache::insert() QVERIFY(estimatedNum - 1 <= num <= estimatedNum + 1); QPixmap p3; QPixmapCache::insert("null", p3); + + QPixmap c1(10, 10); + c1.fill(Qt::yellow); + QPixmapCache::insert("custom", c1); + QVERIFY(!c1.isDetached()); + QPixmap c2(10, 10); + c2.fill(Qt::red); + QPixmapCache::insert("custom", c2); + //We have deleted the old pixmap in the cache for the same key + QVERIFY(c1.isDetached()); } void tst_QPixmapCache::remove() -- cgit v0.12 From 73fefcfb67b2de42a0675eb88aaa5cb2751402e6 Mon Sep 17 00:00:00 2001 From: kh Date: Mon, 27 Apr 2009 17:30:20 +0200 Subject: fixes undefined behavior will closing all tabs Task-number: 249001, 236473 Reviewed-by: kh --- tools/assistant/tools/assistant/centralwidget.cpp | 241 ++++++++++++---------- tools/assistant/tools/assistant/centralwidget.h | 14 +- tools/assistant/tools/assistant/mainwindow.cpp | 10 +- tools/assistant/tools/assistant/mainwindow.h | 1 + tools/assistant/tools/assistant/searchwidget.cpp | 11 + tools/assistant/tools/assistant/searchwidget.h | 4 + 6 files changed, 165 insertions(+), 116 deletions(-) diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 0a94a3d..f953ab7 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -161,7 +161,7 @@ void FindWidget::updateButtons() QToolButton* FindWidget::setupToolButton(const QString &text, const QString &icon) { - QToolButton* toolButton = new QToolButton(this); + QToolButton *toolButton = new QToolButton(this); toolButton->setText(text); toolButton->setAutoRaise(true); @@ -262,13 +262,16 @@ CentralWidget::~CentralWidget() QString zoomCount; QString currentPages; QLatin1Char separator('|'); - for (int i = 1; i < tabWidget->count(); ++i) { + int i = m_searchWidget->isAttached() ? 1 : 0; + + for (; i < tabWidget->count(); ++i) { HelpViewer *viewer = qobject_cast(tabWidget->widget(i)); if (viewer && viewer->source().isValid()) { currentPages += viewer->source().toString() + separator; zoomCount += QString::number(viewer->zoom()) + separator; } } + engine.setCustomValue(QLatin1String("LastTabPage"), lastTabPage); engine.setCustomValue(QLatin1String("LastShownPages"), currentPages); #if !defined(QT_NO_WEBKIT) @@ -285,7 +288,7 @@ CentralWidget *CentralWidget::instance() void CentralWidget::newTab() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); #if !defined(QT_NO_WEBKIT) if (viewer && viewer->hasLoadFinished()) #else @@ -296,7 +299,7 @@ void CentralWidget::newTab() void CentralWidget::zoomIn() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (viewer) viewer->zoomIn(); @@ -306,7 +309,7 @@ void CentralWidget::zoomIn() void CentralWidget::zoomOut() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (viewer) viewer->zoomOut(); @@ -329,7 +332,7 @@ void CentralWidget::nextPage() void CentralWidget::resetZoom() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (viewer) viewer->resetZoom(); @@ -353,7 +356,7 @@ void CentralWidget::findPrevious() void CentralWidget::closeTab() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (!viewer|| tabWidget->count() == 1) return; @@ -363,8 +366,8 @@ void CentralWidget::closeTab() void CentralWidget::setSource(const QUrl &url) { - HelpViewer* viewer = currentHelpViewer(); - HelpViewer* lastViewer = qobject_cast(tabWidget->widget(lastTabPage)); + HelpViewer *viewer = currentHelpViewer(); + HelpViewer *lastViewer = qobject_cast(tabWidget->widget(lastTabPage)); if (!viewer && !lastViewer) { viewer = new HelpViewer(helpEngine, this); @@ -418,13 +421,13 @@ void CentralWidget::setLastShownPages() bool CentralWidget::hasSelection() const { - const HelpViewer* viewer = currentHelpViewer(); + const HelpViewer *viewer = currentHelpViewer(); return viewer ? viewer->hasSelection() : false; } QUrl CentralWidget::currentSource() const { - const HelpViewer* viewer = currentHelpViewer(); + const HelpViewer *viewer = currentHelpViewer(); if (viewer) return viewer->source(); @@ -433,7 +436,7 @@ QUrl CentralWidget::currentSource() const QString CentralWidget::currentTitle() const { - const HelpViewer* viewer = currentHelpViewer(); + const HelpViewer *viewer = currentHelpViewer(); if (viewer) return viewer->documentTitle(); @@ -442,7 +445,7 @@ QString CentralWidget::currentTitle() const void CentralWidget::copySelection() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (viewer) viewer->copy(); } @@ -465,7 +468,7 @@ void CentralWidget::initPrinter() void CentralWidget::print() { #ifndef QT_NO_PRINTER - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (!viewer) return; @@ -522,14 +525,14 @@ bool CentralWidget::isHomeAvailable() const void CentralWidget::home() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (viewer) viewer->home(); } bool CentralWidget::isForwardAvailable() const { - const HelpViewer* viewer = currentHelpViewer(); + const HelpViewer *viewer = currentHelpViewer(); if (viewer) return viewer->isForwardAvailable(); @@ -538,14 +541,14 @@ bool CentralWidget::isForwardAvailable() const void CentralWidget::forward() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (viewer) viewer->forward(); } bool CentralWidget::isBackwardAvailable() const { - const HelpViewer* viewer = currentHelpViewer(); + const HelpViewer *viewer = currentHelpViewer(); if (viewer) return viewer->isBackwardAvailable(); @@ -554,7 +557,7 @@ bool CentralWidget::isBackwardAvailable() const void CentralWidget::backward() { - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (viewer) viewer->backward(); } @@ -572,7 +575,7 @@ void CentralWidget::setGlobalActions(const QList &actions) void CentralWidget::setSourceInNewTab(const QUrl &url, qreal zoom) { - HelpViewer* viewer; + HelpViewer *viewer; #if defined(QT_NO_WEBKIT) viewer = currentHelpViewer(); @@ -595,20 +598,20 @@ void CentralWidget::setSourceInNewTab(const QUrl &url, qreal zoom) } #if !defined(QT_NO_WEBKIT) - QWebSettings* settings = QWebSettings::globalSettings(); + QWebSettings *settings = QWebSettings::globalSettings(); if (!userFont) { int fontSize = settings->fontSize(QWebSettings::DefaultFontSize); QString fontFamily = settings->fontFamily(QWebSettings::StandardFont); font = QFont(fontFamily, fontSize); } - QWebView* view = qobject_cast (viewer); + QWebView *view = qobject_cast (viewer); if (view) { settings = view->settings(); settings->setFontFamily(QWebSettings::StandardFont, font.family()); settings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize()); } else if (viewer) { - viewer->setFont(font); + viewer->setFont(font); } viewer->setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom); #else @@ -622,7 +625,7 @@ void CentralWidget::setSourceInNewTab(const QUrl &url, qreal zoom) HelpViewer *CentralWidget::newEmptyTab() { - HelpViewer* viewer = new HelpViewer(helpEngine, this); + HelpViewer *viewer = new HelpViewer(helpEngine, this); viewer->installEventFilter(this); viewer->setFocus(Qt::OtherFocusReason); #if defined(QT_NO_WEBKIT) @@ -641,7 +644,7 @@ void CentralWidget::findCurrentText(const QString &text) void CentralWidget::connectSignals() { - const HelpViewer* viewer = currentHelpViewer(); + const HelpViewer *viewer = currentHelpViewer(); if (viewer) { connect(viewer, SIGNAL(copyAvailable(bool)), this, SIGNAL(copyAvailable(bool))); @@ -676,18 +679,18 @@ void CentralWidget::activateTab(bool onlyHelpViewer) } } -void CentralWidget::setTabTitle(const QUrl& url) +void CentralWidget::setTabTitle(const QUrl &url) { Q_UNUSED(url) #if !defined(QT_NO_WEBKIT) QTabBar *tabBar = qFindChild(tabWidget); for (int tab = 0; tab < tabBar->count(); ++tab) { - HelpViewer* viewer = qobject_cast(tabWidget->widget(tab)); + HelpViewer *viewer = qobject_cast(tabWidget->widget(tab)); if (viewer) tabWidget->setTabText(tab, viewer->documentTitle().trimmed()); } #else - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); if (viewer) { tabWidget->setTabText(lastTabPage, quoteTabTitle(viewer->documentTitle().trimmed())); @@ -698,61 +701,50 @@ void CentralWidget::setTabTitle(const QUrl& url) void CentralWidget::currentPageChanged(int index) { const HelpViewer *viewer = currentHelpViewer(); - - if (viewer || tabWidget->count() == 1) + if (viewer) lastTabPage = index; - bool enabled = false; - if (viewer) { - enabled = true; - if (!m_searchWidget) - enabled = tabWidget->count() > 1; - } + QWidget *widget = tabWidget->cornerWidget(Qt::TopRightCorner); + widget->setEnabled(viewer && enableTabCloseAction()); - QWidget *widget = tabWidget->cornerWidget(Qt::TopLeftCorner); - widget->setEnabled(m_searchWidget ? enabled : true); + widget = tabWidget->cornerWidget(Qt::TopLeftCorner); + widget->setEnabled(viewer ? true : false); - widget = tabWidget->cornerWidget(Qt::TopRightCorner); - widget->setEnabled(enabled); - - emit currentViewerChanged(); + emit currentViewerChanged(); } void CentralWidget::showTabBarContextMenu(const QPoint &point) { - HelpViewer* viewer = helpViewerFromTabPosition(tabWidget, point); + HelpViewer *viewer = helpViewerFromTabPosition(tabWidget, point); if (!viewer) return; QTabBar *tabBar = qFindChild(tabWidget); QMenu menu(QLatin1String(""), tabBar); - QAction *new_page = menu.addAction(tr("Add New Page")); - QAction *close_page = menu.addAction(tr("Close This Page")); - QAction *close_pages = menu.addAction(tr("Close Other Pages")); - menu.addSeparator(); - QAction *newBookmark = menu.addAction(tr("Add Bookmark for this Page...")); + QAction *newPage = menu.addAction(tr("Add New Page")); - if (tabBar->count() == 1) { - close_page->setEnabled(false); - close_pages->setEnabled(false); - } else if (m_searchWidget && tabBar->count() == 2) { - close_pages->setEnabled(false); - } + bool enableAction = enableTabCloseAction(); + QAction *closePage = menu.addAction(tr("Close This Page")); + closePage->setEnabled(enableAction); - QAction *picked_action = menu.exec(tabBar->mapToGlobal(point)); - if (!picked_action) - return; + QAction *closePages = menu.addAction(tr("Close Other Pages")); + closePages->setEnabled(enableAction); - if (picked_action == new_page) + menu.addSeparator(); + + QAction *newBookmark = menu.addAction(tr("Add Bookmark for this Page...")); + + QAction *pickedAction = menu.exec(tabBar->mapToGlobal(point)); + if (pickedAction == newPage) setSourceInNewTab(viewer->source()); - if (picked_action == close_page) { + if (pickedAction == closePage) { tabWidget->removeTab(tabWidget->indexOf(viewer)); QTimer::singleShot(0, viewer, SLOT(deleteLater())); } - if (picked_action == close_pages) { + if (pickedAction == closePages) { int currentPage = tabWidget->indexOf(viewer); for (int i = tabBar->count() -1; i >= 0; --i) { viewer = qobject_cast(tabWidget->widget(i)); @@ -766,58 +758,68 @@ void CentralWidget::showTabBarContextMenu(const QPoint &point) } } - if (picked_action == newBookmark) + if (pickedAction == newBookmark) emit addNewBookmark(viewer->documentTitle(), viewer->source().toString()); } bool CentralWidget::eventFilter(QObject *object, QEvent *e) { - if (currentHelpViewer() == object && e->type() == QEvent::KeyPress){ + if (e->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast(e); - if (ke->key() == Qt::Key_Backspace) { - HelpViewer *viewer = currentHelpViewer(); + switch (ke->key()) { + default: { + return QWidget::eventFilter(object, e); + } break; + + case Qt::Key_Escape: { + if (findWidget->editFind == object) { + findBar->hide(); + if (HelpViewer *viewer = currentHelpViewer()) + viewer->setFocus(); + } + } break; + + case Qt::Key_Backspace: { + HelpViewer *viewer = currentHelpViewer(); + if (viewer == object) { #if defined(QT_NO_WEBKIT) - if (viewer && viewer->isBackwardAvailable()) { + if (viewer->isBackwardAvailable()) { #else - if (viewer && viewer->isBackwardAvailable() && !viewer->hasFocus()) { + if (viewer->isBackwardAvailable() && !viewer->hasFocus()) { #endif - viewer->backward(); - return true; - } + viewer->backward(); + return true; + } + } + } break; } } - QTabBar *tabBar = qobject_cast(object); - bool mousRel = e->type() == QEvent::MouseButtonRelease; - bool dblClick = e->type() == QEvent::MouseButtonDblClick; - - if (tabBar && (mousRel || dblClick)) { - QMouseEvent *mouseEvent = static_cast(e); - HelpViewer *viewer = helpViewerFromTabPosition(tabWidget, mouseEvent->pos()); - if (!m_searchWidget && tabWidget->count() <= 1) - return QWidget::eventFilter(object, e); - - if (viewer && (mouseEvent->button() == Qt::MidButton || dblClick)) { - tabWidget->removeTab(tabWidget->indexOf(viewer)); - QTimer::singleShot(0, viewer, SLOT(deleteLater())); - currentPageChanged(tabWidget->currentIndex()); - return true; - } - } else if (object == findWidget->editFind && e->type() == QEvent::KeyPress) { - QKeyEvent *ke = static_cast(e); - if (ke->key() == Qt::Key_Escape) { - findBar->hide(); - HelpViewer *hv = currentHelpViewer(); - if (hv) - hv->setFocus(); + if (QTabBar *tabBar = qobject_cast(object)) { + const bool dblClick = e->type() == QEvent::MouseButtonDblClick; + if ((e->type() == QEvent::MouseButtonRelease) || dblClick) { + QMouseEvent *mouseEvent = static_cast(e); + HelpViewer *viewer = helpViewerFromTabPosition(tabWidget, + mouseEvent->pos()); + if (viewer) { + if ((mouseEvent->button() == Qt::MidButton) || dblClick) { + if (availableHelpViewer() > 1) { + tabWidget->removeTab(tabWidget->indexOf(viewer)); + QTimer::singleShot(0, viewer, SLOT(deleteLater())); + currentPageChanged(tabWidget->currentIndex()); + return true; + } + } + } } } + return QWidget::eventFilter(object, e); } void CentralWidget::keyPressEvent(QKeyEvent *e) { - QString text = e->text(); + const QString &text = e->text(); if (text.startsWith(QLatin1Char('/'))) { if (!findBar->isVisible()) { findBar->show(); @@ -837,7 +839,7 @@ void CentralWidget::find(QString ttf, bool forward, bool backward) QTextDocument *doc = 0; QTextBrowser *browser = 0; - HelpViewer* viewer = currentHelpViewer(); + HelpViewer *viewer = currentHelpViewer(); QPalette p = findWidget->editFind->palette(); p.setColor(QPalette::Active, QPalette::Base, Qt::white); @@ -876,7 +878,7 @@ void CentralWidget::find(QString ttf, bool forward, bool backward) } if (tabWidget->currentWidget() == m_searchWidget) { - QTextBrowser* browser = qFindChild(m_searchWidget); + QTextBrowser *browser = qFindChild(m_searchWidget); if (browser) { doc = browser->document(); cursor = browser->textCursor(); @@ -933,15 +935,6 @@ void CentralWidget::find(QString ttf, bool forward, bool backward) findWidget->editFind->setPalette(p); } -void CentralWidget::activateSearch() -{ - if (tabWidget->widget(0) != m_searchWidget) - createSearchWidget(helpEngine->searchEngine()); - - tabWidget->setCurrentWidget(m_searchWidget); - m_searchWidget->setFocus(); -} - void CentralWidget::updateBrowserFont() { QFont font = qApp->font(); @@ -952,7 +945,7 @@ void CentralWidget::updateBrowserFont() } #if !defined(QT_NO_WEBKIT) - QWebSettings* settings = QWebSettings::globalSettings(); + QWebSettings *settings = QWebSettings::globalSettings(); if (!userFont) { int fontSize = settings->fontSize(QWebSettings::DefaultFontSize); QString fontFamily = settings->fontFamily(QWebSettings::StandardFont); @@ -960,11 +953,11 @@ void CentralWidget::updateBrowserFont() } #endif - QWidget* widget = 0; + QWidget *widget = 0; for (int i = 0; i < tabWidget->count(); ++i) { widget = tabWidget->widget(i); #if !defined(QT_NO_WEBKIT) - QWebView* view = qobject_cast (widget); + QWebView *view = qobject_cast (widget); if (view) { settings = view->settings(); settings->setFontFamily(QWebSettings::StandardFont, font.family()); @@ -991,11 +984,41 @@ void CentralWidget::createSearchWidget(QHelpSearchEngine *searchEngine) SLOT(setSourceFromSearchInNewTab(QUrl))); } tabWidget->insertTab(0, m_searchWidget, tr("Search")); + m_searchWidget->setAttached(true); +} + +void CentralWidget::activateSearchWidget() +{ + if (!m_searchWidget->isAttached()) + createSearchWidget(helpEngine->searchEngine()); + + tabWidget->setCurrentWidget(m_searchWidget); + m_searchWidget->setFocus(); } void CentralWidget::removeSearchWidget() { - tabWidget->removeTab(0); + if (m_searchWidget && m_searchWidget->isAttached()) { + tabWidget->removeTab(0); + m_searchWidget->setAttached(false); + } +} + +int CentralWidget::availableHelpViewer() const +{ + int count = tabWidget->count(); + if (m_searchWidget && m_searchWidget->isAttached()) + count--; + return count; +} + +bool CentralWidget::enableTabCloseAction() const +{ + int minTabCount = 1; + if (m_searchWidget && m_searchWidget->isAttached()) + minTabCount = 2; + + return (tabWidget->count() > minTabCount); } QString CentralWidget::quoteTabTitle(const QString &title) const @@ -1026,7 +1049,7 @@ CentralWidget::highlightSearchTerms() if (!viewer) return; - QHelpSearchEngine* searchEngine = helpEngine->searchEngine(); + QHelpSearchEngine *searchEngine = helpEngine->searchEngine(); QList queryList = searchEngine->query(); QStringList terms; diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h index a34ba65..2c28091 100644 --- a/tools/assistant/tools/assistant/centralwidget.h +++ b/tools/assistant/tools/assistant/centralwidget.h @@ -116,10 +116,14 @@ public: void setGlobalActions(const QList &actions); HelpViewer *currentHelpViewer() const; void activateTab(bool onlyHelpViewer = false); - void activateSearch(); + void createSearchWidget(QHelpSearchEngine *searchEngine); + void activateSearchWidget(); void removeSearchWidget(); + int availableHelpViewer() const; + bool enableTabCloseAction() const; + void closeTabAt(int index); QMap currentSourceFileList() const; @@ -170,7 +174,7 @@ private slots: void setSourceFromSearchInNewTab(const QUrl &url); private: - void connectSignals(); + void connectSignals(); bool eventFilter(QObject *object, QEvent *e); void find(QString ttf, bool forward, bool backward); void initPrinter(); @@ -183,13 +187,13 @@ private: QList globalActionList; QWidget *findBar; - QTabWidget* tabWidget; + QTabWidget *tabWidget; FindWidget *findWidget; QHelpEngine *helpEngine; QPrinter *printer; bool usesDefaultCollection; - - SearchWidget* m_searchWidget; + + SearchWidget *m_searchWidget; }; QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 6e22413..426a828 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -535,6 +535,8 @@ void MainWindow::setupActions() SLOT(copyAvailable(bool))); connect(m_centralWidget, SIGNAL(currentViewerChanged()), this, SLOT(updateNavigationItems())); + connect(m_centralWidget, SIGNAL(currentViewerChanged()), this, + SLOT(updateTabCloseAction())); connect(m_centralWidget, SIGNAL(forwardAvailable(bool)), this, SLOT(updateNavigationItems())); connect(m_centralWidget, SIGNAL(backwardAvailable(bool)), this, @@ -697,10 +699,14 @@ void MainWindow::updateNavigationItems() m_printAction->setEnabled(hasCurrentViewer); m_nextAction->setEnabled(m_centralWidget->isForwardAvailable()); m_backAction->setEnabled(m_centralWidget->isBackwardAvailable()); - m_closeTabAction->setEnabled(hasCurrentViewer); m_newTabAction->setEnabled(hasCurrentViewer); } +void MainWindow::updateTabCloseAction() +{ + m_closeTabAction->setEnabled(m_centralWidget->enableTabCloseAction()); +} + void MainWindow::showTopicChooser(const QMap &links, const QString &keyword) { @@ -871,7 +877,7 @@ void MainWindow::activateCurrentCentralWidgetTab() void MainWindow::showSearch() { - m_centralWidget->activateSearch(); + m_centralWidget->activateSearchWidget(); } void MainWindow::hideSearch() diff --git a/tools/assistant/tools/assistant/mainwindow.h b/tools/assistant/tools/assistant/mainwindow.h index 1bd8005..7d08a74 100644 --- a/tools/assistant/tools/assistant/mainwindow.h +++ b/tools/assistant/tools/assistant/mainwindow.h @@ -104,6 +104,7 @@ private slots: void showAboutDialog(); void copyAvailable(bool yes); void updateNavigationItems(); + void updateTabCloseAction(); void showNewAddress(const QUrl &url); void addNewBookmark(const QString &title, const QString &url); void showTopicChooser(const QMap &links, const QString &keyword); diff --git a/tools/assistant/tools/assistant/searchwidget.cpp b/tools/assistant/tools/assistant/searchwidget.cpp index 677e18e..c40a9c4 100644 --- a/tools/assistant/tools/assistant/searchwidget.cpp +++ b/tools/assistant/tools/assistant/searchwidget.cpp @@ -62,6 +62,7 @@ QT_BEGIN_NAMESPACE SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent) : QWidget(parent) , zoomCount(0) + , attached(false) , searchEngine(engine) { QVBoxLayout *vLayout = new QVBoxLayout(this); @@ -122,6 +123,16 @@ void SearchWidget::resetZoom() } } +bool SearchWidget::isAttached() const +{ + return attached; +} + +void SearchWidget::setAttached(bool state) +{ + attached = state; +} + void SearchWidget::search() const { QList query = searchEngine->queryWidget()->query(); diff --git a/tools/assistant/tools/assistant/searchwidget.h b/tools/assistant/tools/assistant/searchwidget.h index 22fe80d..34eb86f 100644 --- a/tools/assistant/tools/assistant/searchwidget.h +++ b/tools/assistant/tools/assistant/searchwidget.h @@ -65,6 +65,9 @@ public: void zoomOut(); void resetZoom(); + bool isAttached() const; + void setAttached(bool state); + signals: void requestShowLink(const QUrl &url); void requestShowLinkInNewTab(const QUrl &url); @@ -81,6 +84,7 @@ private: private: int zoomCount; + bool attached; QHelpSearchEngine *searchEngine; QHelpSearchResultWidget *resultWidget; }; -- cgit v0.12 From 8ebe882b077fffedc3ff80fb80d2e181d5e56ab8 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 27 Apr 2009 17:16:59 +0200 Subject: Fixes wrong QPaintEvent::region() in QGLWidget::paintEvent. QGLWidget does not support partial updates unless the context is single buffered and auto-fill background is disabled. The problem was that QPaintEvent::region() returned the requested update region without taking into account the limitation of QGLWidget. If QGLWidget doesn't support partial updates, it means everything has to be updated, and QPaintEvent::region() must return the whole widget rect. Auto test included. Task-number: 241785 Reviewed-by: Trond --- src/gui/kernel/qwidget.cpp | 1 + src/gui/kernel/qwidget_p.h | 1 + src/gui/painting/qbackingstore.cpp | 11 +++++-- src/opengl/qgl.cpp | 4 +++ tests/auto/qgl/tst_qgl.cpp | 61 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index eb2e9f7..f612601 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -183,6 +183,7 @@ QWidgetPrivate::QWidgetPrivate(int version) : ,inDirtyList(0) ,isScrolled(0) ,isMoved(0) + ,usesDoubleBufferedGLContext(0) #ifdef Q_WS_WIN ,noPaintOnScreen(0) #endif diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 423e833..db78682 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -536,6 +536,7 @@ public: uint inDirtyList : 1; uint isScrolled : 1; uint isMoved : 1; + uint usesDoubleBufferedGLContext : 1; #ifdef Q_WS_WIN uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index fbac811a..34df6c9 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -1517,13 +1517,20 @@ void QWidgetPrivate::repaint_sys(const QRegion &rgn) extra->staticContentsSize = data.crect.size(); } + QPaintEngine *engine = q->paintEngine(); + // QGLWidget does not support partial updates if: + // 1) The context is double buffered + // 2) The context is single buffered and auto-fill background is enabled. + const bool noPartialUpdateSupport = (engine && engine->type() == QPaintEngine::OpenGL) + && (usesDoubleBufferedGLContext || q->autoFillBackground()); + QRegion toBePainted(noPartialUpdateSupport ? q->rect() : rgn); + #ifdef Q_WS_MAC // No difference between update() and repaint() on the Mac. - update_sys(rgn); + update_sys(toBePainted); return; #endif - QRegion toBePainted(rgn); toBePainted &= clipRect(); clipToEffectiveMask(toBePainted); if (toBePainted.isEmpty()) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index b4a0e5c..8ffee87 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2398,6 +2398,10 @@ bool QGLContext::create(const QGLContext* shareContext) return false; reset(); d->valid = chooseContext(shareContext); + if (d->valid && d->paintDevice->devType() == QInternal::Widget) { + QWidgetPrivate *wd = qt_widget_private(static_cast(d->paintDevice)); + wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer(); + } if (d->sharing) // ok, we managed to share qgl_share_reg()->addShare(this, shareContext); return d->valid; diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index a64dfc4..f982e6d 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -66,6 +66,8 @@ private slots: void getSetCheck(); void openGLVersionCheck(); void graphicsViewClipping(); + void partialGLWidgetUpdates_data(); + void partialGLWidgetUpdates(); }; tst_QGL::tst_QGL() @@ -404,5 +406,64 @@ void tst_QGL::graphicsViewClipping() #endif } +void tst_QGL::partialGLWidgetUpdates_data() +{ + QTest::addColumn("doubleBufferedContext"); + QTest::addColumn("autoFillBackground"); + QTest::addColumn("supportsPartialUpdates"); + + QTest::newRow("Double buffered context") << true << true << false; + QTest::newRow("Double buffered context without auto-fill background") << true << false << false; + QTest::newRow("Single buffered context") << false << true << false; + QTest::newRow("Single buffered context without auto-fill background") << false << false << true; +} + +void tst_QGL::partialGLWidgetUpdates() +{ +#ifdef QT_NO_OPENGL + QSKIP("QGL not yet supported", SkipAll); +#else + if (!QGLFormat::hasOpenGL()) + QSKIP("QGL not supported on this platform", SkipAll); + + QFETCH(bool, doubleBufferedContext); + QFETCH(bool, autoFillBackground); + QFETCH(bool, supportsPartialUpdates); + + class MyGLWidget : public QGLWidget + { + public: + QRegion paintEventRegion; + void paintEvent(QPaintEvent *e) + { + paintEventRegion = e->region(); + } + }; + + QGLFormat format = QGLFormat::defaultFormat(); + format.setDoubleBuffer(doubleBufferedContext); + QGLFormat::setDefaultFormat(format); + + MyGLWidget widget; + widget.setFixedSize(150, 150); + widget.setAutoFillBackground(autoFillBackground); + widget.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&widget); +#endif + QTest::qWait(200); + + if (widget.format().doubleBuffer() != doubleBufferedContext) + QSKIP("Platform does not support requested format", SkipAll); + + widget.paintEventRegion = QRegion(); + widget.repaint(50, 50, 50, 50); + if (supportsPartialUpdates) + QCOMPARE(widget.paintEventRegion, QRegion(50, 50, 50, 50)); + else + QCOMPARE(widget.paintEventRegion, QRegion(widget.rect())); +#endif +} + QTEST_MAIN(tst_QGL) #include "tst_qgl.moc" -- cgit v0.12 From 572d3b04aacfd211ea930ac5460562d8b3f6232b Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 27 Apr 2009 18:07:00 +0200 Subject: Stabilize auto test added in 8ebe882b077fffedc3ff80fb80d2e181d5e56ab8 QWidget::repaint() is not immediate on the Mac; it has to go through the event loop. --- tests/auto/qgl/tst_qgl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/qgl/tst_qgl.cpp b/tests/auto/qgl/tst_qgl.cpp index f982e6d..69141f3 100644 --- a/tests/auto/qgl/tst_qgl.cpp +++ b/tests/auto/qgl/tst_qgl.cpp @@ -458,6 +458,10 @@ void tst_QGL::partialGLWidgetUpdates() widget.paintEventRegion = QRegion(); widget.repaint(50, 50, 50, 50); +#ifdef Q_WS_MAC + // repaint() is not immediate on the Mac; it has to go through the event loop. + QTest::qWait(200); +#endif if (supportsPartialUpdates) QCOMPARE(widget.paintEventRegion, QRegion(50, 50, 50, 50)); else -- cgit v0.12