diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-03-25 13:38:54 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2009-03-25 13:38:54 (GMT) |
commit | e0bd0b685c913e6bf1b1f46ed28fc233aa5694ac (patch) | |
tree | a67834b5030461f149d4a1e47736b0d4cf07042e | |
parent | 761cac16eb0a6d32f9e7d558867c5c1bbfb244f9 (diff) | |
parent | 9b40f0275043566a6e1f1471e1f608dd66929b81 (diff) | |
download | Qt-e0bd0b685c913e6bf1b1f46ed28fc233aa5694ac.zip Qt-e0bd0b685c913e6bf1b1f46ed28fc233aa5694ac.tar.gz Qt-e0bd0b685c913e6bf1b1f46ed28fc233aa5694ac.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt into windows-7-multitouch
38 files changed, 718 insertions, 186 deletions
diff --git a/doc/src/deployment.qdoc b/doc/src/deployment.qdoc index d2c7a9e..7e02f1a 100644 --- a/doc/src/deployment.qdoc +++ b/doc/src/deployment.qdoc @@ -89,8 +89,9 @@ of Qt, you get Qt as a shared library. The disadvantage with the shared library approach is that you - will get more files to deploy. - + will get more files to deploy. For more information, see + \l{sharedlibrary.html}{Creating Shared Libraries}. + \section1 Deploying Qt's Libraries \table diff --git a/doc/src/designer-manual.qdoc b/doc/src/designer-manual.qdoc index 083d782..97713b1 100644 --- a/doc/src/designer-manual.qdoc +++ b/doc/src/designer-manual.qdoc @@ -2537,6 +2537,10 @@ pixmap property in the property editor. \target BuildingandInstallingthePlugin \section1 Building and Installing the Plugin + \section2 A Simple Plugin + + The \l{Custom Widget Plugin Example} demonstrates a simple \QD plugin. + The \c{.pro} file for a plugin must specify the headers and sources for both the custom widget and the plugin interface. Typically, this file only has to specify that the plugin's project is to be built as a library, but @@ -2571,65 +2575,42 @@ pixmap property in the property editor. See QCoreApplication::libraryPaths() for more information about customizing paths for libraries and plugins with Qt applications. -\omit - \section1 Using Qt Script to Aid in Building Forms - - Starting with Qt 4.3, \c .ui files may contain - \l{QtScript}{Qt Script} snippets that are executed by \l uic or QUiLoader - when building forms. + \section2 Splitting up the Plugin - The snippets are executed per widget. The snippet may modify properties - or invoke slots on the widget. + In a real world scenario, you do not want to have dependencies of the + application making use of the custom widgets to the \QD headers and + libraries as introduced by the simple approach explained above. - Special variables are used to access the widget: + There are two ways to resolve this: - \table - \header - \o Name - \o Value - \row \o \c widget - \o The widget being built. - \row \o \c childWidgets - \o An array containing the child widgets. This is useful - for QDesignerContainerExtension subclasses. - \endtable + \list + \i Create a \c{.pri} file that contains the headers sources and sources + of the custom widget: - If scripts are present in an \c {uic}-generated form, the application - must be configured with Qt Script support. + \code + INCLUDEPATH += $$PWD + HEADERS += $$PWD/analogclock.h + SOURCES += $$PWD/analogclock.cpp + \endcode - \snippet doc/src/snippets/code/doc_src_designer-manual.qdoc 5 + This file would then be included by the \c{.pro} file of the plugin and + the application: - For security reasons, the execution of scripts is disabled - by default in QUiLoader. You can enable it by - calling the QUiLoader::setScriptingEnabled() method. + \code + include(customwidget.pri) + \endcode - The resulting script snippet is concatenated from snippets occurring in - several places: + Running \c{qmake -Wall} on the \c{.pro} files causes a warning to be + printed if an included \c{.pri} file cannot be found. - \table - \header - \o Source - \o Usage - \row \o The \c codeTemplate() function of QDesignerCustomWidgetInterface - \o Allows snippets to be run on a per-class basis; for example, to set up a - container using the QDesignerContainerExtension. - \row \o The \c script() method of QDesignerScriptExtension - \o Allows snippets to be run on a per-widget basis; for example, - to set up the internal state of a custom widget. - - Such an internal state might be, for example, the contents of - a custom item view container widget, for which an editor - is provided by an QDesignerTaskMenuExtension object. - - \row \o Snippets entered at run-time using the \gui{Change script...} - option of the form's context menu - \o Fast prototyping. To get an idea, - drag a QLineEdit onto the form, enter the script - \snippet doc/src/snippets/code/doc_src_designer-manual.qdoc 6 - and preview the form. - \endtable -\endomit + \i Create a standalone shared library containing the custom widgets only + as described in + \l{sharedlibrary.html}{Creating Shared Libraries}. + This library would then be used by the application as well as by the + \QD plugin. Care must be taken to ensure that the plugin can locate + the library at run-time. + \endlist \section1 Related Examples diff --git a/doc/src/sharedlibrary.qdoc b/doc/src/sharedlibrary.qdoc new file mode 100644 index 0000000..3febb8f --- /dev/null +++ b/doc/src/sharedlibrary.qdoc @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the documentation 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$ +** +****************************************************************************/ + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt GUI Toolkit. +** EDITIONS: FREE, PROFESSIONAL, ENTERPRISE +** +****************************************************************************/ + +/*! + \group deployment + \page sharedlibrary.html + \ingroup buildsystem + + \title Creating Shared Libraries + The following sections list certain things that should be taken into + account when creating shared libraries. + + \section1 Using Symbols from Shared Libraries + + Symbols - functions, variables or classes - contained in shared libraries + intended to be used by \e{clients}, such as applications or other + libraries, must be marked in a special way. These symbols are called + \e{public symbols} that are \e{exported} or made publicly visible. + + The remaining symbols should not be visible from the outside. On most + platforms, compilers will hide them by default. On some platforms, a + special compiler option is required to hide these symbols. + + When compiling a shared library, it must be marked for \e{export}. To use + the shared library from a client, some platforms may require a special + \e{import} declaration as well. + + Depending on your target platform, Qt provides special macros that contain + the necessary definitions: + \list + \o \c{Q_DECL_EXPORT} must be added to the declarations of symbols used + when compiling a shared library. + \o \c{Q_DECL_IMPORT} must be added to the declarations of symbols used + when compiling a client that uses the shared library. + \endlist + + Now, we need to ensure that the right macro is invoked -- whether we + compile a share library itself, or just the client using the shared + library. + Typically, this can be solved by adding a special header. + + Let us assume we want to create a shared library called \e{mysharedlib}. + A special header for this library, \c{mysharedlib_global.h}, looks like + this: + + \code + #include <QtCore/QtGlobal> + + #if defined(MYSHAREDLIB_LIBRARY) + # define MYSHAREDLIB_EXPORT Q_DECL_EXPORT + #else + # define MYSHAREDLIB_EXPORT Q_DECL_IMPORT + #endif + \endcode + + In the \c{.pro} file of the shared library, we add: + + \code + DEFINES += MYSHAREDLIB_LIBRARY + \endcode + + In each header of the library, we specify the following: + + \code + #include "mysharedlib_global.h" + + MYSHAREDLIB_EXPORT void foo(); + class MYSHAREDLIB_EXPORT MyClass... + \endcode + This ensures that the right macro is seen by both library and clients. We + also use this technique in Qt's sources. + + + \section1 Header File Considerations + + Typically, clients will include only the public header files of shared + libraries. These libraries might be installed in a different location, when + deployed. Therefore, it is important to exclude other internal header files + that were used when building the shared library. + + For example, the library might provide a class that wraps a hardware device + and contains a handle to that device, provided by some 3rd-party library: + + \code + #include <footronics/device.h> + + class MyDevice { + private: + FOOTRONICS_DEVICE_HANDLE handle; + }; + \endcode + + A similar situation arises with forms created by Qt Designer when using + aggregation or multiple inheritance: + + \code + #include "ui_widget.h" + + class MyWidget : public QWidget { + private: + Ui::MyWidget m_ui; + }; + \endcode + + When deploying the library, there should be no dependency to the internal + headers \c{footronics/device.h} or \c{ui_widget.h}. + + This can be avoided by making use of the \e{Pointer to implementation} + idiom described in various C++ programming books. For classes with + \e{value semantics}, consider using QSharedDataPointer. + + + \section1 Binary compatibility + + For clients loading a shared library, to work correctly, the memory + layout of the classes being used must match exactly the memory layout of + the library version that was used to compile the client. In other words, + the library found by the client at runtime must be \e{binary compatible} + with the version used at compile time. + + This is usually not a problem if the client is a self-contained software + package that ships all the libraries it needs. + + However, if the client application relies on a shared library that belongs + to a different installation package or to the operating system, then we + need to think of a versioning scheme for shared libraries and decide at + which level \e{Binary compatibility} is to be maintained. For example, Qt + libraries of the same \e{major version number} are guaranteed to be binary + compatible. + + Maintaining \e{Binary compatibility} places some restrictions on the changes + you can make to the classes. A good explanation can be found at + \l{http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++} + {KDE - Policies/Binary Compatibility Issues With C++}. These issues should + be considered right from the start of library design. + We recommend that the principle of \e{Information hiding} and the + \e{Pointer to implementation} technique be used wherever possible. +*/ diff --git a/doc/src/tutorials/widgets-tutorial.qdoc b/doc/src/tutorials/widgets-tutorial.qdoc index ce977f3..ead44af 100644 --- a/doc/src/tutorials/widgets-tutorial.qdoc +++ b/doc/src/tutorials/widgets-tutorial.qdoc @@ -80,7 +80,7 @@ \raw HTML <table align="left" width="100%"> - <tr><td> + <tr class="qt-code"><td> \endraw \snippet snippets/widgets-tutorial/toplevel/main.cpp create, resize and show \raw HTML @@ -98,7 +98,7 @@ \raw HTML <table align="left" width="100%"> - <tr><td> + <tr class="qt-code"><td> \endraw \snippet snippets/widgets-tutorial/childwidget/main.cpp create, position and show \raw HTML @@ -123,7 +123,7 @@ \raw HTML <table align="left" width="100%"> - <tr><td> + <tr class="qt-code"><td> \endraw \snippet snippets/widgets-tutorial/windowlayout/main.cpp create, lay out widgets and show \raw HTML @@ -157,7 +157,7 @@ \raw HTML <table align="left" width="100%"> - <tr><td> + <tr class="qt-code"><td> \endraw \snippet snippets/widgets-tutorial/nestedlayouts/main.cpp create, lay out widgets and show \raw HTML @@ -171,23 +171,4 @@ As well as QHBoxLayout and QVBoxLayout, Qt also provides QGridLayout and QFormLayout classes to help with more complex user interfaces. - - - - \omit - In the simple example below, the widget is created on the stack and will - automatically be deleted when the \c{main()} function exits. - - {{{#include <QtGui> - - int main(int argc, char *argv[]) - { - QApplication app(argc, argv); - QWidget window; - window.resize(480, 360); - window.show(); - return app.exec(); - } - }}} - \endomit */ diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index 6d55f7c..c172f5f 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -120,6 +120,9 @@ // QMovie //#define QT_NO_MOVIE +// QNetworkInterface +//#define QT_NO_NETWORKINTERFACE + // QNetworkProxy //#define QT_NO_NETWORKPROXY @@ -198,12 +201,12 @@ // Qt Prerendered Font Format //#define QT_NO_QWS_QPF -// Raster Paint Engine callback functions -//#define QT_NO_RASTERCALLBACKS - // Qt Prerendered Font Format 2 //#define QT_NO_QWS_QPF2 +// Raster Paint Engine callback functions +//#define QT_NO_RASTERCALLBACKS + // Resize Handler //#define QT_NO_RESIZEHANDLER @@ -273,9 +276,6 @@ // HtmlParser //#define QT_NO_TEXTHTMLPARSER -// OdfWriter -//#define QT_NO_TEXTODFWRITER - // QTextStream //#define QT_NO_TEXTSTREAM @@ -316,6 +316,11 @@ #define QT_NO_BUTTONGROUP #endif +// QClipboard +#if !defined(QT_NO_CLIPBOARD) && (defined(QT_NO_QWS_PROPERTIES)) +#define QT_NO_CLIPBOARD +#endif + // Codecs #if !defined(QT_NO_CODECS) && (defined(QT_NO_TEXTCODEC)) #define QT_NO_CODECS @@ -356,6 +361,11 @@ #define QT_NO_MENU #endif +// QNetworkDiskCache +#if !defined(QT_NO_NETWORKDISKCACHE) && (defined(QT_NO_TEMPORARYFILE)) +#define QT_NO_NETWORKDISKCACHE +#endif + // Phonon::SeekSlider #if !defined(QT_NO_PHONON_SEEKSLIDER) && (defined(QT_NO_SLIDER)) #define QT_NO_PHONON_SEEKSLIDER @@ -481,11 +491,6 @@ #define QT_NO_XMLSTREAMWRITER #endif -// Odf Writer -#if !defined(QT_NO_TEXTODFWRITER) && (defined(QT_NO_XMLSTREAMWRITER)) -#define QT_NO_TEXTODFWRITER -#endif - // Context menu #if !defined(QT_NO_CONTEXTMENU) && (defined(QT_NO_MENU)) #define QT_NO_CONTEXTMENU @@ -516,6 +521,11 @@ #define QT_NO_SCROLLAREA #endif +// OdfWriter +#if !defined(QT_NO_TEXTODFWRITER) && (defined(QT_NO_XMLSTREAMWRITER)) +#define QT_NO_TEXTODFWRITER +#endif + // QToolButton #if !defined(QT_NO_TOOLBUTTON) && (defined(QT_NO_ICON) || defined(QT_NO_ACTION)) #define QT_NO_TOOLBUTTON @@ -636,11 +646,6 @@ #define QT_NO_WHATSTHIS #endif -// QClipboard -#if !defined(QT_NO_CLIPBOARD) && (defined(QT_NO_QWS_PROPERTIES)) -#define QT_NO_CLIPBOARD -#endif - // Common UNIX Printing System #if !defined(QT_NO_CUPS) && (defined(QT_NO_PRINTER) || defined(QT_NO_LIBRARY)) #define QT_NO_CUPS diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index c26c274..2c5b580 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -1085,6 +1085,13 @@ Requires: Name: QNetworkInterface SeeAlso: ??? +Feature: NETWORKDISKCACHE +Description: Supports a disk cache for network resources +Section: Networking +Requires: TEMPORARYFILE +Name: QNetworkDiskCache +SeeAlso: ??? + # Utilities Feature: COMPLETER diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 2767f6f..459167e 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2033,11 +2033,12 @@ void qt_message_output(QtMsgType msgType, const char *buf) \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 25 - This syntax automatically puts a single space between each item, - and outputs a newline at the end. It supports many C++ and Qt - types. + With this syntax, the function returns a QDebug object that is + configured to use the QtDebugMsg message type. It automatically + puts a single space between each item, and outputs a newline at + the end. It supports many C++ and Qt types. - To supress the output at runtime, install your own message handler + To suppress the output at run-time, install your own message handler with qInstallMsgHandler(). \sa qWarning(), qCritical(), qFatal(), qInstallMsgHandler(), @@ -2966,4 +2967,24 @@ bool QInternal::callFunction(InternalFunction func, void **args) \snippet doc/src/snippets/code/src_gui_dialogs_qmessagebox.cpp 4 */ +/*! + \macro Q_DECL_EXPORT + \relates <QtGlobal> + + This macro marks a symbol for shared library export (see + \l{sharedlibrary.html}{Creating Shared Libraries}). + + \sa Q_DECL_IMPORT +*/ + +/*! + \macro Q_DECL_IMPORT + \relates <QtGlobal> + + This macro declares a symbol to be an import from a shared library (see + \l{sharedlibrary.html}{Creating Shared Libraries}). + + \sa Q_DECL_EXPORT +*/ + QT_END_NAMESPACE diff --git a/src/gui/dialogs/qfileinfogatherer.cpp b/src/gui/dialogs/qfileinfogatherer.cpp index 3fe64ff..23a2cbc 100644 --- a/src/gui/dialogs/qfileinfogatherer.cpp +++ b/src/gui/dialogs/qfileinfogatherer.cpp @@ -168,6 +168,20 @@ void QFileInfoGatherer::clear() } /* + Remove a \a path from the watcher + + \sa listed() +*/ +void QFileInfoGatherer::removePath(const QString &path) +{ +#ifndef QT_NO_FILESYSTEMWATCHER + mutex.lock(); + watcher->removePath(path); + mutex.unlock(); +#endif +} + +/* List all files in \a directoryPath \sa listed() @@ -286,15 +300,9 @@ QString QFileInfoGatherer::translateDriveName(const QFileInfo &drive) const void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &files) { #ifndef QT_NO_FILESYSTEMWATCHER - //### We test here if the path still exist before adding it in the watcher - //### because sometime the file is deleted just before enter here so QStringList files is not up to date - //### It is not a proper fix, perhaps in 4.6 we should have a better way to avoid that - //### to ensure the gatherer have fresh information - QFileInfo info(path); if (files.isEmpty() && !watcher->directories().contains(path) && !path.isEmpty() - && info.exists() && !path.startsWith(QLatin1String("//")) /*don't watch UNC path*/) { watcher->addPath(path); } diff --git a/src/gui/dialogs/qfileinfogatherer_p.h b/src/gui/dialogs/qfileinfogatherer_p.h index eac0d46..60b9d5f 100644 --- a/src/gui/dialogs/qfileinfogatherer_p.h +++ b/src/gui/dialogs/qfileinfogatherer_p.h @@ -161,6 +161,7 @@ public: ~QFileInfoGatherer(); void clear(); + void removePath(const QString &path); QExtendedInformation getInfo(const QFileInfo &info) const; public Q_SLOTS: diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index 51d3314..c7b3137 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -166,6 +166,8 @@ bool QFileSystemModel::remove(const QModelIndex &aindex) const { //### TODO optim QString path = filePath(aindex); + QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func()); + d->fileInfoGatherer.removePath(path); QDirIterator it(path, QDir::AllDirs | QDir:: Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); @@ -375,7 +377,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS if (!info.exists()) return rootNode; QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this); - p->addNode(rootNode, host); + p->addNode(rootNode, host,info); p->addVisibleFiles(rootNode, QStringList(host)); } r = rootNode->visibleLocation(host); @@ -395,6 +397,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS #endif QFileSystemModelPrivate::QFileSystemNode *parent = node(index); + for (int i = 0; i < pathElements.count(); ++i) { QString element = pathElements.at(i); #ifdef Q_OS_WIN @@ -423,7 +426,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS if (!info.exists()) return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this); - node = p->addNode(parent, element); + node = p->addNode(parent, element,info); #ifndef QT_NO_FILESYSTEMWATCHER node->populate(fileInfoGatherer.getInfo(info)); #endif @@ -843,7 +846,7 @@ bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, in QFileSystemModelPrivate::QFileSystemNode *parentNode = indexNode->parent; int visibleLocation = parentNode->visibleLocation(parentNode->children.value(indexNode->fileName)->fileName); - d->addNode(parentNode, newName); + d->addNode(parentNode, newName,indexNode->info->fileInfo()); parentNode->visibleChildren.removeAt(visibleLocation); QFileSystemModelPrivate::QFileSystemNode * oldValue = parentNode->children.value(oldName); parentNode->children[newName] = oldValue; @@ -1282,7 +1285,7 @@ QModelIndex QFileSystemModel::mkdir(const QModelIndex &parent, const QString &na if (!dir.mkdir(name)) return QModelIndex(); QFileSystemModelPrivate::QFileSystemNode *parentNode = d->node(parent); - d->addNode(parentNode, name); + d->addNode(parentNode, name, QFileInfo()); Q_ASSERT(parentNode->children.contains(name)); QFileSystemModelPrivate::QFileSystemNode *node = parentNode->children[name]; node->populate(d->fileInfoGatherer.getInfo(QFileInfo(dir.absolutePath() + QDir::separator() + name))); @@ -1601,10 +1604,13 @@ void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, cons *WARNING* this will change the count of children */ -QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFileSystemNode *parentNode, const QString &fileName) +QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFileSystemNode *parentNode, const QString &fileName, const QFileInfo& info) { // In the common case, itemLocation == count() so check there first QFileSystemModelPrivate::QFileSystemNode *node = new QFileSystemModelPrivate::QFileSystemNode(fileName, parentNode); +#ifndef QT_NO_FILESYSTEMWATCHER + node->populate(info); +#endif parentNode->children.insert(fileName, node); return node; } @@ -1722,7 +1728,7 @@ void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QL QExtendedInformation info = fileInfoGatherer.getInfo(updates.at(i).second); bool previouslyHere = parentNode->children.contains(fileName); if (!previouslyHere) { - addNode(parentNode, fileName); + addNode(parentNode, fileName, info.fileInfo()); } QFileSystemModelPrivate::QFileSystemNode * node = parentNode->children.value(fileName); bool isCaseSensitive = parentNode->caseSensitive(); diff --git a/src/gui/dialogs/qfilesystemmodel_p.h b/src/gui/dialogs/qfilesystemmodel_p.h index f1e798b..77c35a2 100644 --- a/src/gui/dialogs/qfilesystemmodel_p.h +++ b/src/gui/dialogs/qfilesystemmodel_p.h @@ -182,7 +182,7 @@ public: QList<QString> visibleChildren; QFileSystemNode *parent; - private: + QExtendedInformation *info; }; @@ -216,7 +216,7 @@ public: bool filtersAcceptsNode(const QFileSystemNode *node) const; bool passNameFilters(const QFileSystemNode *node) const; void removeNode(QFileSystemNode *parentNode, const QString &name); - QFileSystemNode* addNode(QFileSystemNode *parentNode, const QString &fileName); + QFileSystemNode* addNode(QFileSystemNode *parentNode, const QString &fileName, const QFileInfo &info); void addVisibleFiles(QFileSystemNode *parentNode, const QStringList &newFiles); void removeVisibleFile(QFileSystemNode *parentNode, int visibleLocation); void sortChildren(int column, const QModelIndex &parent); diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 5cc18f9..64ec0e7 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1269,6 +1269,8 @@ bool QGraphicsWidget::event(QEvent *event) break; case QEvent::Polish: polishEvent(); + d->polished = true; + d->updateFont(d->font); break; case QEvent::WindowActivate: case QEvent::WindowDeactivate: diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 641409d..789f8da 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -274,6 +274,8 @@ void QGraphicsWidgetPrivate::updateFont(const QFont &font) } } + if (!polished) + return; // Notify change. QEvent event(QEvent::FontChange); QApplication::sendEvent(q, &event); diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index afa6812..455a129 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -85,6 +85,7 @@ public: inheritedPaletteResolveMask(0), inheritedFontResolveMask(0), inSetGeometry(0), + polished(0), focusPolicy(Qt::NoFocus), focusNext(0), focusPrev(0), @@ -193,6 +194,7 @@ public: } quint32 attributes : 10; quint32 inSetGeometry : 1; + quint32 polished: 1; // Focus Qt::FocusPolicy focusPolicy; diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 9d99d2e..725caeb 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -1288,6 +1288,12 @@ void QX11PixmapData::setMask(const QBitmap &newmask) 0, 0, 0, 0, 0, 0, w, h); release(); *this = newData; + // the new QX11PixmapData object isn't referenced yet, so + // ref it + ref.ref(); + + // the below is to make sure the QX11PixmapData destructor + // doesn't delete our newly created render picture newData.hd = 0; newData.x11_mask = 0; newData.picture = 0; diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index df26c42..abb3181 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -110,6 +110,7 @@ protected: private: friend class QPixmap; friend class QGLContextPrivate; + friend class QX11PixmapData; QAtomicInt ref; int detach_no; diff --git a/src/gui/inputmethod/qximinputcontext_p.h b/src/gui/inputmethod/qximinputcontext_p.h index ca2103b..3773122 100644 --- a/src/gui/inputmethod/qximinputcontext_p.h +++ b/src/gui/inputmethod/qximinputcontext_p.h @@ -98,6 +98,7 @@ public: QString text; QBitArray selectedChars; bool composing; + bool preeditEmpty; void clear(); }; diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp index 48a96b1..1c8560f 100644 --- a/src/gui/inputmethod/qximinputcontext_x11.cpp +++ b/src/gui/inputmethod/qximinputcontext_x11.cpp @@ -264,6 +264,7 @@ extern "C" { qic->standardFormat(QInputContext::PreeditFormat)); attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, sellen ? 0 : 1, QVariant()); QInputMethodEvent e(data->text, attrs); + data->preeditEmpty = data->text.isEmpty(); qic->sendEvent(e); return 0; @@ -286,6 +287,7 @@ void QXIMInputContext::ICData::clear() text = QString(); selectedChars.clear(); composing = false; + preeditEmpty = true; } QXIMInputContext::ICData *QXIMInputContext::icData() const @@ -537,9 +539,12 @@ void QXIMInputContext::reset() if (mb) { e.setCommitString(QString::fromLocal8Bit(mb)); XFree(mb); + data->preeditEmpty = false; // force sending an event + } + if (!data->preeditEmpty) { + sendEvent(e); + update(); } - sendEvent(e); - update(); } data->clear(); } @@ -686,6 +691,7 @@ QXIMInputContext::ICData *QXIMInputContext::createICData(QWidget *w) { ICData *data = new ICData; data->widget = w; + data->preeditEmpty = true; XVaNestedList preedit_attr = 0; XIMCallback startcallback, drawcallback, donecallback; diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index b3993c7..10bcb9a 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1103,6 +1103,8 @@ void QSortFilterProxyModelPrivate::_q_sourceReset() // All internal structures are deleted in clear() q->reset(); update_source_sort_column(); + if (dynamic_sortfilter) + sort(); } void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged() @@ -1495,6 +1497,7 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) d->clear_mapping(); reset(); + d->update_source_sort_column(); } /*! @@ -1893,7 +1896,7 @@ QSize QSortFilterProxyModel::span(const QModelIndex &index) const void QSortFilterProxyModel::sort(int column, Qt::SortOrder order) { Q_D(QSortFilterProxyModel); - if (d->proxy_sort_column == column && d->sort_order == order) + if (d->dynamic_sortfilter && d->proxy_sort_column == column && d->sort_order == order) return; d->sort_order = order; d->proxy_sort_column = column; @@ -2107,6 +2110,8 @@ void QSortFilterProxyModel::setDynamicSortFilter(bool enable) { Q_D(QSortFilterProxyModel); d->dynamic_sortfilter = enable; + if (enable) + d->sort(); } /*! diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 9c70208..e52ec70 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2462,7 +2462,9 @@ void QApplication::setActiveWindow(QWidget* act) } else { // If the focus widget is not in the activate_window, clear the focus w = QApplicationPrivate::focus_widget; - if (w && !QApplicationPrivate::active_window->isAncestorOf(w)) + if (!w && QApplicationPrivate::active_window->focusPolicy() != Qt::NoFocus) + QApplicationPrivate::setFocusWidget(QApplicationPrivate::active_window, Qt::ActiveWindowFocusReason); + else if (!QApplicationPrivate::active_window->isAncestorOf(w)) QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason); } } diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index ff69c24..d571212 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -1656,7 +1656,7 @@ Qt::ButtonState QContextMenuEvent::state() const The variant contains a QLocale object specifying the language of a certain part of the preedit string. There should be at most one language set for every part of the preedit string. If several are - specified for any character in the string the behaviour is undefined. + specified for any character in the string the behavior is undefined. \value Ruby The ruby text for a part of the preedit string. There should be at diff --git a/src/gui/kernel/qt_mac.cpp b/src/gui/kernel/qt_mac.cpp index b462b13..4703475 100644 --- a/src/gui/kernel/qt_mac.cpp +++ b/src/gui/kernel/qt_mac.cpp @@ -93,6 +93,8 @@ static QColor qcolorFromCGColor(CGColorRef cgcolor) pc.setRgbF(components[0], components[1], components[2], components[3]); } else if (model == kCGColorSpaceModelCMYK) { pc.setCmykF(components[0], components[1], components[2], components[3]); + } else if (model == kCGColorSpaceModelMonochrome) { + pc.setRgbF(components[0], components[0], components[0], components[1]); } else { // Colorspace we can't deal with. qWarning("Qt: qcolorFromCGColor: cannot convert from colorspace model: %d", model); diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index d2f4ab7..6589439 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -535,6 +535,8 @@ static void qt_blend_argb32_on_rgb16(uchar *destPixels, int dbpl, s += BYTE_MUL_RGB16(*dst, 255 - alpha); *dst = s; } + ++dst; + ++src; } dst += dstExtraStride; src += srcExtraStride; diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index f728f9d..8169ef8 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qregion.h" +#include "qpainterpath.h" #include "qpolygon.h" #include "qbuffer.h" #include "qdatastream.h" @@ -49,7 +50,6 @@ #include <qdebug.h> #if defined(Q_OS_UNIX) || defined(Q_OS_WINCE) -#include "qpainterpath.h" #include "qimage.h" #include "qbitmap.h" #include <stdlib.h> diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index a3f5cfe..08d6fed 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -125,6 +125,13 @@ static const QColor titlebarSeparatorLineInactive(131, 131, 131); static const QColor mainWindowGradientBegin(240, 240, 240); static const QColor mainWindowGradientEnd(200, 200, 200); +#if (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5) +enum { + kThemePushButtonTextured = 31, + kThemePushButtonTexturedSmall = 32, + kThemePushButtonTexturedMini = 33 +}; +#endif // Resolve these at run-time, since the functions was moved in Leopard. typedef HIRect * (*PtrHIShapeGetBounds)(HIShapeRef, HIRect *); @@ -3629,7 +3636,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter QRect cr = tb->rect; int shiftX = 0; int shiftY = 0; - if (tb->state & (State_Sunken | State_On)) { + bool needText = false; + int alignment = 0; + bool down = tb->state & (State_Sunken | State_On); + if (down) { shiftX = pixelMetric(PM_ButtonShiftHorizontal, tb, w); shiftY = pixelMetric(PM_ButtonShiftVertical, tb, w); } @@ -3637,30 +3647,29 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter // The text is a bit bolder and gets a drop shadow and the icons are also darkened. // This doesn't really fit into any particular case in QIcon, so we // do the majority of the work ourselves. - if (tb->state & State_Sunken - && !(tb->features & QStyleOptionToolButton::Arrow)) { + if (!(tb->features & QStyleOptionToolButton::Arrow)) { Qt::ToolButtonStyle tbstyle = tb->toolButtonStyle; if (tb->icon.isNull() && !tb->text.isEmpty()) tbstyle = Qt::ToolButtonTextOnly; switch (tbstyle) { - case Qt::ToolButtonTextOnly: - drawItemText(p, cr, Qt::AlignCenter, tb->palette, - tb->state & State_Enabled, tb->text); - break; + case Qt::ToolButtonTextOnly: { + needText = true; + alignment = Qt::AlignCenter; + break; } case Qt::ToolButtonIconOnly: case Qt::ToolButtonTextBesideIcon: case Qt::ToolButtonTextUnderIcon: { QRect pr = cr; QIcon::Mode iconMode = (tb->state & State_Enabled) ? QIcon::Normal - : QIcon::Disabled; + : QIcon::Disabled; QIcon::State iconState = (tb->state & State_On) ? QIcon::On - : QIcon::Off; + : QIcon::Off; QPixmap pixmap = tb->icon.pixmap(tb->rect.size().boundedTo(tb->iconSize), iconMode, iconState); // Draw the text if it's needed. if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) { - int alignment = 0; + needText = true; if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { pr.setHeight(pixmap.size().height() + 6); cr.adjust(0, pr.bottom(), 0, -3); @@ -3670,18 +3679,43 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter cr.adjust(pr.right(), 0, 0, 0); alignment |= Qt::AlignLeft | Qt::AlignVCenter; } - cr.translate(shiftX, shiftY); - drawItemText(p, cr, alignment, tb->palette, - tb->state & State_Enabled, tb->text); - cr.adjust(0, 3, 0, -3); // the drop shadow - drawItemText(p, cr, alignment, tb->palette, - tb->state & State_Enabled, tb->text); } - pr.translate(shiftX, shiftY); - pixmap = darkenPixmap(pixmap); + if (down) { + pr.translate(shiftX, shiftY); + pixmap = darkenPixmap(pixmap); + } drawItemPixmap(p, pr, Qt::AlignCenter, pixmap); break; } } + + if (needText) { + QPalette pal = tb->palette; + QPalette::ColorRole role = QPalette::NoRole; + if (down) + cr.translate(shiftX, shiftY); + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5 + && (tbstyle == Qt::ToolButtonTextOnly + || (tbstyle != Qt::ToolButtonTextOnly && !down))) { + QPen pen = p->pen(); + QColor light = down ? Qt::black : Qt::white; + light.setAlphaF(0.375f); + p->setPen(light); + p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text); + p->setPen(pen); + if (down && tbstyle == Qt::ToolButtonTextOnly) { + pal = QApplication::palette("QMenu"); + pal.setCurrentColorGroup(tb->palette.currentColorGroup()); + role = QPalette::HighlightedText; + } + } + drawItemText(p, cr, alignment, pal, + tb->state & State_Enabled, tb->text, role); + if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_5 && down) { + // Draw a "drop shadow" in earlier versions. + drawItemText(p, cr.adjusted(0, 1, 0, 1), alignment, + tb->palette, tb->state & State_Enabled, tb->text); + } + } } else { QWindowsStyle::drawControl(ce, &myTb, p, w); } diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index c5977e4..c92dfc0 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -56,6 +56,10 @@ QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QWidget) QT_FORWARD_DECLARE_CLASS(QApplication) +QT_BEGIN_NAMESPACE +extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication.cpp +QT_END_NAMESPACE + @implementation QT_MANGLE_NAMESPACE(QCocoaMenu) - (id)initWithQMenu:(QMenu*)menu diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index b239e32..01ab884 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -1478,7 +1478,8 @@ void QTextEditPrivate::paint(QPainter *p, QPaintEvent *e) layout->setViewport(QRect()); } -/*! \reimp +/*! \warning The underlying text document must not be modified from within a reimplementation +of this function. */ void QTextEdit::paintEvent(QPaintEvent *e) { diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index fa0fccb..e472b9d 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -41,6 +41,8 @@ //#define QNETWORKDISKCACHE_DEBUG +#ifndef QT_NO_NETWORKDISKCACHE + #include "qnetworkdiskcache.h" #include "qnetworkdiskcache_p.h" @@ -664,3 +666,5 @@ bool QCacheItem::read(QFile *device, bool readData) } QT_END_NAMESPACE + +#endif // QT_NO_NETWORKDISKCACHE diff --git a/src/network/access/qnetworkdiskcache.h b/src/network/access/qnetworkdiskcache.h index ca4bb94..78e3f6b 100644 --- a/src/network/access/qnetworkdiskcache.h +++ b/src/network/access/qnetworkdiskcache.h @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE QT_MODULE(Network) +#ifndef QT_NO_NETWORKDISKCACHE + class QNetworkDiskCachePrivate; class Q_NETWORK_EXPORT QNetworkDiskCache : public QAbstractNetworkCache { @@ -86,9 +88,10 @@ private: Q_DISABLE_COPY(QNetworkDiskCache) }; +#endif // QT_NO_NETWORKDISKCACHE + QT_END_NAMESPACE QT_END_HEADER #endif // QNETWORKDISKCACHE_H - diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index de023f5..dee3f54 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -259,6 +259,35 @@ void tst_QGraphicsWidget::cleanup() { } +class SizeHinter : public QGraphicsWidget +{ +public: + SizeHinter(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0, + const QSizeF &min = QSizeF(5,5), + const QSizeF &pref = QSizeF(50, 50), + const QSizeF &max = QSizeF(500, 500)) + : QGraphicsWidget(parent, wFlags) + { + m_sizes[Qt::MinimumSize] = min; + m_sizes[Qt::PreferredSize] = pref; + m_sizes[Qt::MaximumSize] = max; + + } + void setSizeHint(Qt::SizeHint which, const QSizeF &newSizeHint) + { + m_sizes[which] = newSizeHint; + } + +protected: + QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const + { + Q_UNUSED(constraint); + return m_sizes[which]; + } +private: + QSizeF m_sizes[4]; +}; + void tst_QGraphicsWidget::qgraphicswidget() { SubQGraphicsWidget widget; @@ -282,6 +311,12 @@ void tst_QGraphicsWidget::qgraphicswidget() QCOMPARE(widget.type(), (int)QGraphicsWidget::Type); QCOMPARE(widget.call_propertyChange(QString(), QVariant()), QVariant()); widget.call_sizeHint(Qt::PreferredSize, QSizeF()); + + QGraphicsScene scene; + QGraphicsWidget *parent = new QGraphicsWidget; + SizeHinter *child = new SizeHinter(parent); + + QCOMPARE(child->minimumSize(), QSizeF(5, 5)); } void tst_QGraphicsWidget::activation() @@ -1516,35 +1551,6 @@ enum WhichSize { None, }; -class SizeHinter : public QGraphicsWidget -{ -public: - SizeHinter(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0, - const QSizeF &min = QSizeF(5,5), - const QSizeF &pref = QSizeF(50, 50), - const QSizeF &max = QSizeF(500, 500)) - : QGraphicsWidget(parent, wFlags) - { - m_sizes[Qt::MinimumSize] = min; - m_sizes[Qt::PreferredSize] = pref; - m_sizes[Qt::MaximumSize] = max; - - } - void setSizeHint(Qt::SizeHint which, const QSizeF &newSizeHint) - { - m_sizes[which] = newSizeHint; - } - -protected: - QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const - { - Q_UNUSED(constraint); - return m_sizes[which]; - } -private: - QSizeF m_sizes[4]; -}; - typedef QPair<int, QVariant> Inst; Q_DECLARE_METATYPE(Inst) diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index 5a15683..2e1335c 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -204,6 +204,9 @@ private slots: void drawImage_task217400(); void drawRect_task215378(); + void drawImage_data(); + void drawImage(); + void clippedImage(); void stateResetBetweenQPainters(); @@ -3586,6 +3589,77 @@ void tst_QPainter::drawRect_task215378() QVERIFY(img.pixel(0, 0) != img.pixel(1, 1)); } +void tst_QPainter::drawImage_data() +{ + QTest::addColumn<int>("x"); + QTest::addColumn<int>("y"); + QTest::addColumn<int>("w"); + QTest::addColumn<int>("h"); + QTest::addColumn<QImage::Format>("srcFormat"); + QTest::addColumn<QImage::Format>("dstFormat"); + + for (int srcFormat = QImage::Format_Mono; srcFormat < QImage::NImageFormats; ++srcFormat) { + for (int dstFormat = QImage::Format_Mono; dstFormat < QImage::NImageFormats; ++dstFormat) { + if (dstFormat == QImage::Format_Indexed8) + continue; + for (int odd_x = 0; odd_x <= 1; ++odd_x) { + for (int odd_width = 0; odd_width <= 1; ++odd_width) { + QString description = + QString("srcFormat %1, dstFormat %2, odd x: %3, odd width: %4") + .arg(srcFormat).arg(dstFormat).arg(odd_x).arg(odd_width); + + QTest::newRow(description) << (10 + odd_x) << 10 << (20 + odd_width) << 20 + << QImage::Format(srcFormat) + << QImage::Format(dstFormat); + } + } + } + } +} + +bool verifyImage(const QImage &img, int x, int y, int w, int h, uint background) +{ + int imgWidth = img.width(); + int imgHeight = img.height(); + for (int i = 0; i < imgHeight; ++i) { + for (int j = 0; j < imgWidth; ++j) { + uint pixel = img.pixel(j, i); + bool outside = j < x || j >= (x + w) || i < y || i >= (y + h); + if (outside != (pixel == background)) { + //printf("%d %d, expected %x, got %x, outside: %d\n", x, y, background, pixel, outside); + return false; + } + } + } + + return true; +} + +void tst_QPainter::drawImage() +{ + QFETCH(int, x); + QFETCH(int, y); + QFETCH(int, w); + QFETCH(int, h); + QFETCH(QImage::Format, srcFormat); + QFETCH(QImage::Format, dstFormat); + + QImage dst(40, 40, QImage::Format_RGB32); + dst.fill(0xffffffff); + + dst = dst.convertToFormat(dstFormat); + uint background = dst.pixel(0, 0); + + QImage src(w, h, QImage::Format_RGB32); + src.fill(0xff000000); + src = src.convertToFormat(srcFormat); + + QPainter p(&dst); + p.drawImage(x, y, src); + p.end(); + + QVERIFY(verifyImage(dst, x, y, w, h, background)); +} void tst_QPainter::imageCoordinateLimit() { diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 1590fc0..8a6b63b 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -106,6 +106,7 @@ private slots: void grabWidget(); void grabWindow(); void isNull(); + void task_246446(); #ifdef Q_WS_QWS void convertFromImageNoDetach(); @@ -1111,5 +1112,20 @@ void tst_QPixmap::fromData() QCOMPARE(img.pixel(0, 1), QRgb(0xff000000)); } +void tst_QPixmap::task_246446() +{ + // This crashed without the bugfix in 246446 + QPixmap pm(10, 10); + pm.fill(Qt::transparent); // force 32-bit depth + QBitmap bm; + pm.setMask(bm); + { + QPixmap pm2(pm); + } + QVERIFY(pm.width() == 10); + QVERIFY(pm.mask().isNull()); +} + + QTEST_MAIN(tst_QPixmap) #include "tst_qpixmap.moc" diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 9f92c37..0a48066 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -129,6 +129,8 @@ private slots: void task236755_hiddenColumns(); void task247867_insertRowsSort(); + void task248868_staticSorting(); + void task248868_dynamicSorting(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -2479,5 +2481,115 @@ void tst_QSortFilterProxyModel::task247867_insertRowsSort() QCOMPARE(proxyModel.sortColumn(), 0); } +void tst_QSortFilterProxyModel::task248868_staticSorting() +{ + QStandardItemModel model(0, 1); + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + proxy.setDynamicSortFilter(false); + QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(" "); + + // prepare model + QStandardItem *root = model.invisibleRootItem (); + QList<QStandardItem *> items; + for (int i = 0; i < initial.count(); ++i) { + items.append(new QStandardItem(initial.at(i))); + } + root->insertRows(0, items); + QCOMPARE(model.rowCount(QModelIndex()), initial.count()); + QCOMPARE(model.columnCount(QModelIndex()), 1); + + // make sure the proxy is unsorted + QCOMPARE(proxy.columnCount(QModelIndex()), 1); + QCOMPARE(proxy.rowCount(QModelIndex()), initial.count()); + for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy.index(row, 0, QModelIndex()); + QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), initial.at(row)); + } + + // sort + proxy.sort(0); + + QStringList expected = initial; + expected.sort(); + // make sure the proxy is sorted + for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy.index(row, 0, QModelIndex()); + QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row)); + } + + //update one item. + model.setItem(0, 0, new QStandardItem("girafe")); + + // make sure the proxy is updated but not sorted + expected.replaceInStrings("bateau", "girafe"); + for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy.index(row, 0, QModelIndex()); + QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row)); + } + + // sort again + proxy.sort(0); + expected.sort(); + + // make sure the proxy is sorted + for (int row = 0; row < proxy.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy.index(row, 0, QModelIndex()); + QCOMPARE(proxy.data(index, Qt::DisplayRole).toString(), expected.at(row)); + } + +} + +void tst_QSortFilterProxyModel::task248868_dynamicSorting() +{ + QStringListModel model1; + const QStringList initial = QString("bateau avion dragon hirondelle flamme camion elephant").split(" "); + model1.setStringList(initial); + QSortFilterProxyModel proxy1; + proxy1.sort(0); + proxy1.setSourceModel(&model1); + + QCOMPARE(proxy1.columnCount(QModelIndex()), 1); + //the model should not be sorted because sorting has not been set to dynamic yet. + QCOMPARE(proxy1.rowCount(QModelIndex()), initial.count()); + for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy1.index(row, 0, QModelIndex()); + QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), initial.at(row)); + } + + proxy1.setDynamicSortFilter(true); + + //now the model should be sorted. + QStringList expected = initial; + expected.sort(); + for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy1.index(row, 0, QModelIndex()); + QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row)); + } + + QStringList initial2 = initial; + initial2.replaceInStrings("bateau", "girafe"); + model1.setStringList(initial2); //this will cause a reset + + QStringList expected2 = initial2; + expected2.sort(); + + //now the model should still be sorted. + for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy1.index(row, 0, QModelIndex()); + QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected2.at(row)); + } + + QStringListModel model2(initial); + proxy1.setSourceModel(&model2); + + //the model should again be sorted + for (int row = 0; row < proxy1.rowCount(QModelIndex()); ++row) { + QModelIndex index = proxy1.index(row, 0, QModelIndex()); + QCOMPARE(proxy1.data(index, Qt::DisplayRole).toString(), expected.at(row)); + } +} + + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 42f496a..dfd0792 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -343,6 +343,7 @@ private slots: void paintOutsidePaintEvent(); #endif void updateOnDestroyedSignal(); + void toplevelLineEditFocus(); private: bool ensureScreenSize(int width, int height); @@ -8727,5 +8728,18 @@ void tst_QWidget::updateOnDestroyedSignal() QTest::qWait(200); } +void tst_QWidget::toplevelLineEditFocus() +{ + testWidget->hide(); + + QLineEdit w; + w.show(); + qt_x11_wait_for_window_manager(&w); + QTest::qWait(200); + + QCOMPARE(QApplication::activeWindow(), &w); + QCOMPARE(QApplication::focusWidget(), &w); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp index 569ed22..8a21409 100644 --- a/tools/linguist/lconvert/main.cpp +++ b/tools/linguist/lconvert/main.cpp @@ -51,20 +51,16 @@ static int usage(const QStringList &args) Q_UNUSED(args); QString loaders; - QString savers; - QString line = QString(QLatin1String(" %1 - %2\n")); - foreach (Translator::FileFormat format, Translator::registeredFileFormats()) { + QString line(QLatin1String(" %1 - %2\n")); + foreach (Translator::FileFormat format, Translator::registeredFileFormats()) loaders += line.arg(format.extension, -5).arg(format.description); - savers += line.arg(format.extension, -5).arg(format.description); - } qWarning("%s", qPrintable(QString(QLatin1String("\nUsage:\n" " lconvert [options] <infile> [<infile>...]\n\n" "lconvert is part of Qt's Linguist tool chain. It can be used as a\n" - "stand-alone tool to convert translation data files from one of the\n" - "following input formats\n\n%1\n" - "to one of the following output formats\n\n%2\n" - "If multiple input files are specified the translations are merged with\n" + "stand-alone tool to convert and filter translation data files.\n" + "The following file formats are supported:\n\n%1\n" + "If multiple input files are specified, they are merged with\n" "translations from later files taking precedence.\n\n" "Options:\n" " -h\n" @@ -92,7 +88,7 @@ static int usage(const QStringList &args) " Note: this implies --no-obsolete.\n\n" " --source-language <language>[_<region>]\n" " Specify/override the language of the source strings. Defaults to\n" - " POSIX if not specified and the file does not name it yet.\n" + " POSIX if not specified and the file does not name it yet.\n\n" " --target-language <language>[_<region>]\n" " Specify/override the language of the translation.\n" " The target language is guessed from the file name if this option\n" @@ -108,7 +104,7 @@ static int usage(const QStringList &args) " 0 on success\n" " 1 on command line parse failures\n" " 2 on read failures\n" - " 3 on write failures\n")).arg(loaders).arg(savers))); + " 3 on write failures\n")).arg(loaders))); return 1; } diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 7d79024..dd890ce 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -84,12 +84,12 @@ static void printUsage() { printOut(QObject::tr( "Usage:\n" - " lupdate [options] [project-file]\n" + " lupdate [options] [project-file]...\n" " lupdate [options] [source-file|path]... -ts ts-files\n\n" - "lupdate is part of Qt's Linguist tool chain. It can be used as a\n" - "stand-alone tool to create XML based translations files in the .ts\n" - "format from translatable messages in C++ and Java source code.\n\n" - "lupdate can also merge such messages into existing .ts files.\n\n" + "lupdate is part of Qt's Linguist tool chain. It extracts translatable\n" + "messages from Qt UI files, C++, Java and JavaScript/QtScript source code.\n" + "Extracted messages are stored in textual translation source files (typically\n" + "Qt TS XML). New and modified messages can be merged into existing TS files.\n\n" "Options:\n" " -help Display this information and exit.\n" " -no-obsolete\n" diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css index 0d0b664..6cf7377 100644 --- a/tools/qdoc3/test/classic.css +++ b/tools/qdoc3/test/classic.css @@ -99,6 +99,14 @@ body pre color: black } +table tr.qt-code pre +{ + padding: 0.2em; + border: #e7e7e7 1px solid; + background: #f1f1f1; + color: black +} + span.preprocessor, span.preprocessor a { color: darkblue; diff --git a/util/scripts/make_qfeatures_dot_h b/util/scripts/make_qfeatures_dot_h index c434649..056c113 100755 --- a/util/scripts/make_qfeatures_dot_h +++ b/util/scripts/make_qfeatures_dot_h @@ -83,23 +83,55 @@ open OUT, ">$ENV{QTDIR}/src/corelib/global/qfeatures.h" or die "Cannot open $ENV{QTDIR}/src/corelib/global/qfeatures.h for writing"; print OUT -"/**************************************************************************** +'/**************************************************************************** ** -** Copyright (C) 1992-\$THISYEAR\$ \$TROLLTECH\$. All rights reserved. +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) ** -** This file is part of the \$MODULE\$ of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** -** \$TROLLTECH_DUAL_LICENSE\$ +** $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$ ** ****************************************************************************/ /* * All features and their dependencies. * - * This list is generated from \$QTDIR/src/corelib/global/qfeatures.txt + * This list is generated from $QTDIR/src/corelib/global/qfeatures.txt */ -"; +'; + for $macro ( @macros ) { print OUT "// $label{$macro}\n"; |