Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"

This commit is contained in:
Qt Forward Merge Bot 2020-01-06 01:00:08 +01:00 committed by Fabian Kosmale
commit 68c30e372b
39 changed files with 511 additions and 138 deletions

View File

@ -85,8 +85,8 @@
\snippet widgets/styles/norwegianwoodstyle.cpp 0 \snippet widgets/styles/norwegianwoodstyle.cpp 0
The \c polish() function is reimplemented from QStyle. It takes a The \c standardPalette() function is reimplemented from QStyle.
QPalette as a reference and adapts the palette to fit the style. It returns a QPalette with the style's preferred colors and textures.
Most styles don't need to reimplement that function. The Most styles don't need to reimplement that function. The
Norwegian Wood style reimplements it to set a "wooden" palette. Norwegian Wood style reimplements it to set a "wooden" palette.
@ -381,7 +381,7 @@
a certain \l{QPalette::ColorRole}{color role}, for all three a certain \l{QPalette::ColorRole}{color role}, for all three
\l{QPalette::ColorGroup}{color groups} (active, disabled, \l{QPalette::ColorGroup}{color groups} (active, disabled,
inactive). We used it to initialize the Norwegian Wood palette in inactive). We used it to initialize the Norwegian Wood palette in
\c polish(QPalette &). \c standardPalette.
\snippet widgets/styles/norwegianwoodstyle.cpp 39 \snippet widgets/styles/norwegianwoodstyle.cpp 39
\snippet widgets/styles/norwegianwoodstyle.cpp 40 \snippet widgets/styles/norwegianwoodstyle.cpp 40
@ -444,10 +444,6 @@
current style's \l{QStyle::standardPalette()}{standard palette} current style's \l{QStyle::standardPalette()}{standard palette}
is used; otherwise, the system's default palette is honored. is used; otherwise, the system's default palette is honored.
For the Norwegian Wood style, this makes no difference because we
always override the palette with our own palette in \c
NorwegianWoodStyle::polish().
\snippet widgets/styles/widgetgallery.cpp 9 \snippet widgets/styles/widgetgallery.cpp 9
\snippet widgets/styles/widgetgallery.cpp 10 \snippet widgets/styles/widgetgallery.cpp 10

View File

@ -62,42 +62,48 @@ NorwegianWoodStyle::NorwegianWoodStyle() :
} }
//! [0] //! [0]
void NorwegianWoodStyle::polish(QPalette &palette) QPalette NorwegianWoodStyle::standardPalette() const
{ {
QColor brown(212, 140, 95); if (!m_standardPalette.isBrushSet(QPalette::Disabled, QPalette::Mid)) {
QColor beige(236, 182, 120); QColor brown(212, 140, 95);
QColor slightlyOpaqueBlack(0, 0, 0, 63); QColor beige(236, 182, 120);
QColor slightlyOpaqueBlack(0, 0, 0, 63);
QImage backgroundImage(":/images/woodbackground.png"); QImage backgroundImage(":/images/woodbackground.png");
QImage buttonImage(":/images/woodbutton.png"); QImage buttonImage(":/images/woodbutton.png");
QImage midImage = buttonImage.convertToFormat(QImage::Format_RGB32); QImage midImage = buttonImage.convertToFormat(QImage::Format_RGB32);
QPainter painter; QPainter painter;
painter.begin(&midImage); painter.begin(&midImage);
painter.setPen(Qt::NoPen); painter.setPen(Qt::NoPen);
painter.fillRect(midImage.rect(), slightlyOpaqueBlack); painter.fillRect(midImage.rect(), slightlyOpaqueBlack);
painter.end(); painter.end();
//! [0] //! [0]
//! [1] //! [1]
palette = QPalette(brown); QPalette palette(brown);
palette.setBrush(QPalette::BrightText, Qt::white); palette.setBrush(QPalette::BrightText, Qt::white);
palette.setBrush(QPalette::Base, beige); palette.setBrush(QPalette::Base, beige);
palette.setBrush(QPalette::Highlight, Qt::darkGreen); palette.setBrush(QPalette::Highlight, Qt::darkGreen);
setTexture(palette, QPalette::Button, buttonImage); setTexture(palette, QPalette::Button, buttonImage);
setTexture(palette, QPalette::Mid, midImage); setTexture(palette, QPalette::Mid, midImage);
setTexture(palette, QPalette::Window, backgroundImage); setTexture(palette, QPalette::Window, backgroundImage);
QBrush brush = palette.window(); QBrush brush = palette.window();
brush.setColor(brush.color().darker()); brush.setColor(brush.color().darker());
palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush); palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush);
palette.setBrush(QPalette::Disabled, QPalette::Text, brush); palette.setBrush(QPalette::Disabled, QPalette::Text, brush);
palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush); palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush);
palette.setBrush(QPalette::Disabled, QPalette::Base, brush); palette.setBrush(QPalette::Disabled, QPalette::Base, brush);
palette.setBrush(QPalette::Disabled, QPalette::Button, brush); palette.setBrush(QPalette::Disabled, QPalette::Button, brush);
palette.setBrush(QPalette::Disabled, QPalette::Mid, brush); palette.setBrush(QPalette::Disabled, QPalette::Mid, brush);
m_standardPalette = palette;
}
return m_standardPalette;
} }
//! [1] //! [1]

View File

@ -66,7 +66,8 @@ class NorwegianWoodStyle : public QProxyStyle
public: public:
NorwegianWoodStyle(); NorwegianWoodStyle();
void polish(QPalette &palette) override; QPalette standardPalette() const override;
void polish(QWidget *widget) override; void polish(QWidget *widget) override;
void unpolish(QWidget *widget) override; void unpolish(QWidget *widget) override;
int pixelMetric(PixelMetric metric, const QStyleOption *option, int pixelMetric(PixelMetric metric, const QStyleOption *option,
@ -82,6 +83,7 @@ private:
static void setTexture(QPalette &palette, QPalette::ColorRole role, static void setTexture(QPalette &palette, QPalette::ColorRole role,
const QImage &image); const QImage &image);
static QPainterPath roundRectPath(const QRect &rect); static QPainterPath roundRectPath(const QRect &rect);
mutable QPalette m_standardPalette;
}; };
//! [0] //! [0]

View File

@ -41,10 +41,9 @@ build_pass {
INSTALLS *= target INSTALLS *= target
} }
} else { } else {
QMAKE_EXTRA_TARGETS *= aab apk apk_install_target
android-build-distclean.commands = \ android-build-distclean.commands = \
$$QMAKE_DEL_TREE $$shell_quote($$shell_path($$OUT_PWD/android-build)) $$QMAKE_DEL_TREE $$shell_quote($$shell_path($$OUT_PWD/android-build))
QMAKE_EXTRA_TARGETS *= android-build-distclean QMAKE_EXTRA_TARGETS *= android-build-distclean
CLEAN_DEPS += android-build-distclean CLEAN_DEPS += android-build-distclean
} }
QMAKE_EXTRA_TARGETS *= aab apk apk_install_target

View File

@ -26,9 +26,9 @@ QMAKE_EXTRA_COMPILERS += dumpcpp_impl
!build_pass:have_target:!contains(TEMPLATE, vc.*) { !build_pass:have_target:!contains(TEMPLATE, vc.*) {
for(tlb, TYPELIBS) { for(tlb, TYPELIBS) {
tlbCopy = $$replace(tlb, \", ) tlbCopy = $$replace(tlb, \", )
hdr = $$basename(tlb) hdr = $$basename(tlbCopy)
hdr = $$section(hdr, ., 0, -2) hdr = $$section(hdr, ., 0, -2)
tmp_command = $$QMAKE_DUMPCPP $$system_quote($$absolute_path($$tlb, $$_PRO_FILE_PWD_)) \ tmp_command = $$QMAKE_DUMPCPP $$system_quote($$absolute_path($$tlbCopy, $$_PRO_FILE_PWD_)) \
-o $$system_quote($$OUT_PWD/$$hdr) -o $$system_quote($$OUT_PWD/$$hdr)
qaxcontainer_compat: tmp_command += -compat qaxcontainer_compat: tmp_command += -compat
!exists($$OUT_PWD/$${hdr}.h): system($$tmp_command) !exists($$OUT_PWD/$${hdr}.h): system($$tmp_command)

View File

@ -0,0 +1,31 @@
From 7905740b8e79479298e83d8e559fc49b46cf980e Mon Sep 17 00:00:00 2001
From: Andy Shaw <andy.shaw@qt.io>
Date: Thu, 19 Dec 2019 21:59:09 +0100
Subject: [PATCH] Fix CVE-2019-19242 in SQLite
Change-Id: I78a72a574da5cf3503950afe47146ae6424f00c6
---
src/3rdparty/sqlite/sqlite3.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index bd647ca1c2..d3e0c065b6 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -101055,7 +101055,12 @@ expr_code_doover:
** constant.
*/
int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
- int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+ int aff;
+ if( pExpr->y.pTab ){
+ aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+ }else{
+ aff = pExpr->affExpr;
+ }
if( aff>SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' );
--
2.21.0 (Apple Git-122.2)

View File

@ -0,0 +1,95 @@
From 11a2f4647b67494fb731a6fd793f1b28074631d3 Mon Sep 17 00:00:00 2001
From: Andy Shaw <andy.shaw@qt.io>
Date: Thu, 19 Dec 2019 22:31:15 +0100
Subject: [PATCH] Fix CVE-2019-19603 in SQLite
This includes the patch needed to fix this CVE and a supporting one to
include a new function added that it depends on.
Task-number: QTBUG-80903
Change-Id: Ic7639d50c89a3ee7d45426588c3ab0efd0eebb72
---
src/3rdparty/sqlite/sqlite3.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index d3e0c065b6..a430554db7 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -19519,6 +19519,12 @@ SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
);
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
+SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
+#else
+# define sqlite3ShadowTableName(A,B) 0
+#endif
SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
@@ -108483,6 +108489,22 @@ SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){
return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
}
+/*
+ ** Return TRUE if shadow tables should be read-only in the current
+ ** context.
+ */
+int sqlite3ReadOnlyShadowTables(sqlite3 *db){
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( (db->flags & SQLITE_Defensive)!=0
+ && db->pVtabCtx==0
+ && db->nVdbeExec==0
+ ){
+ return 1;
+ }
+#endif
+ return 0;
+}
+
/*
** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or
@@ -108516,8 +108538,8 @@ SQLITE_PRIVATE int sqlite3CheckObjectName(
}
}
}else{
- if( pParse->nested==0
- && 0==sqlite3StrNICmp(zName, "sqlite_", 7)
+ if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7))
+ || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName))
){
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s",
zName);
@@ -109662,7 +109684,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
** zName is temporarily modified while this routine is running, but is
** restored to its original value prior to this routine returning.
*/
-static int isShadowTableName(sqlite3 *db, char *zName){
+int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
char *zTail; /* Pointer to the last "_" in zName */
Table *pTab; /* Table that zName is a shadow of */
Module *pMod; /* Module for the virtual table */
@@ -109680,8 +109702,6 @@ static int isShadowTableName(sqlite3 *db, char *zName){
if( pMod->pModule->xShadowName==0 ) return 0;
return pMod->pModule->xShadowName(zTail+1);
}
-#else
-# define isShadowTableName(x,y) 0
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
/*
@@ -109723,7 +109743,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
p = pParse->pNewTable;
if( p==0 ) return;
- if( pSelect==0 && isShadowTableName(db, p->zName) ){
+ if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){
p->tabFlags |= TF_Shadow;
}
--
2.21.0 (Apple Git-122.2)

View File

@ -0,0 +1,29 @@
From a83bbce4d6f31d93ea4d2a681aa52c148f148e26 Mon Sep 17 00:00:00 2001
From: Andy Shaw <andy.shaw@qt.io>
Date: Thu, 2 Jan 2020 09:07:08 +0100
Subject: [PATCH] Fix CVE-2019-19646 in SQLite
Task-number: QTBUG-81020
Change-Id: I7176db20d4a44b1fb443a6108675f719e9643343
---
src/3rdparty/sqlite/sqlite3.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index 57e61b8313..980a149b1a 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -123765,7 +123765,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( j==pTab->iPKey ) continue;
if( pTab->aCol[j].notNull==0 ) continue;
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
- sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+ if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){
+ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+ }
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pTab->aCol[j].zName);
--
2.21.0 (Apple Git-122.2)

View File

@ -0,0 +1,83 @@
From 78c972eec5bab03a408b8ba1373572bcfe2db630 Mon Sep 17 00:00:00 2001
From: Andy Shaw <andy.shaw@qt.io>
Date: Thu, 2 Jan 2020 08:47:23 +0100
Subject: [PATCH] Fix CVE-2019-19645 in SQLite
Task-number: QTBUG-81020
Change-Id: I58b1dd9e7a90ba998c3af7f25a4627d8bdd70970
---
src/3rdparty/sqlite/sqlite3.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index d3e0c065b6..57e61b8313 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -17946,6 +17946,7 @@ struct Select {
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
#define SF_ComplexResult 0x40000 /* Result contains subquery or function */
#define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */
+#define SF_View 0x0200000 /* SELECT statement is a view */
/*
** The results of a SELECT can be distributed in several ways, as defined
@@ -103920,6 +103921,7 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i;
+ if( p->selFlags & SF_View ) return WRC_Prune;
if( ALWAYS(p->pEList) ){
ExprList *pList = p->pEList;
for(i=0; i<pList->nExpr; i++){
@@ -104024,6 +104026,7 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){
** descend into sub-select statements.
*/
static int renameColumnSelectCb(Walker *pWalker, Select *p){
+ if( p->selFlags & SF_View ) return WRC_Prune;
renameWalkWith(pWalker, p);
return WRC_Continue;
}
@@ -104489,8 +104492,9 @@ static void renameColumnFunc(
if( sParse.pNewTable ){
Select *pSelect = sParse.pNewTable->pSelect;
if( pSelect ){
+ pSelect->selFlags &= ~SF_View;
sParse.rc = SQLITE_OK;
- sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0);
+ sqlite3SelectPrep(&sParse, pSelect, 0);
rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
if( rc==SQLITE_OK ){
sqlite3WalkSelect(&sWalker, pSelect);
@@ -104602,6 +104606,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
int i;
RenameCtx *p = pWalker->u.pRename;
SrcList *pSrc = pSelect->pSrc;
+ if( pSelect->selFlags & SF_View ) return WRC_Prune;
if( pSrc==0 ){
assert( pWalker->pParse->db->mallocFailed );
return WRC_Abort;
@@ -104681,10 +104686,13 @@ static void renameTableFunc(
if( pTab->pSelect ){
if( isLegacy==0 ){
+ Select *pSelect = pTab->pSelect;
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = &sParse;
+ assert( pSelect->selFlags & SF_View );
+ pSelect->selFlags &= ~SF_View;
sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
if( sParse.nErr ) rc = sParse.rc;
sqlite3WalkSelect(&sWalker, pTab->pSelect);
@@ -109994,6 +110002,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
** allocated rather than point to the input string - which means that
** they will persist after the current sqlite3_exec() call returns.
*/
+ pSelect->selFlags |= SF_View;
if( IN_RENAME_OBJECT ){
p->pSelect = pSelect;
pSelect = 0;
--
2.21.0 (Apple Git-122.2)

View File

@ -17946,6 +17946,7 @@ struct Select {
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
#define SF_ComplexResult 0x40000 /* Result contains subquery or function */ #define SF_ComplexResult 0x40000 /* Result contains subquery or function */
#define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */ #define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */
#define SF_View 0x0200000 /* SELECT statement is a view */
/* /*
** The results of a SELECT can be distributed in several ways, as defined ** The results of a SELECT can be distributed in several ways, as defined
@ -19519,6 +19520,12 @@ SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
); );
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif #endif
SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
#ifndef SQLITE_OMIT_VIRTUALTABLE
SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
#else
# define sqlite3ShadowTableName(A,B) 0
#endif
SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*); SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*); SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
@ -101055,7 +101062,12 @@ expr_code_doover:
** constant. ** constant.
*/ */
int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); int aff;
if( pExpr->y.pTab ){
aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
}else{
aff = pExpr->affExpr;
}
if( aff>SQLITE_AFF_BLOB ){ if( aff>SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E"; static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' ); assert( SQLITE_AFF_BLOB=='A' );
@ -103915,6 +103927,7 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
static int renameUnmapSelectCb(Walker *pWalker, Select *p){ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse; Parse *pParse = pWalker->pParse;
int i; int i;
if( p->selFlags & SF_View ) return WRC_Prune;
if( ALWAYS(p->pEList) ){ if( ALWAYS(p->pEList) ){
ExprList *pList = p->pEList; ExprList *pList = p->pEList;
for(i=0; i<pList->nExpr; i++){ for(i=0; i<pList->nExpr; i++){
@ -104019,6 +104032,7 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){
** descend into sub-select statements. ** descend into sub-select statements.
*/ */
static int renameColumnSelectCb(Walker *pWalker, Select *p){ static int renameColumnSelectCb(Walker *pWalker, Select *p){
if( p->selFlags & SF_View ) return WRC_Prune;
renameWalkWith(pWalker, p); renameWalkWith(pWalker, p);
return WRC_Continue; return WRC_Continue;
} }
@ -104484,8 +104498,9 @@ static void renameColumnFunc(
if( sParse.pNewTable ){ if( sParse.pNewTable ){
Select *pSelect = sParse.pNewTable->pSelect; Select *pSelect = sParse.pNewTable->pSelect;
if( pSelect ){ if( pSelect ){
pSelect->selFlags &= ~SF_View;
sParse.rc = SQLITE_OK; sParse.rc = SQLITE_OK;
sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); sqlite3SelectPrep(&sParse, pSelect, 0);
rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
sqlite3WalkSelect(&sWalker, pSelect); sqlite3WalkSelect(&sWalker, pSelect);
@ -104597,6 +104612,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
int i; int i;
RenameCtx *p = pWalker->u.pRename; RenameCtx *p = pWalker->u.pRename;
SrcList *pSrc = pSelect->pSrc; SrcList *pSrc = pSelect->pSrc;
if( pSelect->selFlags & SF_View ) return WRC_Prune;
if( pSrc==0 ){ if( pSrc==0 ){
assert( pWalker->pParse->db->mallocFailed ); assert( pWalker->pParse->db->mallocFailed );
return WRC_Abort; return WRC_Abort;
@ -104676,10 +104692,13 @@ static void renameTableFunc(
if( pTab->pSelect ){ if( pTab->pSelect ){
if( isLegacy==0 ){ if( isLegacy==0 ){
Select *pSelect = pTab->pSelect;
NameContext sNC; NameContext sNC;
memset(&sNC, 0, sizeof(sNC)); memset(&sNC, 0, sizeof(sNC));
sNC.pParse = &sParse; sNC.pParse = &sParse;
assert( pSelect->selFlags & SF_View );
pSelect->selFlags &= ~SF_View;
sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
if( sParse.nErr ) rc = sParse.rc; if( sParse.nErr ) rc = sParse.rc;
sqlite3WalkSelect(&sWalker, pTab->pSelect); sqlite3WalkSelect(&sWalker, pTab->pSelect);
@ -108478,6 +108497,22 @@ SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){
return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema; return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema;
} }
/*
** Return TRUE if shadow tables should be read-only in the current
** context.
*/
int sqlite3ReadOnlyShadowTables(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( (db->flags & SQLITE_Defensive)!=0
&& db->pVtabCtx==0
&& db->nVdbeExec==0
){
return 1;
}
#endif
return 0;
}
/* /*
** This routine is used to check if the UTF-8 string zName is a legal ** This routine is used to check if the UTF-8 string zName is a legal
** unqualified name for a new schema object (table, index, view or ** unqualified name for a new schema object (table, index, view or
@ -108511,8 +108546,8 @@ SQLITE_PRIVATE int sqlite3CheckObjectName(
} }
} }
}else{ }else{
if( pParse->nested==0 if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7))
&& 0==sqlite3StrNICmp(zName, "sqlite_", 7) || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName))
){ ){
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s",
zName); zName);
@ -109657,7 +109692,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
** zName is temporarily modified while this routine is running, but is ** zName is temporarily modified while this routine is running, but is
** restored to its original value prior to this routine returning. ** restored to its original value prior to this routine returning.
*/ */
static int isShadowTableName(sqlite3 *db, char *zName){ int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
char *zTail; /* Pointer to the last "_" in zName */ char *zTail; /* Pointer to the last "_" in zName */
Table *pTab; /* Table that zName is a shadow of */ Table *pTab; /* Table that zName is a shadow of */
Module *pMod; /* Module for the virtual table */ Module *pMod; /* Module for the virtual table */
@ -109675,8 +109710,6 @@ static int isShadowTableName(sqlite3 *db, char *zName){
if( pMod->pModule->xShadowName==0 ) return 0; if( pMod->pModule->xShadowName==0 ) return 0;
return pMod->pModule->xShadowName(zTail+1); return pMod->pModule->xShadowName(zTail+1);
} }
#else
# define isShadowTableName(x,y) 0
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
/* /*
@ -109718,7 +109751,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
p = pParse->pNewTable; p = pParse->pNewTable;
if( p==0 ) return; if( p==0 ) return;
if( pSelect==0 && isShadowTableName(db, p->zName) ){ if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){
p->tabFlags |= TF_Shadow; p->tabFlags |= TF_Shadow;
} }
@ -109989,6 +110022,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
** allocated rather than point to the input string - which means that ** allocated rather than point to the input string - which means that
** they will persist after the current sqlite3_exec() call returns. ** they will persist after the current sqlite3_exec() call returns.
*/ */
pSelect->selFlags |= SF_View;
if( IN_RENAME_OBJECT ){ if( IN_RENAME_OBJECT ){
p->pSelect = pSelect; p->pSelect = pSelect;
pSelect = 0; pSelect = 0;
@ -123751,7 +123785,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( j==pTab->iPKey ) continue; if( j==pTab->iPKey ) continue;
if( pTab->aCol[j].notNull==0 ) continue; if( pTab->aCol[j].notNull==0 ) continue;
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
}
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pTab->aCol[j].zName); pTab->aCol[j].zName);

View File

@ -109,7 +109,7 @@ QT_BEGIN_NAMESPACE
/*! /*!
\internal \internal
\since 5.14 \since 5.14
bool qfloat16::isInf() const noexcept \fn bool qfloat16::isInf() const noexcept
Tests whether this \c qfloat16 value is an infinity. Tests whether this \c qfloat16 value is an infinity.
@ -119,7 +119,7 @@ QT_BEGIN_NAMESPACE
/*! /*!
\internal \internal
\since 5.14 \since 5.14
bool qfloat16::isNaN() const noexcept \fn bool qfloat16::isNaN() const noexcept
Tests whether this \c qfloat16 value is "not a number". Tests whether this \c qfloat16 value is "not a number".
@ -128,7 +128,7 @@ QT_BEGIN_NAMESPACE
/*! /*!
\since 5.14 \since 5.14
bool qfloat16::isNormal() const noexcept \fn bool qfloat16::isNormal() const noexcept
Tests whether this \c qfloat16 value is finite and in normal form. Tests whether this \c qfloat16 value is finite and in normal form.
@ -138,7 +138,7 @@ QT_BEGIN_NAMESPACE
/*! /*!
\internal \internal
\since 5.14 \since 5.14
bool qfloat16::isFinite() const noexcept \fn bool qfloat16::isFinite() const noexcept
Tests whether this \c qfloat16 value is finite. Tests whether this \c qfloat16 value is finite.

View File

@ -4600,7 +4600,7 @@ QDebug operator<<(QDebug dbg, const QObject *o)
It works exactly like the Q_NAMESPACE macro. However, the external It works exactly like the Q_NAMESPACE macro. However, the external
\c{staticMetaObject} variable that gets defined in the namespace \c{staticMetaObject} variable that gets defined in the namespace
is declared with the supplied \c{EXPORT_MACRO} qualifier. This is is declared with the supplied \a EXPORT_MACRO qualifier. This is
useful if the object needs to be exported from a dynamic library. useful if the object needs to be exported from a dynamic library.
\sa Q_NAMESPACE, {Creating Shared Libraries} \sa Q_NAMESPACE, {Creating Shared Libraries}

View File

@ -803,7 +803,8 @@ namespace QtPrivate {
static QVariantList invoke(const QVariant &v) static QVariantList invoke(const QVariant &v)
{ {
const int typeId = v.userType(); const int typeId = v.userType();
if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>())) { if (typeId == qMetaTypeId<QStringList>() || typeId == qMetaTypeId<QByteArrayList>() ||
(QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QSequentialIterableImpl>()) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantList>()))) {
QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v); QSequentialIterable iter = QVariantValueHelperInterface<QSequentialIterable>::invoke(v);
QVariantList l; QVariantList l;
l.reserve(iter.size()); l.reserve(iter.size());
@ -820,7 +821,7 @@ namespace QtPrivate {
static QVariantHash invoke(const QVariant &v) static QVariantHash invoke(const QVariant &v)
{ {
const int typeId = v.userType(); const int typeId = v.userType();
if (typeId == qMetaTypeId<QVariantMap>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) { if (typeId == qMetaTypeId<QVariantMap>() || ((QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantHash>()))) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v); QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantHash l; QVariantHash l;
l.reserve(iter.size()); l.reserve(iter.size());
@ -837,7 +838,7 @@ namespace QtPrivate {
static QVariantMap invoke(const QVariant &v) static QVariantMap invoke(const QVariant &v)
{ {
const int typeId = v.userType(); const int typeId = v.userType();
if (typeId == qMetaTypeId<QVariantHash>() || QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>())) { if (typeId == qMetaTypeId<QVariantHash>() || (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QAssociativeIterableImpl>()) && !QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QVariantMap>()))) {
QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v); QAssociativeIterable iter = QVariantValueHelperInterface<QAssociativeIterable>::invoke(v);
QVariantMap l; QVariantMap l;
for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it) for (QAssociativeIterable::const_iterator it = iter.begin(), end = iter.end(); it != end; ++it)
@ -853,12 +854,9 @@ namespace QtPrivate {
static QPair<QVariant, QVariant> invoke(const QVariant &v) static QPair<QVariant, QVariant> invoke(const QVariant &v)
{ {
const int typeId = v.userType(); const int typeId = v.userType();
if (typeId == qMetaTypeId<QPair<QVariant, QVariant> >())
return QVariantValueHelper<QPair<QVariant, QVariant> >::invoke(v);
if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>())) {
QtMetaTypePrivate::QPairVariantInterfaceImpl pi = qvariant_cast<QtMetaTypePrivate::QPairVariantInterfaceImpl>(v);
if (QMetaType::hasRegisteredConverterFunction(typeId, qMetaTypeId<QtMetaTypePrivate::QPairVariantInterfaceImpl>()) && !(typeId == qMetaTypeId<QPair<QVariant, QVariant> >())) {
QtMetaTypePrivate::QPairVariantInterfaceImpl pi = v.value<QtMetaTypePrivate::QPairVariantInterfaceImpl>();
const QtMetaTypePrivate::VariantData d1 = pi.first(); const QtMetaTypePrivate::VariantData d1 = pi.first();
QVariant v1(d1.metaTypeId, d1.data, d1.flags); QVariant v1(d1.metaTypeId, d1.data, d1.flags);
if (d1.metaTypeId == qMetaTypeId<QVariant>()) if (d1.metaTypeId == qMetaTypeId<QVariant>())

View File

@ -174,7 +174,7 @@
\value Chewa Obsolete, please use Nyanja \value Chewa Obsolete, please use Nyanja
\value Chickasaw Since Qt 5.14 \value Chickasaw Since Qt 5.14
\value Chiga \value Chiga
\value Chinese \value Chinese (Mandarin)
\value Church \value Church
\value Chuvash \value Chuvash
\value ClassicalMandaic Since Qt 5.1 \value ClassicalMandaic Since Qt 5.1
@ -1201,14 +1201,6 @@
\sa toShort() \sa toShort()
*/ */
/*!
\fn QString QLocale::toString(ushort i) const
\overload
\sa toUShort()
*/
/*! /*!
\fn QString QLocale::toString(int i) const \fn QString QLocale::toString(int i) const

View File

@ -2593,7 +2593,7 @@ uint qHash(long double key, uint seed) noexcept
\sa operator=() \sa operator=()
*/ */
/*! \fn template <class Key, class T> template <class InputIterator> QMultiHash::QMultiHash(InputIterator begin, InputIterator end) /*! \fn template <class Key, class T> template <class InputIterator> QMultiHash<Key, T>::QMultiHash(InputIterator begin, InputIterator end)
\since 5.14 \since 5.14
Constructs a multi-hash with a copy of each of the elements in the iterator range Constructs a multi-hash with a copy of each of the elements in the iterator range

View File

@ -6048,7 +6048,11 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba
// Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571 // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571
blend_pixel(*dst, src, qRgbAvg(coverage)); blend_pixel(*dst, src, qRgbAvg(coverage));
} else if (!colorProfile) { } else if (!colorProfile) {
*dst = rgbBlend(*dst, src, coverage); // First do naive blend with text-color
QRgb s = *dst;
blend_pixel(s, src);
// Then a naive blend with glyph shape
*dst = rgbBlend(*dst, s, coverage);
} else if (srcLinear.isOpaque()) { } else if (srcLinear.isOpaque()) {
rgbBlendPixel(dst, coverage, srcLinear, colorProfile); rgbBlendPixel(dst, coverage, srcLinear, colorProfile);
} else { } else {

View File

@ -2297,6 +2297,17 @@ QTextHtmlExporter::QTextHtmlExporter(const QTextDocument *_doc)
defaultCharFormat.clearProperty(QTextFormat::TextUnderlineStyle); defaultCharFormat.clearProperty(QTextFormat::TextUnderlineStyle);
} }
static QStringList resolvedFontFamilies(const QTextCharFormat &format)
{
QStringList fontFamilies = format.fontFamilies().toStringList();
const QString mainFontFamily = format.fontFamily();
if (!mainFontFamily.isEmpty() && !fontFamilies.startsWith(mainFontFamily)) {
fontFamilies.removeAll(mainFontFamily);
fontFamilies.prepend(mainFontFamily);
}
return fontFamilies;
}
/*! /*!
Returns the document in HTML format. The conversion may not be Returns the document in HTML format. The conversion may not be
perfect, especially for complex documents, due to the limitations perfect, especially for complex documents, due to the limitations
@ -2325,11 +2336,7 @@ QString QTextHtmlExporter::toHtml(const QByteArray &encoding, ExportMode mode)
if (mode == ExportEntireDocument) { if (mode == ExportEntireDocument) {
html += QLatin1String(" style=\""); html += QLatin1String(" style=\"");
QStringList fontFamilies = defaultCharFormat.fontFamilies().toStringList(); emitFontFamily(resolvedFontFamilies(defaultCharFormat));
if (!fontFamilies.isEmpty())
emitFontFamily(fontFamilies);
else
emitFontFamily(defaultCharFormat.fontFamily());
if (defaultCharFormat.hasProperty(QTextFormat::FontPointSize)) { if (defaultCharFormat.hasProperty(QTextFormat::FontPointSize)) {
html += QLatin1String(" font-size:"); html += QLatin1String(" font-size:");
@ -2391,14 +2398,10 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format)
bool attributesEmitted = false; bool attributesEmitted = false;
{ {
const QStringList families = format.fontFamilies().toStringList(); const QStringList families = resolvedFontFamilies(format);
const QString family = format.fontFamily(); if (!families.isEmpty() && families != resolvedFontFamilies(defaultCharFormat)) {
if (!families.isEmpty() && families != defaultCharFormat.fontFamilies().toStringList()) {
emitFontFamily(families); emitFontFamily(families);
attributesEmitted = true; attributesEmitted = true;
} else if (!family.isEmpty() && family != defaultCharFormat.fontFamily()) {
emitFontFamily(family);
attributesEmitted = true;
} }
} }
@ -2661,20 +2664,6 @@ void QTextHtmlExporter::emitPageBreakPolicy(QTextFormat::PageBreakFlags policy)
html += QLatin1String(" page-break-after:always;"); html += QLatin1String(" page-break-after:always;");
} }
void QTextHtmlExporter::emitFontFamily(const QString &family)
{
html += QLatin1String(" font-family:");
QLatin1String quote("\'");
if (family.contains(QLatin1Char('\'')))
quote = QLatin1String("&quot;");
html += quote;
html += family.toHtmlEscaped();
html += quote;
html += QLatin1Char(';');
}
void QTextHtmlExporter::emitFontFamily(const QStringList &families) void QTextHtmlExporter::emitFontFamily(const QStringList &families)
{ {
html += QLatin1String(" font-family:"); html += QLatin1String(" font-family:");

View File

@ -396,7 +396,6 @@ private:
void emitBorderStyle(QTextFrameFormat::BorderStyle style); void emitBorderStyle(QTextFrameFormat::BorderStyle style);
void emitPageBreakPolicy(QTextFormat::PageBreakFlags policy); void emitPageBreakPolicy(QTextFormat::PageBreakFlags policy);
void emitFontFamily(const QString &family);
void emitFontFamily(const QStringList &families); void emitFontFamily(const QStringList &families);
void emitBackgroundAttribute(const QTextFormat &format); void emitBackgroundAttribute(const QTextFormat &format);

View File

@ -595,7 +595,7 @@ QHostInfo::QHostInfo(const QHostInfo &other)
} }
/*! /*!
\fn QHostInfo(QHostInfo &&other) \fn QHostInfo::QHostInfo(QHostInfo &&other)
Move-constructs a new QHostInfo from \a other. Move-constructs a new QHostInfo from \a other.

View File

@ -617,8 +617,10 @@ QImage QCALayerBackingStore::toImage() const
void QCALayerBackingStore::backingPropertiesChanged() void QCALayerBackingStore::backingPropertiesChanged()
{ {
qCDebug(lcQpaBackingStore) << "Updating color space of existing buffers"; qCDebug(lcQpaBackingStore) << "Updating color space of existing buffers";
for (auto &buffer : m_buffers) for (auto &buffer : m_buffers) {
buffer->setColorSpace(colorSpace()); if (buffer)
buffer->setColorSpace(colorSpace());
}
} }
QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const QPlatformGraphicsBuffer *QCALayerBackingStore::graphicsBuffer() const

View File

@ -406,8 +406,6 @@ QVariant QCocoaIntegration::styleHint(StyleHint hint) const
return QCoreTextFontEngine::fontSmoothingGamma(); return QCoreTextFontEngine::fontSmoothingGamma();
case ShowShortcutsInContextMenus: case ShowShortcutsInContextMenus:
return QVariant(false); return QVariant(false);
// case CursorFlashTime:
// return 50000;
default: break; default: break;
} }

View File

@ -89,9 +89,16 @@ QIOSurfaceGraphicsBuffer::~QIOSurfaceGraphicsBuffer()
void QIOSurfaceGraphicsBuffer::setColorSpace(QCFType<CGColorSpaceRef> colorSpace) void QIOSurfaceGraphicsBuffer::setColorSpace(QCFType<CGColorSpaceRef> colorSpace)
{ {
Q_ASSERT(colorSpace); static const auto kIOSurfaceColorSpace = CFSTR("IOSurfaceColorSpace");
IOSurfaceSetValue(m_surface, CFSTR("IOSurfaceColorSpace"),
QCFType<CFPropertyListRef>(CGColorSpaceCopyPropertyList(colorSpace))); qCDebug(lcQpaIOSurface) << "Tagging" << this << "with color space" << colorSpace;
if (colorSpace) {
IOSurfaceSetValue(m_surface, kIOSurfaceColorSpace,
QCFType<CFPropertyListRef>(CGColorSpaceCopyPropertyList(colorSpace)));
} else {
IOSurfaceRemoveValue(m_surface, kIOSurfaceColorSpace);
}
} }
const uchar *QIOSurfaceGraphicsBuffer::data() const const uchar *QIOSurfaceGraphicsBuffer::data() const

View File

@ -343,13 +343,6 @@ void QAbstractPrintDialogPrivate::setPrinter(QPrinter *newPrinter)
pd = printer->d_func(); pd = printer->d_func();
} }
/*!
\fn int QAbstractPrintDialog::exec()
This virtual function is called to pop up the dialog. It must be
reimplemented in subclasses.
*/
/*! /*!
\class QPrintDialog \class QPrintDialog

View File

@ -243,7 +243,7 @@
Instead of \c Q_ASSERT, the \l QCOMPARE() or \l QVERIFY() macro variants Instead of \c Q_ASSERT, the \l QCOMPARE() or \l QVERIFY() macro variants
should be used. They cause the current test to report a failure and should be used. They cause the current test to report a failure and
terminate, but allow the remaining test functions to be executed and the terminate, but allow the remaining test functions to be executed and the
entire test program to terminate normally. \l Q_VERIFY2() even allows a entire test program to terminate normally. \l QVERIFY2() even allows a
descriptive error message to be recorded in the test log. descriptive error message to be recorded in the test log.
\section1 Writing Reliable Tests \section1 Writing Reliable Tests

View File

@ -98,7 +98,7 @@
\snippet code/doc_src_qsignalspy.cpp 6 \snippet code/doc_src_qsignalspy.cpp 6
*/ */
/*! \fn QSignalSpy(const QObject *obj, const QMetaMethod &signal) /*! \fn QSignalSpy::QSignalSpy(const QObject *obj, const QMetaMethod &signal)
\since 5.14 \since 5.14
Constructs a new QSignalSpy that listens for emissions of the \a signal Constructs a new QSignalSpy that listens for emissions of the \a signal

View File

@ -731,7 +731,7 @@ void WriteInitialization::acceptWidget(DomWidget *node)
if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) if (const DomProperty *picon = attributes.value(QLatin1String("icon")))
icon = QLatin1String(", ") + iconCall(picon); // Side effect: Writes icon definition icon = QLatin1String(", ") + iconCall(picon); // Side effect: Writes icon definition
m_output << m_indent << parentWidget << language::derefPointer << "addTab(" m_output << m_indent << parentWidget << language::derefPointer << "addTab("
<< varName << icon << ", " << "QString())" << language::eol; << varName << icon << ", " << language::emptyString << ')' << language::eol;
autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget
<< language::derefPointer << "setTabText(" << parentWidget << language::derefPointer << "setTabText(" << parentWidget
@ -1612,7 +1612,7 @@ QString WriteInitialization::writeFontProperties(const DomFont *f)
} }
if (f->hasElementWeight() && f->elementWeight() > 0) { if (f->hasElementWeight() && f->elementWeight() > 0) {
m_output << m_indent << fontName << ".setWeight(" m_output << m_indent << fontName << ".setWeight("
<< f->elementWeight() << ");" << Qt::endl; << f->elementWeight() << ")" << language::eol;
} }
if (f->hasElementStrikeOut()) { if (f->hasElementStrikeOut()) {
m_output << m_indent << fontName << ".setStrikeOut(" m_output << m_indent << fontName << ".setStrikeOut("
@ -2086,7 +2086,7 @@ void WriteInitialization::initializeComboBox(DomWidget *w)
m_output << iconValue << ", "; m_output << iconValue << ", ";
if (needsTranslation(text->elementString())) { if (needsTranslation(text->elementString())) {
m_output << "QString())" << language::eol; m_output << language::emptyString << ')' << language::eol;
m_refreshOut << m_indent << varName << language::derefPointer m_refreshOut << m_indent << varName << language::derefPointer
<< "setItemText(" << i << ", " << trCall(text->elementString()) << "setItemText(" << i << ", " << trCall(text->elementString())
<< ')' << language::eol; << ')' << language::eol;
@ -2288,7 +2288,7 @@ void WriteInitialization::initializeTreeWidget(DomWidget *w)
if (str && str->text().isEmpty()) { if (str && str->text().isEmpty()) {
m_output << m_indent << varName << language::derefPointer m_output << m_indent << varName << language::derefPointer
<< "headerItem()" << language::derefPointer << "setText(" << "headerItem()" << language::derefPointer << "setText("
<< i << ", QString())" << language::eol; << i << ", " << language::emptyString << ')' << language::eol;
} }
} }
} }
@ -2372,9 +2372,11 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
const auto &columns = w->elementColumn(); const auto &columns = w->elementColumn();
if (!columns.empty()) { if (!columns.empty()) {
m_output << m_indent << "if (" << varName << language::derefPointer << "columnCount() < " m_output << m_indent << "if (" << varName << language::derefPointer
<< columns.size() << ")\n" << "columnCount() < " << columns.size() << ')';
<< m_dindent << varName << language::derefPointer << "setColumnCount(" if (language::language() == Language::Python)
m_output << ':';
m_output << '\n' << m_dindent << varName << language::derefPointer << "setColumnCount("
<< columns.size() << ')' << language::eol; << columns.size() << ')' << language::eol;
} }
@ -2400,8 +2402,11 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
const auto &rows = w->elementRow(); const auto &rows = w->elementRow();
if (!rows.isEmpty()) { if (!rows.isEmpty()) {
m_output << m_indent << "if (" << varName << language::derefPointer << "rowCount() < " << rows.size() << ")\n" m_output << m_indent << "if (" << varName << language::derefPointer
<< m_dindent << varName << language::derefPointer << "setRowCount(" << "rowCount() < " << rows.size() << ')';
if (language::language() == Language::Python)
m_output << ':';
m_output << '\n' << m_dindent << varName << language::derefPointer << "setRowCount("
<< rows.size() << ')' << language::eol; << rows.size() << ')' << language::eol;
} }
@ -2451,10 +2456,8 @@ void WriteInitialization::initializeTableWidget(DomWidget *w)
QString WriteInitialization::trCall(const QString &str, const QString &commentHint, const QString &id) const QString WriteInitialization::trCall(const QString &str, const QString &commentHint, const QString &id) const
{ {
if (str.isEmpty()) { if (str.isEmpty())
return language::language() == Language::Cpp return language::emptyString;
? QLatin1String("QString()") : QLatin1String("\"\"");
}
QString result; QString result;
QTextStream ts(&result); QTextStream ts(&result);

View File

@ -108,6 +108,10 @@ int runUic(int argc, char *argv[])
idBasedOption.setDescription(QStringLiteral("Use id based function for i18n")); idBasedOption.setDescription(QStringLiteral("Use id based function for i18n"));
parser.addOption(idBasedOption); parser.addOption(idBasedOption);
QCommandLineOption fromImportsOption(QStringLiteral("from-imports"));
fromImportsOption.setDescription(QStringLiteral("Python: generate imports relative to '.'"));
parser.addOption(fromImportsOption);
parser.addPositionalArgument(QStringLiteral("[uifile]"), QStringLiteral("Input file (*.ui), otherwise stdin.")); parser.addPositionalArgument(QStringLiteral("[uifile]"), QStringLiteral("Input file (*.ui), otherwise stdin."));
parser.process(app); parser.process(app);
@ -118,6 +122,7 @@ int runUic(int argc, char *argv[])
driver.option().headerProtection = !parser.isSet(noProtOption); driver.option().headerProtection = !parser.isSet(noProtOption);
driver.option().implicitIncludes = !parser.isSet(noImplicitIncludesOption); driver.option().implicitIncludes = !parser.isSet(noImplicitIncludesOption);
driver.option().idBased = parser.isSet(idBasedOption); driver.option().idBased = parser.isSet(idBasedOption);
driver.option().fromImports = parser.isSet(fromImportsOption);
driver.option().postfix = parser.value(postfixOption); driver.option().postfix = parser.value(postfixOption);
driver.option().translateFunction = parser.value(translateOption); driver.option().translateFunction = parser.value(translateOption);
driver.option().includeFile = parser.value(includeOption); driver.option().includeFile = parser.value(includeOption);

View File

@ -45,6 +45,7 @@ struct Option
unsigned int limitXPM_LineLength : 1; unsigned int limitXPM_LineLength : 1;
unsigned int implicitIncludes: 1; unsigned int implicitIncludes: 1;
unsigned int idBased: 1; unsigned int idBased: 1;
unsigned int fromImports: 1;
QString inputFile; QString inputFile;
QString outputFile; QString outputFile;
@ -65,6 +66,7 @@ struct Option
limitXPM_LineLength(0), limitXPM_LineLength(0),
implicitIncludes(1), implicitIncludes(1),
idBased(0), idBased(0),
fromImports(0),
prefix(QLatin1String("Ui_")) prefix(QLatin1String("Ui_"))
{ indent.fill(QLatin1Char(' '), 4); } { indent.fill(QLatin1Char(' '), 4); }

View File

@ -29,6 +29,7 @@
#include "pythonwriteimports.h" #include "pythonwriteimports.h"
#include <customwidgetsinfo.h> #include <customwidgetsinfo.h>
#include <option.h>
#include <uic.h> #include <uic.h>
#include <ui4.h> #include <ui4.h>
@ -46,6 +47,20 @@ from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QFont,
from PySide2.QtWidgets import * from PySide2.QtWidgets import *
)I"; )I";
// Change the name of a qrc file "dir/foo.qrc" file to the Python
// module name "foo_rc" according to project conventions.
static QString pythonResource(QString resource)
{
const int lastSlash = resource.lastIndexOf(QLatin1Char('/'));
if (lastSlash != -1)
resource.remove(0, lastSlash + 1);
if (resource.endsWith(QLatin1String(".qrc"))) {
resource.chop(4);
resource.append(QLatin1String("_rc"));
}
return resource;
}
namespace Python { namespace Python {
WriteImports::WriteImports(Uic *uic) : m_uic(uic) WriteImports::WriteImports(Uic *uic) : m_uic(uic)
@ -60,6 +75,23 @@ void WriteImports::acceptUI(DomUI *node)
TreeWalker::acceptCustomWidgets(customWidgets); TreeWalker::acceptCustomWidgets(customWidgets);
output << '\n'; output << '\n';
} }
if (auto resources = node->elementResources()) {
const auto includes = resources->elementInclude();
for (auto include : includes) {
if (include->hasAttributeLocation())
writeImport(pythonResource(include->attributeLocation()));
}
output << '\n';
}
}
void WriteImports::writeImport(const QString &module)
{
if (m_uic->option().fromImports)
m_uic->output() << "from . ";
m_uic->output() << "import " << module << '\n';
} }
QString WriteImports::qtModuleOf(const DomCustomWidget *node) const QString WriteImports::qtModuleOf(const DomCustomWidget *node) const

View File

@ -46,6 +46,7 @@ public:
void acceptCustomWidget(DomCustomWidget *node) override; void acceptCustomWidget(DomCustomWidget *node) override;
private: private:
void writeImport(const QString &module);
QString qtModuleOf(const DomCustomWidget *node) const; QString qtModuleOf(const DomCustomWidget *node) const;
Uic *const m_uic; Uic *const m_uic;

View File

@ -49,6 +49,7 @@ void setLanguage(Language l)
qualifier = QLatin1String("::"); qualifier = QLatin1String("::");
self = QLatin1String(""); // for testing: change to "this->"; self = QLatin1String(""); // for testing: change to "this->";
eol = QLatin1String(";\n"); eol = QLatin1String(";\n");
emptyString = QLatin1String("QString()");
encoding = Encoding::Utf8; encoding = Encoding::Utf8;
break; break;
case Language::Python: case Language::Python:
@ -59,6 +60,7 @@ void setLanguage(Language l)
qualifier = QLatin1String("."); qualifier = QLatin1String(".");
self = QLatin1String("self."); self = QLatin1String("self.");
eol = QLatin1String("\n"); eol = QLatin1String("\n");
emptyString = QLatin1String("\"\"");
encoding = Encoding::Unicode; encoding = Encoding::Unicode;
break; break;
} }
@ -71,6 +73,7 @@ QString qtQualifier;
QString qualifier; QString qualifier;
QString self; QString self;
QString eol; QString eol;
QString emptyString;
QString cppQualifier = QLatin1String("::"); QString cppQualifier = QLatin1String("::");
QString cppTrue = QLatin1String("true"); QString cppTrue = QLatin1String("true");

View File

@ -49,6 +49,7 @@ extern QString qtQualifier;
extern QString qualifier; extern QString qualifier;
extern QString self; extern QString self;
extern QString eol; extern QString eol;
extern QString emptyString;
extern QString cppQualifier; extern QString cppQualifier;
extern QString cppTrue; extern QString cppTrue;

View File

@ -292,7 +292,8 @@ QList<QAction*> QActionGroup::actions() const
\brief Enable or disable the group exclusion checking \brief Enable or disable the group exclusion checking
This is a convenience method that calls This is a convenience method that calls
setExclusionPolicy(ExclusionPolicy::Exclusive). setExclusionPolicy(ExclusionPolicy::Exclusive) when \a b is true,
else setExclusionPolicy(QActionGroup::ExclusionPolicy::None).
\sa QActionGroup::exclusionPolicy \sa QActionGroup::exclusionPolicy
*/ */
@ -303,7 +304,7 @@ void QActionGroup::setExclusive(bool b)
} }
/*! /*!
\brief Returs true if the group is exclusive \brief Returns true if the group is exclusive
The group is exclusive if the ExclusionPolicy is either Exclusive The group is exclusive if the ExclusionPolicy is either Exclusive
or ExclusionOptional. or ExclusionOptional.

View File

@ -545,7 +545,7 @@ QShortcut::QShortcut(QWidget *parent)
match the \a key sequence. Depending on the ambiguity of the match the \a key sequence. Depending on the ambiguity of the
event, the shortcut will call the \a member function, or the \a event, the shortcut will call the \a member function, or the \a
ambiguousMember function, if the key press was in the shortcut's ambiguousMember function, if the key press was in the shortcut's
\a context. \a shortcutContext.
*/ */
QShortcut::QShortcut(const QKeySequence &key, QWidget *parent, QShortcut::QShortcut(const QKeySequence &key, QWidget *parent,
const char *member, const char *ambiguousMember, const char *member, const char *ambiguousMember,

View File

@ -3027,6 +3027,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC
r = positionRect(w, subRule, subRule2, PseudoElement_ComboBoxArrow, r, opt->direction); r = positionRect(w, subRule, subRule2, PseudoElement_ComboBoxArrow, r, opt->direction);
subRule2.drawRule(p, r); subRule2.drawRule(p, r);
} else { } else {
rule.configurePalette(&cmbOpt.palette, QPalette::ButtonText, QPalette::Button);
cmbOpt.subControls = QStyle::SC_ComboBoxArrow; cmbOpt.subControls = QStyle::SC_ComboBoxArrow;
QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w); QWindowsStyle::drawComplexControl(cc, &cmbOpt, p, w);
} }

View File

@ -335,7 +335,6 @@ void QDateTimeEdit::setCalendar(QCalendar calendar)
/*! /*!
\since 4.4 \since 4.4
\property QDateTimeEdit::minimumDateTime \property QDateTimeEdit::minimumDateTime
\brief the minimum datetime of the date time edit \brief the minimum datetime of the date time edit
Changing this property implicitly updates the \l minimumDate and \l Changing this property implicitly updates the \l minimumDate and \l
@ -637,8 +636,8 @@ void QDateTimeEdit::setDateRange(const QDate &min, const QDate &max)
Note that these only constrain the date time edit's value on, Note that these only constrain the date time edit's value on,
respectively, the \l minimumDate and \l maximumDate. When these date respectively, the \l minimumDate and \l maximumDate. When these date
properties do not coincide, times after \a maximumTime are allowed on dates properties do not coincide, times after \a max are allowed on dates
before \l maximumDate and times before \a minimumTime are allowed on dates before \l maximumDate and times before \a min are allowed on dates
after \l minimumDate. after \l minimumDate.
\snippet code/src_gui_widgets_qdatetimeedit.cpp 5 \snippet code/src_gui_widgets_qdatetimeedit.cpp 5
@ -649,7 +648,7 @@ void QDateTimeEdit::setDateRange(const QDate &min, const QDate &max)
If either \a min or \a max is invalid, this function does nothing. This If either \a min or \a max is invalid, this function does nothing. This
function preserves the \l minimumDate and \l maximumDate properties. If those function preserves the \l minimumDate and \l maximumDate properties. If those
properties coincide and max is \a less than \a min, \a min is used as \a max. properties coincide and \a max is less than \a min, \a min is used as \a max.
\sa minimumTime, maximumTime, setDateTimeRange(), QTime::isValid() \sa minimumTime, maximumTime, setDateTimeRange(), QTime::isValid()
*/ */

View File

@ -839,7 +839,8 @@ void QPlainTextEditPrivate::_q_textChanged()
placeholderVisible = !placeholderText.isEmpty() placeholderVisible = !placeholderText.isEmpty()
&& q->document()->isEmpty() && q->document()->isEmpty()
&& q->firstVisibleBlock().layout()->preeditAreaText().isEmpty(); && (!q->firstVisibleBlock().isValid() ||
q->firstVisibleBlock().layout()->preeditAreaText().isEmpty());
if (placeholderCurrentyVisible != placeholderVisible) if (placeholderCurrentyVisible != placeholderVisible)
viewport->update(); viewport->update();

View File

@ -282,6 +282,8 @@ private slots:
void fromStdVariant(); void fromStdVariant();
void qt4UuidDataStream(); void qt4UuidDataStream();
void preferDirectConversionOverInterfaces();
private: private:
void dataStream_data(QDataStream::Version version); void dataStream_data(QDataStream::Version version);
void loadQVariantFromDataStream(QDataStream::Version version); void loadQVariantFromDataStream(QDataStream::Version version);
@ -5140,5 +5142,47 @@ void tst_QVariant::qt4UuidDataStream()
QCOMPARE(result.value<QUuid>(), source); QCOMPARE(result.value<QUuid>(), source);
} }
void tst_QVariant::preferDirectConversionOverInterfaces()
{
using namespace QtMetaTypePrivate;
bool calledCorrectConverter = false;
QMetaType::registerConverter<MyType, QSequentialIterableImpl>([](const MyType &) {
return QSequentialIterableImpl {};
});
QMetaType::registerConverter<MyType, QVariantList>([&calledCorrectConverter](const MyType &) {
calledCorrectConverter = true;
return QVariantList {};
});
QMetaType::registerConverter<MyType, QAssociativeIterableImpl>([](const MyType &) {
return QAssociativeIterableImpl {};
});
QMetaType::registerConverter<MyType, QVariantHash>([&calledCorrectConverter](const MyType &) {
calledCorrectConverter = true;
return QVariantHash {};
});
QMetaType::registerConverter<MyType, QVariantMap>([&calledCorrectConverter](const MyType &) {
calledCorrectConverter = true;
return QVariantMap {};
});
auto holder = QVariant::fromValue(MyType {});
QVERIFY(holder.canConvert<QSequentialIterableImpl>());
QVERIFY(holder.canConvert<QVariantList>());
QVERIFY(holder.canConvert<QAssociativeIterableImpl>());
QVERIFY(holder.canConvert<QVariantHash>());
QVERIFY(holder.canConvert<QVariantMap>());
holder.value<QVariantList>();
QVERIFY(calledCorrectConverter);
calledCorrectConverter = false;
holder.value<QVariantHash>();
QVERIFY(calledCorrectConverter);
calledCorrectConverter = false;
holder.value<QVariantMap>();
QVERIFY(calledCorrectConverter);
}
QTEST_MAIN(tst_QVariant) QTEST_MAIN(tst_QVariant)
#include "tst_qvariant.moc" #include "tst_qvariant.moc"

View File

@ -194,6 +194,8 @@ private slots:
void fontTagFace(); void fontTagFace();
void clearUndoRedoStacks(); void clearUndoRedoStacks();
void mergeFontFamilies();
private: private:
void backgroundImage_checkExpectedHtml(const QTextDocument &doc); void backgroundImage_checkExpectedHtml(const QTextDocument &doc);
void buildRegExpData(); void buildRegExpData();
@ -3585,6 +3587,25 @@ void tst_QTextDocument::fontTagFace()
} }
} }
void tst_QTextDocument::mergeFontFamilies()
{
QTextDocument td;
td.setHtml(QLatin1String(
"<html><body>"
"<span style=\" font-family:'MS Shell Dlg 2';\">Hello world</span>"
"</body></html>"));
QTextCharFormat newFormat;
newFormat.setFontFamily(QLatin1String("Jokerman"));
QTextCursor cursor = QTextCursor(&td);
cursor.setPosition(0);
cursor.setPosition(QByteArray("Hello World").length(), QTextCursor::KeepAnchor);
cursor.mergeCharFormat(newFormat);
QVERIFY(td.toHtml().contains(QLatin1String("font-family:'Jokerman','MS Shell Dlg 2';")));
}
void tst_QTextDocument::clearUndoRedoStacks() void tst_QTextDocument::clearUndoRedoStacks()
{ {
QTextDocument doc; QTextDocument doc;