Merge "Merge remote-tracking branch 'origin/5.11' into dev" into refs/staging/dev

This commit is contained in:
Liang Qi 2018-02-12 11:15:20 +00:00 committed by The Qt Project
commit 3d31afe1e4
56 changed files with 9682 additions and 6024 deletions

View File

@ -13,7 +13,6 @@ defines += Q_QDOC \
QT_DEPRECATED \
QT_DEPRECATED_* \
Q_NO_USING_KEYWORD \
__cplusplus \
Q_OS_.* \
Q_STDLIB_UNICODE_STRINGS \
Q_COMPILER_INITIALIZER_LISTS \
@ -21,8 +20,7 @@ defines += Q_QDOC \
Q_COMPILER_UNIFORM_INIT \
Q_COMPILER_RVALUE_REFS
clangdefines += __cplusplus \
Q_QDOC \
clangdefines += Q_QDOC \
Q_CLANG_QDOC \
QT_COMPAT \
QT3_SUPPORT \

View File

@ -48,7 +48,7 @@
\section1 MainWindow Class
\c MainWindow inherits QWidget, and is the application's main window defined in
\c mainwindow.ui. The style of \c MainWindow can be modified with \l StyleSheetEditor.
\c mainwindow.ui. The style of \c MainWindow can be modified with \c StyleSheetEditor.
\section1 StyleSheetEditor Class

File diff suppressed because it is too large Load Diff

View File

@ -115,15 +115,17 @@ extern "C" {
** a string which identifies a particular check-in of SQLite
** within its configuration management system. ^The SQLITE_SOURCE_ID
** string contains the date and time of the check-in (UTC) and a SHA1
** or SHA3-256 hash of the entire source tree.
** or SHA3-256 hash of the entire source tree. If the source code has
** been edited in any way since it was last checked in, then the last
** four hexadecimal digits of the hash may be modified.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.20.1"
#define SQLITE_VERSION_NUMBER 3020001
#define SQLITE_SOURCE_ID "2017-08-24 16:21:36 8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34"
#define SQLITE_VERSION "3.22.0"
#define SQLITE_VERSION_NUMBER 3022000
#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"
/*
** CAPI3REF: Run-Time Library Version Numbers
@ -139,7 +141,7 @@ extern "C" {
**
** <blockquote><pre>
** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
** </pre></blockquote>)^
**
@ -149,9 +151,11 @@ extern "C" {
** function is provided for use in DLLs since DLL users usually do not have
** direct access to string constants within the DLL. ^The
** sqlite3_libversion_number() function returns an integer equal to
** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns
** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns
** a pointer to a string constant whose value is the same as the
** [SQLITE_SOURCE_ID] C preprocessor macro.
** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built
** using an edited copy of [the amalgamation], then the last four characters
** of the hash might be different from [SQLITE_SOURCE_ID].)^
**
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
@ -432,7 +436,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_FULL 13 /* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
#define SQLITE_EMPTY 16 /* Not used */
#define SQLITE_EMPTY 16 /* Internal use only */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
@ -466,6 +470,8 @@ SQLITE_API int sqlite3_exec(
** the most recent error can be obtained using
** [sqlite3_extended_errcode()].
*/
#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
@ -494,6 +500,9 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
@ -506,6 +515,8 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@ -580,6 +591,11 @@ SQLITE_API int sqlite3_exec(
** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
** read-only media and cannot be changed even by processes with
** elevated privileges.
**
** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
** filesystem supports doing multiple write operations atomically when those
** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@ -595,6 +611,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
/*
** CAPI3REF: File Locking Levels
@ -729,6 +746,7 @@ struct sqlite3_file {
** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
** <li> [SQLITE_IOCAP_IMMUTABLE]
** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
** </ul>
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@ -1012,6 +1030,40 @@ struct sqlite3_io_methods {
** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for
** this opcode.
**
** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
** the file descriptor is placed in "batch write mode", which
** means all subsequent write operations will be deferred and done
** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems
** that do not support batch atomic writes will return SQLITE_NOTFOUND.
** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
** no VFS interface calls on the same [sqlite3_file] file descriptor
** except for calls to the xWrite method and the xFileControl method
** with [SQLITE_FCNTL_SIZE_HINT].
**
** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
** operations since the previous successful call to
** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
** This file control returns [SQLITE_OK] if and only if the writes were
** all performed successfully and have been committed to persistent storage.
** ^Regardless of whether or not it is successful, this file control takes
** the file descriptor out of batch write mode so that all subsequent
** write operations are independent.
** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
**
** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
** operations since the previous successful call to
** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
** ^This file control takes the file descriptor out of batch write mode
** so that all subsequent write operations are independent.
** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@ -1043,6 +1095,9 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_JOURNAL_POINTER 28
#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
#define SQLITE_FCNTL_PDB 30
#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@ -1080,12 +1135,18 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** in the name of the object stands for "virtual file system". See
** the [VFS | VFS documentation] for further information.
**
** The value of the iVersion field is initially 1 but may be larger in
** future versions of SQLite. Additional fields may be appended to this
** object when the iVersion value is increased. Note that the structure
** of the sqlite3_vfs object changes in the transaction between
** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
** modified.
** The VFS interface is sometimes extended by adding new methods onto
** the end. Each time such an extension occurs, the iVersion field
** is incremented. The iVersion value started out as 1 in
** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
** may be appended to the sqlite3_vfs object and the iVersion value
** may increase again in future versions of SQLite.
** Note that the structure
** of the sqlite3_vfs object changes in the transition from
** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
** and yet the iVersion field was not modified.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
** structure used by this VFS. mxPathname is the maximum length of
@ -1613,6 +1674,16 @@ struct sqlite3_mem_methods {
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
** type int, interpreted as a boolean, which if true provides a hint to
** SQLite that it should avoid large memory allocations if possible.
** SQLite will run faster if it is free to make large memory allocations,
** but some application might prefer to run slower in exchange for
** guarantees about memory fragmentation that are possible if large
** allocations are avoided. This hint is normally off.
** </dd>
**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
@ -1630,25 +1701,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
** that SQLite can use for scratch memory. ^(There are three arguments
** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte
** aligned memory buffer from which the scratch allocations will be
** drawn, the size of each scratch allocation (sz),
** and the maximum number of scratch allocations (N).)^
** The first argument must be a pointer to an 8-byte aligned buffer
** of at least sz*N bytes of memory.
** ^SQLite will not use more than one scratch buffers per thread.
** ^SQLite will never request a scratch buffer that is more than 6
** times the database page size.
** ^If SQLite needs needs additional
** scratch memory beyond what is provided by this configuration option, then
** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
** ^When the application provides any amount of scratch memory using
** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
** [sqlite3_malloc|heap allocations].
** This can help [Robson proof|prevent memory allocation failures] due to heap
** fragmentation in low-memory embedded systems.
** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
@ -1684,8 +1737,7 @@ struct sqlite3_mem_methods {
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
** that SQLite will use for all of its dynamic memory allocation needs
** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and
** [SQLITE_CONFIG_PAGECACHE].
** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
** [SQLITE_ERROR] if invoked otherwise.
@ -1878,7 +1930,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */
#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */
#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
@ -1899,6 +1951,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
/*
** CAPI3REF: Database Connection Configuration Options
@ -2006,7 +2059,6 @@ struct sqlite3_mem_methods {
** into which is written 0 or 1 to indicate whether checkpoints-on-close
** have been disabled - 0 if they are not disabled, 1 if they are.
** </dd>
**
** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
@ -2017,7 +2069,16 @@ struct sqlite3_mem_methods {
** the QPSG active, SQLite will always use the same query plan in the field as
** was used during testing in the lab.
** </dd>
**
** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
** include output for any operations performed by trigger programs. This
** option is used to set or clear (the default) a flag that governs this
** behavior. The first parameter passed to this operation is an integer -
** non-zero to enable output for trigger programs, or zero to disable it.
** The second parameter is a pointer to an integer into which is written
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
** it is not disabled, 1 if it is.
** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@ -2028,7 +2089,8 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
#define SQLITE_DBCONFIG_MAX 1008 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@ -2889,8 +2951,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** KEYWORDS: SQLITE_TRACE
**
** These constants identify classes of events that can be monitored
** using the [sqlite3_trace_v2()] tracing logic. The third argument
** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
** using the [sqlite3_trace_v2()] tracing logic. The M argument
** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
** the following constants. ^The first argument to the trace callback
** is one of the following constants.
**
@ -3099,10 +3161,10 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** ^If [URI filename] interpretation is enabled, and the filename argument
** begins with "file:", then the filename is interpreted as a URI. ^URI
** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
** set in the fourth argument to sqlite3_open_v2(), or if it has
** set in the third argument to sqlite3_open_v2(), or if it has
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
** As of SQLite version 3.7.7, URI filename interpretation is turned off
** URI filename interpretation is turned off
** by default, but future releases of SQLite might enable URI filename
** interpretation by default. See "[URI filenames]" for additional
** information.
@ -3776,8 +3838,9 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** implementation of [application-defined SQL functions] are protected.
** ^The sqlite3_value object returned by
** [sqlite3_column_value()] is unprotected.
** Unprotected sqlite3_value objects may only be used with
** [sqlite3_result_value()] and [sqlite3_bind_value()].
** Unprotected sqlite3_value objects may only be used as arguments
** to [sqlite3_result_value()], [sqlite3_bind_value()], and
** [sqlite3_value_dup()].
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
@ -4199,7 +4262,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]),
** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
@ -4735,6 +4798,9 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** datatype of the value
** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
** against a virtual table.
** </table></blockquote>
**
** <b>Details:</b>
@ -4783,6 +4849,19 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
** ^Within the [xUpdate] method of a [virtual table], the
** sqlite3_value_nochange(X) interface returns true if and only if
** the column corresponding to X is unchanged by the UPDATE operation
** that the xUpdate method call was invoked to implement and if
** and the prior [xColumn] method call that was invoked to extracted
** the value for that column returned without setting a result (probably
** because it queried [sqlite3_vtab_nochange()] and found that the column
** was unchanging). ^Within an [xUpdate] method, any value for which
** sqlite3_value_nochange(X) is true will in all other respects appear
** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
** than within an [xUpdate] method call for an UPDATE statement, then
** the return value is arbitrary and meaningless.
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
@ -4805,6 +4884,7 @@ SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@ -6203,15 +6283,20 @@ struct sqlite3_index_info {
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
#define SQLITE_INDEX_CONSTRAINT_LE 8
#define SQLITE_INDEX_CONSTRAINT_LT 16
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
#define SQLITE_INDEX_CONSTRAINT_EQ 2
#define SQLITE_INDEX_CONSTRAINT_GT 4
#define SQLITE_INDEX_CONSTRAINT_LE 8
#define SQLITE_INDEX_CONSTRAINT_LT 16
#define SQLITE_INDEX_CONSTRAINT_GE 32
#define SQLITE_INDEX_CONSTRAINT_MATCH 64
#define SQLITE_INDEX_CONSTRAINT_LIKE 65
#define SQLITE_INDEX_CONSTRAINT_GLOB 66
#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
#define SQLITE_INDEX_CONSTRAINT_NE 68
#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
#define SQLITE_INDEX_CONSTRAINT_IS 72
/*
** CAPI3REF: Register A Virtual Table Implementation
@ -6902,9 +6987,9 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** the xFileControl method. ^The return value of the xFileControl
** method becomes the return value of this routine.
**
** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
** a pointer to the underlying [sqlite3_file] object to be written into
** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER
** the space pointed to by the 4th parameter. ^The [SQLITE_FCNTL_FILE_POINTER]
** case is a short-circuit path which does not actually invoke the
** underlying sqlite3_io_methods.xFileControl method.
**
@ -6916,7 +7001,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** an incorrect zDbName and an SQLITE_ERROR return from the underlying
** xFileControl method.
**
** See also: [SQLITE_FCNTL_LOCKSTATE]
** See also: [file control opcodes]
*/
SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
@ -6963,7 +7048,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@ -6973,7 +7058,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ISINIT 23
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
#define SQLITE_TESTCTRL_LAST 25
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
/*
** CAPI3REF: SQLite Runtime Status
@ -7022,8 +7108,7 @@ SQLITE_API int sqlite3_status64(
** <dd>This parameter is the current amount of memory checked out
** using [sqlite3_malloc()], either directly or indirectly. The
** figure includes calls made to [sqlite3_malloc()] by the application
** and internal memory usage by the SQLite library. Scratch memory
** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
** and internal memory usage by the SQLite library. Auxiliary page-cache
** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
** this parameter. The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
@ -7061,29 +7146,14 @@ SQLITE_API int sqlite3_status64(
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
** <dd>This parameter returns the number of allocations used out of the
** [scratch memory allocator] configured using
** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
** in bytes. Since a single thread may only have one scratch allocation
** outstanding at time, this parameter also reports the number of threads
** using scratch memory at the same time.</dd>)^
** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
** <dd>This parameter returns the number of bytes of scratch memory
** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
** buffer and where forced to overflow to [sqlite3_malloc()]. The values
** returned include overflows because the requested allocation was too
** larger (that is, because the requested allocation was larger than the
** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
** slots were available.
** </dd>)^
** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
** handed to [scratch memory allocator]. Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>The *pHighwater parameter records the deepest parser stack.
@ -7096,12 +7166,12 @@ SQLITE_API int sqlite3_status64(
#define SQLITE_STATUS_MEMORY_USED 0
#define SQLITE_STATUS_PAGECACHE_USED 1
#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
#define SQLITE_STATUS_SCRATCH_USED 3
#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */
#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */
#define SQLITE_STATUS_MALLOC_SIZE 5
#define SQLITE_STATUS_PARSER_STACK 6
#define SQLITE_STATUS_PAGECACHE_SIZE 7
#define SQLITE_STATUS_SCRATCH_SIZE 8
#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
@ -8243,6 +8313,40 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
*/
SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
**
** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
** method of a [virtual table], then it returns true if and only if the
** column is being fetched as part of an UPDATE operation during which the
** column value will not change. Applications might use this to substitute
** a lighter-weight value to return that the corresponding [xUpdate] method
** understands as a "no-change" value.
**
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
** the column is not changed by the UPDATE statement, they the xColumn
** method can optionally return without setting a result, without calling
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
** In that case, [sqlite3_value_nochange(X)] will return true for the
** same column in the [xUpdate] method.
*/
SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
/*
** CAPI3REF: Determine The Collation For a Virtual Table Constraint
**
** This function may only be called from within a call to the [xBestIndex]
** method of a [virtual table].
**
** The first argument must be the sqlite3_index_info object that is the
** first parameter to the xBestIndex() method. The second argument must be
** an index into the aConstraint[] array belonging to the sqlite3_index_info
** structure passed to xBestIndex. This function returns a pointer to a buffer
** containing the name of the collation sequence for the corresponding
** constraint.
*/
SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
@ -8970,6 +9074,35 @@ SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect)
**
** SQLITE_OK is returned if the call completes without error. Or, if an error
** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
**
** <h3>Special sqlite_stat1 Handling</h3>
**
** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to
** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
** <pre>
** &nbsp; CREATE TABLE sqlite_stat1(tbl,idx,stat)
** </pre>
**
** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are
** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes
** are recorded for rows for which (idx IS NULL) is true. However, for such
** rows a zero-length blob (SQL value X'') is stored in the changeset or
** patchset instead of a NULL value. This allows such changesets to be
** manipulated by legacy implementations of sqlite3changeset_invert(),
** concat() and similar.
**
** The sqlite3changeset_apply() function automatically converts the
** zero-length blob back to a NULL value when updating the sqlite_stat1
** table. However, if the application calls sqlite3changeset_new(),
** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset
** iterator directly (including on a changeset iterator passed to a
** conflict-handler callback) then the X'' value is returned. The application
** must translate X'' to NULL itself if required.
**
** Legacy (older than 3.22.0) versions of the sessions module cannot capture
** changes made to the sqlite_stat1 table. Legacy versions of the
** sqlite3changeset_apply() function silently ignore any modifications to the
** sqlite_stat1 table that are part of a changeset or patchset.
*/
SQLITE_API int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
@ -9198,8 +9331,8 @@ SQLITE_API int sqlite3session_diff(
*/
SQLITE_API int sqlite3session_patchset(
sqlite3_session *pSession, /* Session object */
int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
void **ppPatchset /* OUT: Buffer containing changeset */
int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */
void **ppPatchset /* OUT: Buffer containing patchset */
);
/*
@ -9966,12 +10099,12 @@ SQLITE_API int sqlite3changeset_apply(
**
** <table border=1 style="margin-left:8ex;margin-right:8ex">
** <tr><th>Streaming function<th>Non-streaming equivalent</th>
** <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply]
** <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat]
** <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert]
** <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start]
** <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset]
** <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset]
** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply]
** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat]
** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert]
** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start]
** <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset]
** <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset]
** </table>
**
** Non-streaming functions that accept changesets (or patchsets) as input

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -152,6 +152,44 @@ static inline bool simdDecodeAscii(ushort *&dst, const uchar *&nextAscii, const
}
return src == end;
}
static inline const uchar *simdFindNonAscii(const uchar *src, const uchar *end, const uchar *&nextAscii)
{
// do sixteen characters at a time
for ( ; end - src >= 16; src += 16) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
// check if everything is ASCII
// movemask extracts the high bit of every byte, so n is non-zero if something isn't ASCII
uint n = _mm_movemask_epi8(data);
if (!n)
continue;
// find the next probable ASCII character
// we don't want to load 16 bytes again in this loop if we know there are non-ASCII
// characters still coming
nextAscii = src + qBitScanReverse(n) + 1;
// return the non-ASCII character
return src + qCountTrailingZeroBits(n);
}
// do four characters at a time
for ( ; end - src >= 4; src += 4) {
quint32 data = qFromUnaligned<quint32>(src);
data &= 0x80808080U;
if (!data)
continue;
// We don't try to guess which of the three bytes is ASCII and which
// one isn't. The chance that at least two of them are non-ASCII is
// better than 75%.
nextAscii = src;
return src;
}
nextAscii = end;
return src;
}
#elif defined(__ARM_NEON__) && defined(Q_PROCESSOR_ARM_64) // vaddv is only available on Aarch64
static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const ushort *&src, const ushort *end)
{
@ -220,6 +258,34 @@ static inline bool simdDecodeAscii(ushort *&dst, const uchar *&nextAscii, const
}
return src == end;
}
static inline const uchar *simdFindNonAscii(const uchar *src, const uchar *end, const uchar *&nextAscii)
{
// The SIMD code below is untested, so just force an early return until
// we've had the time to verify it works.
nextAscii = end;
return src;
// do eight characters at a time
uint8x8_t msb_mask = vdup_n_u8(0x80);
uint8x8_t add_mask = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 };
for ( ; end - src >= 8; src += 8) {
uint8x8_t c = vld1_u8(src);
uint8_t n = vaddv_u8(vand_u8(vcge_u8(c, msb_mask), add_mask));
if (!n)
continue;
// find the next probable ASCII character
// we don't want to load 16 bytes again in this loop if we know there are non-ASCII
// characters still coming
nextAscii = src + qBitScanReverse(n) + 1;
// return the non-ASCII character
return src + qCountTrailingZeroBits(n);
}
nextAscii = end;
return src;
}
#else
static inline bool simdEncodeAscii(uchar *, const ushort *, const ushort *, const ushort *)
{
@ -230,6 +296,12 @@ static inline bool simdDecodeAscii(ushort *, const uchar *, const uchar *, const
{
return false;
}
static inline const uchar *simdFindNonAscii(const uchar *src, const uchar *end, const uchar *&nextAscii)
{
nextAscii = end;
return src;
}
#endif
QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len)
@ -518,6 +590,95 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte
return result;
}
struct QUtf8NoOutputTraits : public QUtf8BaseTraitsNoAscii
{
struct NoOutput {};
static void appendUtf16(const NoOutput &, ushort) {}
static void appendUcs4(const NoOutput &, uint) {}
};
QUtf8::ValidUtf8Result QUtf8::isValidUtf8(const char *chars, qsizetype len)
{
const uchar *src = reinterpret_cast<const uchar *>(chars);
const uchar *end = src + len;
const uchar *nextAscii = src;
bool isValidAscii = true;
while (src < end) {
if (src >= nextAscii)
src = simdFindNonAscii(src, end, nextAscii);
if (src == end)
break;
do {
uchar b = *src++;
if ((b & 0x80) == 0)
continue;
isValidAscii = false;
QUtf8NoOutputTraits::NoOutput output;
int res = QUtf8Functions::fromUtf8<QUtf8NoOutputTraits>(b, output, src, end);
if (res < 0) {
// decoding error
return { false, false };
}
} while (src < nextAscii);
}
return { true, isValidAscii };
}
int QUtf8::compareUtf8(const char *utf8, qsizetype u8len, const QChar *utf16, int u16len)
{
uint uc1, uc2;
auto src1 = reinterpret_cast<const uchar *>(utf8);
auto end1 = src1 + u8len;
QStringIterator src2(utf16, utf16 + u16len);
while (src1 < end1 && src2.hasNext()) {
uchar b = *src1++;
uint *output = &uc1;
int res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(b, output, src1, end1);
if (res < 0) {
// decoding error
uc1 = QChar::ReplacementCharacter;
}
uc2 = src2.next();
if (uc1 != uc2)
return int(uc1) - int(uc2);
}
// the shorter string sorts first
return (end1 > src1) - int(src2.hasNext());
}
int QUtf8::compareUtf8(const char *utf8, qsizetype u8len, QLatin1String s)
{
uint uc1;
auto src1 = reinterpret_cast<const uchar *>(utf8);
auto end1 = src1 + u8len;
auto src2 = reinterpret_cast<const uchar *>(s.latin1());
auto end2 = src2 + s.size();
while (src1 < end1 && src2 < end2) {
uchar b = *src1++;
uint *output = &uc1;
int res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(b, output, src1, end1);
if (res < 0) {
// decoding error
uc1 = QChar::ReplacementCharacter;
}
uint uc2 = *src2++;
if (uc1 != uc2)
return int(uc1) - int(uc2);
}
// the shorter string sorts first
return (end1 > src1) - (end2 > src2);
}
QByteArray QUtf16::convertFromUnicode(const QChar *uc, int len, QTextCodec::ConverterState *state, DataEndianness e)
{
DataEndianness endian = e;

View File

@ -290,6 +290,13 @@ struct QUtf8
static QString convertToUnicode(const char *, int, QTextCodec::ConverterState *);
static QByteArray convertFromUnicode(const QChar *, int);
static QByteArray convertFromUnicode(const QChar *, int, QTextCodec::ConverterState *);
struct ValidUtf8Result {
bool isValidUtf8;
bool isValidAscii;
};
static ValidUtf8Result isValidUtf8(const char *, qsizetype);
static int compareUtf8(const char *, qsizetype, const QChar *, int);
static int compareUtf8(const char *, qsizetype, QLatin1String s);
};
struct QUtf16

View File

@ -3610,7 +3610,7 @@ bool qunsetenv(const char *varName)
*/
/*!
\fn template <typename T> qAsConst(T &t)
\fn template <typename T> typename std::add_const<T>::type &qAsConst(T &t)
\relates <QtGlobal>
\since 5.7
@ -3662,7 +3662,7 @@ bool qunsetenv(const char *varName)
*/
/*!
\fn template <typename T> qAsConst(const T &&t)
\fn template <typename T> void qAsConst(const T &&t)
\relates <QtGlobal>
\since 5.7
\overload

View File

@ -155,6 +155,7 @@ Q_NORETURN
#endif
static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const QString &message);
static void qt_message_print(QtMsgType, const QMessageLogContext &context, const QString &message);
static void qt_message_print(const QString &message);
static int checked_var_value(const char *varname)
{
@ -204,8 +205,6 @@ static bool willLogToConsole()
#if defined(Q_OS_WINRT)
// these systems have no stderr, so always log to the system log
return false;
#elif defined(QT_BOOTSTRAPPED)
return true;
#else
// rules to determine if we'll log preferably to the console:
// 1) if QT_LOGGING_TO_CONSOLE is set, it determines behavior:
@ -1214,20 +1213,10 @@ void QMessagePattern::setPattern(const QString &pattern)
error += QLatin1String("QT_MESSAGE_PATTERN: %{if-*} cannot be nested\n");
else if (inIf)
error += QLatin1String("QT_MESSAGE_PATTERN: missing %{endif}\n");
if (!error.isEmpty()) {
#if defined(Q_OS_WINRT)
OutputDebugString(reinterpret_cast<const wchar_t*>(error.utf16()));
if (0)
#elif defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
if (!qt_logging_to_console()) {
OutputDebugString(reinterpret_cast<const wchar_t*>(error.utf16()));
} else
#endif
{
fprintf(stderr, "%s", error.toLocal8Bit().constData());
fflush(stderr);
}
}
if (!error.isEmpty())
qt_message_print(error);
literals = new const char*[literalsVar.size() + 1];
literals[literalsVar.size()] = 0;
memcpy(literals, literalsVar.constData(), literalsVar.size() * sizeof(const char*));
@ -1255,7 +1244,7 @@ static QStringList backtraceFramesForLogMessage(int frameCount)
static QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"),
QRegularExpression::OptimizeOnFirstUsageOption);
QVarLengthArray<void*, 32> buffer(7 + frameCount);
QVarLengthArray<void*, 32> buffer(8 + frameCount);
int n = backtrace(buffer.data(), buffer.size());
if (n > 0) {
int numberPrinted = 0;
@ -1317,64 +1306,6 @@ static QString formatBacktraceForLogMessage(const QMessagePattern::BacktracePara
}
#endif // QLOGGING_HAVE_BACKTRACE && !QT_BOOTSTRAPPED
#if QT_CONFIG(slog2)
#ifndef QT_LOG_CODE
#define QT_LOG_CODE 9000
#endif
static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
if (!qt_logging_to_console())
return false;
QString formattedMessage = qFormatLogMessage(type, context, message);
formattedMessage.append(QLatin1Char('\n'));
if (slog2_set_default_buffer((slog2_buffer_t)-1) == 0) {
slog2_buffer_set_config_t buffer_config;
slog2_buffer_t buffer_handle;
buffer_config.buffer_set_name = __progname;
buffer_config.num_buffers = 1;
buffer_config.verbosity_level = SLOG2_DEBUG1;
buffer_config.buffer_config[0].buffer_name = "default";
buffer_config.buffer_config[0].num_pages = 8;
if (slog2_register(&buffer_config, &buffer_handle, 0) == -1) {
fprintf(stderr, "Error registering slogger2 buffer!\n");
fprintf(stderr, "%s", formattedMessage.toLocal8Bit().constData());
fflush(stderr);
return false;
}
// Set as the default buffer
slog2_set_default_buffer(buffer_handle);
}
int severity;
//Determines the severity level
switch (type) {
case QtDebugMsg:
severity = SLOG2_DEBUG1;
break;
case QtInfoMsg:
severity = SLOG2_INFO;
break;
case QtWarningMsg:
severity = SLOG2_NOTICE;
break;
case QtCriticalMsg:
severity = SLOG2_WARNING;
break;
case QtFatalMsg:
severity = SLOG2_ERROR;
break;
}
//writes to the slog2 buffer
slog2c(NULL, QT_LOG_CODE, severity, formattedMessage.toLocal8Bit().constData());
return false;
}
#endif // slog2
Q_GLOBAL_STATIC(QMessagePattern, qMessagePattern)
/*!
@ -1524,6 +1455,70 @@ static QBasicAtomicPointer<void (QtMsgType, const char*)> msgHandler = Q_BASIC_A
// pointer to QtMessageHandler debug handler (with context)
static QBasicAtomicPointer<void (QtMsgType, const QMessageLogContext &, const QString &)> messageHandler = Q_BASIC_ATOMIC_INITIALIZER(qDefaultMessageHandler);
// ------------------------ Alternate logging sinks -------------------------
#if defined(QT_BOOTSTRAPPED)
// Boostrapped tools always print to stderr, so no need for alternate sinks
#else
#if QT_CONFIG(slog2)
#ifndef QT_LOG_CODE
#define QT_LOG_CODE 9000
#endif
static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
if (qt_logging_to_console())
return false;
QString formattedMessage = qFormatLogMessage(type, context, message);
formattedMessage.append(QLatin1Char('\n'));
if (slog2_set_default_buffer((slog2_buffer_t)-1) == 0) {
slog2_buffer_set_config_t buffer_config;
slog2_buffer_t buffer_handle;
buffer_config.buffer_set_name = __progname;
buffer_config.num_buffers = 1;
buffer_config.verbosity_level = SLOG2_DEBUG1;
buffer_config.buffer_config[0].buffer_name = "default";
buffer_config.buffer_config[0].num_pages = 8;
if (slog2_register(&buffer_config, &buffer_handle, 0) == -1) {
fprintf(stderr, "Error registering slogger2 buffer!\n");
fprintf(stderr, "%s", formattedMessage.toLocal8Bit().constData());
fflush(stderr);
return false;
}
// Set as the default buffer
slog2_set_default_buffer(buffer_handle);
}
int severity;
//Determines the severity level
switch (type) {
case QtDebugMsg:
severity = SLOG2_DEBUG1;
break;
case QtInfoMsg:
severity = SLOG2_INFO;
break;
case QtWarningMsg:
severity = SLOG2_NOTICE;
break;
case QtCriticalMsg:
severity = SLOG2_WARNING;
break;
case QtFatalMsg:
severity = SLOG2_ERROR;
break;
}
//writes to the slog2 buffer
slog2c(NULL, QT_LOG_CODE, severity, formattedMessage.toLocal8Bit().constData());
return true; // Prevent further output to stderr
}
#endif // slog2
#if QT_CONFIG(journald)
static bool systemd_default_message_handler(QtMsgType type,
const QMessageLogContext &context,
@ -1561,7 +1556,7 @@ static bool systemd_default_message_handler(QtMsgType type,
"QT_CATEGORY=%s", context.category ? context.category : "unknown",
NULL);
return false;
return true; // Prevent further output to stderr
}
#endif
@ -1594,7 +1589,7 @@ static bool syslog_default_message_handler(QtMsgType type, const QMessageLogCont
syslog(priority, "%s", formattedMessage.toUtf8().constData());
return false;
return true; // Prevent further output to stderr
}
#endif
@ -1621,7 +1616,7 @@ static bool android_default_message_handler(QtMsgType type,
"%s:%d (%s): %s\n", context.file, context.line,
context.function, qPrintable(formattedMessage));
return false;
return true; // Prevent further output to stderr
}
#endif //Q_OS_ANDROID
@ -1634,10 +1629,28 @@ static bool win_message_handler(QtMsgType type, const QMessageLogContext &contex
QString formattedMessage = qFormatLogMessage(type, context, message);
formattedMessage.append(QLatin1Char('\n'));
OutputDebugString(reinterpret_cast<const wchar_t *>(formattedMessage.utf16()));
return false;
return true; // Prevent further output to stderr
}
#endif
#endif // Bootstrap check
// --------------------------------------------------------------------------
static void stderr_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message)
{
QString formattedMessage = qFormatLogMessage(type, context, message);
// print nothing if message pattern didn't apply / was empty.
// (still print empty lines, e.g. because message itself was empty)
if (formattedMessage.isNull())
return;
fprintf(stderr, "%s\n", formattedMessage.toLocal8Bit().constData());
fflush(stderr);
}
/*!
\internal
*/
@ -1652,30 +1665,22 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
// In the future, if we allow multiple/dynamic sinks, this will be iterating
// a list of sinks.
#if defined(Q_OS_WIN)
#if !defined(QT_BOOTSTRAPPED)
# if defined(Q_OS_WIN)
handledStderr |= win_message_handler(type, context, message);
#elif QT_CONFIG(slog2)
# elif QT_CONFIG(slog2)
handledStderr |= slog2_default_handler(type, context, message);
#elif QT_CONFIG(journald)
# elif QT_CONFIG(journald)
handledStderr |= systemd_default_message_handler(type, context, message);
#elif QT_CONFIG(syslog)
# elif QT_CONFIG(syslog)
handledStderr |= syslog_default_message_handler(type, context, message);
#elif defined(Q_OS_ANDROID)
# elif defined(Q_OS_ANDROID)
handledStderr |= android_default_message_handler(type, context, message);
# endif
#endif
if (handledStderr || !qt_logging_to_console())
return;
QString formattedMessage = qFormatLogMessage(type, context, message);
// print nothing if message pattern didn't apply / was empty.
// (still print empty lines, e.g. because message itself was empty)
if (formattedMessage.isNull())
return;
fprintf(stderr, "%s\n", formattedMessage.toLocal8Bit().constData());
fflush(stderr);
if (!handledStderr)
stderr_message_handler(type, context, message);
}
/*!
@ -1738,6 +1743,21 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex
}
}
static void qt_message_print(const QString &message)
{
#if defined(Q_OS_WINRT)
OutputDebugString(reinterpret_cast<const wchar_t*>(message.utf16()));
return;
#elif defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED)
if (!qt_logging_to_console()) {
OutputDebugString(reinterpret_cast<const wchar_t*>(message.utf16()));
return;
}
#endif
fprintf(stderr, "%s", message.toLocal8Bit().constData());
fflush(stderr);
}
static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const QString &message)
{
#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)

View File

@ -1406,6 +1406,9 @@ public:
ImhMultiLine = 0x400,
ImhNoEditMenu = 0x800,
ImhNoTextHandles = 0x1000,
ImhDigitsOnly = 0x10000,
ImhFormattedNumbersOnly = 0x20000,
ImhUppercaseOnly = 0x40000,

View File

@ -993,12 +993,7 @@
\value WA_LayoutUsesWidgetRect Ignore the layout item rect from the style
when laying out this widget with QLayout.
\value WA_MacNoClickThrough When a widget that has this attribute set
is clicked, and its window is inactive, the click will make the window
active but won't be seen by the widget. Typical use of this attribute
is on widgets with "destructive" actions, such as a "Delete" button.
WA_MacNoClickThrough also applies to all child widgets of the widget
that has it set.
\value WA_MacNoClickThrough This value is obsolete and has no effect.
\value WA_MacOpaqueSizeGrip Indicates that the native Carbon size grip
should be opaque instead of transparent (the default). This attribute
@ -1027,9 +1022,7 @@
alternative sizes for widgets to avoid clipping.
This attribute is only applicable to \macos.
\value WA_MacBrushedMetal Indicates the widget should be drawn in
the brushed metal style as supported by the windowing system. This
attribute is only applicable to \macos.
\value WA_MacBrushedMetal This value is obsolete and has no effect.
\omitvalue WA_MacMetalStyle
@ -1284,9 +1277,7 @@
has no effect on non-X11 platforms. \b Note: Qt automatically sets this
attribute on the feedback widget used during a drag.
\value WA_MacFrameworkScaled Enables resolution independence aware mode
on Mac when using Carbon. This attribute has no effect on Cocoa.
The attribute is off by default and can be enabled on a per-window basis.
\value WA_MacFrameworkScaled This value is obsolete and has no effect.
\value WA_AcceptTouchEvents Allows touch events (see QTouchEvent)
to be sent to the widget. Must be set on all widgets that can
@ -2160,7 +2151,7 @@
with a somewhat lighter frame. It can also be
combined with Qt::FramelessWindowHint.
On \macos, tool windows correspond to the
\l{http://developer.apple.com/documentation/Carbon/Conceptual/HandlingWindowsControls/hitb-wind_cont_concept/chapter_2_section_2.html}{Floating}
\l{https://developer.apple.com/documentation/appkit/nspanel}{NSPanel}
class of windows. This means that the window lives on a
level above normal windows making it impossible to put a normal
window on top of it. By default, tool windows will disappear
@ -2595,6 +2586,9 @@
\value ImhMultiLine Multiple lines can be entered into the text field.
\value ImhNoEditMenu Do not use built-in edit menu. This flag was introduced in Qt 5.11.
\value ImhNoTextHandles Do not use built-in text cursor and selection handles. This flag was introduced in Qt 5.11.
Flags that restrict input (exclusive flags):
\value ImhDigitsOnly Only digits are allowed.

View File

@ -440,10 +440,10 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok)
*str = v_cast<QDate>(d)->toString(Qt::ISODate);
break;
case QVariant::Time:
*str = v_cast<QTime>(d)->toString(Qt::ISODate);
*str = v_cast<QTime>(d)->toString(Qt::ISODateWithMs);
break;
case QVariant::DateTime:
*str = v_cast<QDateTime>(d)->toString(Qt::ISODate);
*str = v_cast<QDateTime>(d)->toString(Qt::ISODateWithMs);
break;
#endif
case QVariant::Bool:

View File

@ -83,21 +83,27 @@ bool _q_fromHex(const char *&src, Integral &value)
return true;
}
static char *_q_uuidToHex(const QUuid &uuid, char *dst)
static char *_q_uuidToHex(const QUuid &uuid, char *dst, QUuid::StringFormat mode = QUuid::WithBraces)
{
*dst++ = '{';
if ((mode & QUuid::WithoutBraces) == 0)
*dst++ = '{';
_q_toHex(dst, uuid.data1);
*dst++ = '-';
if ((mode & QUuid::Id128) != QUuid::Id128)
*dst++ = '-';
_q_toHex(dst, uuid.data2);
*dst++ = '-';
if ((mode & QUuid::Id128) != QUuid::Id128)
*dst++ = '-';
_q_toHex(dst, uuid.data3);
*dst++ = '-';
if ((mode & QUuid::Id128) != QUuid::Id128)
*dst++ = '-';
for (int i = 0; i < 2; i++)
_q_toHex(dst, uuid.data4[i]);
*dst++ = '-';
if ((mode & QUuid::Id128) != QUuid::Id128)
*dst++ = '-';
for (int i = 2; i < 8; i++)
_q_toHex(dst, uuid.data4[i]);
*dst++ = '}';
if ((mode & QUuid::WithoutBraces) == 0)
*dst++ = '}';
return dst;
}
@ -304,6 +310,22 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
and null UUIDs return true from isNull().
*/
/*!
\enum QUuid::StringFormat
\since 5.11
This enum is used by toString(StringFormat) to control the formatting of the
string representation. The possible values are:
\value WithBraces The default, toString() will return five hex fields, separated by
dashes and surrounded by braces. Example:
{00000000-0000-0000-0000-000000000000}.
\value WithoutBraces Only the five dash-separated fields, without the braces. Example:
00000000-0000-0000-0000-000000000000.
\value Id128 Only the hex digits, without braces or dashes. Note that QUuid
cannot parse this back again as input.
*/
/*!
\fn QUuid::QUuid(const GUID &guid)
@ -589,6 +611,47 @@ QString QUuid::toString() const
return QString::fromLatin1(latin1, MaxStringUuidLength);
}
/*!
\since 5.11
Returns the string representation of this QUuid, with the formattiong
controlled by the \a mode parameter. From left to right, the five hex
fields are obtained from the four public data members in QUuid as follows:
\table
\header
\li Field #
\li Source
\row
\li 1
\li data1
\row
\li 2
\li data2
\row
\li 3
\li data3
\row
\li 4
\li data4[0] .. data4[1]
\row
\li 5
\li data4[2] .. data4[7]
\endtable
*/
QString QUuid::toString(QUuid::StringFormat mode) const
{
char latin1[MaxStringUuidLength];
const auto end = _q_uuidToHex(*this, latin1, mode);
return QString::fromLatin1(latin1, end - latin1);
}
/*!
Returns the binary representation of this QUuid. The byte array is
formatted as five hex fields separated by '-' and enclosed in
@ -634,6 +697,48 @@ QByteArray QUuid::toByteArray() const
return result;
}
/*!
\since 5.11
Returns the string representation of this QUuid, with the formattiong
controlled by the \a mode parameter. From left to right, the five hex
fields are obtained from the four public data members in QUuid as follows:
\table
\header
\li Field #
\li Source
\row
\li 1
\li data1
\row
\li 2
\li data2
\row
\li 3
\li data3
\row
\li 4
\li data4[0] .. data4[1]
\row
\li 5
\li data4[2] .. data4[7]
\endtable
*/
QByteArray QUuid::toByteArray(QUuid::StringFormat mode) const
{
QByteArray result(MaxStringUuidLength, Qt::Uninitialized);
const auto end = _q_uuidToHex(*this, const_cast<char*>(result.constData()), mode);
result.resize(end - result.constData());
return result;
}
/*!
Returns the binary representation of this QUuid. The byte array is in big
endian format, and formatted according to RFC 4122, section 4.1.2 -

View File

@ -85,7 +85,14 @@ public:
Sha1 = 5 // 0 1 0 1
};
enum StringFormat {
WithBraces = 0,
WithoutBraces = 1,
Id128 = 3
};
#if defined(Q_COMPILER_UNIFORM_INIT) && !defined(Q_CLANG_QDOC)
Q_DECL_CONSTEXPR QUuid() Q_DECL_NOTHROW : data1(0), data2(0), data3(0), data4{0,0,0,0,0,0,0,0} {}
Q_DECL_CONSTEXPR QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3,
@ -121,8 +128,10 @@ public:
static QUuid fromString(QLatin1String string) Q_DECL_NOTHROW;
QUuid(const char *);
QString toString() const;
QString toString(StringFormat mode) const; // ### Qt6: merge with previous
QUuid(const QByteArray &);
QByteArray toByteArray() const;
QByteArray toByteArray(StringFormat mode) const; // ### Qt6: merge with previous
QByteArray toRfc4122() const;
static QUuid fromRfc4122(const QByteArray &);
bool isNull() const Q_DECL_NOTHROW;

View File

@ -516,7 +516,9 @@
Typedef for \c{std::reverse_iterator<T*>}. Provided for STL compatibility.
*/
/*! \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::prepend(const T &value)
/*!
\fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::prepend(const T &value)
\fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::prepend(T &&value)
\since 4.8
Inserts \a value at the beginning of the array.
@ -533,13 +535,6 @@
\sa append(), insert()
*/
/*!
\fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::prepend(T &&value)
\since 5.11
\overload
*/
/*! \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::replace(int i, const T &value)
\since 4.8
@ -703,7 +698,9 @@
before the call.
*/
/*! \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::insert(int i, const T &value)
/*!
\fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::insert(int i, const T &value)
\fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::insert(int i, T &&value)
\since 4.8
Inserts \a value at index position \a i in the array. If \a i is
@ -728,15 +725,8 @@
vector.
*/
/*! \fn template<class T, int Prealloc> void QVarLengthArray<T, Prealloc>::insert(int i, T &&value)
\overload
\since 5.11
*/
/*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, const T &value)
\fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, T &&value)
\overload
\since 4.8
@ -745,12 +735,6 @@
\a before. Returns an iterator pointing at the inserted item.
*/
/*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, T &&value)
\overload
\since 5.11
*/
/*! \fn template<class T, int Prealloc> QVarLengthArray<T, Prealloc>::iterator QVarLengthArray<T, Prealloc>::insert(const_iterator before, int count, const T &value)
\since 4.8

View File

@ -72,7 +72,7 @@ public:
inline QVector(const QVector<T> &v);
inline ~QVector() { if (!d->ref.deref()) freeData(d); }
QVector<T> &operator=(const QVector<T> &v);
#ifdef Q_COMPILER_RVALUE_REFS
#if defined(Q_COMPILER_RVALUE_REFS) || defined(Q_CLANG_QDOC)
QVector(QVector<T> &&other) Q_DECL_NOTHROW : d(other.d) { other.d = Data::sharedNull(); }
QVector<T> &operator=(QVector<T> &&other) Q_DECL_NOTHROW
{ QVector moved(std::move(other)); swap(moved); return *this; }
@ -133,7 +133,7 @@ public:
T &operator[](int i);
const T &operator[](int i) const;
void append(const T &t);
#ifdef Q_COMPILER_RVALUE_REFS
#if defined(Q_COMPILER_RVALUE_REFS) || defined(Q_CLANG_QDOC)
void append(T &&t);
#endif
inline void append(const QVector<T> &l) { *this += l; }
@ -201,7 +201,7 @@ public:
typedef typename Data::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
#if !defined(QT_STRICT_ITERATORS) || defined(Q_QDOC)
#if !defined(QT_STRICT_ITERATORS) || defined(Q_CLANG_QDOC)
inline iterator begin() { detach(); return d->begin(); }
inline const_iterator begin() const Q_DECL_NOTHROW { return d->constBegin(); }
inline const_iterator cbegin() const Q_DECL_NOTHROW { return d->constBegin(); }
@ -258,7 +258,7 @@ public:
typedef const_iterator ConstIterator;
typedef int size_type;
inline void push_back(const T &t) { append(t); }
#ifdef Q_COMPILER_RVALUE_REFS
#if defined(Q_COMPILER_RVALUE_REFS) || defined(Q_CLANG_QDOC)
void push_back(T &&t) { append(std::move(t)); }
void push_front(T &&t) { prepend(std::move(t)); }
#endif

View File

@ -587,7 +587,9 @@
*/
/*! \fn template <typename T> void QVector<T>::prepend(const T &value)
/*!
\fn template <typename T> void QVector<T>::prepend(const T &value)
\fn template <typename T> void QVector<T>::prepend(T &&value)
Inserts \a value at the beginning of the vector.
@ -605,17 +607,8 @@
\sa append(), insert()
*/
/*!
\fn template <typename T> void QVector<T>::prepend(T &&value)
\since 5.11
\overload
Inserts \a value at the beginning of the vector using move semantics.
*/
/*! \fn template <typename T> void QVector<T>::insert(int i, const T &value)
\fn template <typename T> void QVector<T>::insert(int i, T &&value)
Inserts \a value at index position \a i in the vector. If \a i is
0, the value is prepended to the vector. If \a i is size(), the
@ -633,14 +626,6 @@
\sa append(), prepend(), remove()
*/
/*! \fn template <typename T> void QVector<T>::insert(int i, T &&value)
\since 5.11
\overload
Inserts \a value at index position \a i in the vector using move semantics.
*/
/*! \fn template <typename T> void QVector<T>::insert(int i, int count, const T &value)
\overload
@ -652,7 +637,9 @@
\snippet code/src_corelib_tools_qvector.cpp 10
*/
/*! \fn template <typename T> QVector<T>::iterator QVector<T>::insert(iterator before, const T &value)
/*!
\fn template <typename T> QVector<T>::iterator QVector<T>::insert(iterator before, const T &value)
\fn template <typename T> QVector<T>::iterator QVector<T>::insert(iterator before, T &&value)
\overload
@ -1102,17 +1089,14 @@
\overload
*/
/*! \fn template <typename T> void QVector<T>::push_front(const T &value)
/*!
\fn template <typename T> void QVector<T>::push_front(const T &value)
\fn template <typename T> void QVector<T>::push_front(T &&value)
This function is provided for STL compatibility. It is equivalent
to prepend(\a value).
*/
/*! \fn template <typename T> void QVector<T>::push_front(T &&value)
\since 5.11
\overload
*/
/*! \fn template <typename T> void QVector<T>::pop_front()
This function is provided for STL compatibility. It is equivalent

View File

@ -2283,6 +2283,8 @@ void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfa
void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *wse)
{
if (QWindow *window = wse->window.data()) {
if (window->screen() == wse->screen.data())
return;
if (window->isTopLevel()) {
if (QScreen *screen = wse->screen.data())
window->d_func()->setTopLevelScreen(screen, false /* recreate */);

View File

@ -42,7 +42,7 @@
#include <qpa/qplatformtheme.h>
#include "private/qguiapplication_p.h"
#ifndef QT_NO_SHORTCUT
#if !defined(QT_NO_SHORTCUT) || defined(Q_CLANG_QDOC)
#include "qdebug.h"
#include <QtCore/qhashfunctions.h>
@ -62,7 +62,7 @@
QT_BEGIN_NAMESPACE
#if defined(Q_OS_MACX)
#if defined(Q_OS_MACOS) || defined(Q_CLANG_QDOC)
static bool qt_sequence_no_mnemonics = true;
struct MacSpecialKey {
int key;

View File

@ -47,19 +47,19 @@
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SHORTCUT
#if !defined(QT_NO_SHORTCUT) || defined(Q_CLANG_QDOC)
class QKeySequence;
/*****************************************************************************
QKeySequence stream functions
*****************************************************************************/
#ifndef QT_NO_DATASTREAM
#if !defined(QT_NO_DATASTREAM) || defined(Q_CLANG_QDOC)
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &in, const QKeySequence &ks);
Q_GUI_EXPORT QDataStream &operator>>(QDataStream &out, QKeySequence &ks);
#endif
#ifdef Q_CLANG_QDOC
#if defined(Q_CLANG_QDOC)
void qt_set_sequence_auto_mnemonic(bool b);
#endif
@ -225,7 +225,7 @@ public:
Q_DECLARE_SHARED(QKeySequence)
#ifndef QT_NO_DEBUG_STREAM
#if !defined(QT_NO_DEBUG_STREAM) || defined(Q_CLANG_QDOC)
Q_GUI_EXPORT QDebug operator<<(QDebug, const QKeySequence &);
#endif

View File

@ -474,6 +474,25 @@ bool QPlatformWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
return false;
}
/*!
Reimplement this method to start a system move operation if
the system supports it and return true to indicate success.
The \a pos is a position of MouseButtonPress event or TouchBegin
event from a sequence of mouse events that triggered the movement.
It must be specified in window coordinates.
The default implementation is empty and does nothing with \a pos.
\since 5.11
*/
bool QPlatformWindow::startSystemMove(const QPoint &pos)
{
Q_UNUSED(pos)
return false;
}
/*!
Reimplement this method to set whether frame strut events
should be sent to \a enabled.

View File

@ -129,6 +129,7 @@ public:
virtual void windowEvent(QEvent *event);
virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner);
virtual bool startSystemMove(const QPoint &pos);
virtual void setFrameStrutEventsEnabled(bool enabled);
virtual bool frameStrutEventsEnabled() const;

View File

@ -98,6 +98,15 @@ public:
return func && func(screen, id, position);
}
typedef bool (*Vsp2SetLayerAlphaType)(const QScreen *screen, int id, qreal alpha);
static QByteArray vsp2SetLayerAlphaTypeIdentifier() { return QByteArrayLiteral("EglFSVsp2SetLayerAlpha"); }
static bool vsp2SetLayerAlpha(const QScreen *screen, int id, qreal alpha)
{
auto func = reinterpret_cast<Vsp2SetLayerAlphaType>(QGuiApplication::platformFunction(vsp2SetLayerAlphaTypeIdentifier()));
return func && func(screen, id, alpha);
}
typedef void (*Vsp2AddBlendListenerType)(const QScreen *screen, void(*callback)());
static QByteArray vsp2AddBlendListenerTypeIdentifier() { return QByteArrayLiteral("EglFSVsp2AddBlendListener"); }

View File

@ -47,10 +47,12 @@
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
QT_BEGIN_NAMESPACE

View File

@ -51,10 +51,12 @@
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
QT_BEGIN_NAMESPACE

View File

@ -686,9 +686,11 @@ static CTFontUIFontType fontTypeFromTheme(QPlatformTheme::Font f)
return kCTFontUIFontWindowTitle;
case QPlatformTheme::MdiSubWindowTitleFont:
case QPlatformTheme::DockWidgetTitleFont:
return kCTFontUIFontSystem;
case QPlatformTheme::DockWidgetTitleFont:
return kCTFontUIFontSmallSystem;
case QPlatformTheme::PushButtonFont:
return kCTFontUIFontPushButton;

View File

@ -133,6 +133,8 @@ QFunctionPointer QEglFSKmsVsp2Integration::platformFunction(const QByteArray &fu
return QFunctionPointer(setLayerBufferStatic);
if (function == QEglFSFunctions::vsp2SetLayerPositionTypeIdentifier())
return QFunctionPointer(setLayerPositionStatic);
if (function == QEglFSFunctions::vsp2SetLayerAlphaTypeIdentifier())
return QFunctionPointer(setLayerAlphaStatic);
if (function == QEglFSFunctions::vsp2AddBlendListenerTypeIdentifier())
return QFunctionPointer(addBlendListenerStatic);
@ -184,6 +186,12 @@ void QEglFSKmsVsp2Integration::setLayerPositionStatic(const QScreen *screen, int
vsp2Screen->setLayerPosition(id, position);
}
void QEglFSKmsVsp2Integration::setLayerAlphaStatic(const QScreen *screen, int id, qreal alpha)
{
auto vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen->handle());
vsp2Screen->setLayerAlpha(id, alpha);
}
void QEglFSKmsVsp2Integration::addBlendListenerStatic(const QScreen *screen, void(*callback)())
{
auto vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen->handle());

View File

@ -72,6 +72,7 @@ private:
static bool removeLayerStatic(const QScreen *screen, int id);
static void setLayerBufferStatic(const QScreen *screen, int id, int dmabufFd);
static void setLayerPositionStatic(const QScreen *screen, int id, const QPoint &position);
static void setLayerAlphaStatic(const QScreen *screen, int id, qreal alpha);
static void addBlendListenerStatic(const QScreen *screen, void(*callback)());
};

View File

@ -186,6 +186,12 @@ void QEglFSKmsVsp2Screen::setLayerPosition(int id, const QPoint &position)
m_blendDevice->setInputPosition(layerIndex, position);
}
void QEglFSKmsVsp2Screen::setLayerAlpha(int id, qreal alpha)
{
int layerIndex = id;
m_blendDevice->setInputAlpha(layerIndex, alpha);
}
bool QEglFSKmsVsp2Screen::removeLayer(int id)
{
int layerIndex = id;

View File

@ -65,6 +65,7 @@ public:
int addLayer(int dmabufFd, const QSize &size, const QPoint &position, uint drmPixelFormat, uint bytesPerLine);
void setLayerBuffer(int id, int dmabufFd);
void setLayerPosition(int id, const QPoint &position);
void setLayerAlpha(int id, qreal alpha);
bool removeLayer(int id);
void addBlendListener(void (*callback)());

View File

@ -533,6 +533,14 @@ bool QLinuxMediaDevice::OutputSubDevice::streamOff()
return QLinuxMediaDevice::streamOff(m_subdevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
}
int QLinuxMediaDevice::openVideoDevice(media_pad *pad)
{
const char *deviceName = media_entity_get_devname(pad->entity);
int fd = open(deviceName, O_RDWR);
qCDebug(qLcEglfsKmsDebug) << "Opened video device:" << deviceName << "with fd" << fd;
return fd;
}
bool QLinuxMediaDevice::setSubdevFormat(struct media_pad *pad, const QSize &size, uint32_t mbusFormat)
{
Q_ASSERT(size.isValid());
@ -556,6 +564,18 @@ bool QLinuxMediaDevice::setSubdevFormat(struct media_pad *pad, const QSize &size
return true;
}
bool QLinuxMediaDevice::setSubdevAlpha(int subdevFd, qreal alpha)
{
struct v4l2_control control;
control.id = V4L2_CID_ALPHA_COMPONENT;
control.value = static_cast<__s32>(alpha * 0xff);
if (ioctl(subdevFd, VIDIOC_S_CTRL, &control) == -1) {
qErrnoWarning("Setting alpha (%d) failed", control.value);
return false;
}
return true;
}
bool QLinuxMediaDevice::setSubdevSelection(struct media_pad *pad, const QRect &geometry, uint target)
{
Q_ASSERT(geometry.isValid());

View File

@ -95,7 +95,10 @@ public:
int m_subdevFd = -1;
};
static int openVideoDevice(media_pad *pad);
static bool setSubdevFormat(struct media_pad *pad, const QSize &size, uint32_t mbusFormat = MEDIA_BUS_FMT_ARGB8888_1X32);
static bool setSubdevAlpha(int subdevFd, qreal alpha);
static bool setSubdevSelection(struct media_pad *pad, const QRect &geometry, uint target);
static bool setSubdevCrop(struct media_pad *pad, const QRect &geometry);

View File

@ -99,6 +99,7 @@ QVsp2BlendingDevice::QVsp2BlendingDevice(const QSize &screenSize)
input.linkToBru = md.parseLink(QString("'%1 rpf.%2':1 -> '%1 bru':%2").arg(deviceName).arg(i));
input.inputFormatPad = md.parsePad(QString("'%1 rpf.%2':0").arg(deviceName).arg(i));
input.outputFormatPad = md.parsePad(QString("'%1 rpf.%2':1").arg(deviceName).arg(i));
input.outputFormatFd = QLinuxMediaDevice::openVideoDevice(input.outputFormatPad);
input.bruInputFormatPad = md.parsePad(QString("'%1 bru':%2").arg(deviceName).arg(i));
input.rpfInput = new QLinuxMediaDevice::OutputSubDevice(&md, QString("%1 rpf.%2 input").arg(deviceName).arg(i));
m_inputs.append(input);
@ -202,6 +203,17 @@ bool QVsp2BlendingDevice::setInputPosition(int index, const QPoint &position)
return QLinuxMediaDevice::setSubdevCompose(input.bruInputFormatPad, input.geometry);
}
bool QVsp2BlendingDevice::setInputAlpha(int index, qreal alpha)
{
Input &input = m_inputs[index];
if (input.alpha == alpha)
return true;
m_dirty = true;
input.alpha = alpha;
return QLinuxMediaDevice::setSubdevAlpha(input.outputFormatFd, alpha);
}
bool QVsp2BlendingDevice::blend(int outputDmabufFd)
{
if (!m_dirty)
@ -239,6 +251,8 @@ bool QVsp2BlendingDevice::blend(int outputDmabufFd)
if (!m_wpfOutput->dequeueBuffer()) {
qWarning() << "Vsp2: Failed to dequeue blending output buffer";
if (!streamOff())
qWarning() << "Vsp2: Failed to stop streaming when recovering after a broken blend.";
return false;
}
@ -272,19 +286,12 @@ bool QVsp2BlendingDevice::streamOn()
bool QVsp2BlendingDevice::streamOff()
{
if (!m_wpfOutput->streamOff()) {
//TODO: perhaps it's better to try to continue with the other inputs?
return false;
}
bool succeeded = m_wpfOutput->streamOff();
for (auto &input : m_inputs) {
if (input.enabled) {
if (!input.rpfInput->streamOff())
return false;
}
if (input.enabled)
succeeded &= input.rpfInput->streamOff();
}
return true;
return succeeded;
}
bool QVsp2BlendingDevice::setInputFormat(int i, const QRect &bufferGeometry, uint pixelFormat, uint bytesPerLine)

View File

@ -59,6 +59,7 @@ public:
bool disableInput(int i);
bool setInputBuffer(int index, int dmabufFd);
bool setInputPosition(int index, const QPoint &position);
bool setInputAlpha(int index, qreal alpha);
bool blend(int outputDmabufFd);
int numInputs() const;
bool isDirty() const { return m_dirty; }
@ -71,6 +72,7 @@ private:
struct Input {
bool enabled = false;
QRect geometry;
qreal alpha = 1;
struct {
int fd = -1;
uint bytesUsed = 0;
@ -79,6 +81,7 @@ private:
struct media_link *linkToBru = nullptr; //rpf.x:1 -> bru:x
struct media_pad *inputFormatPad = nullptr; // rpf.x:0
struct media_pad *outputFormatPad = nullptr; // rpf.x:1
int outputFormatFd = -1; // rpf.x:1 (again, because v4l2_subdev_* doesn't have a way to set alpha)
struct media_pad *bruInputFormatPad = nullptr; // bru:x
QLinuxMediaDevice::OutputSubDevice *rpfInput = nullptr; // rpf.x input
};

View File

@ -520,7 +520,7 @@ public:
void xi2UpdateScrollingDevices();
#endif
#ifdef XCB_USE_XINPUT22
bool startSystemResizeForTouchBegin(xcb_window_t window, const QPoint &point, Qt::Corner corner);
bool startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner);
bool isTouchScreen(int id);
#endif
#endif
@ -673,12 +673,12 @@ private:
#if QT_CONFIG(xinput2)
QHash<int, TouchDeviceData> m_touchDevices;
#ifdef XCB_USE_XINPUT22
struct StartSystemResizeInfo {
struct StartSystemMoveResizeInfo {
xcb_window_t window = XCB_NONE;
uint16_t deviceid;
uint32_t pointid;
Qt::Corner corner;
} m_startSystemResizeInfo;
int corner;
} m_startSystemMoveResizeInfo;
#endif
#endif
WindowMapper m_mapper;

View File

@ -784,15 +784,15 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
}
if (dev->qtTouchDevice->type() == QTouchDevice::TouchScreen &&
xiDeviceEvent->event == m_startSystemResizeInfo.window &&
xiDeviceEvent->sourceid == m_startSystemResizeInfo.deviceid &&
xiDeviceEvent->detail == m_startSystemResizeInfo.pointid) {
QXcbWindow *window = platformWindowFromId(m_startSystemResizeInfo.window);
xiDeviceEvent->event == m_startSystemMoveResizeInfo.window &&
xiDeviceEvent->sourceid == m_startSystemMoveResizeInfo.deviceid &&
xiDeviceEvent->detail == m_startSystemMoveResizeInfo.pointid) {
QXcbWindow *window = platformWindowFromId(m_startSystemMoveResizeInfo.window);
if (window) {
XIAllowTouchEvents(static_cast<Display *>(m_xlib_display), xiDeviceEvent->deviceid,
xiDeviceEvent->detail, xiDeviceEvent->event, XIRejectTouch);
window->doStartSystemResize(QPoint(x, y), m_startSystemResizeInfo.corner);
m_startSystemResizeInfo.window = XCB_NONE;
window->doStartSystemMoveResize(QPoint(x, y), m_startSystemMoveResizeInfo.corner);
m_startSystemMoveResizeInfo.window = XCB_NONE;
}
}
break;
@ -825,7 +825,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
touchPoint.state = Qt::TouchPointStationary;
}
bool QXcbConnection::startSystemResizeForTouchBegin(xcb_window_t window, const QPoint &point, Qt::Corner corner)
bool QXcbConnection::startSystemMoveResizeForTouchBegin(xcb_window_t window, const QPoint &point, int corner)
{
QHash<int, TouchDeviceData>::const_iterator devIt = m_touchDevices.constBegin();
for (; devIt != m_touchDevices.constEnd(); ++devIt) {
@ -834,10 +834,10 @@ bool QXcbConnection::startSystemResizeForTouchBegin(xcb_window_t window, const Q
QHash<int, QPointF>::const_iterator pointIt = deviceData.pointPressedPosition.constBegin();
for (; pointIt != deviceData.pointPressedPosition.constEnd(); ++pointIt) {
if (pointIt.value().toPoint() == point) {
m_startSystemResizeInfo.window = window;
m_startSystemResizeInfo.deviceid = devIt.key();
m_startSystemResizeInfo.pointid = pointIt.key();
m_startSystemResizeInfo.corner = corner;
m_startSystemMoveResizeInfo.window = window;
m_startSystemMoveResizeInfo.deviceid = devIt.key();
m_startSystemMoveResizeInfo.pointid = pointIt.key();
m_startSystemMoveResizeInfo.corner = corner;
return true;
}
}

View File

@ -2639,19 +2639,29 @@ void QXcbWindow::windowEvent(QEvent *event)
}
bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
{
return startSystemMoveResize(pos, corner);
}
bool QXcbWindow::startSystemMove(const QPoint &pos)
{
return startSystemMoveResize(pos, 4);
}
bool QXcbWindow::startSystemMoveResize(const QPoint &pos, int corner)
{
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
if (!connection()->wmSupport()->isSupportedByWM(moveResize))
return false;
const QPoint globalPos = QHighDpi::toNativePixels(window()->mapToGlobal(pos), window()->screen());
#ifdef XCB_USE_XINPUT22
if (connection()->startSystemResizeForTouchBegin(m_window, globalPos, corner))
if (connection()->startSystemMoveResizeForTouchBegin(m_window, globalPos, corner))
return true;
#endif
return doStartSystemResize(globalPos, corner);
return doStartSystemMoveResize(globalPos, corner);
}
bool QXcbWindow::doStartSystemResize(const QPoint &globalPos, Qt::Corner corner)
bool QXcbWindow::doStartSystemMoveResize(const QPoint &globalPos, int corner)
{
const xcb_atom_t moveResize = connection()->atom(QXcbAtom::_NET_WM_MOVERESIZE);
xcb_client_message_event_t xev;
@ -2662,12 +2672,16 @@ bool QXcbWindow::doStartSystemResize(const QPoint &globalPos, Qt::Corner corner)
xev.format = 32;
xev.data.data32[0] = globalPos.x();
xev.data.data32[1] = globalPos.y();
const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner;
const bool left = corner == Qt::BottomLeftCorner || corner == Qt::TopLeftCorner;
if (bottom)
xev.data.data32[2] = left ? 6 : 4; // bottomleft/bottomright
else
xev.data.data32[2] = left ? 0 : 2; // topleft/topright
if (corner == 4) {
xev.data.data32[2] = 8; // move
} else {
const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner;
const bool left = corner == Qt::BottomLeftCorner || corner == Qt::TopLeftCorner;
if (bottom)
xev.data.data32[2] = left ? 6 : 4; // bottomleft/bottomright
else
xev.data.data32[2] = left ? 0 : 2; // topleft/topright
}
xev.data.data32[3] = XCB_BUTTON_INDEX_1;
xev.data.data32[4] = 0;
xcb_ungrab_pointer(connection()->xcb_connection(), XCB_CURRENT_TIME);

View File

@ -110,6 +110,7 @@ public:
void windowEvent(QEvent *event) override;
bool startSystemResize(const QPoint &pos, Qt::Corner corner) override;
bool startSystemMove(const QPoint &pos) override;
void setOpacity(qreal level) override;
void setMask(const QRegion &region) override;
@ -177,7 +178,8 @@ public:
QXcbScreen *xcbScreen() const;
bool doStartSystemResize(const QPoint &globalPos, Qt::Corner corner);
bool startSystemMoveResize(const QPoint &pos, int corner);
bool doStartSystemMoveResize(const QPoint &globalPos, int corner);
virtual void create();
virtual void destroy();

View File

@ -301,6 +301,10 @@ static const QColor mainWindowGradientEnd(200, 200, 200);
static const int DisclosureOffset = 4;
static const qreal titleBarIconTitleSpacing = 5;
static const qreal titleBarTitleRightMargin = 12;
static const qreal titleBarButtonSpacing = 8;
// Tab bar colors
// active: window is active
// selected: tab is selected
@ -664,7 +668,6 @@ const int qt_mac_hitheme_version = 0; //the HITheme version we speak
const int macItemFrame = 2; // menu item frame width
const int macItemHMargin = 3; // menu item hor text margin
const int macRightBorder = 12; // right border on mac
const ThemeWindowType QtWinType = kThemeDocumentWindow; // Window type we use for QTitleBar.
/*****************************************************************************
QMacCGStyle utility functions
@ -1251,6 +1254,58 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRect &targetRect, int h
p->restore();
}
QPainterPath QMacStylePrivate::windowPanelPath(const QRectF &r) const
{
static const qreal CornerPointOffset = 5.5;
static const qreal CornerControlOffset = 2.1;
QPainterPath path;
// Top-left corner
path.moveTo(r.left(), r.top() + CornerPointOffset);
path.cubicTo(r.left(), r.top() + CornerControlOffset,
r.left() + CornerControlOffset, r.top(),
r.left() + CornerPointOffset, r.top());
// Top-right corner
path.lineTo(r.right() - CornerPointOffset, r.top());
path.cubicTo(r.right() - CornerControlOffset, r.top(),
r.right(), r.top() + CornerControlOffset,
r.right(), r.top() + CornerPointOffset);
// Bottom-right corner
path.lineTo(r.right(), r.bottom() - CornerPointOffset);
path.cubicTo(r.right(), r.bottom() - CornerControlOffset,
r.right() - CornerControlOffset, r.bottom(),
r.right() - CornerPointOffset, r.bottom());
// Bottom-right corner
path.lineTo(r.left() + CornerPointOffset, r.bottom());
path.cubicTo(r.left() + CornerControlOffset, r.bottom(),
r.left(), r.bottom() - CornerControlOffset,
r.left(), r.bottom() - CornerPointOffset);
path.lineTo(r.left(), r.top() + CornerPointOffset);
return path;
}
QMacStylePrivate::CocoaControlType QMacStylePrivate::windowButtonCocoaControl(QStyle::SubControl sc) const
{
struct WindowButtons {
QStyle::SubControl sc;
QMacStylePrivate::CocoaControlType ct;
};
static const WindowButtons buttons[] = {
{ QStyle::SC_TitleBarCloseButton, QMacStylePrivate::Button_WindowClose },
{ QStyle::SC_TitleBarMinButton, QMacStylePrivate::Button_WindowMiniaturize },
{ QStyle::SC_TitleBarMaxButton, QMacStylePrivate::Button_WindowZoom }
};
for (const auto &wb : buttons)
if (wb.sc == sc)
return wb.ct;
return NoControl;
}
#if QT_CONFIG(tabbar)
void QMacStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const
{
@ -1904,6 +1959,37 @@ NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const
case Button_RadioButton:
bv = makeButton(NSRadioButton, NSRegularSquareBezelStyle);
break;
case Button_WindowClose:
case Button_WindowMiniaturize:
case Button_WindowZoom: {
const NSWindowButton button = [=] {
switch (widget.first) {
case Button_WindowClose:
return NSWindowCloseButton;
case Button_WindowMiniaturize:
return NSWindowMiniaturizeButton;
case Button_WindowZoom:
return NSWindowZoomButton;
default:
break;
}
Q_UNREACHABLE();
} ();
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12)
const auto styleMask = NSWindowStyleMaskTitled
| NSWindowStyleMaskClosable
| NSWindowStyleMaskMiniaturizable
| NSWindowStyleMaskResizable;
#else
const auto styleMask = NSTitledWindowMask
| NSClosableWindowMask
| NSMiniaturizableWindowMask
| NSResizableWindowMask;
#endif
bv = [NSWindow standardWindowButton:button forStyleMask:styleMask];
[bv retain];
break;
}
case ComboBox:
bv = [[NSComboBox alloc] init];
break;
@ -2229,15 +2315,20 @@ void QMacStyle::unpolish(QApplication *)
void QMacStyle::polish(QWidget* w)
{
if (false
#if QT_CONFIG(menu)
if (qobject_cast<QMenu*>(w)
#if QT_CONFIG(combobox)
|| qobject_cast<QComboBoxPrivateContainer *>(w)
|| qobject_cast<QMenu*>(w)
# if QT_CONFIG(combobox)
|| qobject_cast<QComboBoxPrivateContainer *>(w)
# endif
#endif
) {
#if QT_CONFIG(mdiarea)
|| qobject_cast<QMdiSubWindow *>(w)
#endif
) {
w->setAttribute(Qt::WA_TranslucentBackground, true);
w->setAutoFillBackground(false);
}
#endif
#if QT_CONFIG(tabbar)
if (QTabBar *tb = qobject_cast<QTabBar*>(w)) {
@ -2409,14 +2500,6 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
break;
case PM_SpinBoxFrameWidth:
ret = qt_mac_aqua_get_metric(EditTextFrameOutset);
switch (d->aquaSizeConstrain(opt, widget)) {
case QStyleHelper::SizeMini:
ret += 1;
break;
default:
ret += 2;
break;
}
break;
case PM_ButtonShiftHorizontal:
case PM_ButtonShiftVertical:
@ -2923,19 +3006,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
ret = true;
break;
case SH_WindowFrame_Mask:
ret = 1;
if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask *>(hret)) {
mask->region = opt->rect;
mask->region -= QRect(opt->rect.left(), opt->rect.top(), 5, 1);
mask->region -= QRect(opt->rect.left(), opt->rect.top() + 1, 3, 1);
mask->region -= QRect(opt->rect.left(), opt->rect.top() + 2, 2, 1);
mask->region -= QRect(opt->rect.left(), opt->rect.top() + 3, 1, 2);
mask->region -= QRect(opt->rect.right() - 4, opt->rect.top(), 5, 1);
mask->region -= QRect(opt->rect.right() - 2, opt->rect.top() + 1, 3, 1);
mask->region -= QRect(opt->rect.right() - 1, opt->rect.top() + 2, 2, 1);
mask->region -= QRect(opt->rect.right() , opt->rect.top() + 3, 1, 2);
}
ret = false;
break;
case SH_TabBar_ElideMode:
ret = Qt::ElideRight;
@ -3023,6 +3094,9 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
case SH_ComboBox_AllowWheelScrolling:
ret = false;
break;
case SH_SpinBox_ButtonsInsideFrame:
ret = false;
break;
default:
ret = QCommonStyle::styleHint(sh, opt, w, hret);
break;
@ -3215,6 +3289,15 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
}
break;
case PE_FrameWindow:
if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
if (w && w->inherits("QMdiSubWindow")) {
p->save();
p->setPen(QPen(frame->palette.dark().color(), frame->lineWidth));
p->setBrush(frame->palette.window());
p->drawRect(frame->rect);
p->restore();
}
}
break;
case PE_IndicatorDockWidgetResizeHandle: {
// The docwidget resize handle is drawn as a one-pixel wide line.
@ -3489,31 +3572,7 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
p->setPen(Qt::transparent);
p->setBrush(opt->palette.window());
p->setRenderHint(QPainter::Antialiasing, true);
QPainterPath path;
static const qreal CornerPointOffset = 5.5;
static const qreal CornerControlOffset = 2.1;
QRectF r = opt->rect;
// Top-left corner
path.moveTo(r.left(), r.top() + CornerPointOffset);
path.cubicTo(r.left(), r.top() + CornerControlOffset,
r.left() + CornerControlOffset, r.top(),
r.left() + CornerPointOffset, r.top());
// Top-right corner
path.lineTo(r.right() - CornerPointOffset, r.top());
path.cubicTo(r.right() - CornerControlOffset, r.top(),
r.right(), r.top() + CornerControlOffset,
r.right(), r.top() + CornerPointOffset);
// Bottom-right corner
path.lineTo(r.right(), r.bottom() - CornerPointOffset);
path.cubicTo(r.right(), r.bottom() - CornerControlOffset,
r.right() - CornerControlOffset, r.bottom(),
r.right() - CornerPointOffset, r.bottom());
// Bottom-right corner
path.lineTo(r.left() + CornerPointOffset, r.bottom());
path.cubicTo(r.left() + CornerControlOffset, r.bottom(),
r.left(), r.bottom() - CornerControlOffset,
r.left(), r.bottom() - CornerPointOffset);
path.lineTo(r.left(), r.top() + CornerPointOffset);
const QPainterPath path = d->windowPanelPath(opt->rect);
p->drawPath(path);
p->restore();
} break;
@ -4074,78 +4133,41 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
#endif
#if QT_CONFIG(dockwidget)
case CE_DockWidgetTitle:
if (const QDockWidget *dockWidget = qobject_cast<const QDockWidget *>(w)) {
bool floating = dockWidget->isFloating();
if (floating) {
ThemeDrawState tds = d->getDrawState(opt->state);
HIThemeWindowDrawInfo wdi;
wdi.version = qt_mac_hitheme_version;
wdi.state = tds;
wdi.windowType = kThemeMovableDialogWindow;
wdi.titleHeight = opt->rect.height();
wdi.titleWidth = opt->rect.width();
wdi.attributes = 0;
CGRect titleBarRect;
CGRect tmpRect = opt->rect.toCGRect();
{
QCFType<HIShapeRef> titleRegion;
QRect newr = opt->rect.adjusted(0, 0, 2, 0);
HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
HIShapeGetBounds(titleRegion, &tmpRect);
newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
titleBarRect = newr.toCGRect();
}
QMacCGContext cg(p);
HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
} else {
// fill title bar background
QLinearGradient linearGrad(0, opt->rect.top(), 0, opt->rect.bottom());
linearGrad.setColorAt(0, mainWindowGradientBegin);
linearGrad.setColorAt(1, mainWindowGradientEnd);
p->fillRect(opt->rect, linearGrad);
// draw horizontal lines at top and bottom
p->save();
p->setPen(mainWindowGradientBegin.lighter(114));
p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
p->setPen(mainWindowGradientEnd.darker(114));
p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight());
p->restore();
if (const auto *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
const bool isVertical = dwOpt->verticalTitleBar;
const auto effectiveRect = isVertical ? opt->rect.transposed() : opt->rect;
p->save();
if (isVertical) {
p->translate(effectiveRect.left(), effectiveRect.top() + effectiveRect.width());
p->rotate(-90);
p->translate(-effectiveRect.left(), -effectiveRect.top());
}
}
// Draw the text...
if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
// fill title bar background
QLinearGradient linearGrad;
linearGrad.setStart(QPointF(0, 0));
linearGrad.setFinalStop(QPointF(0, 2 * effectiveRect.height()));
linearGrad.setColorAt(0, opt->palette.button().color());
linearGrad.setColorAt(1, opt->palette.dark().color());
p->fillRect(effectiveRect, linearGrad);
// draw horizontal line at bottom
p->setPen(opt->palette.dark().color());
p->drawLine(effectiveRect.bottomLeft(), effectiveRect.bottomRight());
if (!dwOpt->title.isEmpty()) {
auto titleRect = proxy()->subElementRect(SE_DockWidgetTitleBarText, opt, w);
if (isVertical)
titleRect = QRect(effectiveRect.left() + opt->rect.bottom() - titleRect.bottom(),
effectiveRect.top() + titleRect.left() - opt->rect.left(),
titleRect.height(),
titleRect.width());
const bool verticalTitleBar = dwOpt->verticalTitleBar;
QRect titleRect = subElementRect(SE_DockWidgetTitleBarText, opt, w);
if (verticalTitleBar) {
QRect rect = dwOpt->rect;
QRect r = rect.transposed();
titleRect = QRect(r.left() + rect.bottom()
- titleRect.bottom(),
r.top() + titleRect.left() - rect.left(),
titleRect.height(), titleRect.width());
p->translate(r.left(), r.top() + r.width());
p->rotate(-90);
p->translate(-r.left(), -r.top());
}
QFont oldFont = p->font();
p->setFont(qt_app_fonts_hash()->value("QToolButton", p->font()));
QString text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight,
titleRect.width());
drawItemText(p, titleRect,
Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette,
dwOpt->state & State_Enabled, text,
QPalette::WindowText);
p->setFont(oldFont);
const auto text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
proxy()->drawItemText(p, titleRect, Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette,
dwOpt->state & State_Enabled, text, QPalette::WindowText);
}
p->restore();
}
break;
#endif
@ -4326,39 +4348,41 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
// and then the combo inherits it and passes it onward. At that point the resolve mask
// is very, very weak. This makes it stonger.
myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());
#if 0
// QTBUG-65653: This doesn't look good enough, especially on non-retina displays.
// Worked around below while waiting for a proper fix in QCoreTextFontEngine.
p->setFont(myFont);
p->drawText(xpos, yPos, mi->rect.width() - xm - tabwidth + 1,
mi->rect.height(), text_flags, s);
#else
QMacCGContext cgCtx(p);
d->setupNSGraphicsContext(cgCtx, YES);
// Respect the menu item palette as set in the style option.
const auto pc = p->pen().color();
NSColor *c = [NSColor colorWithSRGBRed:pc.redF()
green:pc.greenF()
blue:pc.blueF()
alpha:pc.alphaF()];
// Respect the menu item action font as set in the style option.
// QTBUG-65653: Our own text rendering doesn't look good enough, especially on non-retina
// displays. Worked around here while waiting for a proper fix in QCoreTextFontEngine.
// Only if we're not using QCoreTextFontEngine we do fallback to our own text rendering.
const auto *fontEngine = QFontPrivate::get(myFont)->engineForScript(QChar::Script_Common);
Q_ASSERT(fontEngine);
if (fontEngine->type() == QFontEngine::Multi) {
fontEngine = static_cast<const QFontEngineMulti *>(fontEngine)->engine(0);
Q_ASSERT(fontEngine);
}
Q_ASSERT(fontEngine->type() == QFontEngine::Mac);
NSFont *f = (NSFont *)(CTFontRef)fontEngine->handle();
if (fontEngine->type() == QFontEngine::Mac) {
NSFont *f = (NSFont *)(CTFontRef)fontEngine->handle();
s = qt_mac_removeMnemonics(s);
[s.toNSString() drawInRect:CGRectMake(xpos, yPos, mi->rect.width() - xm - tabwidth + 1, mi->rect.height())
withAttributes:@{ NSFontAttributeName:f, NSForegroundColorAttributeName:c }];
// Respect the menu item palette as set in the style option.
const auto pc = p->pen().color();
NSColor *c = [NSColor colorWithSRGBRed:pc.redF()
green:pc.greenF()
blue:pc.blueF()
alpha:pc.alphaF()];
d->restoreNSGraphicsContext(cgCtx);
#endif
s = qt_mac_removeMnemonics(s);
const auto textRect = CGRectMake(xpos, yPos, mi->rect.width() - xm - tabwidth + 1, mi->rect.height());
QMacCGContext cgCtx(p);
d->setupNSGraphicsContext(cgCtx, YES);
[s.toNSString() drawInRect:textRect
withAttributes:@{ NSFontAttributeName:f, NSForegroundColorAttributeName:c }];
d->restoreNSGraphicsContext(cgCtx);
} else {
p->setFont(myFont);
p->drawText(xpos, yPos, mi->rect.width() - xm - tabwidth + 1,
mi->rect.height(), text_flags, s);
}
}
p->restore();
}
@ -4543,28 +4567,22 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
#if QT_CONFIG(mainwindow)
if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) {
if (toolBar && toolBar->toolBarArea == Qt::TopToolBarArea && mainWindow->unifiedTitleAndToolBarOnMac()) {
// fill with transparent pixels.
p->save();
p->setCompositionMode(QPainter::CompositionMode_Source);
p->fillRect(opt->rect, Qt::transparent);
p->restore();
// Drow a horizontal sepearator line at the toolBar bottom if the "unified" area ends here.
// Drow a horizontal separator line at the toolBar bottom if the "unified" area ends here.
// There might be additional toolbars or other widgets such as tab bars in document
// mode below. Determine this by making a unified toolbar area test for the row below
// this toolbar.
QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft());
bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1);
const QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft());
const bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1);
if (isEndOfUnifiedArea) {
int margin;
margin = qt_mac_aqua_get_metric(SeparatorSize);
CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
HIThemeSeparatorDrawInfo separatorDrawInfo;
separatorDrawInfo.version = 0;
separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive;
QMacCGContext cg(p);
HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal);
const int margin = qt_mac_aqua_get_metric(SeparatorSize);
const auto separatorRect = QRect(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
p->fillRect(separatorRect, opt->palette.dark().color());
}
break;
}
@ -5446,19 +5464,16 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
case CC_SpinBox:
if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
int frame_size;
frame_size = qt_mac_aqua_get_metric(EditTextFrameOutset);
QRect lineeditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget);
lineeditRect.adjust(-frame_size, -frame_size, +frame_size, +frame_size);
HIThemeFrameDrawInfo fdi;
fdi.version = qt_mac_hitheme_version;
fdi.state = tds == kThemeStateInactive ? kThemeStateActive : tds;
fdi.kind = kHIThemeFrameTextFieldSquare;
fdi.isFocused = false;
CGRect cgRect = lineeditRect.toCGRect();
HIThemeDrawFrame(&cgRect, &fdi, cg, kHIThemeOrientationNormal);
const auto lineEditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget);
QStyleOptionFrame frame;
static_cast<QStyleOption &>(frame) = *opt;
frame.rect = lineEditRect;
frame.state |= State_Sunken;
frame.lineWidth = 1;
frame.midLineWidth = 0;
frame.features = QStyleOptionFrame::None;
frame.frameShape = QFrame::Box;
drawPrimitive(PE_FrameLineEdit, &frame, p, widget);
}
if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) {
const QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget)
@ -5476,7 +5491,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
const bool upPressed = sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken);
const bool downPressed = sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken);
const CGFloat x = CGRectGetMidX(newRect);
const CGFloat y = upPressed ? -3 : 3; // FIXME Weird coordinate shift going on
const CGFloat y = upPressed ? -3 : 3; // Weird coordinate shift going on. Verified with Hopper
const CGPoint pressPoint = CGPointMake(x, y);
// Pretend we're pressing the mouse on the right button. Unfortunately, NSStepperCell has no
// API to highlight a specific button. The highlighted property works only on the down button.
@ -5513,115 +5528,74 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
}
break;
case CC_TitleBar:
if (const QStyleOptionTitleBar *titlebar
= qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
if (titlebar->state & State_Active) {
if (titlebar->titleBarState & State_Active)
tds = kThemeStateActive;
else
tds = kThemeStateInactive;
if (const auto *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
const bool isActive = (titlebar->state & State_Active)
&& (titlebar->titleBarState & State_Active);
p->fillRect(opt->rect, Qt::transparent);
p->setRenderHint(QPainter::Antialiasing);
p->setClipRect(opt->rect, Qt::IntersectClip);
// FIXME A single drawPath() with 0-sized pen
// doesn't look as good as this double fillPath().
const auto outterFrameRect = QRectF(opt->rect.adjusted(0, 0, 0, opt->rect.height()));
QPainterPath outterFramePath = d->windowPanelPath(outterFrameRect);
p->fillPath(outterFramePath, opt->palette.dark());
const auto frameAdjust = 1.0 / p->device()->devicePixelRatioF();
const auto innerFrameRect = outterFrameRect.adjusted(frameAdjust, frameAdjust, -frameAdjust, 0);
QPainterPath innerFramePath = d->windowPanelPath(innerFrameRect);
if (isActive) {
QLinearGradient g;
g.setStart(QPointF(0, 0));
g.setFinalStop(QPointF(0, 2 * opt->rect.height()));
g.setColorAt(0, opt->palette.button().color());
g.setColorAt(1, opt->palette.dark().color());
p->fillPath(innerFramePath, g);
} else {
tds = kThemeStateInactive;
p->fillPath(innerFramePath, opt->palette.button());
}
HIThemeWindowDrawInfo wdi;
wdi.version = qt_mac_hitheme_version;
wdi.state = tds;
wdi.windowType = QtWinType;
wdi.titleHeight = titlebar->rect.height();
wdi.titleWidth = titlebar->rect.width();
wdi.attributes = kThemeWindowHasTitleText;
// It seems HIThemeDrawTitleBarWidget is not able to draw a dirty
// close button, so use HIThemeDrawWindowFrame instead.
if (widget && widget->isWindowModified() && titlebar->subControls & SC_TitleBarCloseButton)
wdi.attributes |= kThemeWindowHasCloseBox | kThemeWindowHasDirty;
CGRect titleBarRect;
CGRect tmpRect = titlebar->rect.toCGRect();
{
QCFType<HIShapeRef> titleRegion;
QRect newr = titlebar->rect.adjusted(0, 0, 2, 0);
HIThemeGetWindowShape(&tmpRect, &wdi, kWindowTitleBarRgn, &titleRegion);
HIShapeGetBounds(titleRegion, &tmpRect);
newr.translate(newr.x() - int(tmpRect.origin.x), newr.y() - int(tmpRect.origin.y));
titleBarRect = newr.toCGRect();
}
HIThemeDrawWindowFrame(&titleBarRect, &wdi, cg, kHIThemeOrientationNormal, 0);
if (titlebar->subControls & (SC_TitleBarCloseButton
| SC_TitleBarMaxButton
| SC_TitleBarMinButton
| SC_TitleBarNormalButton)) {
HIThemeWindowWidgetDrawInfo wwdi;
wwdi.version = qt_mac_hitheme_version;
wwdi.widgetState = tds;
if (titlebar->state & State_MouseOver)
wwdi.widgetState = kThemeStateRollover;
wwdi.windowType = QtWinType;
wwdi.attributes = wdi.attributes | kThemeWindowHasFullZoom | kThemeWindowHasCloseBox | kThemeWindowHasCollapseBox;
wwdi.windowState = wdi.state;
wwdi.titleHeight = wdi.titleHeight;
wwdi.titleWidth = wdi.titleWidth;
ThemeDrawState savedControlState = wwdi.widgetState;
uint sc = SC_TitleBarMinButton;
ThemeTitleBarWidget tbw = kThemeWidgetCollapseBox;
bool active = titlebar->state & State_Active;
const bool isHovered = (titlebar->state & State_MouseOver);
static const SubControl buttons[] = {
SC_TitleBarCloseButton, SC_TitleBarMinButton, SC_TitleBarMaxButton
};
for (const auto sc : buttons) {
const auto ct = d->windowButtonCocoaControl(sc);
const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge);
auto *wb = static_cast<NSButton *>(d->cocoaControl(cw));
wb.enabled = (sc & titlebar->subControls);
[wb highlight:(titlebar->state & State_Sunken) && (sc & titlebar->activeSubControls)];
Q_UNUSED(isHovered); // FIXME No public API for this
while (sc <= SC_TitleBarCloseButton) {
if (sc & titlebar->subControls) {
uint tmp = sc;
wwdi.widgetState = savedControlState;
wwdi.widgetType = tbw;
if (sc == SC_TitleBarMinButton)
tmp |= SC_TitleBarNormalButton;
if (active && (titlebar->activeSubControls & tmp)
&& (titlebar->state & State_Sunken))
wwdi.widgetState = kThemeStatePressed;
// Draw all sub controllers except the dirty close button
// (it is already handled by HIThemeDrawWindowFrame).
if (!(widget && widget->isWindowModified() && tbw == kThemeWidgetCloseBox)) {
HIThemeDrawTitleBarWidget(&titleBarRect, &wwdi, cg, kHIThemeOrientationNormal);
p->paintEngine()->syncState();
}
}
sc = sc << 1;
tbw = tbw >> 1;
const auto buttonRect = proxy()->subControlRect(CC_TitleBar, titlebar, sc, widget);
const auto drawBlock = ^ (CGContextRef ctx, const CGRect &rect) {
Q_UNUSED(ctx);
Q_UNUSED(rect);
auto *wbCell = static_cast<NSButtonCell *>(wb.cell);
[wbCell drawWithFrame:rect inView:wb];
};
d->drawNSViewInRect(cw, wb, buttonRect, p, widget != nullptr, drawBlock);
}
}
p->paintEngine()->syncState();
if (titlebar->subControls & SC_TitleBarLabel) {
int iw = 0;
const auto tr = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarLabel, widget);
if (!titlebar->icon.isNull()) {
QCFType<HIShapeRef> titleRegion2;
HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleProxyIconRgn,
&titleRegion2);
HIShapeGetBounds(titleRegion2, &tmpRect);
if (tmpRect.size.width != 1) {
int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
iw = titlebar->icon.actualSize(QSize(iconExtent, iconExtent)).width();
}
}
if (!titlebar->text.isEmpty()) {
p->save();
QCFType<HIShapeRef> titleRegion3;
HIThemeGetWindowShape(&titleBarRect, &wdi, kWindowTitleTextRgn, &titleRegion3);
HIShapeGetBounds(titleRegion3, &tmpRect);
p->setClipRect(QRectF::fromCGRect(tmpRect).toRect());
QRect br = p->clipRegion().boundingRect();
int x = br.x(),
y = br.y() + (titlebar->rect.height() / 2 - p->fontMetrics().height() / 2);
if (br.width() <= (p->fontMetrics().horizontalAdvance(titlebar->text) + iw * 2))
x += iw;
else
x += br.width() / 2 - p->fontMetrics().horizontalAdvance(titlebar->text) / 2;
if (iw) {
int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
p->drawPixmap(x - iw, y,
titlebar->icon.pixmap(window, QSize(iconExtent, iconExtent), QIcon::Normal));
}
drawItemText(p, br, Qt::AlignCenter, opt->palette, tds == kThemeStateActive,
titlebar->text, QPalette::Text);
p->restore();
const auto iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
const auto iconSize = QSize(iconExtent, iconExtent);
const auto iconPos = tr.x() - titlebar->icon.actualSize(iconSize).width() - qRound(titleBarIconTitleSpacing);
// Only render the icon if it'll be fully visible
if (iconPos < tr.right() - titleBarIconTitleSpacing)
p->drawPixmap(iconPos, tr.y(), titlebar->icon.pixmap(window, iconSize, QIcon::Normal));
}
if (!titlebar->text.isEmpty())
drawItemText(p, tr, Qt::AlignCenter, opt->palette, isActive, titlebar->text, QPalette::Text);
}
}
break;
@ -5868,50 +5842,6 @@ QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc,
}
}
break;
/*
I don't know why, but we only get kWindowContentRgn here, which isn't what we want at all.
It would be very nice if this would work.
case QStyle::CC_TitleBar:
if (const QStyleOptionTitleBar *tbar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
HIThemeWindowDrawInfo wdi;
memset(&wdi, 0, sizeof(wdi));
wdi.version = qt_mac_hitheme_version;
wdi.state = kThemeStateActive;
wdi.windowType = QtWinType;
wdi.titleWidth = tbar->rect.width();
wdi.titleHeight = tbar->rect.height();
if (tbar->titleBarState)
wdi.attributes |= kThemeWindowHasFullZoom | kThemeWindowHasCloseBox
| kThemeWindowHasCollapseBox;
else if (tbar->titleBarFlags & Qt::WindowSystemMenuHint)
wdi.attributes |= kThemeWindowHasCloseBox;
QRect tmpRect = tbar->rect;
tmpRect.setHeight(tmpRect.height() + 100);
CGRect cgRect = tmpRect.toCGRect();
WindowRegionCode hit;
CGPoint hipt = CGPointMake(pt.x(), pt.y());
if (HIThemeGetWindowRegionHit(&cgRect, &wdi, &hipt, &hit)) {
switch (hit) {
case kWindowCloseBoxRgn:
sc = QStyle::SC_TitleBarCloseButton;
break;
case kWindowCollapseBoxRgn:
sc = QStyle::SC_TitleBarMinButton;
break;
case kWindowZoomBoxRgn:
sc = QStyle::SC_TitleBarMaxButton;
break;
case kWindowTitleTextRgn:
sc = QStyle::SC_TitleBarLabel;
break;
default:
qDebug("got something else %d", hit);
break;
}
}
}
break;
*/
default:
sc = QCommonStyle::hitTestComplexControl(cc, opt, pt, widget);
break;
@ -6005,49 +5935,47 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
}
break;
case CC_TitleBar:
if (const QStyleOptionTitleBar *titlebar
= qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
HIThemeWindowDrawInfo wdi;
memset(&wdi, 0, sizeof(wdi));
wdi.version = qt_mac_hitheme_version;
wdi.state = kThemeStateActive;
wdi.windowType = QtWinType;
wdi.titleHeight = titlebar->rect.height();
wdi.titleWidth = titlebar->rect.width();
wdi.attributes = kThemeWindowHasTitleText;
if (titlebar->subControls & SC_TitleBarCloseButton)
wdi.attributes |= kThemeWindowHasCloseBox;
if (titlebar->subControls & SC_TitleBarMaxButton
| SC_TitleBarNormalButton)
wdi.attributes |= kThemeWindowHasFullZoom;
if (titlebar->subControls & SC_TitleBarMinButton)
wdi.attributes |= kThemeWindowHasCollapseBox;
WindowRegionCode wrc = kWindowGlobalPortRgn;
if (const auto *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
// The title bar layout is as follows: close, min, zoom, icon, title
// [ x _ + @ Window Title ]
// Center the icon and title until it starts to overlap with the buttons.
// The icon doesn't count towards SC_TitleBarLabel, but it's still rendered
// next to the title text. See drawComplexControl().
if (sc == SC_TitleBarLabel) {
qreal labelWidth = titlebar->fontMetrics.horizontalAdvance(titlebar->text) + 1; // FIXME Rounding error?
qreal labelHeight = titlebar->fontMetrics.height();
if (sc == SC_TitleBarCloseButton)
wrc = kWindowCloseBoxRgn;
else if (sc == SC_TitleBarMinButton)
wrc = kWindowCollapseBoxRgn;
else if (sc == SC_TitleBarMaxButton)
wrc = kWindowZoomBoxRgn;
else if (sc == SC_TitleBarLabel)
wrc = kWindowTitleTextRgn;
else if (sc == SC_TitleBarSysMenu)
ret.setRect(-1024, -1024, 10, proxy()->pixelMetric(PM_TitleBarHeight,
titlebar, widget));
if (wrc != kWindowGlobalPortRgn) {
QCFType<HIShapeRef> region;
QRect tmpRect = titlebar->rect;
CGRect titleRect = tmpRect.toCGRect();
HIThemeGetWindowShape(&titleRect, &wdi, kWindowTitleBarRgn, &region);
HIShapeGetBounds(region, &titleRect);
CFRelease(region);
tmpRect.translate(tmpRect.x() - int(titleRect.origin.x),
tmpRect.y() - int(titleRect.origin.y));
titleRect = tmpRect.toCGRect();
HIThemeGetWindowShape(&titleRect, &wdi, wrc, &region);
HIShapeGetBounds(region, &titleRect);
ret = QRectF::fromCGRect(titleRect).toRect();
const auto lastButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarMaxButton, widget);
qreal controlsSpacing = lastButtonRect.right() + titleBarButtonSpacing;
if (!titlebar->icon.isNull()) {
const auto iconSize = proxy()->pixelMetric(PM_SmallIconSize);
const auto actualIconSize = titlebar->icon.actualSize(QSize(iconSize, iconSize)).width();;
controlsSpacing += actualIconSize + titleBarIconTitleSpacing;
}
const qreal labelPos = qMax(controlsSpacing, (opt->rect.width() - labelWidth) / 2.0);
labelWidth = qMin(labelWidth, opt->rect.width() - (labelPos + titleBarTitleRightMargin));
ret = QRect(labelPos, (opt->rect.height() - labelHeight) / 2,
labelWidth, labelHeight);
} else {
const auto currentButton = d->windowButtonCocoaControl(sc);
if (currentButton == QMacStylePrivate::NoControl)
break;
QPointF buttonPos = titlebar->rect.topLeft() + QPointF(titleBarButtonSpacing, 0);
QSizeF buttonSize;
for (int ct = QMacStylePrivate::Button_WindowClose; ct <= currentButton; ct++) {
const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::CocoaControlType(ct),
QStyleHelper::SizeLarge);
auto *wb = static_cast<NSButton *>(d->cocoaControl(cw));
if (ct == currentButton)
buttonSize = QSizeF::fromCGSize(wb.frame.size);
else
buttonPos.rx() += wb.frame.size.width + titleBarButtonSpacing;
}
const auto vOffset = (opt->rect.height() - buttonSize.height()) / 2.0;
ret = QRectF(buttonPos, buttonSize).translated(0, vOffset).toRect();
}
}
break;
@ -6178,9 +6106,9 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
case CC_SpinBox:
if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
QStyleHelper::WidgetSizePolicy aquaSize = d->effectiveAquaSizeConstrain(spin, widget);
const auto fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget);
int spinner_w;
int spinBoxSep;
int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget);
switch (aquaSize) {
case QStyleHelper::SizeLarge:
spinner_w = 14;
@ -6243,16 +6171,11 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
break;
}
case SC_SpinBoxEditField:
if (spin->buttonSymbols == QAbstractSpinBox::NoButtons) {
ret.setRect(fw, fw,
spin->rect.width() - fw * 2,
spin->rect.height() - fw * 2);
} else {
ret.setRect(fw, fw,
spin->rect.width() - fw * 2 - spinBoxSep - spinner_w,
spin->rect.height() - fw * 2);
ret = spin->rect.adjusted(fw, fw, -fw, -fw);
if (spin->buttonSymbols != QAbstractSpinBox::NoButtons) {
ret.setWidth(spin->rect.width() - spinBoxSep - spinner_w);
ret = visualRect(spin->direction, spin->rect, ret);
}
ret = visualRect(spin->direction, spin->rect, ret);
break;
default:
ret = QCommonStyle::subControlRect(cc, spin, sc, widget);
@ -6289,10 +6212,8 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
#if QT_CONFIG(spinbox)
case CT_SpinBox:
if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
// Add button + frame widths
int buttonWidth = 20;
int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, vopt, widget);
sz += QSize(buttonWidth + 2*fw, 2*fw - 3);
const int buttonWidth = 20; // FIXME Use subControlRect()
sz += QSize(buttonWidth, -3);
}
break;
#endif
@ -6635,24 +6556,14 @@ bool QMacStyle::event(QEvent *e)
}
}
#endif
if (focusWidget && focusWidget->testAttribute(Qt::WA_MacShowFocusRect)) {
f = focusWidget;
QWidget *top = f->parentWidget();
while (top && !top->isWindow() && !(top->windowType() == Qt::SubWindow))
top = top->parentWidget();
#if QT_CONFIG(mainwindow)
if (qobject_cast<QMainWindow *>(top)) {
QWidget *central = static_cast<QMainWindow *>(top)->centralWidget();
for (const QWidget *par = f; par; par = par->parentWidget()) {
if (par == central) {
top = central;
break;
}
if (par->isWindow())
break;
}
}
#if QT_CONFIG(spinbox)
if (const auto sb = qobject_cast<QAbstractSpinBox *>(focusWidget))
f = sb->property("_q_spinbox_lineedit").value<QWidget *>();
else
#endif
f = focusWidget;
}
if (f) {
if(!d->focusWidget)

View File

@ -182,6 +182,7 @@ class QMacStylePrivate : public QCommonStylePrivate
Q_DECLARE_PUBLIC(QMacStyle)
public:
enum CocoaControlType {
NoControl, // For when there's no such a control in Cocoa
Box, // QGroupBox
Button_CheckBox,
Button_Disclosure, // Disclosure triangle, like in QTreeView
@ -189,6 +190,9 @@ public:
Button_PullDown, // QPushButton with menu
Button_PushButton,
Button_RadioButton,
Button_WindowClose,
Button_WindowMiniaturize,
Button_WindowZoom,
ComboBox, // Editable QComboBox
ProgressIndicator_Determinate,
ProgressIndicator_Indeterminate,
@ -275,6 +279,10 @@ public:
void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius = 0) const;
void drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const;
QPainterPath windowPanelPath(const QRectF &r) const;
CocoaControlType windowButtonCocoaControl(QStyle::SubControl sc) const;
#if QT_CONFIG(tabbar)
void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const;
#endif

View File

@ -1667,15 +1667,8 @@ static LONG WINAPI windowsFaultHandler(struct _EXCEPTION_POINTERS *exInfo)
}
#endif // Q_OS_WIN) && !Q_OS_WINRT
static void qputenvIfEmpty(const char *name, const QByteArray &value)
{
if (qEnvironmentVariableIsEmpty(name))
qputenv(name, value);
}
static void initEnvironment()
{
qputenvIfEmpty("QT_LOGGING_TO_CONSOLE", "1");
qputenv("QT_QTESTLIB_RUNNING", "1");
}

View File

@ -26,7 +26,7 @@ qhp.QtWidgets.subprojects.classes.sortPages = true
tagfile = ../../../doc/qtwidgets/qtwidgets.tags
depends += qtcore qtgui qtdoc qtsql qtdesigner qtquick qmake qtplatformheaders qtsvg
depends += qtcore qtgui qtdoc qtsql qtdesigner qtquick qmake qtplatformheaders qtsvg qtlinguist
headerdirs += ..

View File

@ -980,9 +980,18 @@ void QListView::paintEvent(QPaintEvent *e)
? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing()
: qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing();
const int rowCount = d->commonListView->rowCount();
QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd();
for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) {
Q_ASSERT((*it).isValid());
if (rowCount == 1)
option.viewItemPosition = QStyleOptionViewItem::OnlyOne;
else if ((*it).row() == 0)
option.viewItemPosition = QStyleOptionViewItem::Beginning;
else if ((*it).row() == rowCount - 1)
option.viewItemPosition = QStyleOptionViewItem::End;
else
option.viewItemPosition = QStyleOptionViewItem::Middle;
option.rect = visualRect(*it);
if (flow() == TopToBottom)

View File

@ -11219,10 +11219,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
case Qt::WA_NoChildEventsFromChildren:
d->receiveChildEvents = !on;
break;
case Qt::WA_MacBrushedMetal:
#if 0 // Used to be included in Qt4 for Q_WS_MAC
d->setStyle_helper(style(), false, true); // Make sure things get unpolished/polished correctly.
// fall through since changing the metal attribute affects the opaque size grip.
case Qt::WA_MacOpaqueSizeGrip:
d->macUpdateOpaqueSizeGrip();
break;
@ -11235,12 +11232,10 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
case Qt::WA_Hover:
qt_mac_update_mouseTracking(this);
break;
#endif
case Qt::WA_MacAlwaysShowToolWindow:
#if 0 // Used to be included in Qt4 for Q_WS_MAC
d->macUpdateHideOnSuspend();
#endif
break;
#endif
case Qt::WA_MacNormalSize:
case Qt::WA_MacSmallSize:
case Qt::WA_MacMiniSize:

View File

@ -5301,6 +5301,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
case SH_ComboBox_AllowWheelScrolling:
ret = true;
break;
case SH_SpinBox_ButtonsInsideFrame:
ret = true;
break;
default:
ret = 0;
break;

View File

@ -1997,6 +1997,10 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
This is on by default in all styles except the Mac style.
This enum value has been introduced in Qt 5.10.
\value SH_SpinBox_ButtonsInsideFrame
Determnines if the spin box buttons are inside the line edit frame.
This enum value has been introduced in Qt 5.11.
\sa styleHint()
*/

View File

@ -740,6 +740,7 @@ public:
SH_TitleBar_ShowToolTipsOnButtons,
SH_Widget_Animation_Duration,
SH_ComboBox_AllowWheelScrolling,
SH_SpinBox_ButtonsInsideFrame,
// Add new style hint values here
SH_CustomBase = 0xf0000000

View File

@ -678,15 +678,20 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit)
Q_ASSERT(lineEdit);
return;
}
if (lineEdit == d->edit)
return;
delete d->edit;
d->edit = lineEdit;
setProperty("_q_spinbox_lineedit", QVariant::fromValue<QWidget *>(d->edit));
if (!d->edit->validator())
d->edit->setValidator(d->validator);
if (d->edit->parent() != this)
d->edit->setParent(this);
d->edit->setFrame(false);
d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this));
d->edit->setFocusProxy(this);
d->edit->setAcceptDrops(false);
@ -818,6 +823,8 @@ void QAbstractSpinBox::changeEvent(QEvent *event)
d->spinClickTimerInterval = style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate, 0, this);
d->spinClickThresholdTimerInterval =
style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, 0, this);
if (d->edit)
d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this));
d->reset();
d->updateEditFieldGeometry();
break;
@ -1644,7 +1651,9 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const
option->initFrom(this);
option->activeSubControls = QStyle::SC_None;
option->buttonSymbols = d->buttonSymbols;
option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField;
option->subControls = QStyle::SC_SpinBoxEditField;
if (!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this))
option->subControls |= QStyle::SC_SpinBoxFrame;
if (d->buttonSymbols != QAbstractSpinBox::NoButtons) {
option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
if (d->buttonState & Up) {

View File

@ -653,6 +653,8 @@ void QDockWidgetPrivate::init()
QObject::connect(button, SIGNAL(clicked()), q, SLOT(close()));
layout->setWidgetForRole(QDockWidgetLayout::CloseButton, button);
font = QApplication::font("QDockWidgetTitle");
#ifndef QT_NO_ACTION
toggleViewAction = new QAction(q);
toggleViewAction->setCheckable(true);
@ -685,6 +687,7 @@ void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const
// If we are in a floating tab, init from the parent because the attributes and the geometry
// of the title bar should be taken from the floating window.
option->initFrom(floatingTab && !isFloating() ? parentWidget() : this);
option->fontMetrics = QFontMetrics(d->font);
option->rect = dwlayout->titleArea();
option->title = d->fixedWindowTitle;
option->closable = hasFeature(this, QDockWidget::DockWidgetClosable);
@ -1481,6 +1484,7 @@ void QDockWidget::paintEvent(QPaintEvent *event)
// the title may wish to extend out to all sides (eg. Vista style)
QStyleOptionDockWidget titleOpt;
initStyleOption(&titleOpt);
p.setFont(d_func()->font);
p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt);
}
}

View File

@ -99,6 +99,8 @@ public:
QDockWidget::DockWidgetFeatures features;
Qt::DockWidgetAreas allowedAreas;
QFont font;
#ifndef QT_NO_ACTION
QAction *toggleViewAction;
#endif

View File

@ -1986,6 +1986,13 @@ void QMdiSubWindowPrivate::updateActions()
for (int i = 0; i < NumWindowStateActions; ++i)
setVisible(WindowStateAction(i), false);
#ifdef Q_OS_MACOS
if (q_func()->style()->inherits("QMacStyle"))
for (int i = 0; i < NumWindowStateActions; ++i)
if (QAction *action = actions[i])
action->setIconVisibleInMenu(false);
#endif
if (windowFlags & Qt::FramelessWindowHint)
return;

View File

@ -1103,8 +1103,9 @@ void tst_QVariant::toString_data()
QTest::newRow( "bool" ) << QVariant( true ) << QString( "true" );
QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 1, 1 ) ) << QString( "2002-01-01" );
QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56" );
QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56 ) ) ) << QString( "2002-01-01T12:34:56" );
QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QString( "12:34:56.000" );
QTest::newRow( "qtime-with-ms" ) << QVariant( QTime( 12, 34, 56, 789 ) ) << QString( "12:34:56.789" );
QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 1, 1 ), QTime( 12, 34, 56, 789 ) ) ) << QString( "2002-01-01T12:34:56.789" );
QTest::newRow( "llong" ) << QVariant( (qlonglong)Q_INT64_C(123456789012) ) <<
QString( "123456789012" );
QTest::newRow("QJsonValue") << QVariant(QJsonValue(QString("hello"))) << QString("hello");
@ -1155,6 +1156,7 @@ void tst_QVariant::toTime_data()
QTest::newRow( "qtime" ) << QVariant( QTime( 12, 34, 56 ) ) << QTime( 12, 34, 56 );
QTest::newRow( "qdatetime" ) << QVariant( QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) ) ) << QTime( 12, 34, 56 );
QTest::newRow( "qstring" ) << QVariant( QString( "12:34:56" ) ) << QTime( 12, 34, 56 );
QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "12:34:56.789" ) ) << QTime( 12, 34, 56, 789 );
}
void tst_QVariant::toTime()
@ -1175,6 +1177,10 @@ void tst_QVariant::toDateTime_data()
<< QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) );
QTest::newRow( "qdate" ) << QVariant( QDate( 2002, 10, 10 ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 0, 0, 0 ) );
QTest::newRow( "qstring" ) << QVariant( QString( "2002-10-10T12:34:56" ) ) << QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ) );
QTest::newRow( "qstring-utc" ) << QVariant( QString( "2002-10-10T12:34:56Z" ) )
<< QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56 ), Qt::UTC );
QTest::newRow( "qstring-with-ms" ) << QVariant( QString( "2002-10-10T12:34:56.789" ) )
<< QDateTime( QDate( 2002, 10, 10 ), QTime( 12, 34, 56, 789 ) );
}
void tst_QVariant::toDateTime()

View File

@ -124,8 +124,16 @@ void tst_QUuid::fromChar()
void tst_QUuid::toString()
{
QCOMPARE(uuidA.toString(), QString("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"));
QCOMPARE(uuidA.toString(QUuid::WithoutBraces),
QString("fc69b59e-cc34-4436-a43c-ee95d128b8c5"));
QCOMPARE(uuidA.toString(QUuid::Id128),
QString("fc69b59ecc344436a43cee95d128b8c5"));
QCOMPARE(uuidB.toString(), QString("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"));
QCOMPARE(uuidB.toString(QUuid::WithoutBraces),
QString("1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b"));
QCOMPARE(uuidB.toString(QUuid::Id128),
QString("1ab6e93ab1cb4a87ba47ec7e99039a7b"));
}
void tst_QUuid::fromString_data()
@ -185,8 +193,16 @@ void tst_QUuid::fromString()
void tst_QUuid::toByteArray()
{
QCOMPARE(uuidA.toByteArray(), QByteArray("{fc69b59e-cc34-4436-a43c-ee95d128b8c5}"));
QCOMPARE(uuidA.toByteArray(QUuid::WithoutBraces),
QByteArray("fc69b59e-cc34-4436-a43c-ee95d128b8c5"));
QCOMPARE(uuidA.toByteArray(QUuid::Id128),
QByteArray("fc69b59ecc344436a43cee95d128b8c5"));
QCOMPARE(uuidB.toByteArray(), QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}"));
QCOMPARE(uuidB.toByteArray(QUuid::WithoutBraces),
QByteArray("1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b"));
QCOMPARE(uuidB.toByteArray(QUuid::Id128),
QByteArray("1ab6e93ab1cb4a87ba47ec7e99039a7b"));
}
void tst_QUuid::fromByteArray()

View File

@ -220,79 +220,59 @@ public:
bool addDbs()
{
//addDb("QOCI", "localhost", "system", "penandy");
// addDb( "QOCI8", "//horsehead.qt-project.org:1521/pony.troll.no", "scott", "tiger" ); // Oracle 9i on horsehead
// addDb( "QOCI8", "//horsehead.qt-project.org:1521/ustest.troll.no", "scott", "tiger", "" ); // Oracle 9i on horsehead
// addDb( "QOCI8", "//iceblink.qt-project.org:1521/ice.troll.no", "scott", "tiger", "" ); // Oracle 8 on iceblink (not currently working)
// addDb( "QOCI", "//silence.qt-project.org:1521/testdb", "scott", "tiger" ); // Oracle 10g on silence
// addDb( "QOCI", "//bq-oracle10g.qt-project.org:1521/XE", "scott", "tiger" ); // Oracle 10gexpress
// Test databases can be defined in a file using the following format:
//
// {
// "entries": [
// {
// "driver": "QPSQL",
// "name": "testdb",
// "username": "postgres",
// "password": "password",
// "hostname": "localhost",
// "port": 5432,
// "parameters": "extraoptions"
// },
// {
// ....
// }
// ]
// }
// This requires a local ODBC data source to be configured( pointing to a MySql database )
// addDb( "QODBC", "mysqlodbc", "troll", "trond" );
// addDb( "QODBC", "SqlServer", "troll", "trond" );
// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead" );
// addDb( "QODBC", "silencetestdb", "troll", "trond", "silence" );
// addDb( "QODBC", "horseheadtestdb", "troll", "trondk", "horsehead" );
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org" );
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3307 );
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3308, "CLIENT_COMPRESS=1" ); // MySQL 4.1.1
// addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.qt-project.org", 3309, "CLIENT_COMPRESS=1" ); // MySQL 5.0.18 Linux
// addDb( "QMYSQL3", "testdb", "troll", "trond", "silence.qt-project.org" ); // MySQL 5.1.36 Windows
// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql41.qt-project.org" ); // MySQL 4.1.22-2.el4 linux
// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql50.qt-project.org" ); // MySQL 5.0.45-7.el5 linux
// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "bq-mysql51.qt-project.org" ); // MySQL 5.1.36-6.7.2.i586 linux
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org" ); // V7.2 NOT SUPPORTED!
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org", 5435 ); // V7.3
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org", 5436 ); // V7.4
// addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.qt-project.org", 5437 ); // V8.0.3
// addDb( "QPSQL7", "testdb", "troll", "trond", "silence.qt-project.org" ); // V8.2.1, UTF-8
// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-postgres74.qt-project.org" ); // Version 7.4.19-1.el4_6.1
// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql81.qt-project.org" ); // Version 8.1.11-1.el5_1.1
// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql84.qt-project.org" ); // Version 8.4.1-2.1.i586
// addDb( "QPSQL7", "testdb", "testuser", "Ee4Gabf6_", "bq-pgsql90.qt-project.org" ); // Version 9.0.0
// addDb( "QDB2", "testdb", "troll", "trond", "silence.qt-project.org" ); // DB2 v9.1 on silence
// addDb( "QDB2", "testdb", "testuser", "Ee4Gabf6_", "bq-db2-972.qt-project.org" ); // DB2
// yes - interbase really wants the physical path on the host machine.
// addDb( "QIBASE", "/opt/interbase/qttest.gdb", "SYSDBA", "masterkey", "horsehead.qt-project.org" );
// addDb( "QIBASE", "silence.troll.no:c:\\ibase\\testdb", "SYSDBA", "masterkey", "" ); // InterBase 7.5 on silence
// addDb( "QIBASE", "silence.troll.no:c:\\ibase\\testdb_ascii", "SYSDBA", "masterkey", "" ); // InterBase 7.5 on silence
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird1-nokia.trolltech.com.au" ); // Firebird 1.5.5
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird1.qt-project.org" ); // Firebird 1.5.5
// addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "bq-firebird2.qt-project.org" ); // Firebird 2.1.1
// use in-memory database to prevent local files
// addDb("QSQLITE", ":memory:");
bool added = false;
const QString databasesFile(qgetenv("QT_TEST_DATABASES_FILE"));
QFile f(databasesFile.isEmpty() ? "testdbs.json" : databasesFile);
if (f.exists() && f.open(QIODevice::ReadOnly)) {
const QJsonDocument doc = QJsonDocument::fromJson(f.readAll());
f.close();
const QJsonValue entriesV = doc.object().value(QLatin1String("entries"));
if (!entriesV.isArray()) {
qWarning() << "No entries in " + f.fileName();
} else {
const QJsonArray entriesA = entriesV.toArray();
QJsonArray::const_iterator it = entriesA.constBegin();
while (it != entriesA.constEnd()) {
if ((*it).isObject()) {
const QJsonObject object = (*it).toObject();
addDb(object.value(QStringLiteral("driver")).toString(),
object.value(QStringLiteral("name")).toString(),
object.value(QStringLiteral("username")).toString(),
object.value(QStringLiteral("password")).toString(),
object.value(QStringLiteral("hostname")).toString(),
object.value(QStringLiteral("port")).toInt(),
object.value(QStringLiteral("parameters")).toString());
added = true;
}
++it;
}
}
}
QTemporaryDir *sqLiteDir = dbDir();
if (!sqLiteDir)
return false;
addDb( QStringLiteral("QSQLITE"), QDir::toNativeSeparators(sqLiteDir->path() + QStringLiteral("/foo.db")) );
// addDb( "QSQLITE2", QDir::toNativeSeparators(dbDir.path() + "/foo2.db") );
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.qt-project.org\\ICEBLINK", "troll", "trond", "" );
// addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.qt-project.org\\SQLEXPRESS", "troll", "trond", "" );
// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql50.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
// addDb( "QODBC", "DRIVER={MySQL ODBC 5.1 Driver};SERVER=bq-mysql51.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.qt-project.org;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" );
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=silence.qt-project.org;DATABASE=testdb;PORT=2392;UID=troll;PWD=trond", "troll", "trond", "" );
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2003-x86-01.qt-project.org;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=bq-winserv2008-x86-01.qt-project.org;DATABASE=testdb;PORT=1433;UID=testuser;PWD=Ee4Gabf6_;TDS_Version=8.0", "", "", "" );
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2003" );
// addDb( "QTDS7", "testdb", "testuser", "Ee4Gabf6_", "bq-winserv2008" );
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2003-x86-01.qt-project.org;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
// addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=bq-winserv2008-x86-01.qt-project.org;DATABASE=testdb;PORT=1433", "testuser", "Ee4Gabf6_", "" );
// addDb( "QODBC", "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=c:\\dbs\\access\\testdb.mdb", "", "", "" );
// addDb( "QODBC", "DRIVER={Postgresql};SERVER=bq-pgsql84.qt-project.org;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" );
return true;
if (sqLiteDir) {
addDb(QStringLiteral("QSQLITE"), QDir::toNativeSeparators(sqLiteDir->path() + QStringLiteral("/foo.db")));
added = true;
}
return added;
}
// 'false' return indicates a system error, for example failure to create a temporary directory.

View File

@ -2,3 +2,6 @@
ubuntu-14.04
opensuse-13.1
opensuse-42.1
[task232085_spinBoxLineEditBg]
osx

View File

@ -195,6 +195,19 @@ static void formatApplicationState(QDebug debug)
#endif // HAVE_GUI_APPLICATION
}
#ifdef HAVE_APPLICATION
static void formatMouseState(QObject *o, QDebug debug)
{
if (o->isWidgetType()) {
const QWidget *w = static_cast<const QWidget *>(o);
if (QWidget::mouseGrabber() == w)
debug << " [grabbed]";
if (w->hasMouseTracking())
debug << " [tracking]";
}
}
#endif // HAVE_APPLICATION
bool EventFilter::eventFilter(QObject *o, QEvent *e)
{
static int n = 0;
@ -210,6 +223,22 @@ bool EventFilter::eventFilter(QObject *o, QEvent *e)
case QEvent::FocusIn:
formatApplicationState(debug);
break;
#ifdef HAVE_APPLICATION
case QEvent::MouseButtonDblClick:
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
case QEvent::NonClientAreaMouseButtonDblClick:
case QEvent::NonClientAreaMouseButtonPress:
case QEvent::NonClientAreaMouseButtonRelease:
case QEvent::NonClientAreaMouseMove:
# if QT_VERSION >= 0x050000
case QEvent::Enter:
# endif
case QEvent::Leave:
formatMouseState(o, debug);
break;
#endif // HAVE_APPLICATION
default:
break;
}

View File

@ -86,10 +86,12 @@ header = """
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
QT_BEGIN_NAMESPACE