summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/text/qlocale_icu.cpp12
-rw-r--r--src/gui/image/qpaintengine_pic.cpp17
-rw-r--r--src/gui/image/qpicture.cpp6
-rw-r--r--src/gui/image/qpicture_p.h1
-rw-r--r--src/gui/painting/qcolorspace.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp17
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm20
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp41
8 files changed, 69 insertions, 49 deletions
diff --git a/src/corelib/text/qlocale_icu.cpp b/src/corelib/text/qlocale_icu.cpp
index a10ae1c84b2..7e1dba5ee92 100644
--- a/src/corelib/text/qlocale_icu.cpp
+++ b/src/corelib/text/qlocale_icu.cpp
@@ -17,10 +17,10 @@ static_assert(std::is_same_v<UChar, char16_t>,
namespace QtIcuPrivate {
-enum class CaseConversion : bool { Upper, Lower };
+enum class IcuCaseConversion : bool { Upper, Lower };
static bool qt_u_strToCase(const QString &str, QString *out, const char *localeID,
- CaseConversion conv)
+ IcuCaseConversion conv)
{
Q_ASSERT(out);
@@ -34,9 +34,9 @@ static bool qt_u_strToCase(const QString &str, QString *out, const char *localeI
// try to be a completely transparent wrapper:
using R [[maybe_unused]] = decltype(u_strToUpper(std::forward<decltype(args)>(args)...));
switch (conv) {
- case CaseConversion::Upper:
+ case IcuCaseConversion::Upper:
return u_strToUpper(std::forward<decltype(args)>(args)...);
- case CaseConversion::Lower:
+ case IcuCaseConversion::Lower:
return u_strToLower(std::forward<decltype(args)>(args)...);
};
Q_UNREACHABLE_RETURN(R{0});
@@ -79,7 +79,7 @@ QString QLocalePrivate::toUpper(const QString &str, bool *ok) const
Q_ASSERT(ok);
using namespace QtIcuPrivate;
QString out;
- *ok = qt_u_strToCase(str, &out, bcp47Name('_'), CaseConversion::Upper);
+ *ok = qt_u_strToCase(str, &out, bcp47Name('_'), IcuCaseConversion::Upper);
return out;
}
@@ -88,7 +88,7 @@ QString QLocalePrivate::toLower(const QString &str, bool *ok) const
Q_ASSERT(ok);
using namespace QtIcuPrivate;
QString out;
- *ok = qt_u_strToCase(str, &out, bcp47Name('_'), CaseConversion::Lower);
+ *ok = qt_u_strToCase(str, &out, bcp47Name('_'), IcuCaseConversion::Lower);
return out;
}
diff --git a/src/gui/image/qpaintengine_pic.cpp b/src/gui/image/qpaintengine_pic.cpp
index ba4888cef75..b151c3b2d18 100644
--- a/src/gui/image/qpaintengine_pic.cpp
+++ b/src/gui/image/qpaintengine_pic.cpp
@@ -31,6 +31,7 @@ public:
QDataStream s;
QPainter *pt;
QPicturePrivate *pic_d;
+ bool sizeLimitExceeded = false;
};
QPicturePaintEngine::QPicturePaintEngine()
@@ -68,6 +69,7 @@ bool QPicturePaintEngine::begin(QPaintDevice *pd)
d->s.setVersion(d->pic_d->formatMajor);
d->pic_d->pictb.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ d->sizeLimitExceeded = false;
d->s.writeRawData(qt_mfhdr_tag, 4);
d->s << (quint16) 0 << (quint16) d->pic_d->formatMajor << (quint16) d->pic_d->formatMinor;
d->s << (quint8) QPicturePrivate::PdcBegin << (quint8) sizeof(qint32);
@@ -109,7 +111,7 @@ bool QPicturePaintEngine::end()
d->s << cs; // write checksum
d->pic_d->pictb.close();
setActive(false);
- return true;
+ return !d->sizeLimitExceeded;
}
#define SERIALIZE_CMD(c) \
@@ -286,6 +288,19 @@ void QPicturePaintEngine::updateRenderHints(QPainter::RenderHints hints)
void QPicturePaintEngine::writeCmdLength(int pos, const QRectF &r, bool corr)
{
Q_D(QPicturePaintEngine);
+
+ constexpr int sizeLimit = std::numeric_limits<int>::max() - 8; // Leave room for ending bytes
+ if (d->sizeLimitExceeded || d->pic_d->pictb.pos() > sizeLimit) {
+ d->pic_d->trecs--; // Remove last command added, started by SERIALIZE_CMD
+ d->pic_d->pictb.seek(pos - 2);
+ d->pic_d->pictbData.resize(pos - 2);
+ if (!d->sizeLimitExceeded) {
+ d->sizeLimitExceeded = true;
+ qWarning("QPicture: size limit exceeded, will be truncated");
+ }
+ return;
+ }
+
int newpos = d->pic_d->pictb.pos(); // new position
int length = newpos - pos;
QRectF br(r);
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index ac0525d7abf..db2a5fd9ba9 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -970,7 +970,8 @@ QPicture& QPicture::operator=(const QPicture &p)
Constructs a QPicturePrivate
*/
QPicturePrivate::QPicturePrivate()
- : in_memory_only(false)
+ : pictb(&pictbData),
+ in_memory_only(false)
{
}
@@ -980,7 +981,8 @@ QPicturePrivate::QPicturePrivate()
Copy-Constructs a QPicturePrivate. Needed when detaching.
*/
QPicturePrivate::QPicturePrivate(const QPicturePrivate &other)
- : trecs(other.trecs),
+ : pictb(&pictbData),
+ trecs(other.trecs),
formatOk(other.formatOk),
formatMinor(other.formatMinor),
brect(other.brect),
diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h
index c512f49320b..1d8142f44b7 100644
--- a/src/gui/image/qpicture_p.h
+++ b/src/gui/image/qpicture_p.h
@@ -113,6 +113,7 @@ public:
bool checkFormat();
void resetFormat();
+ QByteArray pictbData;
QBuffer pictb;
int trecs;
bool formatOk;
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp
index c43d133dd1e..9149971b999 100644
--- a/src/gui/painting/qcolorspace.cpp
+++ b/src/gui/painting/qcolorspace.cpp
@@ -1206,12 +1206,12 @@ QByteArray QColorSpace::iccProfile() const
QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile)
{
// Must detach if input is fromRawData(); nullTerminated() is trick to do that and nothing else
- const QByteArray ownedIccProfile(iccProfile.nullTerminated());
+ QByteArray ownedIccProfile = iccProfile.nullTerminated();
QColorSpace colorSpace;
if (QIcc::fromIccProfile(ownedIccProfile, &colorSpace))
return colorSpace;
colorSpace.detach();
- colorSpace.d_ptr->iccProfile = ownedIccProfile;
+ colorSpace.d_ptr->iccProfile = std::move(ownedIccProfile);
return colorSpace;
}
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index a3f9f069b69..2b6a8a858f9 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -6474,8 +6474,9 @@ QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextO
and height (on both 1x and 2x displays), and produces high-resolution
output on 2x displays.
- The \a position offset is always in the painter coordinate system,
- indepentent of display devicePixelRatio.
+ The \a position offset is provided in the device independent pixels
+ relative to the top-left corner of the \a rectangle. The \a position
+ can be used to align the repeating pattern inside the \a rectangle.
\sa drawPixmap()
*/
@@ -6497,8 +6498,8 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
qt_painter_thread_test(d->device->devType(), d->engine->type(), "drawTiledPixmap()");
#endif
- qreal sw = pixmap.width();
- qreal sh = pixmap.height();
+ const qreal sw = pixmap.width() / pixmap.devicePixelRatio();
+ const qreal sh = pixmap.height() / pixmap.devicePixelRatio();
qreal sx = sp.x();
qreal sy = sp.y();
if (sx < 0)
@@ -6579,8 +6580,12 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
(\a{x}, \a{y}) specifies the top-left point in the paint device
that is to be drawn onto; with the given \a width and \a
- height. (\a{sx}, \a{sy}) specifies the top-left point in the \a
- pixmap that is to be drawn; this defaults to (0, 0).
+ height.
+
+ (\a{sx}, \a{sy}) specifies the origin inside the specified rectangle
+ where the pixmap will be drawn. The origin position is specified in
+ the device independent pixels relative to (\a{x}, \a{y}). This defaults
+ to (0, 0).
*/
#ifndef QT_NO_PICTURE
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 4c4e5fac962..52540666718 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -733,6 +733,26 @@ bool QCocoaFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModalit
return false;
}
+ if (qt_apple_isSandboxed()) {
+ static bool canRead = qt_mac_processHasEntitlement(
+ u"com.apple.security.files.user-selected.read-only"_s);
+ static bool canReadWrite = qt_mac_processHasEntitlement(
+ u"com.apple.security.files.user-selected.read-write"_s);
+
+ if (options()->acceptMode() == QFileDialogOptions::AcceptSave
+ && !canReadWrite) {
+ qWarning() << "Sandboxed application is missing user-selected files"
+ << "read-write entitlement. Falling back to non-native dialog";
+ return false;
+ }
+
+ if (!canReadWrite && !canRead) {
+ qWarning() << "Sandboxed application is missing user-selected files"
+ << "entitlement. Falling back to non-native dialog";
+ return false;
+ }
+ }
+
createNSOpenSavePanelDelegate();
return [m_delegate showPanel:windowModality withParent:parent];
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index bf4b3c6a9bc..ffba4f775c8 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -24,6 +24,7 @@
#if QT_CONFIG(mdiarea)
#include <QtWidgets/qmdiarea.h>
#endif
+#include <QtWidgets/qplaintextedit.h>
#include <QtWidgets/qtextedit.h>
#include <QtWidgets/qtreeview.h>
#if QT_CONFIG(datetimeedit)
@@ -1027,7 +1028,9 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
if (frame->frameShape == QFrame::NoFrame)
break;
- drawLineEditFrame(painter, rect, option, qobject_cast<const QTextEdit *>(widget) != nullptr);
+ const bool isEditable = qobject_cast<const QTextEdit *>(widget) != nullptr
+ || qobject_cast<const QPlainTextEdit *>(widget) != nullptr;
+ drawLineEditFrame(painter, rect, option, isEditable);
}
break;
}
@@ -1452,36 +1455,10 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
#endif // QT_CONFIG(progressbar)
case CE_PushButtonLabel:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
- using namespace StyleOptionHelper;
- const bool isEnabled = !isDisabled(option);
-
- QRect textRect = btn->rect.marginsRemoved(QMargins(contentHMargin, 0, contentHMargin, 0));
- int tf = Qt::AlignCenter | Qt::TextShowMnemonic;
- if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
- tf |= Qt::TextHideMnemonic;
-
- if (!btn->icon.isNull()) {
- //Center both icon and text
- QIcon::Mode mode = isEnabled ? QIcon::Normal : QIcon::Disabled;
- if (mode == QIcon::Normal && btn->state & State_HasFocus)
- mode = QIcon::Active;
- QIcon::State state = isChecked(btn) ? QIcon::On : QIcon::Off;
-
- int iconSpacing = 4;//### 4 is currently hardcoded in QPushButton::sizeHint()
-
- QRect iconRect = QRect(textRect.x(), textRect.y(), btn->iconSize.width(), textRect.height());
- QRect vIconRect = visualRect(btn->direction, btn->rect, iconRect);
- textRect.setLeft(textRect.left() + iconRect.width() + iconSpacing);
-
- if (isChecked(btn) || isPressed(btn))
- vIconRect.translate(proxy()->pixelMetric(PM_ButtonShiftHorizontal, option, widget),
- proxy()->pixelMetric(PM_ButtonShiftVertical, option, widget));
- btn->icon.paint(painter, vIconRect, Qt::AlignCenter, mode, state);
- }
-
- auto vTextRect = visualRect(btn->direction, btn->rect, textRect);
- painter->setPen(controlTextColor(option));
- proxy()->drawItemText(painter, vTextRect, tf, option->palette, isEnabled, btn->text);
+ QStyleOptionButton btnCopy(*btn);
+ btnCopy.rect = btn->rect.marginsRemoved(QMargins(contentHMargin, 0, contentHMargin, 0));
+ btnCopy.palette.setBrush(QPalette::ButtonText, controlTextColor(option));
+ QCommonStyle::drawControl(element, &btnCopy, painter, widget);
}
break;
case CE_PushButtonBevel:
@@ -2625,7 +2602,7 @@ QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon,
switch (standardIcon) {
case SP_LineEditClearButton: {
if (d->m_lineEditClearButton.isNull()) {
- auto e = new WinFontIconEngine(Clear.at(0), d->assetFont);
+ auto e = new WinFontIconEngine(Clear, d->assetFont);
d->m_lineEditClearButton = QIcon(e);
}
return d->m_lineEditClearButton;