diff options
Diffstat (limited to 'src')
65 files changed, 2364 insertions, 181 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c b/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c index a216005..7bd3b3b 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c +++ b/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c @@ -3012,6 +3012,9 @@ static HB_Error Lookup_MarkMarkPos( GPOS_Instance* gpi, j--; } + if ( i > buffer->in_pos ) + return HB_Err_Not_Covered; + error = _HB_OPEN_Coverage_Index( &mmp->Mark2Coverage, IN_GLYPH( j ), &mark2_index ); if ( error ) diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index c961101..de5b003 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -369,8 +369,7 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo entryFlags &= ~LinkType; #if !defined(Q_OS_WINCE) if ((fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) - && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK - || findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) { + && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) { entryFlags |= LinkType; } #endif diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 0d23a27..548f9cf 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -120,7 +120,7 @@ void QFSFileEnginePrivate::init() openMode = QIODevice::NotOpen; fd = -1; fh = 0; -#ifdef Q_OS_SYMBIAN +#if defined (Q_OS_SYMBIAN) && !defined(QT_SYMBIAN_USE_NATIVE_FILEMAP) fileHandleForMaps = -1; #endif lastIOCommand = IOFlushCommand; @@ -368,8 +368,10 @@ bool QFSFileEnginePrivate::closeFdFh() if (fd == -1 && !fh #ifdef Q_OS_SYMBIAN && !symbianFile.SubSessionHandle() +#ifndef QT_SYMBIAN_USE_NATIVE_FILEMAP && fileHandleForMaps == -1 #endif +#endif ) return false; @@ -378,7 +380,7 @@ bool QFSFileEnginePrivate::closeFdFh() bool closed = true; tried_stat = 0; -#ifdef Q_OS_SYMBIAN +#if defined(Q_OS_SYMBIAN) && !defined(QT_SYMBIAN_USE_NATIVE_FILEMAP) // Map handle is always owned by us so always close it if (fileHandleForMaps >= 0) { QT_CLOSE(fileHandleForMaps); diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 79dda1b..f93250e 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -62,6 +62,12 @@ #ifdef Q_OS_SYMBIAN #include <f32file.h> +//This macro will be defined if the OS supports memory mapped files +#if defined (SYMBIAN_FILE_MAPPING_SUPPORTED) && !defined (WINS) +//simpler define to check in sources +#define QT_SYMBIAN_USE_NATIVE_FILEMAP +#include <f32filemap.h> +#endif #endif #ifndef QT_NO_FSFILEENGINE @@ -139,9 +145,11 @@ public: */ TInt symbianFilePos; #endif +#ifndef QT_SYMBIAN_USE_NATIVE_FILEMAP mutable int fileHandleForMaps; int getMapHandle(); #endif +#endif #ifdef Q_WS_WIN HANDLE fileHandle; @@ -153,6 +161,8 @@ public: #endif mutable DWORD fileAttrib; +#elif defined (QT_SYMBIAN_USE_NATIVE_FILEMAP) + QHash<uchar *, RFileMap> maps; #else QHash<uchar *, QPair<int /*offset % PageSize*/, size_t /*length + offset % PageSize*/> > maps; #endif diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 681e55d..9de282a 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -602,7 +602,7 @@ int QFSFileEnginePrivate::nativeHandle() const return fh ? fileno(fh) : fd; } -#ifdef Q_OS_SYMBIAN +#if defined(Q_OS_SYMBIAN) && !defined(QT_SYMBIAN_USE_NATIVE_FILEMAP) int QFSFileEnginePrivate::getMapHandle() { if (symbianFile.SubSessionHandle()) { @@ -925,6 +925,7 @@ QString QFSFileEngine::owner(FileOwner own) const return QFileSystemEngine::resolveUserName(ownerId(own)); return QFileSystemEngine::resolveGroupName(ownerId(own)); #else + Q_UNUSED(own) return QString(); #endif } @@ -1045,9 +1046,47 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla QT_OFF_T realOffset = QT_OFF_T(offset); realOffset &= ~(QT_OFF_T(pageSize - 1)); +#ifdef QT_SYMBIAN_USE_NATIVE_FILEMAP + TInt nativeMapError = KErrNone; + RFileMap mapping; + TUint mode(EFileMapRemovableMedia); + //If the file was opened for write or read/write, then open the map for read/write + if (openMode & QIODevice::WriteOnly) + mode |= EFileMapWrite; + if (symbianFile.SubSessionHandle()) { + nativeMapError = mapping.Open(symbianFile, offset, size, mode); + } else { + //map file by name if we don't have a native handle + QString fn = QFileSystemEngine::absoluteName(fileEntry).nativeFilePath(); + TUint filemode = EFileShareReadersOrWriters | EFileRead; + if (openMode & QIODevice::WriteOnly) + filemode |= EFileWrite; + nativeMapError = mapping.Open(qt_s60GetRFs(), qt_QString2TPtrC(fn), filemode, offset, size, mode); + } + if (nativeMapError == KErrNone) { + QScopedResource<RFileMap> ptr(mapping); //will call Close if adding to mapping throws an exception + uchar *address = mapping.Base(); + maps[address] = mapping; + ptr.take(); + return address; + } + QFile::FileError reportedError = QFile::UnspecifiedError; + switch (nativeMapError) { + case KErrAccessDenied: + case KErrPermissionDenied: + reportedError = QFile::PermissionsError; + break; + case KErrNoMemory: + reportedError = QFile::ResourceError; + break; + } + q->setError(reportedError, QSystemError(nativeMapError, QSystemError::NativeError).toString()); + return 0; +#else #ifdef Q_OS_SYMBIAN + //older phones & emulator don't support native mapping, so need to keep the open C way around for those. void *mapAddress; - TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize, + TRAPD(err, mapAddress = QT_MMAP((void*)0, realSize, access, MAP_SHARED, getMapHandle(), realOffset)); if (err != KErrNone) { qWarning("OpenC bug: leave from mmap %d", err); @@ -1079,6 +1118,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla break; } return 0; +#endif } bool QFSFileEnginePrivate::unmap(uchar *ptr) @@ -1090,6 +1130,17 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) return false; } +#ifdef QT_SYMBIAN_USE_NATIVE_FILEMAP + RFileMap mapping = maps.value(ptr); + TInt err = mapping.Flush(); + mapping.Close(); + maps.remove(ptr); + if (err) { + q->setError(QFile::WriteError, QSystemError(err, QSystemError::NativeError).toString()); + return false; + } + return true; +#else uchar *start = ptr - maps[ptr].first; size_t len = maps[ptr].second; if (-1 == munmap(start, len)) { @@ -1098,6 +1149,7 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr) } maps.remove(ptr); return true; +#endif #else return false; #endif diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d551009..4226f9e 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -106,6 +106,19 @@ folding rules in QUrl conform to \l{RFC 3491} (Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)). + \section2 Character Conversions + + Follow these rules to avoid erroneous character conversion when + dealing with URLs and strings: + + \list + \o When creating an QString to contain a URL from a QByteArray or a + char*, always use QString::fromUtf8(). + \o Favor the use of QUrl::fromEncoded() and QUrl::toEncoded() instead of + QUrl(string) and QUrl::toString() when converting a QUrl to or from + a string. + \endlist + \sa QUrlInfo */ @@ -6514,16 +6527,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \o hostname becomes http://hostname \o /home/user/test.html becomes file:///home/user/test.html \endlist - - \section2 Tips to avoid erroneous character conversion when dealing with - URLs and strings: - - \list - \o When creating an URL QString from a QByteArray or a char*, always use - QString::fromUtf8(). - \o Favor the use of QUrl::fromEncoded() and QUrl::toEncoded() instead of - QUrl(string) and QUrl::toString() when converting QUrl to/from string. - \endlist */ QUrl QUrl::fromUserInput(const QString &userInput) { diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h index 3019e05..a8f576d 100644 --- a/src/corelib/kernel/qcore_symbian_p.h +++ b/src/corelib/kernel/qcore_symbian_p.h @@ -59,6 +59,7 @@ #include <qstring.h> #include <qrect.h> #include <qhash.h> +#include <qscopedpointer.h> #include <f32file.h> #include <es_sock.h> @@ -262,6 +263,29 @@ private: RConnection *iDefaultConnection; }; +template <typename T> class QScopedPointerResourceCloser +{ +public: + static inline void cleanup(T* pointer) + { + if (pointer) + pointer->Close(); + } +}; + +/*typical use: + RFile file; + file.Open(...); + QScopedResource<RFile> ptr(file); + container.append(file); //this may throw std::bad_alloc, in which case file.Close() is called by destructor + ptr.take(); //if we reach this line, ownership is transferred to the container + */ +template <typename T> class QScopedResource : public QScopedPointer<T, QScopedPointerResourceCloser<T> > +{ +public: + inline QScopedResource(T& resource) : QScopedPointer<T, QScopedPointerResourceCloser<T> >(&resource) {} +}; + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index 12bc795..2a9d23c 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -60,6 +60,7 @@ # include <linux/futex.h> # include <sys/syscall.h> # include <unistd.h> +# include <QtCore/qelapsedtimer.h> #endif QT_BEGIN_NAMESPACE @@ -138,16 +139,31 @@ static inline int _q_futex(volatile int *addr, int op, int val, const struct tim bool QMutexPrivate::wait(int timeout) { + struct timespec ts, *pts = 0; + QElapsedTimer timer; + if (timeout >= 0) { + ts.tv_nsec = ((timeout % 1000) * 1000) * 1000; + ts.tv_sec = (timeout / 1000); + pts = &ts; + timer.start(); + } while (contenders.fetchAndStoreAcquire(2) > 0) { - struct timespec ts, *pts = 0; - if (timeout >= 0) { - ts.tv_nsec = ((timeout % 1000) * 1000) * 1000; - ts.tv_sec = (timeout / 1000); - pts = &ts; - } int r = _q_futex(&contenders._q_value, FUTEX_WAIT, 2, pts, 0, 0); if (r != 0 && errno == ETIMEDOUT) return false; + + if (pts) { + // recalculate the timeout + qint64 xtimeout = timeout * 1000 * 1000; + xtimeout -= timer.nsecsElapsed(); + if (xtimeout < 0) { + // timer expired after we returned + return false; + } + + ts.tv_sec = xtimeout / Q_INT64_C(1000) / 1000 / 1000; + ts.tv_nsec = xtimeout % (Q_INT64_C(1000) * 1000 * 1000); + } } return true; } diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp index cd076a6..d79dc5d 100644 --- a/src/corelib/tools/qelapsedtimer_win.cpp +++ b/src/corelib/tools/qelapsedtimer_win.cpp @@ -42,14 +42,14 @@ #include "qelapsedtimer.h" #include <windows.h> -// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable -static quint64 counterFrequency = 0; - typedef ULONGLONG (WINAPI *PtrGetTickCount64)(void); static PtrGetTickCount64 ptrGetTickCount64 = 0; QT_BEGIN_NAMESPACE +// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable +static quint64 counterFrequency = 0; + static void resolveLibs() { static bool done = false; diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index d791529..8640c8b 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -88,6 +88,8 @@ Q_GLOBAL_STATIC(QLocalePrivate, globalLocalePrivate) #ifdef QT_USE_ICU extern bool qt_initIcu(const QString &localeName); +extern bool qt_u_strToUpper(const QString &str, QString *out, const QLocale &locale); +extern bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale); #endif /****************************************************************************** @@ -2180,6 +2182,42 @@ Qt::LayoutDirection QLocale::textDirection() const return Qt::LeftToRight; } +/*! + \since 4.8 + + Returns an uppercase copy of \a str. +*/ +QString QLocale::toUpper(const QString &str) const +{ +#ifdef QT_USE_ICU + { + QString result; + if (qt_u_strToUpper(str, &result, *this)) + return result; + // else fall through and use Qt's toUpper + } +#endif + return str.toUpper(); +} + +/*! + \since 4.8 + + Returns a lowercase copy of \a str. +*/ +QString QLocale::toLower(const QString &str) const +{ +#ifdef QT_USE_ICU + { + QString result; + if (qt_u_strToLower(str, &result, *this)) + return result; + // else fall through and use Qt's toUpper + } +#endif + return str.toLower(); +} + /*! \since 4.5 diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index 8a5d526..55dd55b 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -724,6 +724,9 @@ public: Qt::LayoutDirection textDirection() const; + QString toUpper(const QString &str) const; + QString toLower(const QString &str) const; + QString currencySymbol(CurrencySymbolFormat = CurrencySymbol) const; QString toCurrencyString(qlonglong, const QString &symbol = QString()) const; QString toCurrencyString(qulonglong, const QString &symbol = QString()) const; diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 791bfff..f5efe55 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -109,8 +109,6 @@ static QHash<void *, QByteArray> *asciiCache = 0; #ifdef QT_USE_ICU // qlocale_icu.cpp extern bool qt_ucol_strcoll(const QChar *source, int sourceLength, const QChar *target, int targetLength, int *result); -extern bool qt_u_strToUpper(const QString &str, QString *out, const QLocale &locale); -extern bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale); #endif @@ -5015,7 +5013,10 @@ QString QString::rightJustified(int width, QChar fill, bool truncate) const \snippet doc/src/snippets/qstring/main.cpp 75 - \sa toUpper() + The case conversion will always happen in the 'C' locale. For locale dependent + case folding use QLocale::toLower() + + \sa toUpper(), QLocale::toLower() */ QString QString::toLower() const @@ -5026,15 +5027,6 @@ QString QString::toLower() const if (!d->size) return *this; -#ifdef QT_USE_ICU - { - QString result; - if (qt_u_strToLower(*this, &result, QLocale())) - return result; - // else fall through and use Qt's toUpper - } -#endif - const ushort *e = d->data + d->size; // this avoids one out of bounds check in the loop @@ -5115,7 +5107,10 @@ QString QString::toCaseFolded() const \snippet doc/src/snippets/qstring/main.cpp 81 - \sa toLower() + The case conversion will always happen in the 'C' locale. For locale dependent + case folding use QLocale::toUpper() + + \sa toLower(), QLocale::toLower() */ QString QString::toUpper() const @@ -5126,15 +5121,6 @@ QString QString::toUpper() const if (!d->size) return *this; -#ifdef QT_USE_ICU - { - QString result; - if (qt_u_strToUpper(*this, &result, QLocale())) - return result; - // else fall through and use Qt's toUpper - } -#endif - const ushort *e = d->data + d->size; // this avoids one out of bounds check in the loop diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 3fd4fcd..5245236 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -1046,7 +1046,7 @@ void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus) Q_Q(QDeclarativeTextInput); focused = hasFocus; q->setCursorVisible(hasFocus && scene && scene->hasFocus()); - if(q->echoMode() == QDeclarativeTextInput::PasswordEchoOnEdit && !hasFocus) + if(!hasFocus && control->passwordEchoEditing()) control->updatePasswordEchoEditing(false);//QLineControl sets it on key events, but doesn't deal with focus events if (!hasFocus) control->deselect(); diff --git a/src/declarative/util/qdeclarativestateoperations_p.h b/src/declarative/util/qdeclarativestateoperations_p.h index 6a6dda6..a05edb8 100644 --- a/src/declarative/util/qdeclarativestateoperations_p.h +++ b/src/declarative/util/qdeclarativestateoperations_p.h @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QDeclarativeParentChangePrivate; -class Q_AUTOTEST_EXPORT QDeclarativeParentChange : public QDeclarativeStateOperation, public QDeclarativeActionEvent +class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeParentChange : public QDeclarativeStateOperation, public QDeclarativeActionEvent { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeParentChange) @@ -251,7 +251,7 @@ private: }; class QDeclarativeAnchorChangesPrivate; -class Q_AUTOTEST_EXPORT QDeclarativeAnchorChanges : public QDeclarativeStateOperation, public QDeclarativeActionEvent +class Q_DECLARATIVE_PRIVATE_EXPORT QDeclarativeAnchorChanges : public QDeclarativeStateOperation, public QDeclarativeActionEvent { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeAnchorChanges) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 337bb99..10e5785 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1048,6 +1048,11 @@ const QAccessibleInterface *other, int otherChild) const */ /*! + \fn QAccessibleTable2Interface *QAccessibleInterface::table2Interface() + \internal +*/ + +/*! \fn QAccessibleActionInterface *QAccessibleInterface::actionInterface() \internal */ diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index fc03e1c..24a6744 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -84,40 +84,40 @@ public: MenuCommand = 0x0018, // Values from IAccessible2 - ActionChanged = 0x0101, - ActiveDescendantChanged, - AttributeChanged, - DocumentContentChanged, - DocumentLoadComplete, - DocumentLoadStopped, - DocumentReload, - HyperlinkEndIndexChanged, - HyperlinkNumberOfAnchorsChanged, - HyperlinkSelectedLinkChanged, - HypertextLinkActivated, - HypertextLinkSelected, - HyperlinkStartIndexChanged, - HypertextChanged, - HypertextNLinksChanged, - ObjectAttributeChanged, - PageChanged, - SectionChanged, - TableCaptionChanged, - TableColumnDescriptionChanged, - TableColumnHeaderChanged, - TableModelChanged, - TableRowDescriptionChanged, - TableRowHeaderChanged, - TableSummaryChanged, - TextAttributeChanged, - TextCaretMoved, - // TextChanged, deprecated, use TextUpdated - TextColumnChanged = TextCaretMoved + 2, - TextInserted, - TextRemoved, - TextUpdated, - TextSelectionChanged, - VisibleDataChanged, + ActionChanged = 0x0101, + ActiveDescendantChanged = 0x0102, + AttributeChanged = 0x0103, + DocumentContentChanged = 0x0104, + DocumentLoadComplete = 0x0105, + DocumentLoadStopped = 0x0106, + DocumentReload = 0x0107, + HyperlinkEndIndexChanged = 0x0108, + HyperlinkNumberOfAnchorsChanged = 0x0109, + HyperlinkSelectedLinkChanged = 0x010A, + HypertextLinkActivated = 0x010B, + HypertextLinkSelected = 0x010C, + HyperlinkStartIndexChanged = 0x010D, + HypertextChanged = 0x010E, + HypertextNLinksChanged = 0x010F, + ObjectAttributeChanged = 0x0110, + PageChanged = 0x0111, + SectionChanged = 0x0112, + TableCaptionChanged = 0x0113, + TableColumnDescriptionChanged = 0x0114, + TableColumnHeaderChanged = 0x0115, + TableModelChanged = 0x0116, + TableRowDescriptionChanged = 0x0117, + TableRowHeaderChanged = 0x0118, + TableSummaryChanged = 0x0119, + TextAttributeChanged = 0x011A, + TextCaretMoved = 0x011B, + // TextChanged = 0x011C, is deprecated in IA2, use TextUpdated + TextColumnChanged = 0x011D, + TextInserted = 0x011E, + TextRemoved = 0x011F, + TextUpdated = 0x0120, + TextSelectionChanged = 0x0121, + VisibleDataChanged = 0x0122, ObjectCreated = 0x8000, ObjectDestroyed = 0x8001, @@ -151,6 +151,7 @@ public: ReadOnly = 0x00000040, HotTracked = 0x00000080, DefaultButton = 0x00000100, + // #### Qt5 Expandable Expanded = 0x00000200, Collapsed = 0x00000400, Busy = 0x00000800, @@ -178,6 +179,8 @@ public: HasPopup = 0x40000000, Modal = 0x80000000, + // #### Qt5 ManagesDescendants + // #### Qt5 remove HasInvokeExtension HasInvokeExtension = 0x10000000 // internal }; Q_DECLARE_FLAGS(State, StateFlag) @@ -348,7 +351,8 @@ namespace QAccessible2 ValueInterface, TableInterface, ActionInterface, - ImageInterface + ImageInterface, + Table2Interface }; } @@ -359,6 +363,7 @@ class QAccessibleValueInterface; class QAccessibleTableInterface; class QAccessibleActionInterface; class QAccessibleImageInterface; +class QAccessibleTable2Interface; class Q_GUI_EXPORT QAccessibleInterface : public QAccessible { @@ -422,6 +427,9 @@ public: inline QAccessibleImageInterface *imageInterface() { return reinterpret_cast<QAccessibleImageInterface *>(cast_helper(QAccessible2::ImageInterface)); } + inline QAccessibleTable2Interface *table2Interface() + { return reinterpret_cast<QAccessibleTable2Interface *>(cast_helper(QAccessible2::Table2Interface)); } + private: QAccessible2Interface *cast_helper(QAccessible2::InterfaceType); }; diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h index 5cb0323..106b69e 100644 --- a/src/gui/accessible/qaccessible2.h +++ b/src/gui/accessible/qaccessible2.h @@ -52,6 +52,8 @@ QT_MODULE(Gui) #ifndef QT_NO_ACCESSIBILITY +class QModelIndex; + namespace QAccessible2 { enum CoordinateType @@ -68,6 +70,24 @@ namespace QAccessible2 LineBoundary, NoBoundary }; + + enum TableModelChangeType { + TableModelChangeInsert, + TableModelChangeDelete, + TableModelChangeUpdate + }; + + struct TableModelChange { + int firstColumn; + int firstRow; + int lastColumn; + int lastRow; + TableModelChangeType type; + + TableModelChange() + : firstColumn(0), firstRow(0), lastColumn(0), lastRow(0), type(TableModelChangeUpdate) + {} + }; } class Q_GUI_EXPORT QAccessible2Interface @@ -83,6 +103,7 @@ inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; } +inline QAccessible2Interface *qAccessibleTable2CastHelper() { return 0; } #define Q_ACCESSIBLE_OBJECT \ public: \ @@ -101,6 +122,8 @@ inline QAccessible2Interface *qAccessibleImageCastHelper() { return 0; } return qAccessibleActionCastHelper(); \ case QAccessible2::ImageInterface: \ return qAccessibleImageCastHelper(); \ + case QAccessible2::Table2Interface: \ + return qAccessibleTable2CastHelper(); \ } \ return 0; \ } \ @@ -214,6 +237,95 @@ public: int *columnSpan, bool *isSelected) = 0; }; +class Q_GUI_EXPORT QAccessibleTable2CellInterface: public QAccessibleInterface +{ +public: + // Returns the number of columns occupied by this cell accessible. + virtual int columnExtent() const = 0; + + // Returns the column headers as an array of cell accessibles. + virtual QList<QAccessibleInterface*> columnHeaderCells() const = 0; + + // Translates this cell accessible into the corresponding column index. + virtual int columnIndex() const = 0; + // Returns the number of rows occupied by this cell accessible. + virtual int rowExtent() const = 0; + // Returns the row headers as an array of cell accessibles. + virtual QList<QAccessibleInterface*> rowHeaderCells() const = 0; + // Translates this cell accessible into the corresponding row index. + virtual int rowIndex() const = 0; + // Returns a boolean value indicating whether this cell is selected. + virtual bool isSelected() const = 0; + + // Gets the row and column indexes and extents of this cell accessible and whether or not it is selected. + virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const = 0; + // Returns a reference to the accessbile of the containing table. + virtual QAccessibleTable2Interface* table() const = 0; + + // #### Qt5 this should not be here but part of the state + virtual bool isExpandable() const = 0; +}; + +class Q_GUI_EXPORT QAccessibleTable2Interface: public QAccessible2Interface +{ +public: + inline QAccessible2Interface *qAccessibleTable2CastHelper() { return this; } + + // Returns the cell at the specified row and column in the table. + virtual QAccessibleTable2CellInterface *cellAt (int row, int column) const = 0; + // Returns the caption for the table. + virtual QAccessibleInterface *caption() const = 0; + // Returns the description text of the specified column in the table. + virtual QString columnDescription(int column) const = 0; + // Returns the total number of columns in table. + virtual int columnCount() const = 0; + // Returns the total number of rows in table. + virtual int rowCount() const = 0; + // Returns the total number of selected cells. + virtual int selectedCellCount() const = 0; + // Returns the total number of selected columns. + virtual int selectedColumnCount() const = 0; + // Returns the total number of selected rows. + virtual int selectedRowCount() const = 0; + // Returns the description text of the specified row in the table. + virtual QString rowDescription(int row) const = 0; + // Returns a list of accessibles currently selected. + virtual QList<QAccessibleTable2CellInterface*> selectedCells() const = 0; + // Returns a list of column indexes currently selected (0 based). + virtual QList<int> selectedColumns() const = 0; + // Returns a list of row indexes currently selected (0 based). + virtual QList<int> selectedRows() const = 0; + // Returns the summary description of the table. + virtual QAccessibleInterface *summary() const = 0; + // Returns a boolean value indicating whether the specified column is completely selected. + virtual bool isColumnSelected(int column) const = 0; + // Returns a boolean value indicating whether the specified row is completely selected. + virtual bool isRowSelected(int row) const = 0; + // Selects a row and unselects all previously selected rows. + virtual bool selectRow(int row) = 0; + // Selects a column and unselects all previously selected columns. + virtual bool selectColumn(int column) = 0; + // Unselects one row, leaving other selected rows selected (if any). + virtual bool unselectRow(int row) = 0; + // Unselects one column, leaving other selected columns selected (if any). + virtual bool unselectColumn(int column) = 0; + // Returns the type and extents describing how a table changed. + virtual QAccessible2::TableModelChange modelChange() const = 0; + +protected: + // These functions are called when the model changes. + virtual void modelReset() = 0; + virtual void rowsInserted(const QModelIndex &parent, int first, int last) = 0; + virtual void rowsRemoved(const QModelIndex &parent, int first, int last) = 0; + virtual void columnsInserted(const QModelIndex &parent, int first, int last) = 0; + virtual void columnsRemoved(const QModelIndex &parent, int first, int last) = 0; + virtual void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) = 0; + virtual void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column) = 0; + +friend class QAbstractItemView; +friend class QAbstractItemViewPrivate; +}; + class Q_GUI_EXPORT QAccessibleActionInterface : public QAccessible2Interface { public: diff --git a/src/gui/accessible/qaccessible_unix.cpp b/src/gui/accessible/qaccessible_unix.cpp index a6b7ec3..19fbe78 100644 --- a/src/gui/accessible/qaccessible_unix.cpp +++ b/src/gui/accessible/qaccessible_unix.cpp @@ -103,6 +103,17 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason) if (!iface) return; + // updates for List/Table/Tree should send child + if (who) { + QAccessibleInterface *child; + iface->navigate(QAccessible::Child, who, &child); + if (child) { + delete iface; + iface = child; + who = 0; + } + } + for (int i = 0; i < bridges()->count(); ++i) bridges()->at(i)->notifyAccessibilityUpdate(reason, iface, who); delete iface; diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp index 376b0d0..b2e7cb3 100644 --- a/src/gui/embedded/qkbdlinuxinput_qws.cpp +++ b/src/gui/embedded/qkbdlinuxinput_qws.cpp @@ -103,6 +103,7 @@ QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, QString dev = QLatin1String("/dev/input/event1"); int repeat_delay = -1; int repeat_rate = -1; + int grab = 0; QStringList args = device.split(QLatin1Char(':')); foreach (const QString &arg, args) { @@ -110,12 +111,15 @@ QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, repeat_delay = arg.mid(13).toInt(); else if (arg.startsWith(QLatin1String("repeat-rate="))) repeat_rate = arg.mid(12).toInt(); + else if (arg.startsWith(QLatin1String("grab="))) + grab = arg.mid(5).toInt(); else if (arg.startsWith(QLatin1String("/dev/"))) dev = arg; } m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDWR, 0); if (m_fd >= 0) { + ::ioctl(m_fd, EVIOCGRAB, grab); if (repeat_delay > 0 && repeat_rate > 0) { int kbdrep[2] = { repeat_delay, repeat_rate }; ::ioctl(m_fd, EVIOCSREP, kbdrep); diff --git a/src/gui/embedded/qmouselinuxinput_qws.cpp b/src/gui/embedded/qmouselinuxinput_qws.cpp index 19a9a99..5b4f664 100644 --- a/src/gui/embedded/qmouselinuxinput_qws.cpp +++ b/src/gui/embedded/qmouselinuxinput_qws.cpp @@ -43,6 +43,7 @@ #include <QScreen> #include <QSocketNotifier> +#include <QStringList> #include <qplatformdefs.h> #include <private/qcore_unix_p.h> // overrides QT_OPEN @@ -101,11 +102,19 @@ QWSLinuxInputMousePrivate::QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler * setObjectName(QLatin1String("LinuxInputSubsystem Mouse Handler")); QString dev = QLatin1String("/dev/input/event0"); - if (device.startsWith(QLatin1String("/dev/"))) - dev = device; + int grab = 0; + + QStringList args = device.split(QLatin1Char(':')); + foreach (const QString &arg, args) { + if (arg.startsWith(QLatin1String("grab="))) + grab = arg.mid(5).toInt(); + else if (arg.startsWith(QLatin1String("/dev/"))) + dev = arg; + } m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (m_fd >= 0) { + ::ioctl(m_fd, EVIOCGRAB, grab); m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); } else { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 655725b..1551944 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1639,7 +1639,8 @@ QGraphicsScene::~QGraphicsScene() Q_D(QGraphicsScene); // Remove this scene from qApp's global scene list. - qApp->d_func()->scene_list.removeAll(this); + if (!QApplicationPrivate::is_app_closing) + qApp->d_func()->scene_list.removeAll(this); clear(); diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index c783b76..2aeb3de 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -275,12 +275,13 @@ public: QString text(const QString &key = QString()) const; void setText(const QString &key, const QString &value); - // The following functions are obsolete as of 4.1 - QString text(const char* key, const char* lang=0) const; - QList<QImageTextKeyLang> textList() const; - QStringList textLanguages() const; - QString text(const QImageTextKeyLang&) const; - void setText(const char* key, const char* lang, const QString&); +#ifdef QT_DEPRECATED + QT_DEPRECATED QString text(const char* key, const char* lang=0) const; + QT_DEPRECATED QList<QImageTextKeyLang> textList() const; + QT_DEPRECATED QStringList textLanguages() const; + QT_DEPRECATED QString text(const QImageTextKeyLang&) const; + QT_DEPRECATED void setText(const char* key, const char* lang, const QString&); +#endif #endif #ifdef QT3_SUPPORT diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 4668913..f5479e7 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -109,8 +109,10 @@ public: QBitmap mask() const; void setMask(const QBitmap &); - QPixmap alphaChannel() const; - void setAlphaChannel(const QPixmap &); +#ifdef QT_DEPRECATED + QT_DEPRECATED QPixmap alphaChannel() const; + QT_DEPRECATED void setAlphaChannel(const QPixmap &); +#endif bool hasAlpha() const; bool hasAlphaChannel() const; @@ -183,7 +185,9 @@ public: inline void scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed = 0); void scroll(int dx, int dy, const QRect &rect, QRegion *exposed = 0); - int serialNumber() const; +#ifdef QT_DEPRECATED + QT_DEPRECATED int serialNumber() const; +#endif qint64 cacheKey() const; bool isDetached() const; diff --git a/src/gui/image/qtiffhandler.cpp b/src/gui/image/qtiffhandler.cpp index c753b83..4dc9775 100644 --- a/src/gui/image/qtiffhandler.cpp +++ b/src/gui/image/qtiffhandler.cpp @@ -236,14 +236,14 @@ bool QTiffHandler::read(QImage *image) } } else { // create the color table - uint16 *redTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16))); - uint16 *greenTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16))); - uint16 *blueTable = static_cast<uint16 *>(qMalloc(tableSize * sizeof(uint16))); - if (!redTable || !greenTable || !blueTable) { + uint16 *redTable = 0; + uint16 *greenTable = 0; + uint16 *blueTable = 0; + if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) { TIFFClose(tiff); return false; } - if (!TIFFGetField(tiff, TIFFTAG_COLORMAP, &redTable, &greenTable, &blueTable)) { + if (!redTable || !greenTable || !blueTable) { TIFFClose(tiff); return false; } @@ -500,6 +500,9 @@ bool QTiffHandler::write(const QImage &image) uint16 *greenTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16))); uint16 *blueTable = static_cast<uint16 *>(qMalloc(256 * sizeof(uint16))); if (!redTable || !greenTable || !blueTable) { + qFree(redTable); + qFree(greenTable); + qFree(blueTable); TIFFClose(tiff); return false; } diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index f53705b..ded4d63 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -60,6 +60,7 @@ #include <private/qabstractitemmodel_p.h> #ifndef QT_NO_ACCESSIBILITY #include <qaccessible.h> +#include <qaccessible2.h> #endif #include <private/qsoftkeymanager_p.h> @@ -645,6 +646,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model) this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(_q_rowsRemoved(QModelIndex,int,int))); + disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(_q_rowsInserted(QModelIndex,int,int))); disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int))); disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), @@ -675,6 +678,8 @@ void QAbstractItemView::setModel(QAbstractItemModel *model) this, SLOT(_q_headerDataChanged())); connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted(QModelIndex,int,int))); + connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), + this, SLOT(_q_rowsInserted(QModelIndex,int,int))); connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int))); connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), @@ -1058,6 +1063,14 @@ void QAbstractItemView::reset() setRootIndex(QModelIndex()); if (d->selectionModel) d->selectionModel->reset(); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + if (QAccessible::isActive()) { + QAccessible::queryAccessibleInterface(this)->table2Interface()->modelReset(); + QAccessible::updateAccessibility(this, 0, QAccessible::TableModelChanged); + } +#endif +#endif } /*! @@ -2805,7 +2818,7 @@ void QAbstractItemView::editorDestroyed(QObject *editor) */ void QAbstractItemView::setHorizontalStepsPerItem(int steps) { - Q_UNUSED(steps); + Q_UNUSED(steps) // do nothing } @@ -2834,7 +2847,7 @@ int QAbstractItemView::horizontalStepsPerItem() const */ void QAbstractItemView::setVerticalStepsPerItem(int steps) { - Q_UNUSED(steps); + Q_UNUSED(steps) // do nothing } @@ -3267,12 +3280,24 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star rows are those under the given \a parent from \a start to \a end inclusive. */ -void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &, int, int) +void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int start, int end) { + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + Q_Q(QAbstractItemView); if (q->isVisible()) q->updateEditorGeometries(); q->setState(QAbstractItemView::NoState); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + if (QAccessible::isActive()) { + QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsRemoved(index, start, end); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } +#endif +#endif } /*! @@ -3335,27 +3360,72 @@ void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &par rows are those under the given \a parent from \a start to \a end inclusive. */ -void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &, int, int) +void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int start, int end) { + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + Q_Q(QAbstractItemView); if (q->isVisible()) q->updateEditorGeometries(); q->setState(QAbstractItemView::NoState); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + if (QAccessible::isActive()) { + QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsRemoved(index, start, end); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } +#endif +#endif } + /*! \internal This slot is called when rows have been inserted. */ -void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &, int, int) +void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int start, int end) { + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + Q_Q(QAbstractItemView); - if (q->isVisible()) - q->updateEditorGeometries(); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + if (QAccessible::isActive()) { + QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsInserted(index, start, end); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } +#endif +#endif } +/*! + \internal + This slot is called when columns have been inserted. +*/ +void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int start, int end) +{ + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + + Q_Q(QAbstractItemView); + if (q->isVisible()) + q->updateEditorGeometries(); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + if (QAccessible::isActive()) { + QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsInserted(index, start, end); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } +#endif +#endif +} /*! \internal @@ -3373,7 +3443,16 @@ void QAbstractItemViewPrivate::_q_modelDestroyed() */ void QAbstractItemViewPrivate::_q_layoutChanged() { + Q_Q(QAbstractItemView); doDelayedItemsLayout(); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + if (QAccessible::isActive()) { + QAccessible::queryAccessibleInterface(q)->table2Interface()->modelReset(); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } +#endif +#endif } /*! @@ -3698,7 +3777,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QM QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::multiSelectionCommand( const QModelIndex &index, const QEvent *event) const { - Q_UNUSED(index); + Q_UNUSED(index) if (event) { switch (event->type()) { diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index cb7b78d..1d0c36e 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -355,6 +355,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_columnsInserted(const QModelIndex&, int, int)) + Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 3ba7227..04babde 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -108,6 +108,7 @@ public: void init(); virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_rowsInserted(const QModelIndex &parent, int start, int end); virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end); virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index a234fde..a0955d2 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -3168,7 +3168,11 @@ void QListView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr if (QAccessible::isActive()) { if (current.isValid()) { int entry = visualIndex(current) + 1; +#ifdef Q_WS_X11 + QAccessible::updateAccessibility(this, entry, QAccessible::Focus); +#else QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus); +#endif } } #endif @@ -3187,12 +3191,20 @@ void QListView::selectionChanged(const QItemSelection &selected, QModelIndex sel = selected.indexes().value(0); if (sel.isValid()) { int entry = visualIndex(sel) + 1; +#ifdef Q_WS_X11 + QAccessible::updateAccessibility(this, entry, QAccessible::Selection); +#else QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection); +#endif } QModelIndex desel = deselected.indexes().value(0); if (desel.isValid()) { int entry = visualIndex(desel) + 1; +#ifdef Q_WS_X11 + QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove); +#else QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove); +#endif } } #endif diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 617409f..6f532eb 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -3164,10 +3164,16 @@ void QTableView::currentChanged(const QModelIndex ¤t, const QModelIndex &p #ifndef QT_NO_ACCESSIBILITY if (QAccessible::isActive()) { if (current.isValid()) { +#ifdef Q_WS_X11 + Q_D(QTableView); + int entry = d->accessibleTable2Index(current); + QAccessible::updateAccessibility(this, entry, QAccessible::Focus); +#else int entry = visualIndex(current) + 1; if (horizontalHeader()) ++entry; QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus); +#endif } } #endif @@ -3180,22 +3186,33 @@ void QTableView::currentChanged(const QModelIndex ¤t, const QModelIndex &p void QTableView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { + Q_D(QTableView); #ifndef QT_NO_ACCESSIBILITY if (QAccessible::isActive()) { // ### does not work properly for selection ranges. QModelIndex sel = selected.indexes().value(0); if (sel.isValid()) { +#ifdef Q_WS_X11 + int entry = d->accessibleTable2Index(sel); + QAccessible::updateAccessibility(this, entry, QAccessible::Selection); +#else int entry = visualIndex(sel); if (horizontalHeader()) ++entry; QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection); +#endif } QModelIndex desel = deselected.indexes().value(0); if (desel.isValid()) { +#ifdef Q_WS_X11 + int entry = d->accessibleTable2Index(sel); + QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove); +#else int entry = visualIndex(sel); if (horizontalHeader()) ++entry; QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove); +#endif } } #endif diff --git a/src/gui/itemviews/qtableview_p.h b/src/gui/itemviews/qtableview_p.h index f973acf..dce0ed0 100644 --- a/src/gui/itemviews/qtableview_p.h +++ b/src/gui/itemviews/qtableview_p.h @@ -167,6 +167,11 @@ public: return horizontalHeader->logicalIndex(visualCol); } + inline int accessibleTable2Index(const QModelIndex &index) const { + return (index.row() + (horizontalHeader ? 1 : 0)) * (index.model()->columnCount() + (verticalHeader ? 1 : 0)) + + index.column() + (verticalHeader ? 1 : 0) + 1; + } + int sectionSpanEndLogical(const QHeaderView *header, int logical, int span) const; int sectionSpanSize(const QHeaderView *header, int logical, int span) const; bool spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const; diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 6a992db..9228ac8 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -54,6 +54,7 @@ #include <qdebug.h> #ifndef QT_NO_ACCESSIBILITY #include <qaccessible.h> +#include <qaccessible2.h> #endif #include <private/qtreeview_p.h> @@ -2883,20 +2884,36 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem) { + Q_Q(QTreeView); viewItems.insert(pos, count, viewItem); QTreeViewItem *items = viewItems.data(); for (int i = pos + count; i < viewItems.count(); i++) if (items[i].parentItem >= pos) items[i].parentItem += count; +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + if (QAccessible::isActive()) { + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } +#endif +#endif } void QTreeViewPrivate::removeViewItems(int pos, int count) { + Q_Q(QTreeView); viewItems.remove(pos, count); QTreeViewItem *items = viewItems.data(); for (int i = pos; i < viewItems.count(); i++) if (items[i].parentItem >= pos) items[i].parentItem -= count; +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + if (QAccessible::isActive()) { + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } +#endif +#endif } #if 0 @@ -3687,14 +3704,6 @@ void QTreeViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order) */ void QTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { -#ifndef QT_NO_ACCESSIBILITY - if (QAccessible::isActive()) { - int entry = visualIndex(current) + 1; - if (header()) - ++entry; - QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus); - } -#endif QAbstractItemView::currentChanged(current, previous); if (allColumnsShowFocus()) { @@ -3711,6 +3720,19 @@ void QTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr viewport()->update(currentRect); } } +#ifndef QT_NO_ACCESSIBILITY + if (QAccessible::isActive() && current.isValid()) { +#ifdef Q_WS_X11 + int entry = (visualIndex(current) + (header()?1:0))*current.model()->columnCount()+current.column() + 1; + QAccessible::updateAccessibility(this, entry, QAccessible::Focus); +#else + int entry = visualIndex(current) + 1; + if (header()) + ++entry; + QAccessible::updateAccessibility(viewport(), entry, QAccessible::Focus); +#endif + } +#endif } /*! @@ -3719,26 +3741,38 @@ void QTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr void QTreeView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { + QAbstractItemView::selectionChanged(selected, deselected); #ifndef QT_NO_ACCESSIBILITY if (QAccessible::isActive()) { // ### does not work properly for selection ranges. QModelIndex sel = selected.indexes().value(0); if (sel.isValid()) { +#ifdef Q_WS_X11 + int entry = (visualIndex(sel) + (header()?1:0))*sel.model()->columnCount()+sel.column() + 1; + Q_ASSERT(entry > 0); + QAccessible::updateAccessibility(this, entry, QAccessible::Selection); +#else int entry = visualIndex(sel) + 1; if (header()) ++entry; QAccessible::updateAccessibility(viewport(), entry, QAccessible::Selection); +#endif } QModelIndex desel = deselected.indexes().value(0); if (desel.isValid()) { +#ifdef Q_WS_X11 + int entry = (visualIndex(desel) + (header()?1:0))*desel.model()->columnCount()+desel.column() + 1; + Q_ASSERT(entry > 0); + QAccessible::updateAccessibility(this, entry, QAccessible::SelectionRemove); +#else int entry = visualIndex(desel) + 1; if (header()) ++entry; QAccessible::updateAccessibility(viewport(), entry, QAccessible::SelectionRemove); +#endif } } #endif - QAbstractItemView::selectionChanged(selected, deselected); } int QTreeView::visualIndex(const QModelIndex &index) const diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 26c7315..b77da4e 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -219,6 +219,9 @@ protected: private: friend class QAccessibleItemView; + friend class QAccessibleTable2; + friend class QAccessibleTree; + friend class QAccessibleTable2Cell; int visualIndex(const QModelIndex &index) const; Q_DECLARE_PRIVATE(QTreeView) diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index b6d8458..a9dc452 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -78,7 +78,7 @@ struct QTreeViewItem Q_DECLARE_TYPEINFO(QTreeViewItem, Q_MOVABLE_TYPE); -class QTreeViewPrivate : public QAbstractItemViewPrivate +class Q_GUI_EXPORT QTreeViewPrivate : public QAbstractItemViewPrivate { Q_DECLARE_PUBLIC(QTreeView) public: @@ -223,6 +223,10 @@ public: inline void invalidateHeightCache(int item) const { viewItems[item].height = 0; } + inline int accessibleTable2Index(const QModelIndex &index) const { + return (viewIndex(index) + (header ? 1 : 0)) * model->columnCount()+index.column() + 1; + } + // used for spanning rows QVector<QPersistentModelIndex> spanningIndexes; diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index eaa9405..f99cc2c 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -2879,6 +2879,12 @@ void QWidgetPrivate::deleteTLSysExtra() { // don't destroy input context here. it will be destroyed in // QWidget::destroy() destroyInputContext(); +#ifndef QT_NO_XSYNC + if (extra && extra->topextra && extra->topextra->syncUpdateCounter) { + XSyncDestroyCounter(X11->display, extra->topextra->syncUpdateCounter); + extra->topextra->syncUpdateCounter = 0; + } +#endif } void QWidgetPrivate::registerDropSite(bool on) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 9bd9733..1d10d75 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6469,10 +6469,16 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QLineF line(pos.x(), pos.y(), pos.x() + qFloor(width), pos.y()); - const qreal underlineOffset = fe->underlinePosition().toReal(); + qreal underlineOffset = fe->underlinePosition().toReal(); + qreal y = pos.y(); + // compensate for different rounding rule in Core Graphics paint engine, + // ideally code like this should be moved to respective engines. + if (painter->paintEngine()->type() == QPaintEngine::CoreGraphics) { + y = qCeil(y); + } // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(underlineOffset); + const qreal underlinePos = y + qCeil(underlineOffset); if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); diff --git a/src/gui/s60framework/qs60keycapture.cpp b/src/gui/s60framework/qs60keycapture.cpp index 415c3e1..1beefd4 100644 --- a/src/gui/s60framework/qs60keycapture.cpp +++ b/src/gui/s60framework/qs60keycapture.cpp @@ -42,7 +42,7 @@ #include <remconinterfaceselector.h> #include <remconcoreapitarget.h> #include <coemain.h> -#include "qkeymapper_p.h" +#include <private/qkeymapper_p.h> #include "qs60keycapture_p.h" QT_BEGIN_NAMESPACE diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index da484ba..b894eb4 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -76,6 +76,10 @@ static const int windowsRightBorder = 15; // right border on windows # define CMDLGS_PRESSED 3 # define CMDLGS_DISABLED 4 #endif +#ifndef PP_TRANSPARENTBAR +# define PP_TRANSPARENTBAR 11 +# define PP_TRANSPARENTBARVERT 12 +#endif // Runtime resolved theme engine function calls @@ -1059,6 +1063,19 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } break; #ifndef QT_NO_PROGRESSBAR + case CE_ProgressBarGroove: + { + Qt::Orientation orient = Qt::Horizontal; + if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(option)) + orient = pb2->orientation; + partId = (orient == Qt::Horizontal) ? PP_TRANSPARENTBAR : PP_TRANSPARENTBARVERT; + name = QLatin1String("PROGRESS"); + stateId = 1; + + XPThemeData theme(widget, painter, name, partId, stateId, rect); + d->drawBackground(theme); + } + break; case CE_ProgressBarContents: if (const QStyleOptionProgressBar *bar = qstyleoption_cast<const QStyleOptionProgressBar *>(option)) { diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 3762f39..26d9f2c 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1130,13 +1130,14 @@ QT_BEGIN_INCLUDE_NAMESPACE #elif defined(Q_OS_SYMBIAN) # include "qfontdatabase_s60.cpp" #endif +QT_END_INCLUDE_NAMESPACE + #if !defined(Q_WS_X11) QString QFontDatabase::resolveFontFamilyAlias(const QString &family) { return family; } #endif -QT_END_INCLUDE_NAMESPACE static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey, const QString &styleName = QString()) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index c900918..41ea56a 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -323,7 +323,7 @@ static QChar::Direction skipBoundryNeutrals(QScriptAnalysis *analysis, const ushort *unicode, int length, int &sor, int &eor, QBidiControl &control) { - QChar::Direction dir; + QChar::Direction dir = control.basicDirection(); int level = sor > 0 ? analysis[sor - 1].bidiLevel : control.level; while (sor < length) { dir = QChar::direction(unicode[sor]); @@ -2808,7 +2808,7 @@ QFixed QTextEngine::alignLine(const QScriptLine &line) if (align & Qt::AlignRight) x = line.width - (line.textAdvance + leadingSpaceWidth(line)); else if (align & Qt::AlignHCenter) - x = (line.width - (line.textAdvance + leadingSpaceWidth(line)))/2; + x = (line.width - line.textAdvance)/2 - leadingSpaceWidth(line); } return x; } @@ -2890,6 +2890,7 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end, } const HB_CharAttributes *attrs = attributes(); + logClusters = this->logClusters(si); clusterLength = getClusterLength(logClusters, attrs, 0, end, glyph_pos, &clusterStart); if (clusterLength) { diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index 251d9b5..9da8f03 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -605,6 +605,12 @@ void QTextEngine::shapeTextMac(int item) const unsigned short *log_clusters = logClusters(&si); bool stringToCMapFailed = false; + // Skip shaping of line or paragraph separators since we are not + // going to draw them anyway + if (si.analysis.flags == QScriptAnalysis::LineOrParagraphSeparator + && !(option.flags() & QTextOption::ShowLineAndParagraphSeparators)) + goto cleanUp; + if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) { ensureSpace(num_glyphs); g = availableGlyphs(&si); @@ -645,6 +651,7 @@ void QTextEngine::shapeTextMac(int item) const } } +cleanUp: const ushort *uc = reinterpret_cast<const ushort *>(str); if ((si.analysis.flags == QScriptAnalysis::SmallCaps || si.analysis.flags == QScriptAnalysis::Uppercase diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 621cae9..41394e3 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -80,6 +80,9 @@ #if defined(Q_WS_S60) #include "private/qt_s60_p.h" #endif +#ifndef QT_NO_ACCESSIBILITY +#include "qaccessible.h" +#endif QT_BEGIN_NAMESPACE @@ -1018,6 +1021,9 @@ void QComboBoxPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIn } q->update(); } +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(q, 0, QAccessible::NameChanged); +#endif } void QComboBoxPrivate::_q_rowsInserted(const QModelIndex &parent, int start, int end) @@ -1271,6 +1277,9 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) Q_Q(QComboBox); emit q->currentIndexChanged(index.row()); emit q->currentIndexChanged(itemText(index)); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(q, 0, QAccessible::NameChanged); +#endif } QString QComboBoxPrivate::itemText(const QModelIndex &index) const @@ -2635,6 +2644,9 @@ void QComboBox::clear() { Q_D(QComboBox); d->model->removeRows(0, d->model->rowCount(d->root), d->root); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged); +#endif } /*! @@ -2651,6 +2663,9 @@ void QComboBox::clearEditText() Q_D(QComboBox); if (d->lineEdit) d->lineEdit->clear(); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged); +#endif } /*! @@ -2661,6 +2676,9 @@ void QComboBox::setEditText(const QString &text) Q_D(QComboBox); if (d->lineEdit) d->lineEdit->setText(text); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged); +#endif } /*! diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index 26dd0e1..dcf35aa 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -55,6 +55,10 @@ #include "private/qstylesheetstyle_p.h" #include <qmath.h> +#ifndef QT_NO_ACCESSIBILITY +#include <qaccessible.h> +#endif + QT_BEGIN_NAMESPACE /*! @@ -370,6 +374,11 @@ void QLabel::setText(const QString &text) #endif d->updateLabel(); + +#ifndef QT_NO_ACCESSIBILITY + if (accessibleName().isEmpty()) + QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged); +#endif } QString QLabel::text() const diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index bf36033..84674a5 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -59,6 +59,22 @@ QT_BEGIN_NAMESPACE +#ifdef QT_GUI_PASSWORD_ECHO_DELAY +static int qt_passwordEchoDelay = QT_GUI_PASSWORD_ECHO_DELAY; +#endif + +/*! + \macro QT_GUI_PASSWORD_ECHO_DELAY + + \internal + + Defines the amount of time in milliseconds the last entered character + should be displayed unmasked in the Password echo mode. + + If not defined in qplatformdefs.h there will be no delay in masking + password characters. +*/ + /*! \internal @@ -74,9 +90,25 @@ void QLineControl::updateDisplayText(bool forceUpdate) else str = m_text; - if (m_echoMode == QLineEdit::Password || (m_echoMode == QLineEdit::PasswordEchoOnEdit - && !m_passwordEchoEditing)) + if (m_echoMode == QLineEdit::Password) { str.fill(m_passwordCharacter); +#ifdef QT_GUI_PASSWORD_ECHO_DELAY + if (m_passwordEchoTimer != 0 && !str.isEmpty()) { + int cursor = m_text.length() - 1; + QChar uc = m_text.at(cursor); + str[cursor] = uc; + if (cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { + // second half of a surrogate, check if we have the first half as well, + // if yes restore both at once + uc = m_text.at(cursor - 1); + if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) + str[cursor - 1] = uc; + } + } +#endif + } else if (m_echoMode == QLineEdit::PasswordEchoOnEdit && !m_passwordEchoEditing) { + str.fill(m_passwordCharacter); + } // replace certain non-printable characters with spaces (to avoid // drawing boxes when using fonts that don't have glyphs for such @@ -311,6 +343,7 @@ void QLineControl::init(const QString &txt) */ void QLineControl::updatePasswordEchoEditing(bool editing) { + cancelPasswordEchoTimer(); m_passwordEchoEditing = editing; updateDisplayText(); } @@ -640,6 +673,7 @@ bool QLineControl::finishChange(int validateFromState, bool update, bool edited) */ void QLineControl::internalSetText(const QString &txt, int pos, bool edited) { + cancelPasswordEchoTimer(); internalDeselect(); emit resetInputContext(); QString oldText = m_text; @@ -692,6 +726,13 @@ void QLineControl::addCommand(const Command &cmd) */ void QLineControl::internalInsert(const QString &s) { +#ifdef QT_GUI_PASSWORD_ECHO_DELAY + if (m_echoMode == QLineEdit::Password) { + if (m_passwordEchoTimer != 0) + killTimer(m_passwordEchoTimer); + m_passwordEchoTimer = startTimer(qt_passwordEchoDelay); + } +#endif if (hasSelectedText()) addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); if (m_maskData) { @@ -729,6 +770,7 @@ void QLineControl::internalInsert(const QString &s) void QLineControl::internalDelete(bool wasBackspace) { if (m_cursor < (int) m_text.length()) { + cancelPasswordEchoTimer(); if (hasSelectedText()) addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)), @@ -755,6 +797,7 @@ void QLineControl::internalDelete(bool wasBackspace) void QLineControl::removeSelectedText() { if (m_selstart < m_selend && m_selend <= (int) m_text.length()) { + cancelPasswordEchoTimer(); separate(); int i ; addCommand(Command(SetSelection, m_cursor, 0, m_selstart, m_selend)); @@ -1153,6 +1196,7 @@ void QLineControl::internalUndo(int until) { if (!isUndoAvailable()) return; + cancelPasswordEchoTimer(); internalDeselect(); while (m_undoState && m_undoState > until) { Command& cmd = m_history[--m_undoState]; @@ -1357,6 +1401,12 @@ void QLineControl::timerEvent(QTimerEvent *event) } else if (event->timerId() == m_tripleClickTimer) { killTimer(m_tripleClickTimer); m_tripleClickTimer = 0; +#ifdef QT_GUI_PASSWORD_ECHO_DELAY + } else if (event->timerId() == m_passwordEchoTimer) { + killTimer(m_passwordEchoTimer); + m_passwordEchoTimer = 0; + updateDisplayText(); +#endif } } diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index cca4bfa..6a1b4e3 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -66,6 +66,8 @@ #include "QtGui/qcompleter.h" #include "QtGui/qaccessible.h" +#include "qplatformdefs.h" + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -85,6 +87,9 @@ public: m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1), m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0), m_selstart(0), m_selend(0), m_passwordEchoEditing(false) +#ifdef QT_GUI_PASSWORD_ECHO_DELAY + , m_passwordEchoTimer(0) +#endif { init(txt); } @@ -222,6 +227,7 @@ public: uint echoMode() const { return m_echoMode; } void setEchoMode(uint mode) { + cancelPasswordEchoTimer(); m_echoMode = mode; m_passwordEchoEditing = false; updateDisplayText(); @@ -271,7 +277,13 @@ public: QString preeditAreaText() const { return m_textLayout.preeditAreaText(); } void updatePasswordEchoEditing(bool editing); - bool passwordEchoEditing() const { return m_passwordEchoEditing; } + bool passwordEchoEditing() const { +#ifdef QT_GUI_PASSWORD_ECHO_DELAY + if (m_passwordEchoTimer != 0) + return true; +#endif + return m_passwordEchoEditing ; + } QChar passwordCharacter() const { return m_passwordCharacter; } void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); } @@ -419,6 +431,18 @@ private: bool m_passwordEchoEditing; QChar m_passwordCharacter; +#ifdef QT_GUI_PASSWORD_ECHO_DELAY + int m_passwordEchoTimer; +#endif + void cancelPasswordEchoTimer() + { +#ifdef QT_GUI_PASSWORD_ECHO_DELAY + if (m_passwordEchoTimer != 0) { + killTimer(m_passwordEchoTimer); + m_passwordEchoTimer = 0; + } +#endif + } Q_SIGNALS: void cursorPositionChanged(int, int); diff --git a/src/network/access/qnetworkaccessfilebackend.cpp b/src/network/access/qnetworkaccessfilebackend.cpp index 42cc2c2..7c4adca 100644 --- a/src/network/access/qnetworkaccessfilebackend.cpp +++ b/src/network/access/qnetworkaccessfilebackend.cpp @@ -67,7 +67,7 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op, QUrl url = request.url(); if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0 || url.isLocalFile()) { return new QNetworkAccessFileBackend; - } else if (!url.scheme().isEmpty() && url.authority().isEmpty()) { + } else if (!url.isEmpty() && url.authority().isEmpty()) { // check if QFile could, in theory, open this URL via the file engines // it has to be in the format: // prefix:path/to/file @@ -75,7 +75,8 @@ QNetworkAccessFileBackendFactory::create(QNetworkAccessManager::Operation op, // // this construct here must match the one below in open() QFileInfo fi(url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery)); - if ((url.scheme().length()==1) && fi.exists()) + // On Windows and Symbian the drive letter is detected as the scheme. + if (fi.exists() && (url.scheme().isEmpty() || (url.scheme().length() == 1))) qWarning("QNetworkAccessFileBackendFactory: URL has no schema set, use file:// for files"); if (fi.exists() || (op == QNetworkAccessManager::PutOperation && fi.dir().exists())) return new QNetworkAccessFileBackend; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 5d2221f..0d2f2a2 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -90,10 +90,9 @@ QT_BEGIN_NAMESPACE -inline static bool isPowerOfTwo(int x) +inline static bool isPowerOfTwo(uint x) { - // Assumption: x >= 1 - return x == (x & -x); + return x && !(x & (x - 1)); } #if defined(Q_WS_WIN) @@ -248,16 +247,13 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption | QGLContext::CanFlipNativePixmapBindOption); -#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2) - QGLFunctions funcs(QGLContext::currentContext()); - bool npotSupported = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures); - bool isNpot = !isPowerOfTwo(currentBrushPixmap.size().width()) - || !isPowerOfTwo(currentBrushPixmap.size().height()); - if (isNpot && !npotSupported) { - qWarning("GL2 Paint Engine: This system does not support the REPEAT wrap mode for non-power-of-two textures."); - } + GLenum wrapMode = GL_REPEAT; +#ifdef QT_OPENGL_ES_2 + // should check for GL_OES_texture_npot or GL_IMG_texture_npot extension + if (!isPowerOfTwo(currentBrushPixmap.width()) || !isPowerOfTwo(currentBrushPixmap.height())) + wrapMode = GL_CLAMP_TO_EDGE; #endif - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); + updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform); textureInvertedY = tex->options & QGLContext::InvertedYBindOption ? -1 : 1; } brushTextureDirty = false; diff --git a/src/opengl/qpixmapdata_symbiangl.cpp b/src/opengl/qpixmapdata_symbiangl.cpp index 78e5ee7..a7e33e2 100644 --- a/src/opengl/qpixmapdata_symbiangl.cpp +++ b/src/opengl/qpixmapdata_symbiangl.cpp @@ -142,6 +142,7 @@ QGLPixmapData::QGLPixmapData(PixelType type) QGLPixmapData::~QGLPixmapData() { +#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE if (m_sgImage) { if (m_texture.id) { QGLSgImageTextureCleanup::cleanupForContext(m_ctx)->remove(m_texture.id); @@ -152,6 +153,7 @@ QGLPixmapData::~QGLPixmapData() delete m_sgImage; m_sgImage = 0; } +#endif delete m_engine; } @@ -668,6 +670,7 @@ static inline bool knownGoodFormat(QImage::Format format) } } +#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE static inline int symbianPixeFormatBitsPerPixel(TUidPixelFormat pixelFormat) { switch (pixelFormat) { @@ -719,6 +722,7 @@ static inline int symbianPixeFormatBitsPerPixel(TUidPixelFormat pixelFormat) return 32; }; } +#endif void QGLPixmapData::fromNativeType(void* pixmap, NativeType type) { diff --git a/src/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index f7961b4..e16eeb3 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -686,6 +686,8 @@ QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget) #endif EGLSurface surface = context->createSurface(widget, &surfaceProps); if (surface == EGL_NO_SURFACE) { + qt_vg_destroy_paint_engine(engine); + engine = 0; qt_vg_destroy_context(context, QInternal::Widget); context = 0; return 0; diff --git a/src/openvg/qwindowsurface_vgegl_p.h b/src/openvg/qwindowsurface_vgegl_p.h index 231c548..2226e28 100644 --- a/src/openvg/qwindowsurface_vgegl_p.h +++ b/src/openvg/qwindowsurface_vgegl_p.h @@ -80,10 +80,8 @@ public: virtual bool supportsStaticContents() const { return false; } virtual bool scroll(QWidget *, const QRegion&, int, int) { return false; } -private: - QVGPaintEngine *engine; - protected: + QVGPaintEngine *engine; QWindowSurface *winSurface; void destroyPaintEngine(); diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp index 8843d3e..563d3b9 100644 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ b/src/plugins/accessible/widgets/complexwidgets.cpp @@ -1776,16 +1776,12 @@ QString QAccessibleComboBox::text(Text t, int child) const switch (t) { case Name: +#ifndef Q_WS_X11 // on Linux we use relations for this, name is text (fall through to Value) if (child == OpenList) str = QComboBox::tr("Open"); else str = QAccessibleWidgetEx::text(t, 0); break; -#ifndef QT_NO_SHORTCUT - case Accelerator: - if (child == OpenList) - str = (QString)QKeySequence(Qt::Key_Down); - // missing break? #endif case Value: if (comboBox()->isEditable()) @@ -1793,6 +1789,12 @@ QString QAccessibleComboBox::text(Text t, int child) const else str = comboBox()->currentText(); break; +#ifndef QT_NO_SHORTCUT + case Accelerator: + if (child == OpenList) + str = (QString)QKeySequence(Qt::Key_Down); + break; +#endif default: break; } diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp new file mode 100644 index 0000000..4618f87 --- /dev/null +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -0,0 +1,1029 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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.1, 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "itemviews.h" + +#include <qheaderview.h> +#include <qtableview.h> +#include <qlistview.h> +#include <qtreeview.h> +#include <private/qtreewidget_p.h> +#include <qaccessible2.h> +#include <QDebug> + +#ifndef QT_NO_ACCESSIBILITY + +QT_BEGIN_NAMESPACE + +QString Q_GUI_EXPORT qt_accStripAmp(const QString &text); + +#ifndef QT_NO_ITEMVIEWS +/* +Implementation of the IAccessible2 table2 interface. Much simpler than +the other table interfaces since there is only the main table and cells: + +TABLE/LIST/TREE + |- HEADER CELL + |- CELL + |- CELL + ... +*/ + +int QAccessibleTable2::logicalIndex(const QModelIndex &index) const +{ + if (!index.isValid()) + return -1; + int vHeader = verticalHeader() ? 1 : 0; + int hHeader = horizontalHeader() ? 1 : 0; + // row * number columns + column + 1 for one based counting + return (index.row() + hHeader)*(index.model()->columnCount() + vHeader) + (index.column() + vHeader) + 1; +} + +QAccessibleInterface *QAccessibleTable2::childFromLogical(int logicalIndex) const +{ + logicalIndex--; // one based counting ftw + int vHeader = verticalHeader() ? 1 : 0; + int hHeader = horizontalHeader() ? 1 : 0; + + int columns = view->model()->columnCount() + vHeader; + + int row = logicalIndex / columns; + int column = logicalIndex % columns; + + if (vHeader) { + if (column == 0) { + if (row == 0) { + return new QAccessibleTable2CornerButton(view); + } + return new QAccessibleTable2HeaderCell(view, row-1, Qt::Vertical); + } + --column; + } + if (hHeader) { + if (row == 0) { + return new QAccessibleTable2HeaderCell(view, column, Qt::Horizontal); + } + --row; + } + return new QAccessibleTable2Cell(view, view->model()->index(row, column), cellRole()); +} + +QAccessibleTable2::QAccessibleTable2(QWidget *w) + : QAccessibleObjectEx(w) +{ + view = qobject_cast<QAbstractItemView *>(w); + Q_ASSERT(view); + + if (qobject_cast<const QTableView*>(view)) { + m_role = QAccessible::Table; + } else if (qobject_cast<const QTreeView*>(view)) { + m_role = QAccessible::Tree; + } else if (qobject_cast<const QListView*>(view)) { + m_role = QAccessible::List; + } else { + // is this our best guess? + m_role = QAccessible::Table; + } +} + +QAccessibleTable2::~QAccessibleTable2() +{ +} + +QHeaderView *QAccessibleTable2::horizontalHeader() const +{ + QHeaderView *header = 0; + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) { + header = tv->horizontalHeader(); +#endif +#ifndef QT_NO_TREEVIEW + } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) { + header = tv->header(); +#endif + } + return header; +} + +QHeaderView *QAccessibleTable2::verticalHeader() const +{ + QHeaderView *header = 0; + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) { + header = tv->verticalHeader(); +#endif + } + return header; +} + +void QAccessibleTable2::modelReset() +{} + +void QAccessibleTable2::rowsInserted(const QModelIndex &, int first, int last) +{ + lastChange.firstRow = first; + lastChange.lastRow = last; + lastChange.firstColumn = 0; + lastChange.lastColumn = 0; + lastChange.type = QAccessible2::TableModelChangeInsert; +} + +void QAccessibleTable2::rowsRemoved(const QModelIndex &, int first, int last) +{ + lastChange.firstRow = first; + lastChange.lastRow = last; + lastChange.firstColumn = 0; + lastChange.lastColumn = 0; + lastChange.type = QAccessible2::TableModelChangeDelete; +} + +void QAccessibleTable2::columnsInserted(const QModelIndex &, int first, int last) +{ + lastChange.firstRow = 0; + lastChange.lastRow = 0; + lastChange.firstColumn = first; + lastChange.lastColumn = last; + lastChange.type = QAccessible2::TableModelChangeInsert; +} + +void QAccessibleTable2::columnsRemoved(const QModelIndex &, int first, int last) +{ + lastChange.firstRow = 0; + lastChange.lastRow = 0; + lastChange.firstColumn = first; + lastChange.lastColumn = last; + lastChange.type = QAccessible2::TableModelChangeDelete; +} + +void QAccessibleTable2::rowsMoved( const QModelIndex &, int, int, const QModelIndex &, int) +{ + lastChange.firstRow = 0; + lastChange.lastRow = 0; + lastChange.firstColumn = 0; + lastChange.lastColumn = 0; + lastChange.type = QAccessible2::TableModelChangeUpdate; +} + +void QAccessibleTable2::columnsMoved( const QModelIndex &, int, int, const QModelIndex &, int) +{ + lastChange.firstRow = 0; + lastChange.lastRow = 0; + lastChange.firstColumn = 0; + lastChange.lastColumn = 0; + lastChange.type = QAccessible2::TableModelChangeUpdate; +} + +QAccessibleTable2Cell *QAccessibleTable2::cell(const QModelIndex &index) const +{ + if (index.isValid()) + return new QAccessibleTable2Cell(view, index, cellRole()); + return 0; +} + +QAccessibleTable2CellInterface *QAccessibleTable2::cellAt(int row, int column) const +{ + Q_ASSERT(role(0) != QAccessible::Tree); + QModelIndex index = view->model()->index(row, column); + //Q_ASSERT(index.isValid()); + if (!index.isValid()) { + qWarning() << "QAccessibleTable2::cellAt: invalid index: " << index << " for " << view; + return 0; + } + return cell(index); +} + +QAccessibleInterface *QAccessibleTable2::caption() const +{ + return 0; +} + +QString QAccessibleTable2::columnDescription(int column) const +{ + return view->model()->headerData(column, Qt::Horizontal).toString(); +} + +int QAccessibleTable2::columnCount() const +{ + return view->model()->columnCount(); +} + +int QAccessibleTable2::rowCount() const +{ + return view->model()->rowCount(); +} + +int QAccessibleTable2::selectedCellCount() const +{ + return view->selectionModel()->selectedIndexes().count(); +} + +int QAccessibleTable2::selectedColumnCount() const +{ + return view->selectionModel()->selectedColumns().count(); +} + +int QAccessibleTable2::selectedRowCount() const +{ + return view->selectionModel()->selectedRows().count(); +} + +QString QAccessibleTable2::rowDescription(int row) const +{ + return view->model()->headerData(row, Qt::Vertical).toString(); +} + +QList<QAccessibleTable2CellInterface*> QAccessibleTable2::selectedCells() const +{ + QList<QAccessibleTable2CellInterface*> cells; + Q_FOREACH (const QModelIndex &index, view->selectionModel()->selectedIndexes()) { + cells.append(cell(index)); + } + return cells; +} + +QList<int> QAccessibleTable2::selectedColumns() const +{ + QList<int> columns; + Q_FOREACH (const QModelIndex &index, view->selectionModel()->selectedColumns()) { + columns.append(index.column()); + } + return columns; +} + +QList<int> QAccessibleTable2::selectedRows() const +{ + QList<int> rows; + Q_FOREACH (const QModelIndex &index, view->selectionModel()->selectedRows()) { + rows.append(index.row()); + } + return rows; +} + +QAccessibleInterface *QAccessibleTable2::summary() const +{ + return 0; +} + +bool QAccessibleTable2::isColumnSelected(int column) const +{ + return view->selectionModel()->isColumnSelected(column, QModelIndex()); +} + +bool QAccessibleTable2::isRowSelected(int row) const +{ + return view->selectionModel()->isRowSelected(row, QModelIndex()); +} + +bool QAccessibleTable2::selectRow(int row) +{ + QModelIndex index = view->model()->index(row, 0); + if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection) + return false; + view->selectionModel()->select(index, QItemSelectionModel::Select); + return true; +} + +bool QAccessibleTable2::selectColumn(int column) +{ + QModelIndex index = view->model()->index(0, column); + if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection) + return false; + view->selectionModel()->select(index, QItemSelectionModel::Select); + return true; +} + +bool QAccessibleTable2::unselectRow(int row) +{ + QModelIndex index = view->model()->index(row, 0); + if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection) + return false; + view->selectionModel()->select(index, QItemSelectionModel::Deselect); + return true; +} + +bool QAccessibleTable2::unselectColumn(int column) +{ + QModelIndex index = view->model()->index(0, column); + if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection) + return false; + view->selectionModel()->select(index, QItemSelectionModel::Columns & QItemSelectionModel::Deselect); + return true; +} + +QAccessible2::TableModelChange QAccessibleTable2::modelChange() const +{ + QAccessible2::TableModelChange change; + // FIXME + return change; +} + +QAccessible::Role QAccessibleTable2::role(int child) const +{ + Q_ASSERT(child >= 0); + if (child > 0) + return QAccessible::Cell; + return m_role; +} + +QAccessible::State QAccessibleTable2::state(int child) const +{ + Q_ASSERT(child == 0); + return QAccessible::Normal | HasInvokeExtension; +} + +int QAccessibleTable2::childAt(int x, int y) const +{ + QPoint viewportOffset = view->viewport()->mapTo(view, QPoint(0,0)); + QPoint indexPosition = view->mapFromGlobal(QPoint(x, y) - viewportOffset); + // FIXME: if indexPosition < 0 in one coordinate, return header + + QModelIndex index = view->indexAt(indexPosition); + if (index.isValid()) { + return logicalIndex(index); + } + return -1; +} + +int QAccessibleTable2::childCount() const +{ + int vHeader = verticalHeader() ? 1 : 0; + int hHeader = horizontalHeader() ? 1 : 0; + return (view->model()->rowCount()+hHeader) * (view->model()->columnCount()+vHeader); +} + +int QAccessibleTable2::indexOfChild(const QAccessibleInterface *iface) const +{ + Q_ASSERT(iface->role(0) != QAccessible::TreeItem); // should be handled by tree class + if (iface->role(0) == QAccessible::Cell || iface->role(0) == QAccessible::ListItem) { + const QAccessibleTable2Cell* cell = static_cast<const QAccessibleTable2Cell*>(iface); + return logicalIndex(cell->m_index); + } else if (iface->role(0) == QAccessible::ColumnHeader){ + const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface); + return cell->index + (verticalHeader() ? 1 : 0) + 1; + } else if (iface->role(0) == QAccessible::RowHeader){ + const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface); + return (cell->index+1) * (view->model()->rowCount()+1) + 1; + } else if (iface->role(0) == QAccessible::Pane) { + return 1; // corner button + } else { + qWarning() << "WARNING QAccessibleTable2::indexOfChild Fix my children..." + << iface->role(0) << iface->text(QAccessible::Name, 0); + } + // FIXME: we are in denial of our children. this should stop. + return -1; +} + +QString QAccessibleTable2::text(Text t, int child) const +{ + Q_ASSERT(child == 0); + if (t == QAccessible::Description) + return view->accessibleDescription(); + return view->accessibleName(); +} + +QRect QAccessibleTable2::rect(int child) const +{ + Q_ASSERT(!child); + if (!view->isVisible()) + return QRect(); + QPoint pos = view->mapToGlobal(QPoint(0, 0)); + return QRect(pos.x(), pos.y(), view->width(), view->height()); +} + +int QAccessibleTable2::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +{ + *iface = 0; + switch (relation) { + case Ancestor: { + if (index == 1 && view->parent()) { + *iface = QAccessible::queryAccessibleInterface(view->parent()); + if (*iface) + return 0; + } + break; + } + case QAccessible::Child: { + Q_ASSERT(index > 0); + *iface = childFromLogical(index); + if (*iface) { + return 0; + } + break; + } + default: + break; + } + return -1; +} + +QAccessible::Relation QAccessibleTable2::relationTo(int, const QAccessibleInterface *, int) const +{ + return QAccessible::Unrelated; +} + +#ifndef QT_NO_ACTION +int QAccessibleTable2::userActionCount(int) const +{ + return 0; +} +QString QAccessibleTable2::actionText(int, Text, int) const +{ + return QString(); +} +bool QAccessibleTable2::doAction(int, int, const QVariantList &) +{ + return false; +} +#endif + + +// TREE VIEW + +QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const +{ + const QTreeView *treeView = qobject_cast<const QTreeView*>(view); + QModelIndex modelIndex = treeView->d_func()->viewItems.at(row).index; + + if (modelIndex.isValid() && column > 0) { + modelIndex = view->model()->index(modelIndex.row(), column, modelIndex.parent()); + } + return modelIndex; +} + +int QAccessibleTree::childAt(int x, int y) const +{ + QPoint viewportOffset = view->viewport()->mapTo(view, QPoint(0,0)); + QPoint indexPosition = view->mapFromGlobal(QPoint(x, y) - viewportOffset); + + QModelIndex index = view->indexAt(indexPosition); + if (!index.isValid()) + return -1; + + const QTreeView *treeView = qobject_cast<const QTreeView*>(view); + int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0); + int column = index.column(); + + int i = row * view->model()->columnCount() + column + 1; + Q_ASSERT(i > view->model()->columnCount()); + return i; +} + +int QAccessibleTree::childCount() const +{ + const QTreeView *treeView = qobject_cast<const QTreeView*>(view); + Q_ASSERT(treeView); + if (!view->model()) + return 0; + + int hHeader = horizontalHeader() ? 1 : 0; + return (treeView->d_func()->viewItems.count() + hHeader)* view->model()->columnCount(); +} + +int QAccessibleTree::rowCount() const +{ + const QTreeView *treeView = qobject_cast<const QTreeView*>(view); + Q_ASSERT(treeView); + return treeView->d_func()->viewItems.count(); +} + +int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const +{ + if (iface->role(0) == QAccessible::TreeItem) { + const QAccessibleTable2Cell* cell = static_cast<const QAccessibleTable2Cell*>(iface); + const QTreeView *treeView = qobject_cast<const QTreeView*>(view); + Q_ASSERT(treeView); + int row = treeView->d_func()->viewIndex(cell->m_index) + (horizontalHeader() ? 1 : 0); + int column = cell->m_index.column(); + + int index = row * view->model()->columnCount() + column + 1; + //qDebug() << "QAccessibleTree::indexOfChild r " << row << " c " << column << "index " << index; + Q_ASSERT(index > treeView->model()->columnCount()); + return index; + } else if (iface->role(0) == QAccessible::ColumnHeader){ + const QAccessibleTable2HeaderCell* cell = static_cast<const QAccessibleTable2HeaderCell*>(iface); + //qDebug() << "QAccessibleTree::indexOfChild header " << cell->index << "is: " << cell->index + 1; + return cell->index + 1; + } else { + qWarning() << "WARNING QAccessibleTable2::indexOfChild invalid child" + << iface->role(0) << iface->text(QAccessible::Name, 0); + } + // FIXME: add scrollbars and don't just ignore them + return -1; +} + +int QAccessibleTree::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +{ + switch (relation) { + case QAccessible::Child: { + Q_ASSERT(index > 0); + --index; + int hHeader = horizontalHeader() ? 1 : 0; + + if (hHeader) { + if (index < view->model()->columnCount()) { + *iface = new QAccessibleTable2HeaderCell(view, index, Qt::Horizontal); + return 0; + } else { + index -= view->model()->columnCount(); + } + } + + int row = index / view->model()->columnCount(); + int column = index % view->model()->columnCount(); + QModelIndex modelIndex = indexFromLogical(row, column); + if (modelIndex.isValid()) { + *iface = cell(modelIndex); + return 0; + } + return -1; + } + default: + break; + } + return QAccessibleTable2::navigate(relation, index, iface); +} + +QAccessible::Relation QAccessibleTree::relationTo(int, const QAccessibleInterface *, int) const +{ + return QAccessible::Unrelated; +} + +QAccessibleTable2CellInterface *QAccessibleTree::cellAt(int row, int column) const +{ + QModelIndex index = indexFromLogical(row, column); + if (!index.isValid()) { + qWarning() << "Requested invalid tree cell: " << row << column; + return 0; + } + return new QAccessibleTable2Cell(view, index, cellRole()); +} + +QString QAccessibleTree::rowDescription(int) const +{ + return QString(); // no headers for rows in trees +} + +bool QAccessibleTree::isRowSelected(int row) const +{ + QModelIndex index = indexFromLogical(row); + return view->selectionModel()->isRowSelected(index.row(), index.parent()); +} + +bool QAccessibleTree::selectRow(int row) +{ + QModelIndex index = indexFromLogical(row); + if (!index.isValid() || view->selectionMode() & QAbstractItemView::NoSelection) + return false; + view->selectionModel()->select(index, QItemSelectionModel::Select); + return true; +} + +// TABLE CELL + +QAccessibleTable2Cell::QAccessibleTable2Cell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_) + : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_) +{ + Q_ASSERT(index_.isValid()); +} + +int QAccessibleTable2Cell::columnExtent() const { return 1; } +int QAccessibleTable2Cell::rowExtent() const { return 1; } + +QList<QAccessibleInterface*> QAccessibleTable2Cell::rowHeaderCells() const +{ + QList<QAccessibleInterface*> headerCell; + if (verticalHeader()) { + headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.row(), Qt::Vertical)); + } + return headerCell; +} + +QList<QAccessibleInterface*> QAccessibleTable2Cell::columnHeaderCells() const +{ + QList<QAccessibleInterface*> headerCell; + if (horizontalHeader()) { + headerCell.append(new QAccessibleTable2HeaderCell(view, m_index.column(), Qt::Horizontal)); + } + return headerCell; +} + +QHeaderView *QAccessibleTable2Cell::horizontalHeader() const +{ + QHeaderView *header = 0; + + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) { + header = tv->horizontalHeader(); +#endif +#ifndef QT_NO_TREEVIEW + } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) { + header = tv->header(); +#endif + } + + return header; +} + +QHeaderView *QAccessibleTable2Cell::verticalHeader() const +{ + QHeaderView *header = 0; +#ifndef QT_NO_TABLEVIEW + if (const QTableView *tv = qobject_cast<const QTableView*>(view)) + header = tv->verticalHeader(); +#endif + return header; +} + +int QAccessibleTable2Cell::columnIndex() const +{ + return m_index.column(); +} + +int QAccessibleTable2Cell::rowIndex() const +{ + if (role(0) == QAccessible::TreeItem) { + const QTreeView *treeView = qobject_cast<const QTreeView*>(view); + Q_ASSERT(treeView); + int row = treeView->d_func()->viewIndex(m_index); + return row; + } + return m_index.row(); +} + +bool QAccessibleTable2Cell::isSelected() const +{ + return view->selectionModel()->isSelected(m_index); +} + +void QAccessibleTable2Cell::rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const +{ + *row = m_index.row(); + *column = m_index.column(); + *rowExtents = 1; + *columnExtents = 1; + *selected = isSelected(); +} + +QAccessibleTable2Interface* QAccessibleTable2Cell::table() const +{ + return QAccessible::queryAccessibleInterface(view)->table2Interface(); +} + +QAccessible::Role QAccessibleTable2Cell::role(int child) const +{ + Q_ASSERT(child == 0); + return m_role; +} + +QAccessible::State QAccessibleTable2Cell::state(int child) const +{ + Q_ASSERT(child == 0); + State st = Normal; + + QRect globalRect = view->rect(); + globalRect.translate(view->mapToGlobal(QPoint(0,0))); + if (!globalRect.intersects(rect(0))) + st |= Invisible; + + if (view->selectionModel()->isSelected(m_index)) + st |= Selected; + if (view->selectionModel()->currentIndex() == m_index) + st |= Focused; + if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked) + st |= Checked; + + Qt::ItemFlags flags = m_index.flags(); + if (flags & Qt::ItemIsSelectable) { + st |= Selectable; + st |= Focusable; + if (view->selectionMode() == QAbstractItemView::MultiSelection) + st |= MultiSelectable; + if (view->selectionMode() == QAbstractItemView::ExtendedSelection) + st |= ExtSelectable; + } + if (m_role == QAccessible::TreeItem) { + const QTreeView *treeView = qobject_cast<const QTreeView*>(view); + if (treeView->isExpanded(m_index)) + st |= Expanded; + } + return st; +} + +bool QAccessibleTable2Cell::isExpandable() const +{ + return view->model()->hasChildren(m_index); +} + +QRect QAccessibleTable2Cell::rect(int child) const +{ + Q_ASSERT(child == 0); + + QRect r; + r = view->visualRect(m_index); + + if (!r.isNull()) + r.translate(view->viewport()->mapTo(view, QPoint(0,0))); + r.translate(view->mapToGlobal(QPoint(0, 0))); + return r; +} + +QString QAccessibleTable2Cell::text(Text t, int child) const +{ + Q_ASSERT(child == 0); + QAbstractItemModel *model = view->model(); + QString value; + switch (t) { + case QAccessible::Value: + case QAccessible::Name: + value = model->data(m_index, Qt::AccessibleTextRole).toString(); + if (value.isEmpty()) + value = model->data(m_index, Qt::DisplayRole).toString(); + break; + case QAccessible::Description: + value = model->data(m_index, Qt::AccessibleDescriptionRole).toString(); + break; + default: + break; + } + return value; +} + +void QAccessibleTable2Cell::setText(Text /*t*/, int child, const QString &text) +{ + Q_ASSERT(child == 0); + if (!m_index.flags() & Qt::ItemIsEditable) + return; + view->model()->setData(m_index, text); +} + +bool QAccessibleTable2Cell::isValid() const +{ + if (!m_index.isValid()) { + qDebug() << "Interface is not valid"; + } + + return m_index.isValid(); +} + +int QAccessibleTable2Cell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +{ + if (relation == Ancestor && index == 1) { + if (m_role == QAccessible::TreeItem) { + *iface = new QAccessibleTree(view); + } else { + *iface = new QAccessibleTable2(view); + } + return 0; + } + + *iface = 0; + if (!view) + return -1; + + switch (relation) { + + case Child: { + return -1; + } + case Sibling: + if (index > 0) { + QAccessibleInterface *parent = queryAccessibleInterface(view); + int ret = parent->navigate(QAccessible::Child, index, iface); + delete parent; + if (*iface) + return ret; + } + return -1; + +// From table1 implementation: +// case Up: +// case Down: +// case Left: +// case Right: { +// // This is in the "not so nice" category. In order to find out which item +// // is geometrically around, we have to set the current index, navigate +// // and restore the index as well as the old selection +// view->setUpdatesEnabled(false); +// const QModelIndex oldIdx = view->currentIndex(); +// QList<QModelIndex> kids = children(); +// const QModelIndex currentIndex = index ? kids.at(index - 1) : QModelIndex(row); +// const QItemSelection oldSelection = view->selectionModel()->selection(); +// view->setCurrentIndex(currentIndex); +// const QModelIndex idx = view->moveCursor(toCursorAction(relation), Qt::NoModifier); +// view->setCurrentIndex(oldIdx); +// view->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect); +// view->setUpdatesEnabled(true); +// if (!idx.isValid()) +// return -1; + +// if (idx.parent() != row.parent() || idx.row() != row.row()) +// *iface = cell(idx); +// return index ? kids.indexOf(idx) + 1 : 0; } + default: + break; + } + + return -1; +} + +QAccessible::Relation QAccessibleTable2Cell::relationTo(int child, const QAccessibleInterface *other, int otherChild) const +{ + Q_ASSERT(child == 0); + Q_ASSERT(otherChild == 0); + // we only check for parent-child relationships in trees + if (m_role == QAccessible::TreeItem && other->role(0) == QAccessible::TreeItem) { + QModelIndex otherIndex = static_cast<const QAccessibleTable2Cell*>(other)->m_index; + // is the other our parent? + if (otherIndex.parent() == m_index) + return QAccessible::Ancestor; + // are we the other's child? + if (m_index.parent() == otherIndex) + return QAccessible::Child; + } + return QAccessible::Unrelated; +} + +#ifndef QT_NO_ACTION +int QAccessibleTable2Cell::userActionCount(int) const +{ + return 0; +} + +QString QAccessibleTable2Cell::actionText(int, Text, int) const +{ + return QString(); +} + +bool QAccessibleTable2Cell::doAction(int, int, const QVariantList &) +{ + return false; +} + +QAccessibleTable2HeaderCell::QAccessibleTable2HeaderCell(QAbstractItemView *view_, int index_, Qt::Orientation orientation_) + : view(view_), index(index_), orientation(orientation_) +{ + Q_ASSERT(index_ >= 0); +} + +QAccessible::Role QAccessibleTable2HeaderCell::role(int child) const +{ + Q_ASSERT(child == 0); + if (orientation == Qt::Horizontal) + return QAccessible::ColumnHeader; + return QAccessible::RowHeader; +} + +QAccessible::State QAccessibleTable2HeaderCell::state(int child) const +{ + Q_ASSERT(child == 0); + return QAccessible::Normal; +} + +QRect QAccessibleTable2HeaderCell::rect(int child) const +{ + Q_ASSERT(child == 0); + + QHeaderView *header = 0; + if (false) { +#ifndef QT_NO_TABLEVIEW + } else if (const QTableView *tv = qobject_cast<const QTableView*>(view)) { + if (orientation == Qt::Horizontal) { + header = tv->horizontalHeader(); + } else { + header = tv->verticalHeader(); + } +#endif +#ifndef QT_NO_TREEVIEW + } else if (const QTreeView *tv = qobject_cast<const QTreeView*>(view)) { + header = tv->header(); +#endif + } + QPoint zero = header->mapToGlobal(QPoint(0, 0)); + int sectionSize = header->sectionSize(index); + int sectionPos = header->sectionPosition(index); + return orientation == Qt::Horizontal + ? QRect(zero.x() + sectionPos, zero.y(), sectionSize, header->height()) + : QRect(zero.x(), zero.y() + sectionPos, header->width(), sectionSize); +} + +QString QAccessibleTable2HeaderCell::text(Text t, int child) const +{ + Q_ASSERT(child == 0); + QAbstractItemModel *model = view->model(); + QString value; + switch (t) { + case QAccessible::Value: + case QAccessible::Name: + value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString(); + if (value.isEmpty()) + value = model->headerData(index, orientation, Qt::DisplayRole).toString(); + break; + case QAccessible::Description: + value = model->headerData(index, orientation, Qt::AccessibleDescriptionRole).toString(); + break; + default: + break; + } + return value; +} + +void QAccessibleTable2HeaderCell::setText(Text, int, const QString &) +{ + return; +} + +bool QAccessibleTable2HeaderCell::isValid() const +{ + return true; +} + +int QAccessibleTable2HeaderCell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +{ + if (relation == QAccessible::Ancestor && index == 1) { + if (false) { +#ifndef QT_NO_TREEVIEW + } else if (qobject_cast<const QTreeView*>(view)) { + *iface = new QAccessibleTree(view); + return 0; +#endif + } else { + *iface = new QAccessibleTable2(view); + return 0; + } + } + *iface = 0; + return -1; +} + +QAccessible::Relation QAccessibleTable2HeaderCell::relationTo(int, const QAccessibleInterface *, int) const +{ + return QAccessible::Unrelated; +} + +#ifndef QT_NO_ACTION +int QAccessibleTable2HeaderCell::userActionCount(int) const +{ + return 0; +} + +QString QAccessibleTable2HeaderCell::actionText(int, Text, int) const +{ + return QString(); +} + +bool QAccessibleTable2HeaderCell::doAction(int, int, const QVariantList &) +{ + return false; +} +#endif + + + +#endif + +#endif // QT_NO_ITEMVIEWS + +QT_END_NAMESPACE + +#endif // QT_NO_ACCESSIBILITY diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h new file mode 100644 index 0000000..c8492e3 --- /dev/null +++ b/src/plugins/accessible/widgets/itemviews.h @@ -0,0 +1,319 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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.1, 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ACCESSIBLE_ITEMVIEWS_H +#define ACCESSIBLE_ITEMVIEWS_H + +#include <QtGui/qabstractitemview.h> +#include <QtGui/qheaderview.h> +#include <QtGui/qaccessible.h> +#include <QtGui/qaccessible2.h> +#include <QtGui/qaccessiblewidget.h> + + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_ACCESSIBILITY + +#ifndef QT_NO_ITEMVIEWS + +class QAccessibleTable2Cell; +class QAccessibleTable2HeaderCell; + +class QAccessibleTable2: public QAccessibleTable2Interface, public QAccessibleObjectEx +{ + Q_ACCESSIBLE_OBJECT +public: + explicit QAccessibleTable2(QWidget *w); + + virtual ~QAccessibleTable2(); + + QObject *object() const { return view; } + Role role(int child) const; + State state(int child) const; + QString text(Text t, int child) const; + QRect rect(int child) const; + + int childAt(int x, int y) const; + int childCount() const; + int indexOfChild(const QAccessibleInterface *) const; + + int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; + Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; + +#ifndef QT_NO_ACTION + int userActionCount(int child) const; + QString actionText(int action, Text t, int child) const; + bool doAction(int action, int child, const QVariantList ¶ms); +#endif + QVariant invokeMethodEx(Method, int, const QVariantList &) { return QVariant(); } + + // table2 interface + virtual QAccessibleTable2CellInterface *cellAt(int row, int column) const; + virtual QAccessibleInterface *caption() const; + virtual QAccessibleInterface *summary() const; + virtual QString columnDescription(int column) const; + virtual QString rowDescription(int row) const; + virtual int columnCount() const; + virtual int rowCount() const; + virtual QAccessible2::TableModelChange modelChange() const; + + // selection + virtual int selectedCellCount() const; + virtual int selectedColumnCount() const; + virtual int selectedRowCount() const; + virtual QList<QAccessibleTable2CellInterface*> selectedCells() const; + virtual QList<int> selectedColumns() const; + virtual QList<int> selectedRows() const; + virtual bool isColumnSelected(int column) const; + virtual bool isRowSelected(int row) const; + virtual bool selectRow(int row); + virtual bool selectColumn(int column); + virtual bool unselectRow(int row); + virtual bool unselectColumn(int column); + +protected: + virtual void modelReset(); + virtual void rowsInserted(const QModelIndex &parent, int first, int last); + virtual void rowsRemoved(const QModelIndex &parent, int first, int last); + virtual void columnsInserted(const QModelIndex &parent, int first, int last); + virtual void columnsRemoved(const QModelIndex &parent, int first, int last); + virtual void rowsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row); + virtual void columnsMoved( const QModelIndex &parent, int start, int end, const QModelIndex &destination, int column); + +protected: + QAbstractItemView* view; + QAccessible2::TableModelChange lastChange; + inline QAccessibleTable2Cell *cell(const QModelIndex &index) const; + inline QAccessible::Role cellRole() const { + switch (m_role) { + case QAccessible::List: + return QAccessible::ListItem; + case QAccessible::Table: + return QAccessible::Cell; + case QAccessible::Tree: + return QAccessible::TreeItem; + default: + Q_ASSERT(0); + } + return QAccessible::NoRole; + } + + QHeaderView *horizontalHeader() const; + QHeaderView *verticalHeader() const; +private: + // the child index for a model index + inline int logicalIndex(const QModelIndex &index) const; + // the model index from the child index + QAccessibleInterface *childFromLogical(int logicalIndex) const; + QAccessible::Role m_role; +}; + +class QAccessibleTree :public QAccessibleTable2 +{ +public: + explicit QAccessibleTree(QWidget *w) + : QAccessibleTable2(w) + {} + + virtual ~QAccessibleTree() {} + + int childAt(int x, int y) const; + int childCount() const; + int indexOfChild(const QAccessibleInterface *) const; + + int rowCount() const; + + int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; + Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; + + // table2 interface + QAccessibleTable2CellInterface *cellAt(int row, int column) const; + QString rowDescription(int row) const; + bool isRowSelected(int row) const; + bool selectRow(int row); + +private: + QModelIndex indexFromLogical(int row, int column = 0) const; +}; + +class QAccessibleTable2Cell: public QAccessibleTable2CellInterface /*), public QAccessibleTextInterface, public QAccessibleSimpleEditableTextInterface*/ +{ +public: + QAccessibleTable2Cell(QAbstractItemView *view, const QModelIndex &m_index, QAccessible::Role role); + + QObject *object() const { return 0; } + Role role(int child) const; + State state(int child) const; + QRect rect(int child) const; + bool isValid() const; + + int childAt(int, int) const { return 0; } + int childCount() const { return 0; } + int indexOfChild(const QAccessibleInterface *) const { return -1; } + + QString text(Text t, int child) const; + void setText(Text t, int child, const QString &text); + + int navigate(RelationFlag relation, int m_index, QAccessibleInterface **iface) const; + Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; + + bool isExpandable() const; + +#ifndef QT_NO_ACTION + int userActionCount(int child) const; + QString actionText(int action, Text t, int child) const; + bool doAction(int action, int child, const QVariantList ¶ms); +#endif + + // cell interface + virtual int columnExtent() const; + virtual QList<QAccessibleInterface*> columnHeaderCells() const; + virtual int columnIndex() const; + virtual int rowExtent() const; + virtual QList<QAccessibleInterface*> rowHeaderCells() const; + virtual int rowIndex() const; + virtual bool isSelected() const; + virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const; + virtual QAccessibleTable2Interface* table() const; + +private: + QHeaderView *verticalHeader() const; + QHeaderView *horizontalHeader() const; + QAbstractItemView *view; + QModelIndex m_index; + QAccessible::Role m_role; + +friend class QAccessibleTable2; +friend class QAccessibleTree; +}; + + +class QAccessibleTable2HeaderCell: public QAccessibleInterface /*), public QAccessibleTextInterface, public QAccessibleSimpleEditableTextInterface*/ +{ +public: + // For header cells, pass the header view in addition + QAccessibleTable2HeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation); + + QObject *object() const { return 0; } + Role role(int child) const; + State state(int child) const; + QRect rect(int child) const; + bool isValid() const; + + int childAt(int, int) const { return 0; } + int childCount() const { return 0; } + int indexOfChild(const QAccessibleInterface *) const { return -1; } + + QString text(Text t, int child) const; + void setText(Text t, int child, const QString &text); + + int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; + Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; + +#ifndef QT_NO_ACTION + int userActionCount(int child) const; + QString actionText(int action, Text t, int child) const; + bool doAction(int action, int child, const QVariantList ¶ms); +#endif + +private: + QAbstractItemView *view; + int index; + Qt::Orientation orientation; + +friend class QAccessibleTable2; +friend class QAccessibleTree; +}; + +// This is the corner button on the top left of a table. +// It can be used to select all cells or it is not active at all. +// For now it is ignored. +class QAccessibleTable2CornerButton: public QAccessibleInterface +{ +public: + QAccessibleTable2CornerButton(QAbstractItemView *view_) + :view(view_) + {} + + QObject *object() const { return 0; } + Role role(int child) const { Q_ASSERT(child == 0); return QAccessible::Pane; } + State state(int child) const { Q_ASSERT(child == 0); return QAccessible::Normal; } + QRect rect(int child) const { Q_ASSERT(child == 0); return QRect(); } + bool isValid() const { return true; } + + int childAt(int, int) const { return 0; } + int childCount() const { return 0; } + int indexOfChild(const QAccessibleInterface *) const { return -1; } + + QString text(Text, int) const { return QString(); } + void setText(Text, int, const QString &) {} + + int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const + { + if (relation == QAccessible::Ancestor && index == 1) { + *iface = QAccessible::queryAccessibleInterface(view); + return 0; + } + return -1; + } + Relation relationTo(int, const QAccessibleInterface *, int) const + { + return QAccessible::Unrelated; + } + +#ifndef QT_NO_ACTION + int userActionCount(int) const { return 0; } + QString actionText(int, Text, int) const { return QString(); } + bool doAction(int, int, const QVariantList &) { return false; } +#endif +private: + QAbstractItemView *view; +}; + + +#endif + +#endif // QT_NO_ACCESSIBILITY + +QT_END_NAMESPACE + +#endif // ACCESSIBLE_ITEMVIEWS_H diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp index aa5459c..cd17a6e 100644 --- a/src/plugins/accessible/widgets/main.cpp +++ b/src/plugins/accessible/widgets/main.cpp @@ -44,11 +44,13 @@ #include "simplewidgets.h" #include "rangecontrols.h" #include "complexwidgets.h" +#include "itemviews.h" #include <qaccessibleplugin.h> #include <qplugin.h> #include <qpushbutton.h> #include <qtoolbutton.h> +#include <qtreeview.h> #include <qvariant.h> #include <qaccessible.h> @@ -56,6 +58,7 @@ QT_BEGIN_NAMESPACE + class AccessibleFactory : public QAccessiblePlugin { public: @@ -251,6 +254,22 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec iface = new QAccessibleMenu(widget); #endif #ifndef QT_NO_ITEMVIEWS +#ifdef Q_WS_X11 + } else if (classname == QLatin1String("QAbstractItemView")) { + if (qobject_cast<const QTreeView*>(widget)) { + iface = new QAccessibleTree(widget); + } else { + iface = new QAccessibleTable2(widget); + } + } else if (classname == QLatin1String("QWidget") + && widget->objectName() == QLatin1String("qt_scrollarea_viewport") + && qobject_cast<QAbstractItemView*>(widget->parentWidget())) { + if (qobject_cast<const QTreeView*>(widget->parentWidget())) { + iface = new QAccessibleTree(widget->parentWidget()); + } else { + iface = new QAccessibleTable2(widget->parentWidget()); + } +#else } else if (classname == QLatin1String("QHeaderView")) { iface = new QAccessibleHeader(widget); } else if (classname == QLatin1String("QAbstractItemView")) { @@ -259,7 +278,8 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec && widget->objectName() == QLatin1String("qt_scrollarea_viewport") && qobject_cast<QAbstractItemView*>(widget->parentWidget())) { iface = new QAccessibleItemView(widget); -#endif +#endif // Q_WS_X11 +#endif // QT_NO_ITEMVIEWS #ifndef QT_NO_TABBAR } else if (classname == QLatin1String("QTabBar")) { iface = new QAccessibleTabBar(widget); diff --git a/src/plugins/accessible/widgets/widgets.pro b/src/plugins/accessible/widgets/widgets.pro index 79110cb..9632f41 100644 --- a/src/plugins/accessible/widgets/widgets.pro +++ b/src/plugins/accessible/widgets/widgets.pro @@ -7,14 +7,18 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/accessible QTDIR_build:REQUIRES += "contains(QT_CONFIG, accessibility)" SOURCES += main.cpp \ - simplewidgets.cpp \ - rangecontrols.cpp \ - complexwidgets.cpp \ - qaccessiblewidgets.cpp \ - qaccessiblemenu.cpp + simplewidgets.cpp \ + rangecontrols.cpp \ + complexwidgets.cpp \ + qaccessiblewidgets.cpp \ + qaccessiblemenu.cpp \ + itemviews.cpp HEADERS += qaccessiblewidgets.h \ - simplewidgets.h \ - rangecontrols.h \ - complexwidgets.h \ - qaccessiblemenu.h + simplewidgets.h \ + rangecontrols.h \ + complexwidgets.h \ + qaccessiblemenu.h \ + itemviews.h + + diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp index ec6c33f..73435df 100644 --- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp +++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp @@ -159,7 +159,9 @@ Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glBindTexture(GL_TEXTURE_2D, textureId); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + EGLImageKHR eglimage = QEgl::eglCreateImageKHR(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->context(), EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer) textureId, diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp index 61f1d25..06b0b51 100644 --- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp +++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp @@ -112,6 +112,8 @@ QDirectFbIntegration::QDirectFbIntegration() QDirectFbIntegration::~QDirectFbIntegration() { mInput->stopInputEventLoop(); + mInputRunner->quit(); + mInputRunner->wait(); delete mInputRunner; delete mInput; } diff --git a/src/plugins/platforms/uikit/quikiteventloop.mm b/src/plugins/platforms/uikit/quikiteventloop.mm index 7c3e929..01ecf3f 100644 --- a/src/plugins/platforms/uikit/quikiteventloop.mm +++ b/src/plugins/platforms/uikit/quikiteventloop.mm @@ -40,6 +40,8 @@ ****************************************************************************/ #include "quikiteventloop.h" +#include "quikitintegration.h" +#include "quikitscreen.h" #include "quikitwindow.h" #include "quikitwindowsurface.h" @@ -50,7 +52,11 @@ #include <QtDebug> @interface QUIKitAppDelegate : NSObject <UIApplicationDelegate> { + UIInterfaceOrientation mOrientation; } + +- (void)updateOrientation:(NSNotification *)notification; + @end @interface EventLoopHelper : NSObject { @@ -69,14 +75,71 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Q_UNUSED(launchOptions) - Q_UNUSED(application) + mOrientation = application.statusBarOrientation; + [self updateOrientation:nil]; + if (QUIKitIntegration::instance()->screens().size() > 0) { + QUIKitScreen *screen = static_cast<QUIKitScreen *>(QUIKitIntegration::instance()->screens().at(0)); + screen->updateInterfaceOrientation(); + } foreach (QWidget *widget, qApp->topLevelWidgets()) { QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow()); if (platformWindow) platformWindow->ensureNativeWindow(); } + // orientation support + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(updateOrientation:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; return YES; } +- (void)updateOrientation:(NSNotification *)notification +{ + Q_UNUSED(notification) + UIInterfaceOrientation newOrientation = mOrientation; + NSString *infoValue = @""; + switch ([UIDevice currentDevice].orientation) { + case UIDeviceOrientationUnknown: + break; + case UIDeviceOrientationPortrait: + newOrientation = UIInterfaceOrientationPortrait; + infoValue = @"UIInterfaceOrientationPortrait"; + break; + case UIDeviceOrientationPortraitUpsideDown: + newOrientation = UIInterfaceOrientationPortraitUpsideDown; + infoValue = @"UIInterfaceOrientationPortraitUpsideDown"; + break; + case UIDeviceOrientationLandscapeLeft: + newOrientation = UIInterfaceOrientationLandscapeRight; // as documentated + infoValue = @"UIInterfaceOrientationLandscapeRight"; + break; + case UIDeviceOrientationLandscapeRight: + newOrientation = UIInterfaceOrientationLandscapeLeft; // as documentated + infoValue = @"UIInterfaceOrientationLandscapeLeft"; + break; + case UIDeviceOrientationFaceUp: + case UIDeviceOrientationFaceDown: + break; + } + + if (newOrientation == mOrientation) + return; + + // check against supported orientations + NSBundle *bundle = [NSBundle mainBundle]; + NSArray *orientations = [bundle objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"]; + if (![orientations containsObject:infoValue]) + return; + + mOrientation = newOrientation; + [UIApplication sharedApplication].statusBarOrientation = mOrientation; + if (QUIKitIntegration::instance()->screens().size() > 0) { + QUIKitScreen *screen = static_cast<QUIKitScreen *>(QUIKitIntegration::instance()->screens().at(0)); + screen->updateInterfaceOrientation(); + } +} + - (void)applicationWillTerminate:(UIApplication *)application { Q_UNUSED(application) diff --git a/src/plugins/platforms/uikit/quikitintegration.h b/src/plugins/platforms/uikit/quikitintegration.h index d9844b2..a392f1d 100644 --- a/src/plugins/platforms/uikit/quikitintegration.h +++ b/src/plugins/platforms/uikit/quikitintegration.h @@ -52,6 +52,8 @@ public: QUIKitIntegration(); ~QUIKitIntegration(); + static QUIKitIntegration *instance(); + QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const; QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const; diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm index 21ab38f..ca020c9 100644 --- a/src/plugins/platforms/uikit/quikitintegration.mm +++ b/src/plugins/platforms/uikit/quikitintegration.mm @@ -66,9 +66,18 @@ public: } }; +static QUIKitIntegration *m_instance = 0; + +QUIKitIntegration * QUIKitIntegration::instance() +{ + return m_instance; +} + QUIKitIntegration::QUIKitIntegration() :mFontDb(new QUIKitFontDatabase() ) { + if (!m_instance) + m_instance = this; mScreens << new QUIKitScreen(0); } diff --git a/src/plugins/platforms/uikit/quikitscreen.h b/src/plugins/platforms/uikit/quikitscreen.h index 23e95f6..1b17d60 100644 --- a/src/plugins/platforms/uikit/quikitscreen.h +++ b/src/plugins/platforms/uikit/quikitscreen.h @@ -61,6 +61,7 @@ public: UIScreen *uiScreen() const; + void updateInterfaceOrientation(); private: QRect m_geometry; int m_depth; diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm index ae1c7cf..d7d8207 100644 --- a/src/plugins/platforms/uikit/quikitscreen.mm +++ b/src/plugins/platforms/uikit/quikitscreen.mm @@ -40,6 +40,7 @@ ****************************************************************************/ #include "quikitscreen.h" +#include "quikitwindow.h" #include <QtGui/QApplication> @@ -52,8 +53,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex) m_index(screenIndex) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex]; - CGRect bounds = [screen bounds]; + CGRect bounds = [uiScreen() bounds]; m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); m_format = QImage::Format_ARGB32; @@ -87,4 +87,26 @@ UIScreen *QUIKitScreen::uiScreen() const return [[UIScreen screens] objectAtIndex:m_index]; } +void QUIKitScreen::updateInterfaceOrientation() +{ + CGRect bounds = [uiScreen() bounds]; + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);; + break; + case UIInterfaceOrientationLandscapeLeft: + case UIInterfaceOrientationLandscapeRight: + m_geometry = QRect(bounds.origin.x, bounds.origin.y, + bounds.size.height, bounds.size.width); + break; + } + foreach (QWidget *widget, qApp->topLevelWidgets()) { + QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow()); + if (platformWindow && platformWindow->platformScreen() == this) { + platformWindow->updateGeometryAndOrientation(); + } + } +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h index c482dae..c91b751 100644 --- a/src/plugins/platforms/uikit/quikitwindow.h +++ b/src/plugins/platforms/uikit/quikitwindow.h @@ -119,9 +119,13 @@ public: QPlatformGLContext *glContext() const; + QUIKitScreen *platformScreen() const { return mScreen; } + + void updateGeometryAndOrientation(); private: QUIKitScreen *mScreen; UIWindow *mWindow; + CGRect mFrame; EAGLView *mView; mutable EAGLPlatformContext *mContext; }; diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm index ec33cd0..6e018fe 100644 --- a/src/plugins/platforms/uikit/quikitwindow.mm +++ b/src/plugins/platforms/uikit/quikitwindow.mm @@ -320,10 +320,7 @@ QUIKitWindow::QUIKitWindow(QWidget *tlw) : mContext(0) { mScreen = static_cast<QUIKitScreen *>(QPlatformScreen::platformScreenForWidget(tlw)); - CGRect screenBounds = [mScreen->uiScreen() bounds]; - QRect geom(screenBounds.origin.x, screenBounds.origin.y, screenBounds.size.width, screenBounds.size.height); - QPlatformWindow::setGeometry(geom); - mView = [[EAGLView alloc] initWithFrame:CGRectMake(geom.x(), geom.y(), geom.width(), geom.height())]; + mView = [[EAGLView alloc] init]; } QUIKitWindow::~QUIKitWindow() @@ -335,29 +332,23 @@ QUIKitWindow::~QUIKitWindow() void QUIKitWindow::setGeometry(const QRect &rect) { - if (mWindow && rect != geometry()) { - mWindow.frame = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); - mView.frame = CGRectMake(0, 0, rect.width(), rect.height()); - [mView deleteFramebuffer]; - [mWindow setNeedsDisplay]; - } + // Not supported. Only a single "full screen" window is supported QPlatformWindow::setGeometry(rect); } UIWindow *QUIKitWindow::ensureNativeWindow() { if (!mWindow) { - // window - CGRect frame = [mScreen->uiScreen() applicationFrame]; - QRect geom = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); - widget()->setGeometry(geom); mWindow = [[UIWindow alloc] init]; + updateGeometryAndOrientation(); + // window mWindow.screen = mScreen->uiScreen(); - mWindow.frame = frame; // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards + // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards + mWindow.frame = mFrame; // view [mView deleteFramebuffer]; - mView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); // fill + mView.frame = CGRectMake(0, 0, mWindow.bounds.size.width, mWindow.bounds.size.height); // fill [mView setMultipleTouchEnabled:YES]; [mView setWindow:this]; [mWindow addSubview:mView]; @@ -367,6 +358,50 @@ UIWindow *QUIKitWindow::ensureNativeWindow() return mWindow; } +void QUIKitWindow::updateGeometryAndOrientation() +{ + if (!mWindow) + return; + mFrame = [mScreen->uiScreen() applicationFrame]; + CGRect screen = [mScreen->uiScreen() bounds]; + QRect geom; + CGFloat angle = 0; + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + geom = QRect(mFrame.origin.x, mFrame.origin.y, mFrame.size.width, mFrame.size.height); + break; + case UIInterfaceOrientationPortraitUpsideDown: + geom = QRect(screen.size.width - mFrame.origin.x - mFrame.size.width, + screen.size.height - mFrame.origin.y - mFrame.size.height, + mFrame.size.width, + mFrame.size.height); + angle = M_PI; + break; + case UIInterfaceOrientationLandscapeLeft: + geom = QRect(screen.size.height - mFrame.origin.y - mFrame.size.height, + mFrame.origin.x, + mFrame.size.height, + mFrame.size.width); + angle = -M_PI/2.; + break; + case UIInterfaceOrientationLandscapeRight: + geom = QRect(mFrame.origin.y, + screen.size.width - mFrame.origin.x - mFrame.size.width, + mFrame.size.height, + mFrame.size.width); + angle = +M_PI/2.; + break; + } + if (angle != 0) { + [mView layer].transform = CATransform3DMakeRotation(angle, 0, 0, 1.); + } else { + [mView layer].transform = CATransform3DIdentity; + } + [mView setNeedsDisplay]; + widget()->setGeometry(geom); + widget()->update(); +} + QPlatformGLContext *QUIKitWindow::glContext() const { if (!mContext) { diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 023df89..d2ea988 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1015,6 +1015,7 @@ static bool isValidSlot(const QMetaMethod &sl) } Q_TESTLIB_EXPORT bool printAvailableFunctions = false; +Q_TESTLIB_EXPORT bool printAvailableTags = false; Q_TESTLIB_EXPORT QStringList testFunctions; Q_TESTLIB_EXPORT QStringList testTags; @@ -1027,6 +1028,65 @@ static void qPrintTestSlots() } } +static void qPrintDataTags() +{ + // Get global data tags: + QTestTable::globalTestTable(); + invokeMethod(QTest::currentTestObject, "initTestCase_data()"); + const QTestTable *gTable = QTestTable::globalTestTable(); + + const QMetaObject *currTestMetaObj = QTest::currentTestObject->metaObject(); + + // Process test functions: + for (int i = 0; i < currTestMetaObj->methodCount(); ++i) { + QMetaMethod tf = currTestMetaObj->method(i); + if (isValidSlot(tf)) { + // Retrieve local tags: + QStringList localTags; + QTestTable table; + char member[512]; + char *slot = qstrdup(tf.signature()); + slot[strlen(slot) - 2] = '\0'; + QTest::qt_snprintf(member, 512, "%s_data()", slot); + invokeMethod(QTest::currentTestObject, member); + for (int j = 0; j < table.dataCount(); ++j) + localTags << QLatin1String(table.testData(j)->dataTag()); + + // Print all tag combinations: + if (gTable->dataCount() == 0) { + if (localTags.count() == 0) { + // No tags at all, so just print the test function: + printf("%s %s\n", currTestMetaObj->className(), slot); + } else { + // Only local tags, so print each of them: + for (int k = 0; k < localTags.size(); ++k) + printf( + "%s %s %s\n", + currTestMetaObj->className(), slot, localTags.at(k).toLatin1().data()); + } + } else { + for (int j = 0; j < gTable->dataCount(); ++j) { + if (localTags.count() == 0) { + // Only global tags, so print the current one: + printf( + "%s %s __global__ %s\n", + currTestMetaObj->className(), slot, gTable->testData(j)->dataTag()); + } else { + // Local and global tags, so print each of the local ones and + // the current global one: + for (int k = 0; k < localTags.size(); ++k) + printf( + "%s %s %s __global__ %s\n", currTestMetaObj->className(), slot, + localTags.at(k).toLatin1().data(), gTable->testData(j)->dataTag()); + } + } + } + + delete[] slot; + } + } +} + static int qToInt(char *str) { char *pEnd; @@ -1043,6 +1103,8 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) const char *testOptions = " options:\n" " -functions : Returns a list of current testfunctions\n" + " -datatags : Returns a list of current data tags.\n" + " A global data tag is preceded by ' __global__ '.\n" " -xunitxml : Outputs results as XML XUnit document\n" " -xml : Outputs results as XML document\n" " -lightxml : Outputs results as stream of XML tags\n" @@ -1094,6 +1156,12 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) qPrintTestSlots(); exit(0); } + } else if (strcmp(argv[i], "-datatags") == 0) { + QTest::printAvailableTags = true; + if (!qml) { + qPrintDataTags(); + exit(0); + } } else if(strcmp(argv[i], "-xunitxml") == 0){ QTestLog::setLogMode(QTestLog::XunitXML); } else if (strcmp(argv[i], "-xml") == 0) { diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 8a2d559..03fafe0 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -191,6 +191,8 @@ void initLogger() } } +extern Q_TESTLIB_EXPORT bool printAvailableTags; + } QTestLog::QTestLog() @@ -203,6 +205,9 @@ QTestLog::~QTestLog() void QTestLog::enterTestFunction(const char* function) { + if (QTest::printAvailableTags) + return; + QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(function); @@ -222,6 +227,9 @@ int QTestLog::unhandledIgnoreMessages() void QTestLog::leaveTestFunction() { + if (QTest::printAvailableTags) + return; + QTEST_ASSERT(QTest::testLogger); QTest::IgnoreResultList::clearList(QTest::ignoreResultList); @@ -244,6 +252,9 @@ void QTestLog::printUnhandledIgnoreMessages() void QTestLog::addPass(const char *msg) { + if (QTest::printAvailableTags) + return; + QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(msg); |
