diff options
Diffstat (limited to 'src/gui')
58 files changed, 889 insertions, 285 deletions
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/dialogs/qfiledialog_symbian.cpp b/src/gui/dialogs/qfiledialog_symbian.cpp index 16ef5b6..cd020f6 100644 --- a/src/gui/dialogs/qfiledialog_symbian.cpp +++ b/src/gui/dialogs/qfiledialog_symbian.cpp @@ -59,7 +59,7 @@ extern QStringList qt_clean_filter_list(const QString &filter); // defined in qf enum DialogMode { DialogOpen, DialogSave, DialogFolder }; #if defined(Q_WS_S60) && !defined(SYMBIAN_VERSION_9_4) -class CExtensionFilter : public MAknFileFilter +class CExtensionFilter : public CBase, public MAknFileFilter { public: void setFilter(const QString filter) @@ -127,7 +127,7 @@ static QString launchSymbianDialog(const QString dialogCaption, const QString st extensionFilter->setFilter(filter); select = AknCommonDialogsDynMem::RunSelectDlgLD(types, target, startFolder, 0, 0, titlePtr, extensionFilter); - CleanupStack::Pop(extensionFilter); + CleanupStack::PopAndDestroy(extensionFilter); } else if (dialogMode == DialogSave) { QString defaultFileName = QFileDialogPrivate::initialSelection(startDirectory); target = qt_QString2TPtrC(defaultFileName); diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp index 6a646ff..34b6317 100644 --- a/src/gui/dialogs/qfontdialog.cpp +++ b/src/gui/dialogs/qfontdialog.cpp @@ -160,7 +160,7 @@ QFontDialog::QFontDialog(QWidget *parent) \since 4.5 Constructs a standard font dialog with the given \a parent and specified - \a initial color. + \a initial font. */ QFontDialog::QFontDialog(const QFont &initial, QWidget *parent) : QDialog(*new QFontDialogPrivate, parent, DefaultWindowFlags) diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index a2f086b..66e7216 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -2486,7 +2486,7 @@ void QMessageBox::setInformativeText(const QString &text) } if (!d->informativeLabel) { - QLabel *label = new QLabel; + QLabel *label = new QLabel(this); label->setObjectName(QLatin1String("qt_msgbox_informativelabel")); label->setTextInteractionFlags(Qt::TextInteractionFlags(style()->styleHint(QStyle::SH_MessageBox_TextInteractionFlags, 0, this))); label->setAlignment(Qt::AlignTop | Qt::AlignLeft); 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/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 07de4d3..8840a83 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -97,8 +97,10 @@ static QDataStream &operator<<(QDataStream &s, const BMP_FILEHDR &bf) const int BMP_OLD = 12; // old Windows/OS2 BMP size -const int BMP_WIN = 40; // new Windows BMP size +const int BMP_WIN = 40; // Windows BMP v3 size const int BMP_OS2 = 64; // new OS/2 BMP size +const int BMP_WIN4 = 108; // Windows BMP v4 size +const int BMP_WIN5 = 124; // Windows BMP v5 size const int BMP_RGB = 0; // no compression const int BMP_RLE8 = 1; // run-length encoded, 8 bits @@ -109,7 +111,7 @@ const int BMP_BITFIELDS = 3; // RGB values encoded in dat static QDataStream &operator>>(QDataStream &s, BMP_INFOHDR &bi) { s >> bi.biSize; - if (bi.biSize == BMP_WIN || bi.biSize == BMP_OS2) { + if (bi.biSize == BMP_WIN || bi.biSize == BMP_OS2 || bi.biSize == BMP_WIN4 || bi.biSize == BMP_WIN5) { s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount; s >> bi.biCompression >> bi.biSizeImage; s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter; @@ -255,7 +257,57 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int image.setDotsPerMeterY(bi.biYPelsPerMeter); if (!d->isSequential()) - d->seek(startpos + BMP_FILEHDR_SIZE + bi.biSize); // goto start of colormap + d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap + + if (bi.biSize >= BMP_WIN4 || (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32))) { + Q_ASSERT(ncols == 0); + + if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask)) + return false; + if (d->read((char *)&green_mask, sizeof(green_mask)) != sizeof(green_mask)) + return false; + if (d->read((char *)&blue_mask, sizeof(blue_mask)) != sizeof(blue_mask)) + return false; + + // Read BMP v4+ header + if (bi.biSize >= BMP_WIN4) { + int alpha_mask = 0; + int CSType = 0; + int gamma_red = 0; + int gamma_green = 0; + int gamma_blue = 0; + int endpoints[9]; + + if (d->read((char *)&alpha_mask, sizeof(alpha_mask)) != sizeof(alpha_mask)) + return false; + if (d->read((char *)&CSType, sizeof(CSType)) != sizeof(CSType)) + return false; + if (d->read((char *)&endpoints, sizeof(endpoints)) != sizeof(endpoints)) + return false; + if (d->read((char *)&gamma_red, sizeof(gamma_red)) != sizeof(gamma_red)) + return false; + if (d->read((char *)&gamma_green, sizeof(gamma_green)) != sizeof(gamma_green)) + return false; + if (d->read((char *)&gamma_blue, sizeof(gamma_blue)) != sizeof(gamma_blue)) + return false; + + if (bi.biSize == BMP_WIN5) { + qint32 intent = 0; + qint32 profileData = 0; + qint32 profileSize = 0; + qint32 reserved = 0; + + if (d->read((char *)&intent, sizeof(intent)) != sizeof(intent)) + return false; + if (d->read((char *)&profileData, sizeof(profileData)) != sizeof(profileData)) + return false; + if (d->read((char *)&profileSize, sizeof(profileSize)) != sizeof(profileSize)) + return false; + if (d->read((char *)&reserved, sizeof(reserved)) != sizeof(reserved) || reserved != 0) + return false; + } + } + } if (ncols > 0) { // read color table uchar rgb[4]; @@ -268,12 +320,6 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int return false; } } else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) { - if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask)) - return false; - if (d->read((char *)&green_mask, sizeof(green_mask)) != sizeof(green_mask)) - return false; - if (d->read((char *)&blue_mask, sizeof(blue_mask)) != sizeof(blue_mask)) - return false; red_shift = calc_shift(red_mask); red_scale = 256 / ((red_mask >> red_shift) + 1); green_shift = calc_shift(green_mask); 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/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index f5a93d9..8c194cc 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -347,7 +347,7 @@ QT_END_NAMESPACE QWidget *qwidget = QApplication::widgetAt(globalPoint); *currentDragTarget() = qwidget; if (!qwidget) - return [super draggingEntered:sender]; + return NSDragOperationNone; if (qwidget->testAttribute(Qt::WA_DropSiteRegistered) == false) return NSDragOperationNone; @@ -413,7 +413,7 @@ QT_END_NAMESPACE QWidget *qwidget = QApplication::widgetAt(globalPoint); if (!qwidget) - return [super draggingEntered:sender]; + return NSDragOperationNone; // First, check if the widget under the mouse has changed since the // last drag move events. If so, we need to change target, and dispatch @@ -500,7 +500,7 @@ QT_END_NAMESPACE QWidget *qwidget = *currentDragTarget(); if (!qwidget) - return [super draggingExited:sender]; + return; if (dropData) { QDragLeaveEvent de; diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index a866da3..500bcff 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -54,7 +54,7 @@ #ifndef QT_NO_SOFTKEYMANAGER QT_BEGIN_NAMESPACE -QSoftKeyManager *QSoftKeyManagerPrivate::self = 0; +QScopedPointer<QSoftKeyManager> QSoftKeyManagerPrivate::self(0); QString QSoftKeyManager::standardSoftKeyText(StandardSoftKey standardKey) { @@ -85,9 +85,9 @@ QString QSoftKeyManager::standardSoftKeyText(StandardSoftKey standardKey) QSoftKeyManager *QSoftKeyManager::instance() { if (!QSoftKeyManagerPrivate::self) - QSoftKeyManagerPrivate::self = new QSoftKeyManager; + QSoftKeyManagerPrivate::self.reset(new QSoftKeyManager); - return QSoftKeyManagerPrivate::self; + return QSoftKeyManagerPrivate::self.data(); } QSoftKeyManager::QSoftKeyManager() : diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h index 5b76e60..e9cbd7d 100644 --- a/src/gui/kernel/qsoftkeymanager_common_p.h +++ b/src/gui/kernel/qsoftkeymanager_common_p.h @@ -67,7 +67,7 @@ public: virtual void updateSoftKeys_sys() {}; protected: - static QSoftKeyManager *self; + static QScopedPointer<QSoftKeyManager> self; QHash<QAction*, Qt::Key> keyedActions; QMultiHash<int, QAction*> requestedSoftKeyActions; QWidget *initialSoftKeySource; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index a2109b4..ad8fbb7 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1670,6 +1670,10 @@ QWidget::~QWidget() if (!d->children.isEmpty()) d->deleteChildren(); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::ObjectDestroyed); +#endif + QApplication::removePostedEvents(this); QT_TRY { 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/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp index 98294cb..1e98b05 100644 --- a/src/gui/painting/qdrawutil.cpp +++ b/src/gui/painting/qdrawutil.cpp @@ -1084,7 +1084,7 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs, according to the \a margins structure. */ -typedef QVarLengthArray<QPainter::PixmapFragment, 16> QPixmapFragmentsArray; +typedef QVarLengthArray<QRectF, 16> QRectFArray; /*! \since 4.6 @@ -1105,12 +1105,8 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin const QPixmap &pixmap, const QRect &sourceRect,const QMargins &sourceMargins, const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints) { - QPainter::PixmapFragment d; - d.opacity = 1.0; - d.rotation = 0.0; - - QPixmapFragmentsArray opaqueData; - QPixmapFragmentsArray translucentData; + QRectFArray sourceData[2]; + QRectFArray targetData[2]; // source center const int sourceCenterTop = sourceRect.top() + sourceMargins.top(); @@ -1192,166 +1188,95 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin // corners if (targetMargins.top() > 0 && targetMargins.left() > 0 && sourceMargins.top() > 0 && sourceMargins.left() > 0) { // top left - d.x = (0.5 * (xTarget[1] + xTarget[0])); - d.y = (0.5 * (yTarget[1] + yTarget[0])); - d.sourceLeft = sourceRect.left(); - d.sourceTop = sourceRect.top(); - d.width = sourceMargins.left(); - d.height = sourceMargins.top(); - d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; - d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; - if (hints & QDrawBorderPixmap::OpaqueTopLeft) - opaqueData.append(d); - else - translucentData.append(d); + int index = bool(hints & QDrawBorderPixmap::OpaqueTopLeft); + sourceData[index].append(QRectF(sourceRect.topLeft(), QSizeF(sourceMargins.left(), sourceMargins.top()))); + targetData[index].append(QRectF(QPointF(xTarget[0], yTarget[0]), QPointF(xTarget[1], yTarget[1]))); } if (targetMargins.top() > 0 && targetMargins.right() > 0 && sourceMargins.top() > 0 && sourceMargins.right() > 0) { // top right - d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); - d.y = (0.5 * (yTarget[1] + yTarget[0])); - d.sourceLeft = sourceCenterRight; - d.sourceTop = sourceRect.top(); - d.width = sourceMargins.right(); - d.height = sourceMargins.top(); - d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; - d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; - if (hints & QDrawBorderPixmap::OpaqueTopRight) - opaqueData.append(d); - else - translucentData.append(d); + int index = bool(hints & QDrawBorderPixmap::OpaqueTopRight); + sourceData[index].append(QRectF(QPointF(sourceCenterRight, sourceRect.top()), QSizeF(sourceMargins.right(), sourceMargins.top()))); + targetData[index].append(QRectF(QPointF(xTarget[columns-1], yTarget[0]), QPointF(xTarget[columns], yTarget[1]))); } if (targetMargins.bottom() > 0 && targetMargins.left() > 0 && sourceMargins.bottom() > 0 && sourceMargins.left() > 0) { // bottom left - d.x = (0.5 * (xTarget[1] + xTarget[0])); - d.y =(0.5 * (yTarget[rows] + yTarget[rows - 1])); - d.sourceLeft = sourceRect.left(); - d.sourceTop = sourceCenterBottom; - d.width = sourceMargins.left(); - d.height = sourceMargins.bottom(); - d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; - d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; - if (hints & QDrawBorderPixmap::OpaqueBottomLeft) - opaqueData.append(d); - else - translucentData.append(d); + int index = bool(hints & QDrawBorderPixmap::OpaqueBottomLeft); + sourceData[index].append(QRectF(QPointF(sourceRect.left(), sourceCenterBottom), QSizeF(sourceMargins.left(), sourceMargins.bottom()))); + targetData[index].append(QRectF(QPointF(xTarget[0], yTarget[rows - 1]), QPointF(xTarget[1], yTarget[rows]))); } if (targetMargins.bottom() > 0 && targetMargins.right() > 0 && sourceMargins.bottom() > 0 && sourceMargins.right() > 0) { // bottom right - d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); - d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); - d.sourceLeft = sourceCenterRight; - d.sourceTop = sourceCenterBottom; - d.width = sourceMargins.right(); - d.height = sourceMargins.bottom(); - d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; - d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; - if (hints & QDrawBorderPixmap::OpaqueBottomRight) - opaqueData.append(d); - else - translucentData.append(d); + int index = bool(hints & QDrawBorderPixmap::OpaqueBottomRight); + sourceData[index].append(QRectF(QPointF(sourceCenterRight, sourceCenterBottom), QSizeF(sourceMargins.right(), sourceMargins.bottom()))); + targetData[index].append(QRectF(QPointF(xTarget[columns - 1], yTarget[rows - 1]), QPointF(xTarget[columns], yTarget[rows]))); } // horizontal edges if (targetCenterWidth > 0 && sourceCenterWidth > 0) { if (targetMargins.top() > 0 && sourceMargins.top() > 0) { // top - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueTop ? opaqueData : translucentData; - d.sourceLeft = sourceCenterLeft; - d.sourceTop = sourceRect.top(); - d.width = sourceCenterWidth; - d.height = sourceMargins.top(); - d.y = (0.5 * (yTarget[1] + yTarget[0])); - d.scaleX = dx / d.width; - d.scaleY = qreal(yTarget[1] - yTarget[0]) / d.height; + int index = bool(hints & QDrawBorderPixmap::OpaqueTop); for (int i = 1; i < columns - 1; ++i) { - d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); - data.append(d); + if (rules.horizontal == Qt::RepeatTile && i == columns - 2) { + sourceData[index].append(QRectF(QPointF(sourceCenterLeft, sourceRect.top()), QSizeF(xTarget[i + 1] - xTarget[i], sourceMargins.top()))); + } else { + sourceData[index].append(QRectF(QPointF(sourceCenterLeft, sourceRect.top()), QSizeF(sourceCenterWidth, sourceMargins.top()))); + } + targetData[index].append(QRectF(QPointF(xTarget[i], yTarget[0]), QPointF(xTarget[i + 1], yTarget[1]))); } - if (rules.horizontal == Qt::RepeatTile) - data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); } if (targetMargins.bottom() > 0 && sourceMargins.bottom() > 0) { // bottom - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueBottom ? opaqueData : translucentData; - d.sourceLeft = sourceCenterLeft; - d.sourceTop = sourceCenterBottom; - d.width = sourceCenterWidth; - d.height = sourceMargins.bottom(); - d.y = (0.5 * (yTarget[rows] + yTarget[rows - 1])); - d.scaleX = dx / d.width; - d.scaleY = qreal(yTarget[rows] - yTarget[rows - 1]) / d.height; + int index = bool(hints & QDrawBorderPixmap::OpaqueBottom); for (int i = 1; i < columns - 1; ++i) { - d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); - data.append(d); + if (rules.horizontal == Qt::RepeatTile && i == columns - 2) { + sourceData[index].append(QRectF(QPointF(sourceCenterLeft, sourceCenterBottom), QSizeF(xTarget[i + 1] - xTarget[i], sourceMargins.bottom()))); + } else { + sourceData[index].append(QRectF(QPointF(sourceCenterLeft, sourceCenterBottom), QSizeF(sourceCenterWidth, sourceMargins.bottom()))); + } + targetData[index].append(QRectF(QPointF(xTarget[i], yTarget[rows - 1]), QPointF(xTarget[i + 1], yTarget[rows]))); } - if (rules.horizontal == Qt::RepeatTile) - data[data.size() - 1].width = ((xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX); } } // vertical edges if (targetCenterHeight > 0 && sourceCenterHeight > 0) { if (targetMargins.left() > 0 && sourceMargins.left() > 0) { // left - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueLeft ? opaqueData : translucentData; - d.sourceLeft = sourceRect.left(); - d.sourceTop = sourceCenterTop; - d.width = sourceMargins.left(); - d.height = sourceCenterHeight; - d.x = (0.5 * (xTarget[1] + xTarget[0])); - d.scaleX = qreal(xTarget[1] - xTarget[0]) / d.width; - d.scaleY = dy / d.height; + int index = bool(hints & QDrawBorderPixmap::OpaqueLeft); for (int i = 1; i < rows - 1; ++i) { - d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); - data.append(d); + if (rules.vertical == Qt::RepeatTile && i == rows - 2) { + sourceData[index].append(QRectF(QPointF(sourceRect.left(), sourceCenterTop), QSizeF(sourceMargins.left(), yTarget[i + 1] - yTarget[i]))); + } else { + sourceData[index].append(QRectF(QPointF(sourceRect.left(), sourceCenterTop), QSizeF(sourceMargins.left(), sourceCenterHeight))); + } + targetData[index].append(QRectF(QPointF(xTarget[0], yTarget[i]), QPointF(xTarget[1], yTarget[i + 1]))); } - if (rules.vertical == Qt::RepeatTile) - data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); } if (targetMargins.right() > 0 && sourceMargins.right() > 0) { // right - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueRight ? opaqueData : translucentData; - d.sourceLeft = sourceCenterRight; - d.sourceTop = sourceCenterTop; - d.width = sourceMargins.right(); - d.height = sourceCenterHeight; - d.x = (0.5 * (xTarget[columns] + xTarget[columns - 1])); - d.scaleX = qreal(xTarget[columns] - xTarget[columns - 1]) / d.width; - d.scaleY = dy / d.height; + int index = bool(hints & QDrawBorderPixmap::OpaqueRight); for (int i = 1; i < rows - 1; ++i) { - d.y = (0.5 * (yTarget[i + 1] + yTarget[i])); - data.append(d); + if (rules.vertical == Qt::RepeatTile && i == rows - 2) { + sourceData[index].append(QRectF(QPointF(sourceCenterRight, sourceCenterTop), QSizeF(sourceMargins.right(), yTarget[i + 1] - yTarget[i]))); + } else { + sourceData[index].append(QRectF(QPointF(sourceCenterRight, sourceCenterTop), QSizeF(sourceMargins.right(), sourceCenterHeight))); + } + targetData[index].append(QRectF(QPointF(xTarget[columns - 1], yTarget[i]), QPointF(xTarget[columns], yTarget[i + 1]))); } - if (rules.vertical == Qt::RepeatTile) - data[data.size() - 1].height = ((yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY); } } // center if (targetCenterWidth > 0 && targetCenterHeight > 0 && sourceCenterWidth > 0 && sourceCenterHeight > 0) { - QPixmapFragmentsArray &data = hints & QDrawBorderPixmap::OpaqueCenter ? opaqueData : translucentData; - d.sourceLeft = sourceCenterLeft; - d.sourceTop = sourceCenterTop; - d.width = sourceCenterWidth; - d.height = sourceCenterHeight; - d.scaleX = dx / d.width; - d.scaleY = dy / d.height; - - qreal repeatWidth = (xTarget[columns - 1] - xTarget[columns - 2]) / d.scaleX; - qreal repeatHeight = (yTarget[rows - 1] - yTarget[rows - 2]) / d.scaleY; - + int index = bool(hints & QDrawBorderPixmap::OpaqueCenter); for (int j = 1; j < rows - 1; ++j) { - d.y = (0.5 * (yTarget[j + 1] + yTarget[j])); + qreal sourceHeight = (rules.vertical == Qt::RepeatTile && j == rows - 2) ? yTarget[j + 1] - yTarget[j] : sourceCenterHeight; for (int i = 1; i < columns - 1; ++i) { - d.x = (0.5 * (xTarget[i + 1] + xTarget[i])); - data.append(d); + qreal sourceWidth = (rules.horizontal == Qt::RepeatTile && i == columns - 2) ? xTarget[i + 1] - xTarget[i] : sourceCenterWidth; + sourceData[index].append(QRectF(QPointF(sourceCenterLeft, sourceCenterTop), QSizeF(sourceWidth, sourceHeight))); + targetData[index].append(QRectF(QPointF(xTarget[i], yTarget[j]), QPointF(xTarget[i + 1], yTarget[j + 1]))); } - if (rules.horizontal == Qt::RepeatTile) - data[data.size() - 1].width = repeatWidth; - } - if (rules.vertical == Qt::RepeatTile) { - for (int i = 1; i < columns - 1; ++i) - data[data.size() - i].height = repeatHeight; } } - if (opaqueData.size()) - painter->drawPixmapFragments(opaqueData.data(), opaqueData.size(), pixmap, QPainter::OpaqueHint); - if (translucentData.size()) - painter->drawPixmapFragments(translucentData.data(), translucentData.size(), pixmap); + for (int i = 0; i < 2; ++i) { + if (sourceData[i].size()) + painter->drawPixmapFragments(targetData[i].data(), sourceData[i].data(), sourceData[i].size(), pixmap, i == 1 ? QPainter::OpaqueHint : QPainter::PixmapFragmentHint(0)); + } if (oldAA) painter->setRenderHint(QPainter::Antialiasing, true); diff --git a/src/gui/painting/qemulationpaintengine.cpp b/src/gui/painting/qemulationpaintengine.cpp index 903ab1f..d7ad0f6 100644 --- a/src/gui/painting/qemulationpaintengine.cpp +++ b/src/gui/painting/qemulationpaintengine.cpp @@ -222,6 +222,47 @@ void QEmulationPaintEngine::drawImage(const QRectF &r, const QImage &pm, const Q real_engine->drawImage(r, pm, sr, flags); } +void QEmulationPaintEngine::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints) +{ + if (state()->bgMode == Qt::OpaqueMode && pixmap.isQBitmap()) { + qreal oldOpacity = real_engine->state()->opacity; + QTransform oldTransform = real_engine->state()->matrix; + + for (int i = 0; i < fragmentCount; ++i) { + QTransform transform = oldTransform; + transform.translate(fragments[i].x, fragments[i].y); + transform.rotate(fragments[i].rotation); + real_engine->state()->opacity = oldOpacity * fragments[i].opacity; + real_engine->state()->matrix = transform; + real_engine->opacityChanged(); + real_engine->transformChanged(); + + qreal w = fragments[i].scaleX * fragments[i].width; + qreal h = fragments[i].scaleY * fragments[i].height; + fillBGRect(QRectF(-0.5 * w, -0.5 * h, w, h)); + } + + real_engine->state()->opacity = oldOpacity; + real_engine->state()->matrix = oldTransform; + real_engine->opacityChanged(); + real_engine->transformChanged(); + } + + real_engine->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); +} + +void QEmulationPaintEngine::drawPixmapFragments(const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints) +{ + if (state()->bgMode == Qt::OpaqueMode && pixmap.isQBitmap()) { + for (int i = 0; i < fragmentCount; ++i) + fillBGRect(targetRects[i]); + } + + real_engine->drawPixmapFragments(targetRects, sourceRects, fragmentCount, pixmap, hints); +} + void QEmulationPaintEngine::clipEnabledChanged() { real_engine->clipEnabledChanged(); diff --git a/src/gui/painting/qemulationpaintengine_p.h b/src/gui/painting/qemulationpaintengine_p.h index fdc3688..b4ed7e7 100644 --- a/src/gui/painting/qemulationpaintengine_p.h +++ b/src/gui/painting/qemulationpaintengine_p.h @@ -81,6 +81,11 @@ public: virtual void drawStaticTextItem(QStaticTextItem *item); virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags); + + virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints); + virtual void drawPixmapFragments(const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints); virtual void clipEnabledChanged(); virtual void penChanged(); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 9ba4592..76d7316 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2396,12 +2396,18 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe d->image_filler_xform.setupMatrix(copy, s->flags.bilinear); if (!s->flags.antialiased && s->matrix.type() == QTransform::TxScale) { - QRectF rr = s->matrix.mapRect(r); + QPointF rr_tl = s->matrix.map(r.topLeft()); + QPointF rr_br = s->matrix.map(r.bottomRight()); - const int x1 = qRound(rr.x()); - const int y1 = qRound(rr.y()); - const int x2 = qRound(rr.right()); - const int y2 = qRound(rr.bottom()); + int x1 = qRound(rr_tl.x()); + int y1 = qRound(rr_tl.y()); + int x2 = qRound(rr_br.x()); + int y2 = qRound(rr_br.y()); + + if (x1 > x2) + qSwap(x1, x2); + if (y1 > y2) + qSwap(y1, y2); fillRect_normalized(QRect(x1, y1, x2-x1, y2-y1), &d->image_filler_xform, d); return; @@ -2862,15 +2868,9 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, } else #endif { - QFontEngineGlyphCache::Type glyphType; - if (fontEngine->glyphFormat >= 0) { - glyphType = QFontEngineGlyphCache::Type(fontEngine->glyphFormat); - } else if (s->matrix.type() > QTransform::TxTranslate - && d->glyphCacheType == QFontEngineGlyphCache::Raster_RGBMask) { - glyphType = QFontEngineGlyphCache::Raster_A8; - } else { - glyphType = d->glyphCacheType; - } + QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 + ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) + : d->glyphCacheType; QImageTextureGlyphCache *cache = static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix)); diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 5105d9a..6df410b 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1003,6 +1003,22 @@ void QPaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragmen transformChanged(); } +void QPaintEngineEx::drawPixmapFragments(const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount, + const QPixmap &pixmap, QPainter::PixmapFragmentHints /*hints*/) +{ + if (pixmap.isNull()) + return; + + if (sourceRects) { + for (int i = 0; i < fragmentCount; ++i) + drawPixmap(targetRects[i], pixmap, sourceRects[i]); + } else { + QRectF sourceRect = pixmap.rect(); + for (int i = 0; i < fragmentCount; ++i) + drawPixmap(targetRects[i], pixmap, sourceRect); + } +} + void QPaintEngineEx::setState(QPainterState *s) { QPaintEngine::state = s; diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index c605685..275a6e0 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -198,7 +198,9 @@ public: virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s); virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, - QFlags<QPainter::PixmapFragmentHint> hints); + QPainter::PixmapFragmentHints hints); + virtual void drawPixmapFragments(const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount, const QPixmap &pixmap, + QPainter::PixmapFragmentHints hints); virtual void updateState(const QPaintEngineState &state); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 1d10d75..8e64f3b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -9248,6 +9248,52 @@ void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragment } /*! + \since 4.8 + + This function is used to draw the same \a pixmap with multiple target + and source rectangles. If \a sourceRects is 0, the whole pixmap will be + rendered at each of the target rectangles. The \a hints parameter can be + used to pass in drawing hints. + + This function is potentially faster than multiple calls to drawPixmap(), + since the backend can optimize state changes. + + \sa QPainter::PixmapFragmentHint +*/ + +void QPainter::drawPixmapFragments(const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount, + const QPixmap &pixmap, PixmapFragmentHints hints) +{ + Q_D(QPainter); + + if (!d->engine || pixmap.isNull()) + return; + +#ifndef QT_NO_DEBUG + if (sourceRects) { + for (int i = 0; i < fragmentCount; ++i) { + QRectF sourceRect = sourceRects[i]; + if (!(QRectF(pixmap.rect()).contains(sourceRect))) + qWarning("QPainter::drawPixmapFragments - the source rect is not contained by the pixmap's rectangle"); + } + } +#endif + + if (d->engine->isExtended()) { + d->extended->drawPixmapFragments(targetRects, sourceRects, fragmentCount, pixmap, hints); + } else { + if (sourceRects) { + for (int i = 0; i < fragmentCount; ++i) + drawPixmap(targetRects[i], pixmap, sourceRects[i]); + } else { + QRectF sourceRect = pixmap.rect(); + for (int i = 0; i < fragmentCount; ++i) + drawPixmap(targetRects[i], pixmap, sourceRect); + } + } +} + +/*! \since 4.7 \class QPainter::PixmapFragment diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 30f8da0..12a14a2 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -380,6 +380,8 @@ public: void drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, PixmapFragmentHints hints = 0); + void drawPixmapFragments(const QRectF *targetRects, const QRectF *sourceRects, int fragmentCount, + const QPixmap &pixmap, PixmapFragmentHints hints = 0); void drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect, Qt::ImageConversionFlags flags = Qt::AutoColor); diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp index 3789a33..96e2652 100644 --- a/src/gui/painting/qwindowsurface_qws.cpp +++ b/src/gui/painting/qwindowsurface_qws.cpp @@ -1087,7 +1087,7 @@ void QWSSharedMemSurface::setDirectRegion(const QRegion &r, int id) const QRegion QWSSharedMemSurface::directRegion() const { - if (mem.address() && *(uint *)mem.address() == uint(directRegionId()) + if (mem.address() && *(uint *)mem.address() == uint(directRegionId())) return QWSMemorySurface::directRegion(); return QRegion(); } 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/qfont_s60.cpp b/src/gui/text/qfont_s60.cpp index 0fc8a97..76133fa 100644 --- a/src/gui/text/qfont_s60.cpp +++ b/src/gui/text/qfont_s60.cpp @@ -49,8 +49,6 @@ QT_BEGIN_NAMESPACE #ifdef QT_NO_FREETYPE Q_GLOBAL_STATIC(QMutex, lastResortFamilyMutex); -#endif // QT_NO_FREETYPE - extern QStringList qt_symbian_fontFamiliesOnFontServer(); // qfontdatabase_s60.cpp Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, fontFamiliesOnFontServer, { // We are only interested in the initial font families. No Application fonts. @@ -58,6 +56,25 @@ Q_GLOBAL_STATIC_WITH_INITIALIZER(QStringList, fontFamiliesOnFontServer, { x->append(qt_symbian_fontFamiliesOnFontServer()); }); +extern bool qt_symbian_isLinkedFont(const TDesC &typefaceName); // qfontdatabase_s60.cpp + +static QString classicalSymbianSystemFont() +{ + static QString font; + if (font.isEmpty()) { + static const char* const classicSymbianSystemFonts[] = { "Nokia Sans S60", "Series 60 Sans" }; + for (int i = 0; i < sizeof classicSymbianSystemFonts / sizeof classicSymbianSystemFonts[0]; ++i) { + const QString classicFont = QLatin1String(classicSymbianSystemFonts[i]); + if (fontFamiliesOnFontServer()->contains(classicFont)) { + font = classicFont; + break; + } + } + } + return font; +} +#endif // QT_NO_FREETYPE + QString QFont::lastResortFont() const { // Symbian's font Api does not distinguish between font and family. @@ -85,6 +102,10 @@ QString QFont::lastResortFamily() const S60->screenDevice()->ReleaseFont(font); lock.relock(); + + // We must not return a Symbian Linked Font. See QTBUG-20007 + if (qt_symbian_isLinkedFont(spec.iTypeface.iName) && !classicalSymbianSystemFont().isEmpty()) + family = classicalSymbianSystemFont(); } return family; #else // QT_NO_FREETYPE @@ -117,14 +138,9 @@ QString QFont::defaultFamily() const { #ifdef QT_NO_FREETYPE switch(d->request.styleHint) { - case QFont::SansSerif: { - static const char* const preferredSansSerif[] = {"Nokia Sans S60", "Series 60 Sans"}; - for (int i = 0; i < sizeof preferredSansSerif / sizeof preferredSansSerif[0]; ++i) { - const QString sansSerif = QLatin1String(preferredSansSerif[i]); - if (fontFamiliesOnFontServer()->contains(sansSerif)) - return sansSerif; - } - } + case QFont::SansSerif: + if (!classicalSymbianSystemFont().isEmpty()) + return classicalSymbianSystemFont(); // No break. Intentional fall through. default: return lastResortFamily(); diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 26d9f2c..79503f9 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2240,6 +2240,16 @@ int QFontDatabase::weight(const QString &family, } +/*! \internal */ +bool QFontDatabase::hasFamily(const QString &family) const +{ + QString parsedFamily, foundry; + parseFontName(family, foundry, parsedFamily); + const QString familyAlias = resolveFontFamilyAlias(parsedFamily); + return families().contains(familyAlias, Qt::CaseInsensitive); +} + + /*! Returns the names the \a writingSystem (e.g. for displaying to the user in a dialog). diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h index d3463a0..b1f370e 100644 --- a/src/gui/text/qfontdatabase.h +++ b/src/gui/text/qfontdatabase.h @@ -138,6 +138,8 @@ public: bool bold(const QString &family, const QString &style) const; int weight(const QString &family, const QString &style) const; + bool hasFamily(const QString &family) const; + static QString writingSystemName(WritingSystem writingSystem); static QString writingSystemSample(WritingSystem writingSystem); diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 2f4d055..cf96733 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -58,8 +58,22 @@ #endif // SYMBIAN_ENABLE_SPLIT_HEADERS #endif // QT_NO_FREETYPE +#ifndef SYMBIAN_VERSION_9_4 +#define SYMBIAN_LINKEDFONTS_SUPPORTED +#endif // !SYMBIAN_VERSION_9_4 + QT_BEGIN_NAMESPACE +bool qt_symbian_isLinkedFont(const TDesC &typefaceName) // Also used in qfont_s60.cpp +{ + bool isLinkedFont = false; +#ifdef SYMBIAN_LINKEDFONTS_SUPPORTED + const QString name((const QChar*)typefaceName.Ptr(), typefaceName.Length()); + isLinkedFont = name.endsWith(QLatin1String("LF")) && name == name.toUpper(); +#endif // SYMBIAN_LINKEDFONTS_SUPPORTED + return isLinkedFont; +} + QStringList qt_symbian_fontFamiliesOnFontServer() // Also used in qfont_s60.cpp { QStringList result; @@ -477,7 +491,10 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex, const QSymbianFontDatabaseExtrasImplementation *dbExtras) { TTypefaceSupport typefaceSupport; - S60->screenDevice()->TypefaceSupport(typefaceSupport, screenDeviceFontIndex); + S60->screenDevice()->TypefaceSupport(typefaceSupport, screenDeviceFontIndex); + + if (qt_symbian_isLinkedFont(typefaceSupport.iTypeface.iName)) + return false; QString familyName((const QChar*)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length()); if (qt_symbian_fontNameHasAppFontMarker(familyName)) { diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index ec5cc18..e3e5c57 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -139,7 +139,7 @@ QRawFont::QRawFont() \note The referenced file must contain a TrueType or OpenType font. */ QRawFont::QRawFont(const QString &fileName, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference) : d(new QRawFontPrivate) { @@ -154,7 +154,7 @@ QRawFont::QRawFont(const QString &fileName, \note The data must contain a TrueType or OpenType font. */ QRawFont::QRawFont(const QByteArray &fontData, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference) : d(new QRawFontPrivate) { @@ -204,7 +204,7 @@ bool QRawFont::isValid() const \sa loadFromData() */ void QRawFont::loadFromFile(const QString &fileName, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference) { QFile file(fileName); @@ -222,7 +222,7 @@ void QRawFont::loadFromFile(const QString &fileName, \sa loadFromFile() */ void QRawFont::loadFromData(const QByteArray &fontData, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference) { detach(); @@ -624,7 +624,7 @@ QList<QFontDatabase::WritingSystem> QRawFont::supportedWritingSystems() const \sa supportedWritingSystems() */ -bool QRawFont::supportsCharacter(const QChar &character) const +bool QRawFont::supportsCharacter(QChar character) const { if (!isValid()) return false; @@ -633,6 +633,7 @@ bool QRawFont::supportsCharacter(const QChar &character) const } /*! + \overload Returns true if the font has a glyph that corresponds to the UCS-4 encoded character \a ucs4. \sa supportedWritingSystems() @@ -642,8 +643,18 @@ bool QRawFont::supportsCharacter(quint32 ucs4) const if (!isValid()) return false; - QString str = QString::fromUcs4(&ucs4, 1); - return d->fontEngine->canRender(str.constData(), str.size()); + QChar str[2]; + int len; + if (!QChar::requiresSurrogates(ucs4)) { + str[0] = QChar(ucs4); + len = 1; + } else { + str[0] = QChar(QChar::highSurrogate(ucs4)); + str[1] = QChar(QChar::lowSurrogate(ucs4)); + len = 2; + } + + return d->fontEngine->canRender(str, len); } // qfontdatabase.cpp diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 99e0837..d5b5680 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -70,10 +70,10 @@ public: QRawFont(); QRawFont(const QString &fileName, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting); QRawFont(const QByteArray &fontData, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting); QRawFont(const QRawFont &other); ~QRawFont(); @@ -114,15 +114,15 @@ public: qreal unitsPerEm() const; void loadFromFile(const QString &fileName, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference); void loadFromData(const QByteArray &fontData, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference); bool supportsCharacter(quint32 ucs4) const; - bool supportsCharacter(const QChar &character) const; + bool supportsCharacter(QChar character) const; QList<QFontDatabase::WritingSystem> supportedWritingSystems() const; QByteArray fontTable(const char *tagName) const; diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp index db60459..5bba221 100644 --- a/src/gui/text/qrawfont_ft.cpp +++ b/src/gui/text/qrawfont_ft.cpp @@ -98,7 +98,7 @@ void QRawFontPrivate::platformCleanUp() // Font engine handles all resources } -void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize, +void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { Q_ASSERT(fontEngine == 0); diff --git a/src/gui/text/qrawfont_mac.cpp b/src/gui/text/qrawfont_mac.cpp index df68eb7..40c719a 100644 --- a/src/gui/text/qrawfont_mac.cpp +++ b/src/gui/text/qrawfont_mac.cpp @@ -55,7 +55,7 @@ void QRawFontPrivate::platformCleanUp() extern int qt_defaultDpi(); void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference) { // Mac OS X ignores it diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h index a7a03b7..fdf7cad 100644 --- a/src/gui/text/qrawfont_p.h +++ b/src/gui/text/qrawfont_p.h @@ -99,7 +99,7 @@ public: void cleanUp(); void platformCleanUp(); void platformLoadFromData(const QByteArray &fontData, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference); static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); } diff --git a/src/gui/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp index 3492946..6a69804 100644 --- a/src/gui/text/qrawfont_qpa.cpp +++ b/src/gui/text/qrawfont_qpa.cpp @@ -53,7 +53,7 @@ void QRawFontPrivate::platformCleanUp() { } -void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize, +void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { Q_ASSERT(fontEngine == 0); diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp index 6c62673..779652f 100644 --- a/src/gui/text/qrawfont_win.cpp +++ b/src/gui/text/qrawfont_win.cpp @@ -545,7 +545,7 @@ void QRawFontPrivate::platformCleanUp() } void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, - int pixelSize, + qreal pixelSize, QFont::HintingPreference hintingPreference) { QByteArray fontData(_fontData); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 31d7e8a..093b43d 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]); @@ -1632,19 +1632,13 @@ bool QTextEngine::isRightToLeft() const int QTextEngine::findItem(int strPos) const { itemize(); - int left = 0; - int right = layoutData->items.size()-1; - while(left <= right) { - int middle = ((right-left)/2)+left; - if (strPos > layoutData->items[middle].position) - left = middle+1; - else if(strPos < layoutData->items[middle].position) - right = middle-1; - else { - return middle; - } + + int item; + for (item = layoutData->items.size()-1; item > 0; --item) { + if (layoutData->items[item].position <= strPos) + break; } - return right; + return item; } QFixed QTextEngine::width(int from, int len) const @@ -2808,7 +2802,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; } 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/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 3f0b9e8..515915a 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1591,6 +1591,7 @@ namespace { QFixed minimumRightBearing; QFontEngine *fontEngine; + QFontEngine *previousFontEngine; const unsigned short *logClusters; bool manualWrap; @@ -1611,12 +1612,19 @@ namespace { return glyphs.glyphs[logClusters[currentPosition - 1]]; } - inline void saveCurrentGlyph() + inline void resetPreviousGlyph() { previousGlyph = 0; + previousFontEngine = 0; + } + + inline void saveCurrentGlyph() + { + resetPreviousGlyph(); if (currentPosition > 0 && logClusters[currentPosition - 1] < glyphs.numGlyphs) { previousGlyph = currentGlyph(); // needed to calculate right bearing later + previousFontEngine = fontEngine; } } @@ -1636,8 +1644,11 @@ namespace { inline void adjustPreviousRightBearing() { - if (previousGlyph > 0) - adjustRightBearing(previousGlyph); + if (previousGlyph > 0 && previousFontEngine) { + qreal rb; + previousFontEngine->getGlyphBearings(previousGlyph, 0, &rb); + rightBearing = qMin(QFixed(), QFixed::fromReal(rb)); + } } inline void resetRightBearing() @@ -1728,7 +1739,7 @@ void QTextLine::layout_helper(int maxGlyphs) lbh.currentPosition = line.from; int end = 0; lbh.logClusters = eng->layoutData->logClustersPtr; - lbh.previousGlyph = 0; + lbh.resetPreviousGlyph(); while (newItem < eng->layoutData->items.size()) { lbh.resetRightBearing(); @@ -1917,8 +1928,12 @@ found: if (line.textWidth > 0 && item < eng->layoutData->items.size()) eng->maxWidth += lbh.spaceData.textWidth; - if (eng->option.flags() & QTextOption::IncludeTrailingSpaces) + // In the latter case, text are drawn with trailing spaces at the beginning + // of a line, so the naturalTextWidth should contain the space width + if ((eng->option.flags() & QTextOption::IncludeTrailingSpaces) || + (line.width == QFIXED_MAX && eng->isRightToLeft())) { line.textWidth += lbh.spaceData.textWidth; + } if (lbh.spaceData.length) { line.length += lbh.spaceData.length; line.hasTrailingSpaces = true; 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..ab88f38 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 /*! @@ -88,6 +92,13 @@ QT_BEGIN_NAMESPACE by clear(). \endtable + \warning When passing a QString to the constructor or calling setText(), + make sure to sanitize your input, as QLabel tries to guess whether it + displays the text as plain text or as rich text. You may want to call + setTextFormat() explicitly, e.g. in case you expect the text to be in + plain format but cannot control the text source (for instance when + displaying data loaded from the Web). + When the content is changed using any of these functions, any previous content is cleared. @@ -370,6 +381,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/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp index 56eca9a..c9dbff5 100644 --- a/src/gui/widgets/qmenu_symbian.cpp +++ b/src/gui/widgets/qmenu_symbian.cpp @@ -357,7 +357,7 @@ QMenuPrivate::QSymbianMenuPrivate::QSymbianMenuPrivate() QMenuPrivate::QSymbianMenuPrivate::~QSymbianMenuPrivate() { - + qDeleteAll(actionItems); } void QMenuPrivate::QSymbianMenuPrivate::addAction(QAction *a, QSymbianMenuAction *before) |