diff options
Diffstat (limited to 'src/widgets')
24 files changed, 412 insertions, 121 deletions
diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp index f7c2ac0cf1..e45be30338 100644 --- a/src/widgets/accessible/complexwidgets.cpp +++ b/src/widgets/accessible/complexwidgets.cpp @@ -67,6 +67,7 @@ QT_BEGIN_NAMESPACE QString qt_accStripAmp(const QString &text); +QString qt_accHotKey(const QString &text); #ifndef QT_NO_TABBAR /*! @@ -94,9 +95,12 @@ public: QObject *object() const { return 0; } QAccessible::Role role() const { return QAccessible::PageTab; } QAccessible::State state() const { - QAccessibleInterface *parentInterface = parent(); - QAccessible::State state = parentInterface->state(); - return state; + if (!isValid()) { + QAccessible::State s; + s.invalid = true; + return s; + } + return parent()->state(); } QRect rect() const { if (!isValid()) @@ -108,7 +112,7 @@ public: return rec; } - bool isValid() const { return true; }// (!m_parent.isNull()) && m_parent->count() > m_index; } + bool isValid() const { return m_parent.data() && m_parent->count() > m_index; } QAccessibleInterface *childAt(int, int) const { return 0; } int childCount() const { return 0; } @@ -116,21 +120,30 @@ public: QString text(QAccessible::Text t) const { - if (t == QAccessible::Name) + if (!isValid()) + return QString(); + switch (t) { + case QAccessible::Name: return qt_accStripAmp(m_parent->tabText(m_index)); - else if (t == QAccessible::Description) + case QAccessible::Accelerator: + return qt_accHotKey(m_parent->tabText(m_index)); + case QAccessible::Description: return m_parent->tabToolTip(m_index); - else if (t == QAccessible::Help) + case QAccessible::Help: return m_parent->tabWhatsThis(m_index); + default: + break; + } return QString(); } void setText(QAccessible::Text, const QString &) {} QAccessibleInterface *parent() const { - return QAccessible::queryAccessibleInterface(m_parent); + return QAccessible::queryAccessibleInterface(m_parent.data()); } QAccessibleInterface *child(int) const { return 0; } + // action interface QStringList actionNames() const { @@ -139,7 +152,7 @@ public: void doAction(const QString &actionName) { - if (actionName == pressAction()) + if (isValid() && actionName == pressAction()) m_parent->setCurrentIndex(m_index); } @@ -227,6 +240,8 @@ QString QAccessibleTabBar::text(QAccessible::Text t) const { if (t == QAccessible::Name) { return qt_accStripAmp(tabBar()->tabText(tabBar()->currentIndex())); + } else if (t == QAccessible::Accelerator) { + return qt_accHotKey(tabBar()->tabText(tabBar()->currentIndex())); } return QString(); } diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 48f99f4d35..29fbc4df97 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -70,7 +70,8 @@ static QList<QWidget*> childWidgets(const QWidget *widget) #if !defined(QT_NO_MENU) && !qobject_cast<QMenu*>(w) #endif - && w->objectName() != QLatin1String("qt_rubberband")) + && w->objectName() != QLatin1String("qt_rubberband") + && w->objectName() != QLatin1String("qt_spinbox_lineedit")) widgets.append(w); } return widgets; @@ -111,7 +112,6 @@ static int qt_accAmpIndex(const QString &text) return -1; int fa = 0; - QChar ac; while ((fa = text.indexOf(QLatin1Char('&'), fa)) != -1) { ++fa; if (fa < text.length()) { diff --git a/src/widgets/accessible/qaccessiblewidgetfactory.cpp b/src/widgets/accessible/qaccessiblewidgetfactory.cpp index 3d123cc9ab..fb81a4aaeb 100644 --- a/src/widgets/accessible/qaccessiblewidgetfactory.cpp +++ b/src/widgets/accessible/qaccessiblewidgetfactory.cpp @@ -66,7 +66,10 @@ QAccessibleInterface *qAccessibleFactory(const QString &classname, QObject *obje if (false) { #ifndef QT_NO_LINEEDIT } else if (classname == QLatin1String("QLineEdit")) { - iface = new QAccessibleLineEdit(widget); + if (widget->objectName() == QLatin1String("qt_spinbox_lineedit")) + iface = 0; + else + iface = new QAccessibleLineEdit(widget); #endif #ifndef QT_NO_COMBOBOX } else if (classname == QLatin1String("QComboBox")) { diff --git a/src/widgets/accessible/rangecontrols.cpp b/src/widgets/accessible/rangecontrols.cpp index d4dc74ea69..e16b99c25e 100644 --- a/src/widgets/accessible/rangecontrols.cpp +++ b/src/widgets/accessible/rangecontrols.cpp @@ -51,20 +51,28 @@ #include <qglobal.h> #include <QDoubleSpinBox> #include <QDial> +#include <QtWidgets/qlineedit.h> #include <qmath.h> #include <private/qmath_p.h> +#include "simplewidgets.h" // let spinbox use line edit's interface + QT_BEGIN_NAMESPACE #ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_SPINBOX QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w) -: QAccessibleWidget(w, QAccessible::SpinBox) +: QAccessibleWidget(w, QAccessible::SpinBox), lineEdit(Q_NULLPTR) { Q_ASSERT(abstractSpinBox()); } +QAccessibleAbstractSpinBox::~QAccessibleAbstractSpinBox() +{ + delete lineEdit; +} + /*! Returns the underlying QAbstractSpinBox. */ @@ -73,6 +81,14 @@ QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const return qobject_cast<QAbstractSpinBox*>(object()); } +QAccessibleInterface *QAccessibleAbstractSpinBox::lineEditIface() const +{ + // QAccessibleLineEdit is only used to forward the text functions + if (!lineEdit) + lineEdit = new QAccessibleLineEdit(abstractSpinBox()->lineEdit()); + return lineEdit; +} + QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const { if (t == QAccessible::Value) @@ -84,6 +100,10 @@ void *QAccessibleAbstractSpinBox::interface_cast(QAccessible::InterfaceType t) { if (t == QAccessible::ValueInterface) return static_cast<QAccessibleValueInterface*>(this); + if (t == QAccessible::TextInterface) + return static_cast<QAccessibleTextInterface*>(this); + if (t == QAccessible::EditableTextInterface) + return static_cast<QAccessibleEditableTextInterface*>(this); return QAccessibleWidget::interface_cast(t); } @@ -112,6 +132,102 @@ QVariant QAccessibleAbstractSpinBox::minimumStepSize() const return abstractSpinBox()->property("stepSize"); } +void QAccessibleAbstractSpinBox::addSelection(int startOffset, int endOffset) +{ + lineEditIface()->textInterface()->addSelection(startOffset, endOffset); +} + +QString QAccessibleAbstractSpinBox::attributes(int offset, int *startOffset, int *endOffset) const +{ + return lineEditIface()->textInterface()->attributes(offset, startOffset, endOffset); +} + +int QAccessibleAbstractSpinBox::cursorPosition() const +{ + return lineEditIface()->textInterface()->cursorPosition(); +} + +QRect QAccessibleAbstractSpinBox::characterRect(int offset) const +{ + return lineEditIface()->textInterface()->characterRect(offset); +} + +int QAccessibleAbstractSpinBox::selectionCount() const +{ + return lineEditIface()->textInterface()->selectionCount(); +} + +int QAccessibleAbstractSpinBox::offsetAtPoint(const QPoint &point) const +{ + return lineEditIface()->textInterface()->offsetAtPoint(point); +} + +void QAccessibleAbstractSpinBox::selection(int selectionIndex, int *startOffset, int *endOffset) const +{ + lineEditIface()->textInterface()->selection(selectionIndex, startOffset, endOffset); +} + +QString QAccessibleAbstractSpinBox::text(int startOffset, int endOffset) const +{ + return lineEditIface()->textInterface()->text(startOffset, endOffset); +} + +QString QAccessibleAbstractSpinBox::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const +{ + return lineEditIface()->textInterface()->textBeforeOffset(offset, boundaryType, startOffset, endOffset); +} + +QString QAccessibleAbstractSpinBox::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const +{ + return lineEditIface()->textInterface()->textAfterOffset(offset, boundaryType, startOffset, endOffset); +} + +QString QAccessibleAbstractSpinBox::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, int *startOffset, int *endOffset) const +{ + return lineEditIface()->textInterface()->textAtOffset(offset, boundaryType, startOffset, endOffset); +} + +void QAccessibleAbstractSpinBox::removeSelection(int selectionIndex) +{ + lineEditIface()->textInterface()->removeSelection(selectionIndex); +} + +void QAccessibleAbstractSpinBox::setCursorPosition(int position) +{ + lineEditIface()->textInterface()->setCursorPosition(position); +} + +void QAccessibleAbstractSpinBox::setSelection(int selectionIndex, int startOffset, int endOffset) +{ + lineEditIface()->textInterface()->setSelection(selectionIndex, startOffset, endOffset); +} + +int QAccessibleAbstractSpinBox::characterCount() const +{ + return lineEditIface()->textInterface()->characterCount(); +} + +void QAccessibleAbstractSpinBox::scrollToSubstring(int startIndex, int endIndex) +{ + lineEditIface()->textInterface()->scrollToSubstring(startIndex, endIndex); +} + +void QAccessibleAbstractSpinBox::deleteText(int startOffset, int endOffset) +{ + lineEditIface()->editableTextInterface()->deleteText(startOffset, endOffset); +} + +void QAccessibleAbstractSpinBox::insertText(int offset, const QString &text) +{ + lineEditIface()->editableTextInterface()->insertText(offset, text); +} + +void QAccessibleAbstractSpinBox::replaceText(int startOffset, int endOffset, const QString &text) +{ + lineEditIface()->editableTextInterface()->replaceText(startOffset, endOffset, text); +} + + /*! \class QAccessibleSpinBox \brief The QAccessibleSpinBox class implements the QAccessibleInterface for spinbox widgets. diff --git a/src/widgets/accessible/rangecontrols.h b/src/widgets/accessible/rangecontrols.h index 98cef46c5c..158e1cfcc0 100644 --- a/src/widgets/accessible/rangecontrols.h +++ b/src/widgets/accessible/rangecontrols.h @@ -55,12 +55,18 @@ class QSlider; class QSpinBox; class QDoubleSpinBox; class QDial; +class QAccessibleLineEdit; #ifndef QT_NO_SPINBOX -class QAccessibleAbstractSpinBox: public QAccessibleWidget, public QAccessibleValueInterface // TODO, public QAccessibleActionInterface +class QAccessibleAbstractSpinBox: + public QAccessibleWidget, + public QAccessibleValueInterface, + public QAccessibleTextInterface, + public QAccessibleEditableTextInterface { public: explicit QAccessibleAbstractSpinBox(QWidget *w); + virtual ~QAccessibleAbstractSpinBox(); QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; @@ -72,10 +78,37 @@ public: QVariant minimumValue() const Q_DECL_OVERRIDE; QVariant minimumStepSize() const Q_DECL_OVERRIDE; - // FIXME Action interface + // QAccessibleTextInterface + void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; + QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int cursorPosition() const Q_DECL_OVERRIDE; + QRect characterRect(int offset) const Q_DECL_OVERRIDE; + int selectionCount() const Q_DECL_OVERRIDE; + int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE; + void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; + QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType, + int *endOffset, int *startOffset) const Q_DECL_OVERRIDE; + QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; + void setCursorPosition(int position) Q_DECL_OVERRIDE; + void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; + int characterCount() const Q_DECL_OVERRIDE; + void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE; + + // QAccessibleEditableTextInterface + void deleteText(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void insertText(int offset, const QString &text) Q_DECL_OVERRIDE; + void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; protected: QAbstractSpinBox *abstractSpinBox() const; + QAccessibleInterface *lineEditIface() const; +private: + mutable QAccessibleLineEdit *lineEdit; }; class QAccessibleSpinBox : public QAccessibleAbstractSpinBox @@ -94,6 +127,7 @@ public: QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; + using QAccessibleAbstractSpinBox::text; protected: QDoubleSpinBox *doubleSpinBox() const; }; diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp index 6fd249f372..e8827f4537 100644 --- a/src/widgets/accessible/simplewidgets.cpp +++ b/src/widgets/accessible/simplewidgets.cpp @@ -298,29 +298,6 @@ QAccessibleInterface *QAccessibleToolButton::child(int index) const return 0; } -/*! - \internal - - Returns the button's text label, depending on the text \a t, and - the \a child. -*/ -QString QAccessibleToolButton::text(QAccessible::Text t) const -{ - QString str; - switch (t) { - case QAccessible::Name: - str = toolButton()->accessibleName(); - if (str.isEmpty()) - str = toolButton()->text(); - break; - default: - break; - } - if (str.isEmpty()) - str = QAccessibleButton::text(t); - return qt_accStripAmp(str); -} - /* The three different tool button types can have the following actions: | DelayedPopup | ShowMenuAction + (PressedAction || CheckedAction) | diff --git a/src/widgets/accessible/simplewidgets.h b/src/widgets/accessible/simplewidgets.h index e4ce6150e2..c46ea9b6be 100644 --- a/src/widgets/accessible/simplewidgets.h +++ b/src/widgets/accessible/simplewidgets.h @@ -84,8 +84,6 @@ public: int childCount() const Q_DECL_OVERRIDE; QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; - QString text(QAccessible::Text t) const Q_DECL_OVERRIDE; - // QAccessibleActionInterface QStringList actionNames() const Q_DECL_OVERRIDE; void doAction(const QString &actionName) Q_DECL_OVERRIDE; @@ -174,6 +172,7 @@ public: void replaceText(int startOffset, int endOffset, const QString &text) Q_DECL_OVERRIDE; protected: QLineEdit *lineEdit() const; + friend class QAccessibleAbstractSpinBox; }; #endif // QT_NO_LINEEDIT diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index d202884416..77b94c02a4 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -91,9 +91,7 @@ Q_GLOBAL_STATIC(QUrl, lastVisitedDir) The QFileDialog class enables a user to traverse the file system in order to select one or many files or a directory. - The easiest way to create a QFileDialog is to use the static - functions. On Windows, Mac OS X, KDE and GNOME, these static functions will - call the native file dialog when possible. + The easiest way to create a QFileDialog is to use the static functions. \snippet code/src_gui_dialogs_qfiledialog.cpp 0 diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index 5a68bfbc66..fc9f36f0c2 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -65,6 +65,10 @@ #include <private/qdialog_p.h> #include <private/qfont_p.h> +#include <QtGui/private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformfontdatabase.h> + QT_BEGIN_NAMESPACE class QFontListView : public QListView @@ -485,8 +489,13 @@ void QFontDialogPrivate::updateFamilies() const QFontDialog::FontDialogOptions spacingMask = (QFontDialog::ProportionalFonts | QFontDialog::MonospacedFonts); const QFontDialog::FontDialogOptions options = q->options(); + QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); + QStringList familyNames; foreach (const QString &family, fdb.families(writingSystem)) { + if (pfdb->isPrivateFontFamily(family)) + continue; + if ((options & scalableMask) && (options & scalableMask) != scalableMask) { if (bool(options & QFontDialog::ScalableFonts) != fdb.isSmoothlyScalable(family)) continue; diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 747115984d..84781b4099 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -172,6 +172,7 @@ static PtrGetThemePartSize pGetThemePartSize = 0; static PtrGetThemeColor pGetThemeColor = 0; int QVistaHelper::instanceCount = 0; +int QVistaHelper::m_devicePixelRatio = 1; bool QVistaHelper::is_vista = false; QVistaHelper::VistaState QVistaHelper::cachedVistaState = QVistaHelper::Dirty; @@ -228,11 +229,15 @@ void QVistaBackButton::paintEvent(QPaintEvent *) RECT clipRect; int xoffset = origin.x() + QWidget::mapToParent(r.topLeft()).x() - 1; int yoffset = origin.y() + QWidget::mapToParent(r.topLeft()).y() - 1; + const int dpr = devicePixelRatio(); + const QRect rDp = QRect(r.topLeft() * dpr, r.size() * dpr); + const int xoffsetDp = xoffset * dpr; + const int yoffsetDp = yoffset * dpr; - clipRect.top = r.top() + yoffset; - clipRect.bottom = r.bottom() + yoffset; - clipRect.left = r.left() + xoffset; - clipRect.right = r.right() + xoffset; + clipRect.top = rDp.top() + yoffsetDp; + clipRect.bottom = rDp.bottom() + yoffsetDp; + clipRect.left = rDp.left() + xoffsetDp; + clipRect.right = rDp.right() + xoffsetDp; int state = WIZ_NAV_BB_NORMAL; if (!isEnabled()) @@ -259,6 +264,7 @@ QVistaHelper::QVistaHelper(QWizard *wizard) , wizard(wizard) , backButton_(0) { + QVistaHelper::m_devicePixelRatio = wizard->devicePixelRatio(); is_vista = resolveSymbols(); if (instanceCount++ == 0) cachedVistaState = Dirty; @@ -281,10 +287,12 @@ QVistaHelper::~QVistaHelper() void QVistaHelper::updateCustomMargins(bool vistaMargins) { if (QWindow *window = wizard->windowHandle()) { - // Reduce top frame to zero since we paint it ourselves. - const QMargins customMargins = vistaMargins ? - QMargins(0, -titleBarSize(), 0, 0) : QMargins(); - const QVariant customMarginsV = qVariantFromValue(customMargins); + // Reduce top frame to zero since we paint it ourselves. Use + // device pixel to avoid rounding errors. + const QMargins customMarginsDp = vistaMargins + ? QMargins(0, -titleBarSizeDp(), 0, 0) + : QMargins(); + const QVariant customMarginsV = qVariantFromValue(customMarginsDp); // The dynamic property takes effect when creating the platform window. window->setProperty("_q_windowsCustomMargins", customMarginsV); // If a platform window exists, change via native interface. @@ -351,7 +359,7 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type) if (type == NormalTitleBar) mar.cyTopHeight = 0; else - mar.cyTopHeight = titleBarSize() + topOffset(); + mar.cyTopHeight = (titleBarSize() + topOffset()) * QVistaHelper::m_devicePixelRatio; if (const HWND wizardHandle = wizardHWND()) if (SUCCEEDED(pDwmExtendFrameIntoClientArea(wizardHandle, &mar))) value = true; @@ -371,6 +379,8 @@ void QVistaHelper::drawTitleBar(QPainter *painter) if (vistaState() == VistaAero && isWindow) drawBlackRect(QRect(0, 0, wizard->width(), titleBarSize() + topOffset()), hdc); + // The button is positioned in QWizardPrivate::handleAeroStyleChange(), + // all calculation is relative to it. const int btnTop = backButton_->mapToParent(QPoint()).y(); const int btnHeight = backButton_->size().height(); const int verticalCenter = (btnTop + btnHeight / 2) - 1; @@ -405,14 +415,15 @@ void QVistaHelper::drawTitleBar(QPainter *painter) const QIcon windowIcon = wizard->windowIcon(); if (!windowIcon.isNull()) { + const int size = QVistaHelper::iconSize(); const int iconLeft = (wizard->layoutDirection() == Qt::LeftToRight ? leftMargin() - : wizard->width() - leftMargin() - iconSize()); + : wizard->width() - leftMargin() - size); - const QRect rect(origin.x() + iconLeft, - origin.y() + verticalCenter - iconSize() / 2, iconSize(), iconSize()); - const HICON hIcon = qt_pixmapToWinHICON(windowIcon.pixmap(iconSize())); - DrawIconEx(hdc, rect.left(), rect.top(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT); + const QPoint pos(origin.x() + iconLeft, origin.y() + verticalCenter - size / 2); + const QPoint posDp = pos * QVistaHelper::m_devicePixelRatio; + const HICON hIcon = qt_pixmapToWinHICON(windowIcon.pixmap(size * QVistaHelper::m_devicePixelRatio)); + DrawIconEx(hdc, posDp.x(), posDp.y(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT); DestroyIcon(hIcon); } } @@ -691,6 +702,8 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q { bool value = false; if (vistaState() == VistaAero) { + const QRect rectDp = QRect(rect.topLeft() * QVistaHelper::m_devicePixelRatio, + rect.size() * QVistaHelper::m_devicePixelRatio); HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop()); HANDLE hTheme = pOpenThemeData(handle, L"WINDOW"); if (!hTheme) return false; @@ -702,8 +715,8 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q dcMem = CreateCompatibleDC(hdc); dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - dib.bmiHeader.biWidth = rect.width(); - dib.bmiHeader.biHeight = -rect.height(); + dib.bmiHeader.biWidth = rectDp.width(); + dib.bmiHeader.biHeight = -rectDp.height(); dib.bmiHeader.biPlanes = 1; dib.bmiHeader.biBitCount = 32; dib.bmiHeader.biCompression = BI_RGB; @@ -719,13 +732,13 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q WIZ_DTTOPTS dto; dto.dwSize = sizeof(WIZ_DTTOPTS); const UINT uFormat = WIZ_DT_SINGLELINE|WIZ_DT_CENTER|WIZ_DT_VCENTER|WIZ_DT_NOPREFIX; - RECT rctext ={0,0, rect.width(), rect.height()}; + RECT rctext ={0,0, rectDp.width(), rectDp.height()}; dto.dwFlags = WIZ_DTT_COMPOSITED|WIZ_DTT_GLOWSIZE; dto.iGlowSize = glowSize(); pDrawThemeTextEx(hTheme, dcMem, 0, 0, (LPCWSTR)text.utf16(), -1, uFormat, &rctext, &dto ); - BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY); + BitBlt(hdc, rectDp.left(), rectDp.top(), rectDp.width(), rectDp.height(), dcMem, 0, 0, SRCCOPY); SelectObject(dcMem, (HGDIOBJ) hOldBmp); SelectObject(dcMem, (HGDIOBJ) hOldFont); DeleteObject(bmp); @@ -743,6 +756,8 @@ bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc) bool value = false; if (vistaState() == VistaAero) { // Set up a memory DC and bitmap that we'll draw into + const QRect rectDp = QRect(rect.topLeft() * QVistaHelper::m_devicePixelRatio, + rect.size() * QVistaHelper::m_devicePixelRatio); HDC dcMem; HBITMAP bmp; BITMAPINFO dib; @@ -750,8 +765,8 @@ bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc) dcMem = CreateCompatibleDC(hdc); dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - dib.bmiHeader.biWidth = rect.width(); - dib.bmiHeader.biHeight = -rect.height(); + dib.bmiHeader.biWidth = rectDp.width(); + dib.bmiHeader.biHeight = -rectDp.height(); dib.bmiHeader.biPlanes = 1; dib.bmiHeader.biBitCount = 32; dib.bmiHeader.biCompression = BI_RGB; @@ -759,7 +774,7 @@ bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc) bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0); HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp); - BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(), dcMem, 0, 0, SRCCOPY); + BitBlt(hdc, rectDp.left(), rectDp.top(), rectDp.width(), rectDp.height(), dcMem, 0, 0, SRCCOPY); SelectObject(dcMem, (HGDIOBJ) hOldBmp); DeleteObject(bmp); @@ -785,12 +800,12 @@ static inline int getWindowBottomMargin() } #endif // _MSC_VER >= 1700 -int QVistaHelper::frameSize() +int QVistaHelper::frameSizeDp() { return getWindowBottomMargin(); } -int QVistaHelper::captionSize() +int QVistaHelper::captionSizeDp() { return GetSystemMetrics(SM_CYCAPTION); } @@ -846,6 +861,16 @@ int QVistaHelper::titleOffset() return leftMargin() + iconOffset; } +int QVistaHelper::iconSize() +{ + return QStyleHelper::dpiScaled(16); // Standard Aero +} + +int QVistaHelper::glowSize() +{ + return QStyleHelper::dpiScaled(10); +} + int QVistaHelper::topOffset() { if (vistaState() != VistaAero) diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h index 81514a8950..ac58e76a45 100644 --- a/src/widgets/dialogs/qwizard_win_p.h +++ b/src/widgets/dialogs/qwizard_win_p.h @@ -102,7 +102,8 @@ public: QColor basicWindowFrameColor(); enum VistaState { VistaAero, VistaBasic, Classic, Dirty }; static VistaState vistaState(); - static int titleBarSize() { return frameSize() + captionSize(); } + static int titleBarSize() { return QVistaHelper::titleBarSizeDp() / QVistaHelper::m_devicePixelRatio; } + static int titleBarSizeDp() { return QVistaHelper::frameSizeDp() + QVistaHelper::captionSizeDp(); } static int topPadding() { // padding under text return int(QStyleHelper::dpiScaled( QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ? 4 : 6)); @@ -117,12 +118,14 @@ private: bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc); static bool drawBlackRect(const QRect &rect, HDC hdc); - static int frameSize(); - static int captionSize(); + static int frameSize() { return QVistaHelper::frameSizeDp() / QVistaHelper::m_devicePixelRatio; } + static int frameSizeDp(); + static int captionSize() { return QVistaHelper::captionSizeDp() / QVistaHelper::m_devicePixelRatio; } + static int captionSizeDp(); static int backButtonSize() { return int(QStyleHelper::dpiScaled(30)); } - static int iconSize() { return 16; } // Standard Aero - static int glowSize() { return 10; } + static int iconSize(); + static int glowSize(); int leftMargin() { return backButton_->isVisible() ? backButtonSize() + iconSpacing : 0; } int titleOffset(); @@ -152,6 +155,7 @@ private: int titleBarOffset; // Extra spacing above the text int iconSpacing; // Space between button and icon int textSpacing; // Space between icon and text + static int m_devicePixelRatio; }; diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 4b59e72545..37dcede6e3 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -1370,6 +1370,15 @@ bool QAbstractItemView::tabKeyNavigation() const return d->tabKeyNavigation; } +/*! + \since 5.2 + \reimp +*/ +QSize QAbstractItemView::viewportSizeHint() const +{ + return QAbstractScrollArea::viewportSizeHint(); +} + #ifndef QT_NO_DRAGANDDROP /*! \property QAbstractItemView::showDropIndicator @@ -1391,15 +1400,6 @@ bool QAbstractItemView::showDropIndicator() const } /*! - \since 5.2 - \reimp -*/ -QSize QAbstractItemView::viewportSizeHint() const -{ - return QAbstractScrollArea::viewportSizeHint(); -} - -/*! \property QAbstractItemView::dragEnabled \brief whether the view supports dragging of its own items diff --git a/src/widgets/itemviews/qdatawidgetmapper.cpp b/src/widgets/itemviews/qdatawidgetmapper.cpp index 76d01dbb2b..4158e00dfc 100644 --- a/src/widgets/itemviews/qdatawidgetmapper.cpp +++ b/src/widgets/itemviews/qdatawidgetmapper.cpp @@ -50,6 +50,8 @@ #include "private/qobject_p.h" #include "private/qabstractitemmodel_p.h" +#include <iterator> + QT_BEGIN_NAMESPACE class QDataWidgetMapperPrivate: public QObjectPrivate @@ -92,8 +94,8 @@ public: inline void flipEventFilters(QAbstractItemDelegate *oldDelegate, QAbstractItemDelegate *newDelegate) { - for (int i = 0; i < widgetMap.count(); ++i) { - QWidget *w = widgetMap.at(i).widget; + for (QList<WidgetMapper>::const_iterator it = widgetMap.cbegin(), end = widgetMap.cend(); it != end; ++it) { + QWidget *w = it->widget; if (!w) continue; w->removeEventFilter(oldDelegate); @@ -132,9 +134,9 @@ public: int QDataWidgetMapperPrivate::findWidget(QWidget *w) const { - for (int i = 0; i < widgetMap.count(); ++i) { - if (widgetMap.at(i).widget == w) - return i; + for (QList<WidgetMapper>::const_iterator it = widgetMap.cbegin(), end = widgetMap.cend(); it != end; ++it) { + if (it->widget == w) + return int(std::distance(widgetMap.cbegin(), it)); } return -1; } @@ -171,8 +173,8 @@ void QDataWidgetMapperPrivate::populate(WidgetMapper &m) void QDataWidgetMapperPrivate::populate() { - for (int i = 0; i < widgetMap.count(); ++i) - populate(widgetMap[i]); + for (QList<WidgetMapper>::iterator it = widgetMap.begin(), end = widgetMap.end(); it != end; ++it) + populate(*it); } static bool qContainsIndex(const QModelIndex &idx, const QModelIndex &topLeft, @@ -187,10 +189,9 @@ void QDataWidgetMapperPrivate::_q_dataChanged(const QModelIndex &topLeft, const if (topLeft.parent() != rootIndex) return; // not in our hierarchy - for (int i = 0; i < widgetMap.count(); ++i) { - WidgetMapper &m = widgetMap[i]; - if (qContainsIndex(m.currentIndex, topLeft, bottomRight)) - populate(m); + for (QList<WidgetMapper>::iterator it = widgetMap.begin(), end = widgetMap.end(); it != end; ++it) { + if (qContainsIndex(it->currentIndex, topLeft, bottomRight)) + populate(*it); } } @@ -582,9 +583,9 @@ QWidget *QDataWidgetMapper::mappedWidgetAt(int section) const { Q_D(const QDataWidgetMapper); - for (int i = 0; i < d->widgetMap.count(); ++i) { - if (d->widgetMap.at(i).section == section) - return d->widgetMap.at(i).widget; + for (QList<QDataWidgetMapperPrivate::WidgetMapper>::const_iterator it = d->widgetMap.cbegin(), end = d->widgetMap.cend(); it != end; ++it) { + if (it->section == section) + return it->widget; } return 0; @@ -621,9 +622,8 @@ bool QDataWidgetMapper::submit() { Q_D(QDataWidgetMapper); - for (int i = 0; i < d->widgetMap.count(); ++i) { - const QDataWidgetMapperPrivate::WidgetMapper &m = d->widgetMap.at(i); - if (!d->commit(m)) + for (QList<QDataWidgetMapperPrivate::WidgetMapper>::const_iterator it = d->widgetMap.cbegin(), end = d->widgetMap.cend(); it != end; ++it) { + if (!d->commit(*it)) return false; } @@ -762,10 +762,11 @@ void QDataWidgetMapper::clearMapping() { Q_D(QDataWidgetMapper); - while (!d->widgetMap.isEmpty()) { - QWidget *w = d->widgetMap.takeLast().widget; - if (w) - w->removeEventFilter(d->delegate); + QList<QDataWidgetMapperPrivate::WidgetMapper> copy; + d->widgetMap.swap(copy); // a C++98 move + for (std::reverse_iterator<QList<QDataWidgetMapperPrivate::WidgetMapper>::const_iterator> it(copy.cend()), end(copy.cbegin()); it != end; ++it) { + if (it->widget) + it->widget->removeEventFilter(d->delegate); } } diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 135f89d4ac..5706be4b6d 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1846,14 +1846,44 @@ void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step) { horizontalScrollBar()->setSingleStep(step.width() + spacing()); horizontalScrollBar()->setPageStep(viewport()->width()); - horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width()); + + // If both scroll bars are set to auto, we might end up in a situation with enough space + // for the actual content. But still one of the scroll bars will become enabled due to + // the other one using the space. The other one will become invisible in the same cycle. + // -> Infinite loop, QTBUG-39902 + const bool bothScrollBarsAuto = qq->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded && + qq->horizontalScrollBarPolicy() == Qt::ScrollBarAsNeeded; + + if (bothScrollBarsAuto && contentsSize.width() - qq->verticalScrollBar()->width() <= viewport()->width() + && contentsSize.height() - qq->horizontalScrollBar()->height() <= viewport()->height()) { + // break the infinite loop described above by setting the range to 0, 0. + // QAbstractScrollArea will then hide the scroll bar for us + horizontalScrollBar()->setRange(0, 0); + } else { + horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width()); + } } void QCommonListViewBase::updateVerticalScrollBar(const QSize &step) { verticalScrollBar()->setSingleStep(step.height() + spacing()); verticalScrollBar()->setPageStep(viewport()->height()); - verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height()); + + // If both scroll bars are set to auto, we might end up in a situation with enough space + // for the actual content. But still one of the scroll bars will become enabled due to + // the other one using the space. The other one will become invisible in the same cycle. + // -> Infinite loop, QTBUG-39902 + const bool bothScrollBarsAuto = qq->verticalScrollBarPolicy() == Qt::ScrollBarAsNeeded && + qq->horizontalScrollBarPolicy() == Qt::ScrollBarAsNeeded; + + if (bothScrollBarsAuto && contentsSize.width() - qq->verticalScrollBar()->width() <= viewport()->width() + && contentsSize.height() - qq->horizontalScrollBar()->height() <= viewport()->height()) { + // break the infinite loop described above by setting the range to 0, 0. + // QAbstractScrollArea will then hide the scroll bar for us + verticalScrollBar()->setRange(0, 0); + } else { + verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height()); + } } void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 4818dd7eaa..f438f60e47 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3326,6 +3326,15 @@ bool QApplication::notify(QObject *receiver, QEvent *e) { QWidget* w = static_cast<QWidget *>(receiver); QWheelEvent* wheel = static_cast<QWheelEvent*>(e); + + // QTBUG-40656, combo and other popups should close when the main window gets a wheel event. + while (QWidget *popup = QApplication::activePopupWidget()) { + if (w->window() != popup) + popup->close(); + else + break; + } + QPoint relpos = wheel->pos(); bool eventAccepted = wheel->isAccepted(); @@ -4343,7 +4352,16 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window, } Q_ASSERT(target.data() != 0); - StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[static_cast<QWidget *>(target.data())]; + QWidget *targetWidget = static_cast<QWidget *>(target.data()); + +#ifdef Q_OS_OSX + // Single-touch events are normally not sent unless WA_TouchPadAcceptSingleTouchEvents is set. + // In Qt 4 this check was in OS X-only coode. That behavior is preserved here by the #ifdef. + if (touchPoints.count() == 1 && !targetWidget->testAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents)) + continue; +#endif + + StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[targetWidget]; maskAndPoints.first |= touchPoint.state(); maskAndPoints.second.append(touchPoint); } diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 57169edb9d..34adea866e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6569,6 +6569,11 @@ void QWidget::clearFocus() QAccessible::updateAccessibility(&event); #endif } + + if (QTLWExtra *extra = window()->d_func()->maybeTopData()) { + if (extra->window) + emit extra->window->focusObjectChanged(extra->window->focusObject()); + } } } @@ -7198,8 +7203,12 @@ QByteArray QWidget::saveGeometry() const QDataStream stream(&array, QIODevice::WriteOnly); stream.setVersion(QDataStream::Qt_4_0); const quint32 magicNumber = 0x1D9D0CB; + // Version history: + // - Qt 4.2 - 4.8.6, 5.0 - 5.3 : Version 1.0 + // - Qt 4.8.6 - today, 5.4 - today: Version 1.1, save screen width in addition to check for high DPI scaling. quint16 majorVersion = 1; - quint16 minorVersion = 0; + quint16 minorVersion = 1; + const int screenNumber = QApplication::desktop()->screenNumber(this); stream << magicNumber << majorVersion << minorVersion @@ -7210,9 +7219,10 @@ QByteArray QWidget::saveGeometry() const << frameGeometry() << normalGeometry() #endif // Q_WS_MAC - << qint32(QApplication::desktop()->screenNumber(this)) + << qint32(screenNumber) << quint8(windowState() & Qt::WindowMaximized) - << quint8(windowState() & Qt::WindowFullScreen); + << quint8(windowState() & Qt::WindowFullScreen) + << qint32(QApplication::desktop()->screenGeometry(screenNumber).width()); // 1.1 onwards return array; } @@ -7267,6 +7277,7 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) qint32 restoredScreenNumber; quint8 maximized; quint8 fullScreen; + qint32 restoredScreenWidth = 0; stream >> restoredFrameGeometry >> restoredNormalGeometry @@ -7274,6 +7285,24 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) >> maximized >> fullScreen; + if (majorVersion > 1 || minorVersion >= 1) + stream >> restoredScreenWidth; + + const QDesktopWidget * const desktop = QApplication::desktop(); + const qreal screenWidthF = qreal(desktop->screenGeometry(restoredScreenNumber).width()); + // Sanity check bailing out when large variations of screen sizes occur due to + // high DPI scaling or different levels of DPI awareness. + if (restoredScreenWidth) { + const qreal factor = qreal(restoredScreenWidth) / screenWidthF; + if (factor < 0.8 || factor > 1.25) + return false; + } else { + // Saved by Qt 5.3 and earlier, try to prevent too large windows + // unless the size will be adapted by maximized or fullscreen. + if (!maximized && !fullScreen && qreal(restoredFrameGeometry.width()) / screenWidthF > 1.5) + return false; + } + const int frameHeight = 20; if (!restoredFrameGeometry.isValid()) restoredFrameGeometry = QRect(QPoint(0,0), sizeHint()); @@ -7287,7 +7316,6 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) .expandedTo(d_func()->adjustedSize())); } - const QDesktopWidget * const desktop = QApplication::desktop(); if (restoredScreenNumber >= desktop->numScreens()) restoredScreenNumber = desktop->primaryScreen(); diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index bb4518ec5e..2a968939e4 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -56,6 +56,7 @@ #include <private/qapplication_p.h> #include <private/qpaintengine_raster_p.h> #include <private/qgraphicseffect_p.h> +#include <QtGui/private/qwindow_p.h> #include <qpa/qplatformbackingstore.h> @@ -1132,6 +1133,7 @@ void QWidgetBackingStore::doSync() widgetTextures = new QPlatformTextureList; findTextureWidgetsRecursively(tlw, tlw, widgetTextures); } + qt_window_private(tlw->windowHandle())->compositing = widgetTextures && !widgetTextures->isEmpty(); fullUpdatePending = false; #endif diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index 87fd7656ea..a2de839404 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -66,6 +66,9 @@ class Q_WIDGETS_EXPORT QStyle : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QStyle) + Q_ENUMS(StateFlag PrimitiveElement ControlElement SubElement ComplexControl) + Q_ENUMS(SubControl PixelMetric ContentsType RequestSoftwareInputPanel StyleHint) + Q_ENUMS(StandardPixmap) protected: QStyle(QStylePrivate &dd); diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 43f5d6fd31..4aed153932 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -699,6 +699,7 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit) } d->updateEditFieldGeometry(); d->edit->setContextMenuPolicy(Qt::NoContextMenu); + d->edit->d_func()->control->setAccessibleObject(this); if (isVisible()) d->edit->show(); diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h index 7989000cc8..5009e4151f 100644 --- a/src/widgets/widgets/qabstractspinbox.h +++ b/src/widgets/widgets/qabstractspinbox.h @@ -170,6 +170,7 @@ private: Q_DECLARE_PRIVATE(QAbstractSpinBox) Q_DISABLE_COPY(QAbstractSpinBox) + friend class QAccessibleAbstractSpinBox; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSpinBox::StepEnabled) diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index db01543629..bdf5092d9e 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -53,6 +53,10 @@ #include <QDesktopWidget> #include <qdebug.h> +#include <QtGui/private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> +#include <qpa/qplatformfontdatabase.h> + QT_BEGIN_NAMESPACE static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script) @@ -328,7 +332,12 @@ void QFontComboBoxPrivate::_q_updateModel() int offset = 0; QFontInfo fi(currentFont); + QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); + for (int i = 0; i < list.size(); ++i) { + if (pfdb->isPrivateFontFamily(list.at(i))) + continue; + if ((filters & scalableMask) && (filters & scalableMask) != scalableMask) { if (bool(filters & QFontComboBox::ScalableFonts) != fdb.isSmoothlyScalable(list.at(i))) continue; diff --git a/src/widgets/widgets/qwidgetanimator.cpp b/src/widgets/widgets/qwidgetanimator.cpp index 1209ade536..a2d950c12b 100644 --- a/src/widgets/widgets/qwidgetanimator.cpp +++ b/src/widgets/widgets/qwidgetanimator.cpp @@ -41,6 +41,7 @@ #include <QtCore/qpropertyanimation.h> #include <QtWidgets/qwidget.h> +#include <QtWidgets/qstyle.h> #include <private/qmainwindowlayout_p.h> #include "qwidgetanimator_p.h" diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index b927004773..569308f5c8 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -737,15 +737,15 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite #ifndef QT_NO_ACCESSIBILITY if (changed) { if (oldText.isEmpty()) { - QAccessibleTextInsertEvent event(parent(), 0, txt); + QAccessibleTextInsertEvent event(accessibleObject(), 0, txt); event.setCursorPosition(m_cursor); QAccessible::updateAccessibility(&event); } else if (txt.isEmpty()) { - QAccessibleTextRemoveEvent event(parent(), 0, oldText); + QAccessibleTextRemoveEvent event(accessibleObject(), 0, oldText); event.setCursorPosition(m_cursor); QAccessible::updateAccessibility(&event); } else { - QAccessibleTextUpdateEvent event(parent(), 0, oldText, txt); + QAccessibleTextUpdateEvent event(accessibleObject(), 0, oldText, txt); event.setCursorPosition(m_cursor); QAccessible::updateAccessibility(&event); } @@ -803,7 +803,7 @@ void QWidgetLineControl::internalInsert(const QString &s) if (m_maskData) { QString ms = maskString(m_cursor, s); #ifndef QT_NO_ACCESSIBILITY - QAccessibleTextInsertEvent insertEvent(parent(), m_cursor, ms); + QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, ms); QAccessible::updateAccessibility(&insertEvent); #endif for (int i = 0; i < (int) ms.length(); ++i) { @@ -815,14 +815,14 @@ void QWidgetLineControl::internalInsert(const QString &s) m_cursor = nextMaskBlank(m_cursor); m_textDirty = true; #ifndef QT_NO_ACCESSIBILITY - QAccessibleTextCursorEvent event(parent(), m_cursor); + QAccessibleTextCursorEvent event(accessibleObject(), m_cursor); QAccessible::updateAccessibility(&event); #endif } else { int remaining = m_maxLength - m_text.length(); if (remaining != 0) { #ifndef QT_NO_ACCESSIBILITY - QAccessibleTextInsertEvent insertEvent(parent(), m_cursor, s); + QAccessibleTextInsertEvent insertEvent(accessibleObject(), m_cursor, s); QAccessible::updateAccessibility(&insertEvent); #endif m_text.insert(m_cursor, s.left(remaining)); @@ -853,7 +853,7 @@ void QWidgetLineControl::internalDelete(bool wasBackspace) addCommand(Command((CommandType)((m_maskData ? 2 : 0) + (wasBackspace ? Remove : Delete)), m_cursor, m_text.at(m_cursor), -1, -1)); #ifndef QT_NO_ACCESSIBILITY - QAccessibleTextRemoveEvent event(parent(), m_cursor, m_text.at(m_cursor)); + QAccessibleTextRemoveEvent event(accessibleObject(), m_cursor, m_text.at(m_cursor)); QAccessible::updateAccessibility(&event); #endif if (m_maskData) { @@ -894,7 +894,7 @@ void QWidgetLineControl::removeSelectedText() addCommand (Command(RemoveSelection, i, m_text.at(i), -1, -1)); } #ifndef QT_NO_ACCESSIBILITY - QAccessibleTextRemoveEvent event(parent(), m_selstart, m_text.mid(m_selstart, m_selend - m_selstart)); + QAccessibleTextRemoveEvent event(accessibleObject(), m_selstart, m_text.mid(m_selstart, m_selend - m_selstart)); QAccessible::updateAccessibility(&event); #endif if (m_maskData) { @@ -1384,7 +1384,7 @@ void QWidgetLineControl::emitCursorPositionChanged() #ifndef QT_NO_ACCESSIBILITY // otherwise we send a selection update which includes the cursor if (!hasSelectedText()) { - QAccessibleTextCursorEvent event(parent(), m_cursor); + QAccessibleTextCursorEvent event(accessibleObject(), m_cursor); QAccessible::updateAccessibility(&event); } #endif @@ -1678,7 +1678,7 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event) } } else if (event == QKeySequence::Cut) { - if (!isReadOnly()) { + if (!isReadOnly() && hasSelectedText()) { copy(); del(); } diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h index ba73e9e25e..85eb1a0f8e 100644 --- a/src/widgets/widgets/qwidgetlinecontrol_p.h +++ b/src/widgets/widgets/qwidgetlinecontrol_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QWidgetLineControl_P_H -#define QWidgetLineControl_P_H +#ifndef QWIDGETLINECONTROL_P_H +#define QWIDGETLINECONTROL_P_H // // W A R N I N G @@ -99,6 +99,7 @@ public: , m_passwordMaskDelayOverride(-1) #endif , m_keyboardScheme(0) + , m_accessibleObject(0) { init(txt); } @@ -108,6 +109,19 @@ public: delete [] m_maskData; } + void setAccessibleObject(QObject *object) + { + Q_ASSERT(object); + m_accessibleObject = object; + } + + QObject *accessibleObject() + { + if (m_accessibleObject) + return m_accessibleObject; + return parent(); + } + int nextMaskBlank(int pos) { int c = findInMask(pos, true, false); @@ -532,10 +546,13 @@ private Q_SLOTS: private: int m_keyboardScheme; + + // accessibility events are sent for this object + QObject *m_accessibleObject; }; QT_END_NAMESPACE #endif // QT_NO_LINEEDIT -#endif // QWidgetLineControl_P_H +#endif // QWIDGETLINECONTROL_P_H |