forked from qt-creator/qt-creator
Merge "Merge remote-tracking branch 'origin/master' into 11.0" into 11.0
This commit is contained in:
7142
src/libs/3rdparty/sqlite/sqlite3.c
vendored
7142
src/libs/3rdparty/sqlite/sqlite3.c
vendored
File diff suppressed because it is too large
Load Diff
202
src/libs/3rdparty/sqlite/sqlite3.h
vendored
202
src/libs/3rdparty/sqlite/sqlite3.h
vendored
@@ -146,9 +146,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.41.0"
|
||||
#define SQLITE_VERSION_NUMBER 3041000
|
||||
#define SQLITE_SOURCE_ID "2023-02-21 18:09:37 05941c2a04037fc3ed2ffae11f5d2260706f89431f463518740f72ada350866d"
|
||||
#define SQLITE_VERSION "3.42.0"
|
||||
#define SQLITE_VERSION_NUMBER 3042000
|
||||
#define SQLITE_SOURCE_ID "2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@@ -1655,20 +1655,23 @@ SQLITE_API int sqlite3_os_end(void);
|
||||
** must ensure that no other SQLite interfaces are invoked by other
|
||||
** threads while sqlite3_config() is running.</b>
|
||||
**
|
||||
** The sqlite3_config() interface
|
||||
** may only be invoked prior to library initialization using
|
||||
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
|
||||
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
|
||||
** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
|
||||
** Note, however, that ^sqlite3_config() can be called as part of the
|
||||
** implementation of an application-defined [sqlite3_os_init()].
|
||||
**
|
||||
** The first argument to sqlite3_config() is an integer
|
||||
** [configuration option] that determines
|
||||
** what property of SQLite is to be configured. Subsequent arguments
|
||||
** vary depending on the [configuration option]
|
||||
** in the first argument.
|
||||
**
|
||||
** For most configuration options, the sqlite3_config() interface
|
||||
** may only be invoked prior to library initialization using
|
||||
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
|
||||
** The exceptional configuration options that may be invoked at any time
|
||||
** are called "anytime configuration options".
|
||||
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
|
||||
** [sqlite3_shutdown()] with a first argument that is not an anytime
|
||||
** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE.
|
||||
** Note, however, that ^sqlite3_config() can be called as part of the
|
||||
** implementation of an application-defined [sqlite3_os_init()].
|
||||
**
|
||||
** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
|
||||
** ^If the option is unknown or SQLite is unable to set the option
|
||||
** then this routine returns a non-zero [error code].
|
||||
@@ -1776,6 +1779,23 @@ struct sqlite3_mem_methods {
|
||||
** These constants are the available integer configuration options that
|
||||
** can be passed as the first argument to the [sqlite3_config()] interface.
|
||||
**
|
||||
** Most of the configuration options for sqlite3_config()
|
||||
** will only work if invoked prior to [sqlite3_initialize()] or after
|
||||
** [sqlite3_shutdown()]. The few exceptions to this rule are called
|
||||
** "anytime configuration options".
|
||||
** ^Calling [sqlite3_config()] with a first argument that is not an
|
||||
** anytime configuration option in between calls to [sqlite3_initialize()] and
|
||||
** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE.
|
||||
**
|
||||
** The set of anytime configuration options can change (by insertions
|
||||
** and/or deletions) from one release of SQLite to the next.
|
||||
** As of SQLite version 3.42.0, the complete set of anytime configuration
|
||||
** options is:
|
||||
** <ul>
|
||||
** <li> SQLITE_CONFIG_LOG
|
||||
** <li> SQLITE_CONFIG_PCACHE_HDRSZ
|
||||
** </ul>
|
||||
**
|
||||
** New configuration options may be added in future releases of SQLite.
|
||||
** Existing configuration options might be discontinued. Applications
|
||||
** should check the return code from [sqlite3_config()] to make sure that
|
||||
@@ -2122,28 +2142,28 @@ struct sqlite3_mem_methods {
|
||||
** compile-time option is not set, then the default maximum is 1073741824.
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
|
||||
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
|
||||
#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 /* 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 */
|
||||
#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */
|
||||
#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */
|
||||
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
|
||||
#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */
|
||||
#define SQLITE_CONFIG_PCACHE 14 /* no-op */
|
||||
#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */
|
||||
#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */
|
||||
#define SQLITE_CONFIG_URI 17 /* int */
|
||||
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
|
||||
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
|
||||
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
|
||||
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
|
||||
#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 /* 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 */
|
||||
#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */
|
||||
#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */
|
||||
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
|
||||
#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */
|
||||
#define SQLITE_CONFIG_PCACHE 14 /* no-op */
|
||||
#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */
|
||||
#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */
|
||||
#define SQLITE_CONFIG_URI 17 /* int */
|
||||
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
|
||||
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
|
||||
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
|
||||
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
|
||||
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
|
||||
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
|
||||
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
|
||||
#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
|
||||
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
|
||||
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
|
||||
@@ -2378,7 +2398,7 @@ struct sqlite3_mem_methods {
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_DQS_DML]]
|
||||
** <dt>SQLITE_DBCONFIG_DQS_DML</td>
|
||||
** <dt>SQLITE_DBCONFIG_DQS_DML</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
|
||||
** the legacy [double-quoted string literal] misfeature for DML statements
|
||||
** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
|
||||
@@ -2387,7 +2407,7 @@ struct sqlite3_mem_methods {
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_DQS_DDL]]
|
||||
** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
|
||||
** <dt>SQLITE_DBCONFIG_DQS_DDL</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
|
||||
** the legacy [double-quoted string literal] misfeature for DDL statements,
|
||||
** such as CREATE TABLE and CREATE INDEX. The
|
||||
@@ -2396,7 +2416,7 @@ struct sqlite3_mem_methods {
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
|
||||
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
|
||||
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
|
||||
** assume that database schemas are untainted by malicious content.
|
||||
** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
|
||||
@@ -2416,7 +2436,7 @@ struct sqlite3_mem_methods {
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]]
|
||||
** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</td>
|
||||
** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates
|
||||
** the legacy file format flag. When activated, this flag causes all newly
|
||||
** created database file to have a schema format version number (the 4-byte
|
||||
@@ -2425,7 +2445,7 @@ struct sqlite3_mem_methods {
|
||||
** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting,
|
||||
** newly created databases are generally not understandable by SQLite versions
|
||||
** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there
|
||||
** is now scarcely any need to generated database files that are compatible
|
||||
** is now scarcely any need to generate database files that are compatible
|
||||
** all the way back to version 3.0.0, and so this setting is of little
|
||||
** practical use, but is provided so that SQLite can continue to claim the
|
||||
** ability to generate new database files that are compatible with version
|
||||
@@ -2436,6 +2456,38 @@ struct sqlite3_mem_methods {
|
||||
** not considered a bug since SQLite versions 3.3.0 and earlier do not support
|
||||
** either generated columns or decending indexes.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
|
||||
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
|
||||
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
|
||||
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
|
||||
** statistics. For statistics to be collected, the flag must be set on
|
||||
** the database handle both when the SQL statement is prepared and when it
|
||||
** is stepped. The flag is set (collection of statistics is enabled)
|
||||
** by default. This option takes two arguments: an integer and a pointer to
|
||||
** an integer.. The first argument is 1, 0, or -1 to enable, disable, or
|
||||
** leave unchanged the statement scanstatus option. If the second argument
|
||||
** is not NULL, then the value of the statement scanstatus setting after
|
||||
** processing the first argument is written into the integer that the second
|
||||
** argument points to.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]]
|
||||
** <dt>SQLITE_DBCONFIG_REVERSE_SCANORDER</dt>
|
||||
** <dd>The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order
|
||||
** in which tables and indexes are scanned so that the scans start at the end
|
||||
** and work toward the beginning rather than starting at the beginning and
|
||||
** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the
|
||||
** same as setting [PRAGMA reverse_unordered_selects]. This option takes
|
||||
** two arguments which are an integer and a pointer to an integer. The first
|
||||
** argument is 1, 0, or -1 to enable, disable, or leave unchanged the
|
||||
** reverse scan order flag, respectively. If the second argument is not NULL,
|
||||
** then 0 or 1 is written into the integer that the second argument points to
|
||||
** depending on if the reverse scan order flag is set after processing the
|
||||
** first argument.
|
||||
** </dd>
|
||||
**
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
|
||||
@@ -2456,7 +2508,9 @@ struct sqlite3_mem_methods {
|
||||
#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */
|
||||
#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */
|
||||
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */
|
||||
#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */
|
||||
#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */
|
||||
#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable Extended Result Codes
|
||||
@@ -6201,6 +6255,13 @@ SQLITE_API void sqlite3_activate_cerod(
|
||||
** of the default VFS is not implemented correctly, or not implemented at
|
||||
** all, then the behavior of sqlite3_sleep() may deviate from the description
|
||||
** in the previous paragraphs.
|
||||
**
|
||||
** If a negative argument is passed to sqlite3_sleep() the results vary by
|
||||
** VFS and operating system. Some system treat a negative argument as an
|
||||
** instruction to sleep forever. Others understand it to mean do not sleep
|
||||
** at all. ^In SQLite version 3.42.0 and later, a negative
|
||||
** argument passed into sqlite3_sleep() is changed to zero before it is relayed
|
||||
** down into the xSleep method of the VFS.
|
||||
*/
|
||||
SQLITE_API int sqlite3_sleep(int);
|
||||
|
||||
@@ -7828,9 +7889,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
|
||||
** is undefined if the mutex is not currently entered by the
|
||||
** calling thread or is not currently allocated.
|
||||
**
|
||||
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
|
||||
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
|
||||
** behave as no-ops.
|
||||
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(),
|
||||
** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer,
|
||||
** then any of the four routines behaves as a no-op.
|
||||
**
|
||||
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
|
||||
*/
|
||||
@@ -9564,18 +9625,28 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
|
||||
** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt>
|
||||
** <dd>Calls of the form
|
||||
** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the
|
||||
** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
|
||||
** the [xConnect] or [xCreate] methods of a [virtual table] implementation
|
||||
** identify that virtual table as being safe to use from within triggers
|
||||
** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the
|
||||
** virtual table can do no serious harm even if it is controlled by a
|
||||
** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS
|
||||
** flag unless absolutely necessary.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]<dt>SQLITE_VTAB_USES_ALL_SCHEMAS</dt>
|
||||
** <dd>Calls of the form
|
||||
** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the
|
||||
** the [xConnect] or [xCreate] methods of a [virtual table] implementation
|
||||
** instruct the query planner to begin at least a read transaction on
|
||||
** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the
|
||||
** virtual table is used.
|
||||
** </dd>
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
|
||||
#define SQLITE_VTAB_INNOCUOUS 2
|
||||
#define SQLITE_VTAB_DIRECTONLY 3
|
||||
#define SQLITE_VTAB_USES_ALL_SCHEMAS 4
|
||||
|
||||
/*
|
||||
** CAPI3REF: Determine The Virtual Table Conflict Policy
|
||||
@@ -10750,16 +10821,20 @@ SQLITE_API int sqlite3session_create(
|
||||
SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
|
||||
|
||||
/*
|
||||
** CAPIREF: Conigure a Session Object
|
||||
** CAPI3REF: Configure a Session Object
|
||||
** METHOD: sqlite3_session
|
||||
**
|
||||
** This method is used to configure a session object after it has been
|
||||
** created. At present the only valid value for the second parameter is
|
||||
** [SQLITE_SESSION_OBJCONFIG_SIZE].
|
||||
** created. At present the only valid values for the second parameter are
|
||||
** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID].
|
||||
**
|
||||
** Arguments for sqlite3session_object_config()
|
||||
*/
|
||||
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Options for sqlite3session_object_config
|
||||
**
|
||||
** The following values may passed as the the 4th parameter to
|
||||
** The following values may passed as the the 2nd parameter to
|
||||
** sqlite3session_object_config().
|
||||
**
|
||||
** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd>
|
||||
@@ -10775,12 +10850,21 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
|
||||
**
|
||||
** It is an error (SQLITE_MISUSE) to attempt to modify this setting after
|
||||
** the first table has been attached to the session object.
|
||||
**
|
||||
** <dt>SQLITE_SESSION_OBJCONFIG_ROWID <dd>
|
||||
** This option is used to set, clear or query the flag that enables
|
||||
** collection of data for tables with no explicit PRIMARY KEY.
|
||||
**
|
||||
** Normally, tables with no explicit PRIMARY KEY are simply ignored
|
||||
** by the sessions module. However, if this flag is set, it behaves
|
||||
** as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted
|
||||
** as their leftmost columns.
|
||||
**
|
||||
** It is an error (SQLITE_MISUSE) to attempt to modify this setting after
|
||||
** the first table has been attached to the session object.
|
||||
*/
|
||||
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
|
||||
|
||||
/*
|
||||
*/
|
||||
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
|
||||
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
|
||||
#define SQLITE_SESSION_OBJCONFIG_ROWID 2
|
||||
|
||||
/*
|
||||
** CAPI3REF: Enable Or Disable A Session Object
|
||||
@@ -11913,9 +11997,23 @@ SQLITE_API int sqlite3changeset_apply_v2(
|
||||
** Invert the changeset before applying it. This is equivalent to inverting
|
||||
** a changeset using sqlite3changeset_invert() before applying it. It is
|
||||
** an error to specify this flag with a patchset.
|
||||
**
|
||||
** <dt>SQLITE_CHANGESETAPPLY_IGNORENOOP <dd>
|
||||
** Do not invoke the conflict handler callback for any changes that
|
||||
** would not actually modify the database even if they were applied.
|
||||
** Specifically, this means that the conflict handler is not invoked
|
||||
** for:
|
||||
** <ul>
|
||||
** <li>a delete change if the row being deleted cannot be found,
|
||||
** <li>an update change if the modified fields are already set to
|
||||
** their new values in the conflicting row, or
|
||||
** <li>an insert change if all fields of the conflicting row match
|
||||
** the row being inserted.
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
|
||||
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
|
||||
#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004
|
||||
|
||||
/*
|
||||
** CAPI3REF: Constants Passed To The Conflict Handler
|
||||
|
||||
@@ -12,12 +12,15 @@ add_subdirectory(nanotrace)
|
||||
add_subdirectory(qmldebug)
|
||||
add_subdirectory(qmleditorwidgets)
|
||||
add_subdirectory(qmljs)
|
||||
add_subdirectory(qmlpuppetcommunication)
|
||||
add_subdirectory(qtcreatorcdbext)
|
||||
add_subdirectory(solutions)
|
||||
add_subdirectory(sqlite)
|
||||
add_subdirectory(tracing)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(solutions)
|
||||
add_subdirectory(tracing)
|
||||
|
||||
if (WITH_QMLDESIGNER)
|
||||
add_subdirectory(sqlite)
|
||||
add_subdirectory(qmlpuppetcommunication)
|
||||
endif()
|
||||
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/qlitehtml/src/CMakeLists.txt)
|
||||
option(BUILD_LIBRARY_QLITEHTML "Build library qlitehtml." ${BUILD_LIBRARIES_BY_DEFAULT})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
add_qtc_library(AdvancedDockingSystem
|
||||
DEPENDS Qt::Widgets Qt::Core Qt::Gui Utils
|
||||
DEPENDS Qt::Widgets Qt::Core Qt::Gui Qt::Xml Utils
|
||||
SOURCES
|
||||
ads_globals.cpp ads_globals.h
|
||||
advanceddockingsystemtr.h
|
||||
@@ -19,7 +19,9 @@ add_qtc_library(AdvancedDockingSystem
|
||||
floatingdockcontainer.cpp floatingdockcontainer.h
|
||||
floatingdragpreview.cpp floatingdragpreview.h
|
||||
iconprovider.cpp iconprovider.h
|
||||
workspace.cpp workspace.h
|
||||
workspacedialog.cpp workspacedialog.h
|
||||
workspaceinputdialog.cpp workspaceinputdialog.h
|
||||
workspacemodel.cpp workspacemodel.h
|
||||
workspaceview.cpp workspaceview.h
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ QtcLibrary {
|
||||
cpp.defines: base.concat("ADVANCEDDOCKINGSYSTEM_LIBRARY")
|
||||
cpp.includePaths: base.concat([".", linux.prefix])
|
||||
|
||||
Depends { name: "Qt"; submodules: ["widgets", "core", "gui"] }
|
||||
Depends { name: "Qt"; submodules: ["widgets", "xml"] }
|
||||
Depends { name: "Utils" }
|
||||
|
||||
Group {
|
||||
@@ -31,6 +31,7 @@ QtcLibrary {
|
||||
"floatingdockcontainer.cpp", "floatingdockcontainer.h",
|
||||
"floatingdragpreview.cpp", "floatingdragpreview.h",
|
||||
"iconprovider.cpp", "iconprovider.h",
|
||||
"workspace.cpp", "workspace.h",
|
||||
"workspacedialog.cpp", "workspacedialog.h",
|
||||
"workspacemodel.cpp", "workspacemodel.h",
|
||||
"workspaceview.cpp", "workspaceview.h",
|
||||
|
||||
@@ -641,8 +641,8 @@ namespace ADS
|
||||
stream.writeAttribute("orientation",
|
||||
QVariant::fromValue(splitter->orientation()).toString());
|
||||
stream.writeAttribute("count", QString::number(splitter->count()));
|
||||
qCInfo(adsLog) << "NodeSplitter orient: " << splitter->orientation()
|
||||
<< " WidgetCont: " << splitter->count();
|
||||
qCInfo(adsLog) << "NodeSplitter orientation:" << splitter->orientation()
|
||||
<< "WidgetCount:" << splitter->count();
|
||||
for (int i = 0; i < splitter->count(); ++i)
|
||||
saveChildNodesState(stream, splitter->widget(i));
|
||||
|
||||
@@ -678,8 +678,8 @@ namespace ADS
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
qCInfo(adsLog) << "Restore NodeSplitter Orientation: " << orientation
|
||||
<< " WidgetCount: " << widgetCount;
|
||||
qCInfo(adsLog) << "Restore NodeSplitter Orientation:" << orientation
|
||||
<< "WidgetCount:" << widgetCount;
|
||||
QSplitter *splitter = nullptr;
|
||||
if (!testing)
|
||||
splitter = createSplitter(orientation);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@
|
||||
#include "dockcontainerwidget.h"
|
||||
#include "dockwidget.h"
|
||||
#include "floatingdockcontainer.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <utils/persistentsettings.h>
|
||||
|
||||
@@ -28,7 +29,7 @@ QT_END_NAMESPACE
|
||||
namespace ADS {
|
||||
|
||||
namespace Constants {
|
||||
const char DEFAULT_WORKSPACE[] = "Basic"; // This needs to align with a name of the shipped presets
|
||||
const char DEFAULT_WORKSPACE[] = "Basic.wrk"; // Needs to align with a shipped preset
|
||||
const char STARTUP_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/StartupWorkspace";
|
||||
const char AUTO_RESTORE_WORKSPACE_SETTINGS_KEY[] = "QML/Designer/AutoRestoreLastWorkspace";
|
||||
} // namespace Constants
|
||||
@@ -46,14 +47,18 @@ class DockWidgetTabPrivate;
|
||||
struct DockAreaWidgetPrivate;
|
||||
class IconProvider;
|
||||
|
||||
inline constexpr QStringView workspaceFolderName{u"workspaces"};
|
||||
inline constexpr QStringView workspaceFileExtension{u"wrk"};
|
||||
inline constexpr QStringView workspaceOrderFileName{u"order.json"};
|
||||
inline constexpr QStringView workspaceDisplayNameAttribute{u"displayName"};
|
||||
inline const int workspaceXmlFormattingIndent = 2;
|
||||
|
||||
/**
|
||||
* The central dock manager that maintains the complete docking system.
|
||||
* With the configuration flags you can globally control the functionality
|
||||
* of the docking system. The dock manager uses an internal stylesheet to
|
||||
* style its components like splitters, tabs and buttons. If you want to
|
||||
* disable this stylesheet because your application uses its own,
|
||||
* just call the function for settings the stylesheet with an empty
|
||||
* string.
|
||||
* The central dock manager that maintains the complete docking system. With the configuration flags
|
||||
* you can globally control the functionality of the docking system. The dock manager uses an
|
||||
* internal stylesheet to style its components like splitters, tabs and buttons. If you want to
|
||||
* disable this stylesheet because your application uses its own, just call the function for
|
||||
* settings the stylesheet with an empty string.
|
||||
* \code
|
||||
* dockManager->setStyleSheet("");
|
||||
* \endcode
|
||||
@@ -76,71 +81,6 @@ private:
|
||||
friend class FloatingDragPreviewPrivate;
|
||||
friend class DockAreaTitleBar;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Registers the given floating widget in the internal list of
|
||||
* floating widgets
|
||||
*/
|
||||
void registerFloatingWidget(FloatingDockContainer *floatingWidget);
|
||||
|
||||
/**
|
||||
* Remove the given floating widget from the list of registered floating
|
||||
* widgets
|
||||
*/
|
||||
void removeFloatingWidget(FloatingDockContainer *floatingWidget);
|
||||
|
||||
/**
|
||||
* Registers the given dock container widget
|
||||
*/
|
||||
void registerDockContainer(DockContainerWidget *dockContainer);
|
||||
|
||||
/**
|
||||
* Remove dock container from the internal list of registered dock
|
||||
* containers
|
||||
*/
|
||||
void removeDockContainer(DockContainerWidget *dockContainer);
|
||||
|
||||
/**
|
||||
* Overlay for containers
|
||||
*/
|
||||
DockOverlay *containerOverlay() const;
|
||||
|
||||
/**
|
||||
* Overlay for dock areas
|
||||
*/
|
||||
DockOverlay *dockAreaOverlay() const;
|
||||
|
||||
/**
|
||||
* A container needs to call this function if a widget has been dropped
|
||||
* into it
|
||||
*/
|
||||
void notifyWidgetOrAreaRelocation(QWidget *droppedWidget);
|
||||
|
||||
/**
|
||||
* This function is called, if a floating widget has been dropped into
|
||||
* an new position.
|
||||
* When this function is called, all dock widgets of the FloatingWidget
|
||||
* are already inserted into its new position
|
||||
*/
|
||||
void notifyFloatingWidgetDrop(FloatingDockContainer *floatingWidget);
|
||||
|
||||
/**
|
||||
* This function is called, if the given DockWidget has been relocated from
|
||||
* the old container ContainerOld to the new container DockWidget->dockContainer()
|
||||
*/
|
||||
void notifyDockWidgetRelocation(DockWidget *dockWidget, DockContainerWidget *containerOld);
|
||||
|
||||
/**
|
||||
* This function is called, if the given DockAreahas been relocated from
|
||||
* the old container ContainerOld to the new container DockArea->dockContainer()
|
||||
*/
|
||||
void notifyDockAreaRelocation(DockAreaWidget *dockArea, DockContainerWidget *containerOld);
|
||||
|
||||
/**
|
||||
* Show the floating widgets that has been created floating
|
||||
*/
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
public:
|
||||
using Super = DockContainerWidget;
|
||||
|
||||
@@ -151,12 +91,10 @@ public:
|
||||
enum eConfigFlag {
|
||||
ActiveTabHasCloseButton
|
||||
= 0x0001, //!< If this flag is set, the active tab in a tab area has a close button
|
||||
DockAreaHasCloseButton
|
||||
= 0x0002, //!< If the flag is set each dock area has a close button
|
||||
DockAreaHasCloseButton = 0x0002, //!< If the flag is set each dock area has a close button
|
||||
DockAreaCloseButtonClosesTab
|
||||
= 0x0004, //!< If the flag is set, the dock area close button closes the active tab, if not set, it closes the complete dock area
|
||||
OpaqueSplitterResize
|
||||
= 0x0008, //!< See QSplitter::setOpaqueResize() documentation
|
||||
OpaqueSplitterResize = 0x0008, //!< See QSplitter::setOpaqueResize() documentation
|
||||
XmlAutoFormattingEnabled
|
||||
= 0x0010, //!< If enabled, the XML writer automatically adds line-breaks and indentation to empty sections between elements (ignorable whitespace).
|
||||
XmlCompressionEnabled
|
||||
@@ -177,8 +115,7 @@ public:
|
||||
= 0x1000, ///< If opaque undocking is disabled, then this flag configures if the drag preview is frameless or looks like a real window
|
||||
AlwaysShowTabs
|
||||
= 0x2000, ///< If this option is enabled, the tab of a dock widget is always displayed - even if it is the only visible dock widget in a floating widget.
|
||||
DockAreaHasUndockButton
|
||||
= 0x4000, //!< If the flag is set each dock area has an undock button
|
||||
DockAreaHasUndockButton = 0x4000, //!< If the flag is set each dock area has an undock button
|
||||
DockAreaHasTabsMenuButton
|
||||
= 0x8000, //!< If the flag is set each dock area has a tabs menu button
|
||||
DockAreaHideDisabledButtons
|
||||
@@ -191,39 +128,39 @@ public:
|
||||
= 0x80000, //!< If set, the Floating Widget icon reflects the icon of the current dock widget otherwise it displays application icon
|
||||
HideSingleCentralWidgetTitleBar
|
||||
= 0x100000, //!< If there is only one single visible dock widget in the main dock container (the dock manager) and if this flag is set, then the titlebar of this dock widget will be hidden
|
||||
//!< this only makes sense for non draggable and non floatable widgets and enables the creation of some kind of "central" widget
|
||||
//!< this only makes sense for non draggable and non floatable widgets and enables the creation of some kind of "central" widget
|
||||
FocusHighlighting
|
||||
= 0x200000, //!< enables styling of focused dock widget tabs or floating widget titlebar
|
||||
EqualSplitOnInsertion
|
||||
= 0x400000, ///!< if enabled, the space is equally distributed to all widgets in a splitter
|
||||
|
||||
DefaultDockAreaButtons = DockAreaHasCloseButton
|
||||
| DockAreaHasUndockButton
|
||||
| DockAreaHasTabsMenuButton,///< default configuration of dock area title bar buttons
|
||||
DefaultDockAreaButtons
|
||||
= DockAreaHasCloseButton | DockAreaHasUndockButton
|
||||
| DockAreaHasTabsMenuButton, ///< default configuration of dock area title bar buttons
|
||||
|
||||
DefaultBaseConfig = DefaultDockAreaButtons
|
||||
| ActiveTabHasCloseButton
|
||||
| XmlCompressionEnabled
|
||||
| FloatingContainerHasWidgetTitle,///< default base configuration settings
|
||||
DefaultBaseConfig = DefaultDockAreaButtons | ActiveTabHasCloseButton
|
||||
| XmlAutoFormattingEnabled
|
||||
| FloatingContainerHasWidgetTitle, ///< default base configuration settings
|
||||
|
||||
DefaultOpaqueConfig = DefaultBaseConfig
|
||||
| OpaqueSplitterResize
|
||||
| OpaqueUndocking, ///< the default configuration with opaque operations - this may cause issues if ActiveX or Qt 3D windows are involved
|
||||
DefaultOpaqueConfig
|
||||
= DefaultBaseConfig | OpaqueSplitterResize
|
||||
| OpaqueUndocking, ///< the default configuration with opaque operations - this may cause issues if ActiveX or Qt 3D windows are involved
|
||||
|
||||
DefaultNonOpaqueConfig = DefaultBaseConfig
|
||||
| DragPreviewShowsContentPixmap, ///< the default configuration for non opaque operations
|
||||
DefaultNonOpaqueConfig
|
||||
= DefaultBaseConfig
|
||||
| DragPreviewShowsContentPixmap, ///< the default configuration for non opaque operations
|
||||
|
||||
NonOpaqueWithWindowFrame = DefaultNonOpaqueConfig
|
||||
| DragPreviewHasWindowFrame ///< the default configuration for non opaque operations that show a real window with frame
|
||||
NonOpaqueWithWindowFrame
|
||||
= DefaultNonOpaqueConfig
|
||||
| DragPreviewHasWindowFrame ///< the default configuration for non opaque operations that show a real window with frame
|
||||
};
|
||||
Q_DECLARE_FLAGS(ConfigFlags, eConfigFlag)
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
* If the given parent is a QMainWindow, the dock manager sets itself as the
|
||||
* central widget.
|
||||
* Before you create any dock widgets, you should properly setup the
|
||||
* configuration flags via setConfigFlags().
|
||||
* If the given parent is a QMainWindow, the dock manager sets itself as the central widget.
|
||||
* Before you create any dock widgets, you should properly setup the configuration flags
|
||||
* via setConfigFlags().
|
||||
*/
|
||||
DockManager(QWidget *parent = nullptr);
|
||||
|
||||
@@ -238,9 +175,8 @@ public:
|
||||
static ConfigFlags configFlags();
|
||||
|
||||
/**
|
||||
* Sets the global configuration flags for the whole docking system.
|
||||
* Call this function before you create the dock manager and before
|
||||
* your create the first dock widget.
|
||||
* Sets the global configuration flags for the whole docking system. Call this function before
|
||||
* you create the dock manager and before your create the first dock widget.
|
||||
*/
|
||||
static void setConfigFlags(const ConfigFlags flags);
|
||||
|
||||
@@ -257,20 +193,19 @@ public:
|
||||
|
||||
/**
|
||||
* Returns the global icon provider.
|
||||
* The icon provider enables the use of custom icons in case using
|
||||
* styleheets for icons is not an option.
|
||||
* The icon provider enables the use of custom icons in case using styleheets for icons is not
|
||||
* an option.
|
||||
*/
|
||||
static IconProvider &iconProvider();
|
||||
|
||||
/**
|
||||
* The distance the user needs to move the mouse with the left button
|
||||
* hold down before a dock widget start floating.
|
||||
* The distance the user needs to move the mouse with the left button hold down before a dock
|
||||
* widget start floating.
|
||||
*/
|
||||
static int startDragDistance();
|
||||
|
||||
/**
|
||||
* Helper function to set focus depending on the configuration of the
|
||||
* FocusStyling flag
|
||||
* Helper function to set focus depending on the configuration of the FocusStyling flag
|
||||
*/
|
||||
template <class QWidgetPtr>
|
||||
static void setWidgetFocus(QWidgetPtr widget)
|
||||
@@ -295,11 +230,10 @@ public:
|
||||
|
||||
/**
|
||||
* Adds dockwidget into the given area.
|
||||
* If DockAreaWidget is not null, then the area parameter indicates the area
|
||||
* into the DockAreaWidget. If DockAreaWidget is null, the Dockwidget will
|
||||
* be dropped into the container. If you would like to add a dock widget
|
||||
* tabified, then you need to add it to an existing dock area object
|
||||
* into the CenterDockWidgetArea. The following code shows this:
|
||||
* If DockAreaWidget is not null, then the area parameter indicates the area into the
|
||||
* DockAreaWidget. If DockAreaWidget is null, the Dockwidget will be dropped into the container.
|
||||
* If you would like to add a dock widget tabified, then you need to add it to an existing
|
||||
* dock area object into the CenterDockWidgetArea. The following code shows this:
|
||||
* \code
|
||||
* DockManager->addDockWidget(ads::CenterDockWidgetArea, NewDockWidget,
|
||||
* ExisitingDockArea);
|
||||
@@ -311,22 +245,18 @@ public:
|
||||
DockAreaWidget *dockAreaWidget = nullptr);
|
||||
|
||||
/**
|
||||
* This function will add the given Dockwidget to the given dock area as
|
||||
* a new tab.
|
||||
* If no dock area widget exists for the given area identifier, a new
|
||||
* dock area widget is created.
|
||||
* This function will add the given Dockwidget to the given dock area as a new tab. If no dock
|
||||
* area widget exists for the given area identifier, a new dock area widget is created.
|
||||
*/
|
||||
DockAreaWidget *addDockWidgetTab(DockWidgetArea area, DockWidget *dockWidget);
|
||||
|
||||
/**
|
||||
* This function will add the given Dockwidget to the given DockAreaWidget
|
||||
* as a new tab.
|
||||
* This function will add the given Dockwidget to the given DockAreaWidget as a new tab.
|
||||
*/
|
||||
DockAreaWidget *addDockWidgetTabToArea(DockWidget *dockWidget, DockAreaWidget *dockAreaWidget);
|
||||
|
||||
/**
|
||||
* Adds the given DockWidget floating and returns the created
|
||||
* CFloatingDockContainer instance.
|
||||
* Adds the given DockWidget floating and returns the created FloatingDockContainer instance.
|
||||
*/
|
||||
FloatingDockContainer *addDockWidgetFloating(DockWidget *dockWidget);
|
||||
|
||||
@@ -343,8 +273,8 @@ public:
|
||||
void removeDockWidget(DockWidget *dockWidget);
|
||||
|
||||
/**
|
||||
* This function returns a readable reference to the internal dock
|
||||
* widgets map so that it is possible to iterate over all dock widgets.
|
||||
* This function returns a readable reference to the internal dock widgets map so that it is
|
||||
* possible to iterate over all dock widgets.
|
||||
*/
|
||||
QMap<QString, DockWidget *> dockWidgetsMap() const;
|
||||
|
||||
@@ -366,39 +296,34 @@ public:
|
||||
unsigned int zOrderIndex() const override;
|
||||
|
||||
/**
|
||||
* Saves the current state of the dockmanger and all its dock widgets
|
||||
* into the returned QByteArray.
|
||||
* The XmlMode enables / disables the auto formatting for the XmlStreamWriter.
|
||||
* Saves the current state of the dockmanger and all its dock widgets into the returned
|
||||
* QByteArray. The XmlMode enables / disables the auto formatting for the XmlStreamWriter.
|
||||
* If auto formatting is enabled, the output is intended and line wrapped.
|
||||
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have
|
||||
* a more compact XML output - i.e. for storage in ini files.
|
||||
* The XmlMode XmlAutoFormattingDisabled is better if you would like to have a more compact
|
||||
* XML output - i.e. for storage in ini files.
|
||||
* The version number is stored as part of the data.
|
||||
* To restore the saved state, pass the return value and version number
|
||||
* to restoreState().
|
||||
* To restore the saved state, pass the return value and version number to restoreState().
|
||||
* \see restoreState()
|
||||
*/
|
||||
QByteArray saveState(int version = 0) const;
|
||||
QByteArray saveState(const QString &displayName, int version = 0) const;
|
||||
|
||||
/**
|
||||
* Restores the state of this dockmanagers dockwidgets.
|
||||
* The version number is compared with that stored in state. If they do
|
||||
* not match, the dockmanager's state is left unchanged, and this function
|
||||
* returns false; otherwise, the state is restored, and this function
|
||||
* returns true.
|
||||
* The version number is compared with that stored in state. If they do not match, the
|
||||
* dockmanager's state is left unchanged, and this function returns false; otherwise, the state
|
||||
* is restored, and this function returns true.
|
||||
* \see saveState()
|
||||
*/
|
||||
bool restoreState(const QByteArray &state, int version = 0);
|
||||
|
||||
/**
|
||||
* This function returns true between the restoringState() and
|
||||
* stateRestored() signals.
|
||||
* This function returns true between the restoringState() and stateRestored() signals.
|
||||
*/
|
||||
bool isRestoringState() const;
|
||||
|
||||
/**
|
||||
* Request a focus change to the given dock widget.
|
||||
* This function only has an effect, if the flag CDockManager::FocusStyling
|
||||
* is enabled
|
||||
* This function only has an effect, if the flag CDockManager::FocusStyling is enabled.
|
||||
*/
|
||||
void setDockWidgetFocused(DockWidget *dockWidget);
|
||||
|
||||
@@ -411,125 +336,234 @@ signals:
|
||||
/**
|
||||
* This signal is emitted if workspaces have been removed.
|
||||
*/
|
||||
void workspacesRemoved();
|
||||
void workspaceRemoved();
|
||||
|
||||
/**
|
||||
* This signal is emitted, if the restore function is called, just before
|
||||
* the dock manager starts restoring the state.
|
||||
* If this function is called, nothing has changed yet.
|
||||
* This signal is emitted, if the restore function is called, just before the dock manager
|
||||
* starts restoring the state. If this function is called, nothing has changed yet.
|
||||
*/
|
||||
void restoringState();
|
||||
|
||||
/**
|
||||
* This signal is emitted if the state changed in restoreState.
|
||||
* The signal is emitted if the restoreState() function is called or
|
||||
* if the openWorkspace() function is called.
|
||||
* The signal is emitted if the restoreState() function is called or if the openWorkspace()
|
||||
* function is called.
|
||||
*/
|
||||
void stateRestored();
|
||||
|
||||
/**
|
||||
* This signal is emitted, if the dock manager starts opening a
|
||||
* workspace.
|
||||
* Opening a workspace may take more than a second if there are
|
||||
* many complex widgets. The application may use this signal
|
||||
* to show some progress indicator or to change the mouse cursor
|
||||
* into a busy cursor.
|
||||
* This signal is emitted, if the dock manager starts opening a workspace.
|
||||
* Opening a workspace may take more than a second if there are many complex widgets. The
|
||||
* application may use this signal to show some progress indicator or to change the mouse
|
||||
* cursor into a busy cursor.
|
||||
*/
|
||||
void openingWorkspace(const QString &workspaceName);
|
||||
void openingWorkspace(const QString &fileName);
|
||||
|
||||
/**
|
||||
* This signal is emitted if the dock manager finished opening a
|
||||
* workspace.
|
||||
* This signal is emitted if the dock manager finished opening a workspace.
|
||||
*/
|
||||
void workspaceOpened(const QString &workspaceName);
|
||||
void workspaceOpened(const QString &fileName);
|
||||
|
||||
/**
|
||||
* This signal is emitted, if a new floating widget has been created.
|
||||
* An application can use this signal to e.g. subscribe to events of
|
||||
* the newly created window.
|
||||
* This signal is emitted, if a new floating widget has been created. An application can use
|
||||
* this signal to e.g. subscribe to events of the newly created window.
|
||||
*/
|
||||
void floatingWidgetCreated(FloatingDockContainer *floatingWidget);
|
||||
void floatingWidgetCreated(ADS::FloatingDockContainer *floatingWidget);
|
||||
|
||||
/**
|
||||
* This signal is emitted, if a new DockArea has been created.
|
||||
* An application can use this signal to set custom icons or custom
|
||||
* tooltips for the DockArea buttons.
|
||||
* This signal is emitted, if a new DockArea has been created. An application can use this
|
||||
* signal to set custom icons or custom tooltips for the DockArea buttons.
|
||||
*/
|
||||
void dockAreaCreated(DockAreaWidget *dockArea);
|
||||
void dockAreaCreated(ADS::DockAreaWidget *dockArea);
|
||||
|
||||
/**
|
||||
* This signal is emitted just before removal of the given DockWidget.
|
||||
*/
|
||||
void dockWidgetAboutToBeRemoved(DockWidget *dockWidget);
|
||||
void dockWidgetAboutToBeRemoved(ADS::DockWidget *dockWidget);
|
||||
|
||||
/**
|
||||
* This signal is emitted if a dock widget has been removed with the remove
|
||||
* removeDockWidget() function.
|
||||
* If this signal is emitted, the dock widget has been removed from the
|
||||
* docking system but it is not deleted yet.
|
||||
* This signal is emitted if a dock widget has been removed with the remove removeDockWidget()
|
||||
* function. If this signal is emitted, the dock widget has been removed from the docking
|
||||
* system but it is not deleted yet.
|
||||
*/
|
||||
void dockWidgetRemoved(DockWidget *dockWidget);
|
||||
void dockWidgetRemoved(ADS::DockWidget *dockWidget);
|
||||
|
||||
/**
|
||||
* This signal is emitted if the focused dock widget changed.
|
||||
* Both old and now can be nullptr.
|
||||
* This signal is emitted if the focused dock widget changed. Both old and now can be nullptr.
|
||||
* The focused dock widget is the one that is highlighted in the GUI
|
||||
*/
|
||||
void focusedDockWidgetChanged(DockWidget *old, DockWidget *now);
|
||||
void focusedDockWidgetChanged(ADS::DockWidget *old, ADS::DockWidget *now);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Registers the given floating widget in the internal list of floating widgets
|
||||
*/
|
||||
void registerFloatingWidget(FloatingDockContainer *floatingWidget);
|
||||
|
||||
/**
|
||||
* Remove the given floating widget from the list of registered floating widgets
|
||||
*/
|
||||
void removeFloatingWidget(FloatingDockContainer *floatingWidget);
|
||||
|
||||
/**
|
||||
* Registers the given dock container widget
|
||||
*/
|
||||
void registerDockContainer(DockContainerWidget *dockContainer);
|
||||
|
||||
/**
|
||||
* Remove dock container from the internal list of registered dock containers
|
||||
*/
|
||||
void removeDockContainer(DockContainerWidget *dockContainer);
|
||||
|
||||
/**
|
||||
* Overlay for containers
|
||||
*/
|
||||
DockOverlay *containerOverlay() const;
|
||||
|
||||
/**
|
||||
* Overlay for dock areas
|
||||
*/
|
||||
DockOverlay *dockAreaOverlay() const;
|
||||
|
||||
/**
|
||||
* A container needs to call this function if a widget has been dropped into it
|
||||
*/
|
||||
void notifyWidgetOrAreaRelocation(QWidget *droppedWidget);
|
||||
|
||||
/**
|
||||
* This function is called, if a floating widget has been dropped into an new position. When
|
||||
* this function is called, all dock widgets of the FloatingWidget are already inserted into
|
||||
* its new position
|
||||
*/
|
||||
void notifyFloatingWidgetDrop(FloatingDockContainer *floatingWidget);
|
||||
|
||||
/**
|
||||
* This function is called, if the given DockWidget has been relocated from the old container
|
||||
* ContainerOld to the new container DockWidget->dockContainer()
|
||||
*/
|
||||
void notifyDockWidgetRelocation(DockWidget *dockWidget, DockContainerWidget *containerOld);
|
||||
|
||||
/**
|
||||
* This function is called, if the given DockArea has been relocated from the old container
|
||||
* ContainerOld to the new container DockArea->dockContainer()
|
||||
*/
|
||||
void notifyDockAreaRelocation(DockAreaWidget *dockArea, DockContainerWidget *containerOld);
|
||||
|
||||
/**
|
||||
* Show the floating widgets that has been created floating
|
||||
*/
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
public:
|
||||
void showWorkspaceMananger();
|
||||
// Workspace state
|
||||
Workspace *activeWorkspace() const;
|
||||
QString startupWorkspace() const;
|
||||
bool autoRestoreWorkspace() const;
|
||||
const QList<Workspace> &workspaces() const;
|
||||
|
||||
// Workspace convenience functions
|
||||
int workspaceIndex(const QString &fileName) const;
|
||||
bool workspaceExists(const QString &fileName) const;
|
||||
Workspace *workspace(const QString &fileName) const;
|
||||
Workspace *workspace(int index) const;
|
||||
QDateTime workspaceDateTime(const QString &fileName) const;
|
||||
|
||||
bool moveWorkspace(int from, int to);
|
||||
bool moveWorkspaceUp(const QString &fileName);
|
||||
bool moveWorkspaceDown(const QString &fileName);
|
||||
|
||||
// higher level workspace management
|
||||
QString activeWorkspace() const;
|
||||
QString lastWorkspace() const;
|
||||
bool autoRestorLastWorkspace() const;
|
||||
QStringView workspaceFileExtension() const;
|
||||
QStringList workspaces();
|
||||
QSet<QString> workspacePresets() const;
|
||||
QDateTime workspaceDateTime(const QString &workspace) const;
|
||||
Utils::FilePath workspaceNameToFilePath(const QString &workspaceName) const;
|
||||
QString fileNameToWorkspaceName(const QString &fileName) const;
|
||||
|
||||
QString workspaceNameToFileName(const QString &workspaceName) const;
|
||||
|
||||
bool createWorkspace(const QString &workspace);
|
||||
void uniqueWorkspaceFileName(QString &fileName) const;
|
||||
|
||||
bool openWorkspace(const QString &workspace);
|
||||
bool reloadActiveWorkspace();
|
||||
// Workspace management functionality
|
||||
void showWorkspaceMananger();
|
||||
|
||||
bool confirmWorkspaceDelete(const QStringList &workspaces);
|
||||
bool deleteWorkspace(const QString &workspace);
|
||||
void deleteWorkspaces(const QStringList &workspaces);
|
||||
/**
|
||||
* \brief Create a workspace.
|
||||
*
|
||||
* The display name does not need to be unique, but the file name must be. So this function will
|
||||
* generate a file name from the display name so it will not collide with an existing workspace.
|
||||
*
|
||||
* \param workspace display name of the workspace that will be created
|
||||
* \return file name of the created workspace or unexpected
|
||||
*/
|
||||
Utils::expected_str<QString> createWorkspace(const QString &workspace);
|
||||
|
||||
bool cloneWorkspace(const QString &original, const QString &clone);
|
||||
bool renameWorkspace(const QString &original, const QString &newName);
|
||||
Utils::expected_str<void> openWorkspace(const QString &fileName);
|
||||
Utils::expected_str<void> reloadActiveWorkspace();
|
||||
|
||||
bool resetWorkspacePreset(const QString &workspace);
|
||||
/**
|
||||
* \brief Deletes a workspace from workspace list and the file from disk.
|
||||
*/
|
||||
bool deleteWorkspace(const QString &fileName);
|
||||
void deleteWorkspaces(const QStringList &fileNames);
|
||||
|
||||
bool save();
|
||||
/**
|
||||
* \brief Clone a workspace.
|
||||
*
|
||||
* \param originalFileName file name of the workspace that will be cloned
|
||||
* \param cloneName display name of cloned workspace
|
||||
* \return file name of the cloned workspace or unexpected
|
||||
*/
|
||||
Utils::expected_str<QString> cloneWorkspace(const QString &originalFileName,
|
||||
const QString &cloneName);
|
||||
|
||||
bool isWorkspacePreset(const QString &workspace) const;
|
||||
/**
|
||||
* \brief Rename a workspace.
|
||||
*
|
||||
* \param originalFileName file name of the workspace that will be renamed
|
||||
* \param newName new display name
|
||||
* \return file name of the renamed workspace or unexpected if rename failed
|
||||
*/
|
||||
Utils::expected_str<QString> renameWorkspace(const QString &originalFileName,
|
||||
const QString &newName);
|
||||
|
||||
Utils::expected_str<void> resetWorkspacePreset(const QString &fileName);
|
||||
|
||||
/**
|
||||
* \brief Save the currently active workspace.
|
||||
*/
|
||||
Utils::expected_str<void> save();
|
||||
|
||||
void setModeChangeState(bool value);
|
||||
bool isModeChangeState() const;
|
||||
|
||||
void importWorkspace(const QString &workspace);
|
||||
void exportWorkspace(const QString &target, const QString &workspace);
|
||||
Utils::expected_str<QString> importWorkspace(const QString &filePath);
|
||||
Utils::expected_str<QString> exportWorkspace(const QString &targetFilePath,
|
||||
const QString &sourceFileName);
|
||||
|
||||
// Workspace convenience functions
|
||||
QStringList loadOrder(const Utils::FilePath &dir) const;
|
||||
bool writeOrder() const;
|
||||
QList<Workspace> loadWorkspaces(const Utils::FilePath &dir) const;
|
||||
|
||||
Utils::FilePath presetDirectory() const;
|
||||
Utils::FilePath userDirectory() const;
|
||||
|
||||
static QByteArray loadFile(const Utils::FilePath &filePath);
|
||||
static QString readDisplayName(const Utils::FilePath &filePath);
|
||||
static bool writeDisplayName(const Utils::FilePath &filePath, const QString &displayName);
|
||||
|
||||
signals:
|
||||
void aboutToUnloadWorkspace(QString workspaceName);
|
||||
void aboutToLoadWorkspace(QString workspaceName);
|
||||
void workspaceLoaded(QString workspaceName);
|
||||
void workspaceReloaded(QString workspaceName);
|
||||
void aboutToUnloadWorkspace(QString fileName);
|
||||
void aboutToLoadWorkspace(QString fileName);
|
||||
void workspaceLoaded(QString fileName);
|
||||
void workspaceReloaded(QString fileName);
|
||||
void aboutToSaveWorkspace();
|
||||
|
||||
private:
|
||||
bool write(const QString &workspace, const QByteArray &data, QString *errorString) const;
|
||||
bool write(const QString &workspace, const QByteArray &data, QWidget *parent) const;
|
||||
static Utils::expected_str<void> write(const Utils::FilePath &filePath, const QByteArray &data);
|
||||
|
||||
QByteArray loadWorkspace(const QString &workspace) const;
|
||||
Utils::expected_str<QByteArray> loadWorkspace(const Workspace &workspace) const;
|
||||
|
||||
/**
|
||||
* \brief Copy all missing workspace presets over to the local workspace folder.
|
||||
*/
|
||||
void syncWorkspacePresets();
|
||||
void prepareWorkspaces();
|
||||
|
||||
void saveStartupWorkspace();
|
||||
}; // class DockManager
|
||||
|
||||
@@ -534,7 +534,17 @@ namespace ADS
|
||||
|
||||
QSize DockWidget::minimumSizeHint() const
|
||||
{
|
||||
if (d->m_minimumSizeHintMode == DockWidget::MinimumSizeHintFromDockWidget || !d->m_widget)
|
||||
if (!d->m_widget)
|
||||
return QSize(60, 40);
|
||||
|
||||
DockContainerWidget *container = this->dockContainer();
|
||||
if (!container || container->isFloating()) {
|
||||
const QSize sh = d->m_widget->minimumSizeHint();
|
||||
const QSize s = d->m_widget->minimumSize();
|
||||
return {std::max(s.width(), sh.width()), std::max(s.height(), sh.height())};
|
||||
}
|
||||
|
||||
if (d->m_minimumSizeHintMode == DockWidget::MinimumSizeHintFromDockWidget)
|
||||
return QSize(60, 40);
|
||||
else
|
||||
return d->m_widget->minimumSizeHint();
|
||||
|
||||
95
src/libs/advanceddockingsystem/workspace.cpp
Normal file
95
src/libs/advanceddockingsystem/workspace.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-2.1-or-later OR GPL-3.0-or-later
|
||||
|
||||
#include "workspace.h"
|
||||
|
||||
#include "dockmanager.h"
|
||||
|
||||
namespace ADS {
|
||||
|
||||
Workspace::Workspace() {}
|
||||
|
||||
Workspace::Workspace(const Utils::FilePath &filePath, bool isPreset)
|
||||
: m_filePath(filePath)
|
||||
, m_preset(isPreset)
|
||||
{
|
||||
if (m_filePath.isEmpty())
|
||||
return;
|
||||
|
||||
QString name = DockManager::readDisplayName(m_filePath);
|
||||
|
||||
if (name.isEmpty()) {
|
||||
name = baseName();
|
||||
// Remove "-" and "_" remove
|
||||
name.replace("-", " ");
|
||||
name.replace("_", " ");
|
||||
|
||||
setName(name);
|
||||
} else {
|
||||
m_name = name;
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::setName(const QString &name)
|
||||
{
|
||||
if (DockManager::writeDisplayName(filePath(), name))
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
const QString &Workspace::name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const Utils::FilePath &Workspace::filePath() const
|
||||
{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
QString Workspace::fileName() const
|
||||
{
|
||||
return m_filePath.fileName();
|
||||
}
|
||||
|
||||
QString Workspace::baseName() const
|
||||
{
|
||||
return m_filePath.baseName();
|
||||
}
|
||||
|
||||
QDateTime Workspace::lastModified() const
|
||||
{
|
||||
return m_filePath.lastModified();
|
||||
}
|
||||
|
||||
bool Workspace::exists() const
|
||||
{
|
||||
return m_filePath.exists();
|
||||
}
|
||||
|
||||
bool Workspace::isValid() const
|
||||
{
|
||||
if (m_filePath.isEmpty())
|
||||
return false;
|
||||
|
||||
return exists();
|
||||
}
|
||||
|
||||
void Workspace::setPreset(bool value)
|
||||
{
|
||||
m_preset = value;
|
||||
}
|
||||
|
||||
bool Workspace::isPreset() const
|
||||
{
|
||||
return m_preset;
|
||||
}
|
||||
|
||||
Workspace::operator QString() const
|
||||
{
|
||||
return QString("Workspace %1 Preset[%2] %3")
|
||||
.arg(name())
|
||||
.arg(isPreset())
|
||||
.arg(filePath().toUserOutput());
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
55
src/libs/advanceddockingsystem/workspace.h
Normal file
55
src/libs/advanceddockingsystem/workspace.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-2.1-or-later OR GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ads_globals.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
namespace ADS {
|
||||
|
||||
class ADS_EXPORT Workspace
|
||||
{
|
||||
public:
|
||||
Workspace();
|
||||
Workspace(const Utils::FilePath &filePath, bool isPreset = false);
|
||||
|
||||
void setName(const QString &name);
|
||||
const QString &name() const;
|
||||
|
||||
const Utils::FilePath &filePath() const;
|
||||
|
||||
QString fileName() const;
|
||||
QString baseName() const;
|
||||
QDateTime lastModified() const;
|
||||
bool exists() const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
void setPreset(bool value);
|
||||
bool isPreset() const;
|
||||
|
||||
friend bool operator==(const Workspace &a, const Workspace &b)
|
||||
{
|
||||
return a.fileName() == b.fileName();
|
||||
}
|
||||
|
||||
friend bool operator==(const QString &fileName, const Workspace &workspace)
|
||||
{
|
||||
return fileName == workspace.fileName();
|
||||
}
|
||||
friend bool operator==(const Workspace &workspace, const QString &fileName)
|
||||
{
|
||||
return workspace.fileName() == fileName;
|
||||
}
|
||||
|
||||
explicit operator QString() const;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
Utils::FilePath m_filePath;
|
||||
bool m_preset = false;
|
||||
};
|
||||
|
||||
} // namespace ADS
|
||||
@@ -13,103 +13,11 @@
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QValidator>
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace ADS {
|
||||
|
||||
class WorkspaceValidator : public QValidator
|
||||
{
|
||||
public:
|
||||
WorkspaceValidator(QObject *parent, const QStringList &workspaces);
|
||||
void fixup(QString &input) const override;
|
||||
QValidator::State validate(QString &input, int &pos) const override;
|
||||
|
||||
private:
|
||||
QStringList m_workspaces;
|
||||
};
|
||||
|
||||
WorkspaceValidator::WorkspaceValidator(QObject *parent, const QStringList &workspaces)
|
||||
: QValidator(parent)
|
||||
, m_workspaces(workspaces)
|
||||
{}
|
||||
|
||||
QValidator::State WorkspaceValidator::validate(QString &input, int &pos) const
|
||||
{
|
||||
Q_UNUSED(pos)
|
||||
|
||||
static const QRegularExpression rx("^[a-zA-Z0-9 ()\\-]*$");
|
||||
|
||||
if (!rx.match(input).hasMatch())
|
||||
return QValidator::Invalid;
|
||||
|
||||
if (m_workspaces.contains(input))
|
||||
return QValidator::Intermediate;
|
||||
else
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
|
||||
void WorkspaceValidator::fixup(QString &input) const
|
||||
{
|
||||
int i = 2;
|
||||
QString copy;
|
||||
do {
|
||||
copy = input + QLatin1String(" (") + QString::number(i) + QLatin1Char(')');
|
||||
++i;
|
||||
} while (m_workspaces.contains(copy));
|
||||
input = copy;
|
||||
}
|
||||
|
||||
WorkspaceNameInputDialog::WorkspaceNameInputDialog(DockManager *manager, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_manager(manager)
|
||||
{
|
||||
auto label = new QLabel(Tr::tr("Enter the name of the workspace:"), this);
|
||||
m_newWorkspaceLineEdit = new QLineEdit(this);
|
||||
m_newWorkspaceLineEdit->setValidator(new WorkspaceValidator(this, m_manager->workspaces()));
|
||||
auto buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
|
||||
Qt::Horizontal,
|
||||
this);
|
||||
m_okButton = buttons->button(QDialogButtonBox::Ok);
|
||||
m_switchToButton = new QPushButton;
|
||||
buttons->addButton(m_switchToButton, QDialogButtonBox::AcceptRole);
|
||||
connect(m_switchToButton, &QPushButton::clicked, this, [this] { m_usedSwitchTo = true; });
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
Column {
|
||||
label,
|
||||
m_newWorkspaceLineEdit,
|
||||
buttons
|
||||
}.attachTo(this);
|
||||
}
|
||||
|
||||
void WorkspaceNameInputDialog::setActionText(const QString &actionText,
|
||||
const QString &openActionText)
|
||||
{
|
||||
m_okButton->setText(actionText);
|
||||
m_switchToButton->setText(openActionText);
|
||||
}
|
||||
|
||||
void WorkspaceNameInputDialog::setValue(const QString &value)
|
||||
{
|
||||
m_newWorkspaceLineEdit->setText(value);
|
||||
}
|
||||
|
||||
QString WorkspaceNameInputDialog::value() const
|
||||
{
|
||||
return m_newWorkspaceLineEdit->text();
|
||||
}
|
||||
|
||||
bool WorkspaceNameInputDialog::isSwitchToRequested() const
|
||||
{
|
||||
return m_usedSwitchTo;
|
||||
}
|
||||
|
||||
WorkspaceDialog::WorkspaceDialog(DockManager *manager, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_manager(manager)
|
||||
@@ -122,9 +30,12 @@ WorkspaceDialog::WorkspaceDialog(DockManager *manager, QWidget *parent)
|
||||
, m_btSwitch(new QPushButton(Tr::tr("&Switch To")))
|
||||
, m_btImport(new QPushButton(Tr::tr("Import")))
|
||||
, m_btExport(new QPushButton(Tr::tr("Export")))
|
||||
, m_btUp(new QPushButton(Tr::tr("Move Up")))
|
||||
, m_btDown(new QPushButton(Tr::tr("Move Down")))
|
||||
, m_autoLoadCheckBox(new QCheckBox(Tr::tr("Restore last workspace on startup")))
|
||||
{
|
||||
setWindowTitle(Tr::tr("Workspace Manager"));
|
||||
resize(550, 380);
|
||||
|
||||
m_workspaceView->setActivationMode(Utils::DoubleClickActivation);
|
||||
|
||||
@@ -139,34 +50,27 @@ WorkspaceDialog::WorkspaceDialog(DockManager *manager, QWidget *parent)
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
Column {
|
||||
Row {
|
||||
Column {
|
||||
m_workspaceView,
|
||||
m_autoLoadCheckBox
|
||||
},
|
||||
Column {
|
||||
m_btCreateNew,
|
||||
m_btRename,
|
||||
m_btClone,
|
||||
m_btDelete,
|
||||
m_btReset,
|
||||
m_btSwitch,
|
||||
st,
|
||||
m_btImport,
|
||||
m_btExport
|
||||
}
|
||||
},
|
||||
hr,
|
||||
Row {
|
||||
whatsAWorkspaceLabel,
|
||||
buttonBox
|
||||
}
|
||||
}.attachTo(this);
|
||||
Column{Row{Column{m_workspaceView, m_autoLoadCheckBox},
|
||||
Column{m_btCreateNew,
|
||||
m_btRename,
|
||||
m_btClone,
|
||||
m_btDelete,
|
||||
m_btReset,
|
||||
m_btSwitch,
|
||||
st,
|
||||
m_btUp,
|
||||
m_btDown,
|
||||
st,
|
||||
m_btImport,
|
||||
m_btExport}},
|
||||
hr,
|
||||
Row{whatsAWorkspaceLabel, buttonBox}}
|
||||
.attachTo(this);
|
||||
|
||||
|
||||
connect(m_btCreateNew, &QAbstractButton::clicked,
|
||||
m_workspaceView, &WorkspaceView::createNewWorkspace);
|
||||
connect(m_btCreateNew,
|
||||
&QAbstractButton::clicked,
|
||||
m_workspaceView,
|
||||
&WorkspaceView::createNewWorkspace);
|
||||
connect(m_btClone, &QAbstractButton::clicked,
|
||||
m_workspaceView, &WorkspaceView::cloneCurrentWorkspace);
|
||||
connect(m_btDelete, &QAbstractButton::clicked,
|
||||
@@ -183,10 +87,15 @@ WorkspaceDialog::WorkspaceDialog(DockManager *manager, QWidget *parent)
|
||||
this, &WorkspaceDialog::updateActions);
|
||||
connect(m_btImport, &QAbstractButton::clicked,
|
||||
m_workspaceView, &WorkspaceView::importWorkspace);
|
||||
connect(m_btExport, &QAbstractButton::clicked,
|
||||
m_workspaceView, &WorkspaceView::exportCurrentWorkspace);
|
||||
connect(m_btExport,
|
||||
&QAbstractButton::clicked,
|
||||
m_workspaceView,
|
||||
&WorkspaceView::exportCurrentWorkspace);
|
||||
|
||||
updateActions(m_workspaceView->selectedWorkspaces());
|
||||
connect(m_btUp, &QAbstractButton::clicked, m_workspaceView, &WorkspaceView::moveWorkspaceUp);
|
||||
connect(m_btDown, &QAbstractButton::clicked, m_workspaceView, &WorkspaceView::moveWorkspaceDown);
|
||||
|
||||
updateActions(m_workspaceView->selectedWorkspaces());
|
||||
}
|
||||
|
||||
void WorkspaceDialog::setAutoLoadWorkspace(bool check)
|
||||
@@ -204,29 +113,50 @@ DockManager *WorkspaceDialog::dockManager() const
|
||||
return m_manager;
|
||||
}
|
||||
|
||||
void WorkspaceDialog::updateActions(const QStringList &workspaces)
|
||||
void WorkspaceDialog::updateActions(const QStringList &fileNames)
|
||||
{
|
||||
if (workspaces.isEmpty()) {
|
||||
if (fileNames.isEmpty()) {
|
||||
m_btDelete->setEnabled(false);
|
||||
m_btRename->setEnabled(false);
|
||||
m_btClone->setEnabled(false);
|
||||
m_btReset->setEnabled(false);
|
||||
m_btSwitch->setEnabled(false);
|
||||
m_btUp->setEnabled(false);
|
||||
m_btDown->setEnabled(false);
|
||||
m_btExport->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
const bool presetIsSelected = Utils::anyOf(workspaces, [this](const QString &workspace) {
|
||||
return m_manager->isWorkspacePreset(workspace);
|
||||
const bool presetIsSelected = Utils::anyOf(fileNames, [this](const QString &fileName) {
|
||||
Workspace *workspace = m_manager->workspace(fileName);
|
||||
if (!workspace)
|
||||
return false;
|
||||
|
||||
return workspace->isPreset();
|
||||
});
|
||||
const bool activeIsSelected = Utils::anyOf(workspaces, [this](const QString &workspace) {
|
||||
return workspace == m_manager->activeWorkspace();
|
||||
const bool activeIsSelected = Utils::anyOf(fileNames, [this](const QString &fileName) {
|
||||
Workspace *workspace = m_manager->workspace(fileName);
|
||||
if (!workspace)
|
||||
return false;
|
||||
|
||||
return *workspace == *m_manager->activeWorkspace();
|
||||
});
|
||||
const bool canMoveUp = Utils::anyOf(fileNames, [this](const QString &fileName) {
|
||||
return m_manager->workspaceIndex(fileName) > 0;
|
||||
});
|
||||
const int count = m_manager->workspaces().count();
|
||||
const bool canMoveDown = Utils::anyOf(fileNames, [this, &count](const QString &fileName) {
|
||||
const int i = m_manager->workspaceIndex(fileName);
|
||||
return i < (count - 1);
|
||||
});
|
||||
|
||||
m_btDelete->setEnabled(!activeIsSelected && !presetIsSelected);
|
||||
m_btRename->setEnabled(workspaces.size() == 1 && !presetIsSelected);
|
||||
m_btClone->setEnabled(workspaces.size() == 1);
|
||||
m_btRename->setEnabled(fileNames.size() == 1 && !presetIsSelected);
|
||||
m_btClone->setEnabled(fileNames.size() == 1);
|
||||
m_btReset->setEnabled(presetIsSelected);
|
||||
m_btSwitch->setEnabled(workspaces.size() == 1);
|
||||
m_btExport->setEnabled(workspaces.size() == 1);
|
||||
m_btSwitch->setEnabled(fileNames.size() == 1 && !activeIsSelected);
|
||||
m_btUp->setEnabled(fileNames.size() == 1 && canMoveUp);
|
||||
m_btDown->setEnabled(fileNames.size() == 1 && canMoveDown);
|
||||
m_btExport->setEnabled(fileNames.size() == 1);
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-2.1-or-later OR GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCheckBox;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@@ -29,7 +28,7 @@ public:
|
||||
DockManager *dockManager() const;
|
||||
|
||||
private:
|
||||
void updateActions(const QStringList &workspaces);
|
||||
void updateActions(const QStringList &fileNames);
|
||||
|
||||
DockManager *m_manager = nullptr;
|
||||
|
||||
@@ -42,28 +41,9 @@ private:
|
||||
QPushButton *m_btSwitch = nullptr;
|
||||
QPushButton *m_btImport = nullptr;
|
||||
QPushButton *m_btExport = nullptr;
|
||||
QPushButton *m_btUp = nullptr;
|
||||
QPushButton *m_btDown = nullptr;
|
||||
QCheckBox *m_autoLoadCheckBox = nullptr;
|
||||
};
|
||||
|
||||
class WorkspaceNameInputDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WorkspaceNameInputDialog(DockManager *manager, QWidget *parent);
|
||||
|
||||
void setActionText(const QString &actionText, const QString &openActionText);
|
||||
void setValue(const QString &value);
|
||||
QString value() const;
|
||||
bool isSwitchToRequested() const;
|
||||
|
||||
private:
|
||||
QLineEdit *m_newWorkspaceLineEdit = nullptr;
|
||||
QPushButton *m_switchToButton = nullptr;
|
||||
QPushButton *m_okButton = nullptr;
|
||||
bool m_usedSwitchTo = false;
|
||||
|
||||
DockManager *m_manager;
|
||||
};
|
||||
|
||||
} // namespace ADS
|
||||
|
||||
103
src/libs/advanceddockingsystem/workspaceinputdialog.cpp
Normal file
103
src/libs/advanceddockingsystem/workspaceinputdialog.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-2.1-or-later OR GPL-3.0-or-later
|
||||
|
||||
#include "workspaceinputdialog.h"
|
||||
|
||||
#include "advanceddockingsystemtr.h"
|
||||
#include "dockmanager.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QValidator>
|
||||
|
||||
namespace ADS {
|
||||
|
||||
class WorkspaceValidator : public QValidator
|
||||
{
|
||||
public:
|
||||
WorkspaceValidator(QObject *parent = nullptr);
|
||||
QValidator::State validate(QString &input, int &pos) const override;
|
||||
};
|
||||
|
||||
WorkspaceValidator::WorkspaceValidator(QObject *parent)
|
||||
: QValidator(parent)
|
||||
{}
|
||||
|
||||
QValidator::State WorkspaceValidator::validate(QString &input, int &pos) const
|
||||
{
|
||||
Q_UNUSED(pos)
|
||||
|
||||
static const QRegularExpression rx("^[a-zA-Z0-9 ()]*$");
|
||||
|
||||
if (!rx.match(input).hasMatch())
|
||||
return QValidator::Invalid;
|
||||
|
||||
if (input.isEmpty())
|
||||
return QValidator::Intermediate;
|
||||
|
||||
return QValidator::Acceptable;
|
||||
}
|
||||
|
||||
WorkspaceNameInputDialog::WorkspaceNameInputDialog(DockManager *manager, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_manager(manager)
|
||||
{
|
||||
auto label = new QLabel(Tr::tr("Enter the name of the workspace:"), this);
|
||||
m_newWorkspaceLineEdit = new QLineEdit(this);
|
||||
m_newWorkspaceLineEdit->setValidator(new WorkspaceValidator(this));
|
||||
auto buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
|
||||
Qt::Horizontal,
|
||||
this);
|
||||
m_okButton = buttons->button(QDialogButtonBox::Ok);
|
||||
m_switchToButton = new QPushButton;
|
||||
buttons->addButton(m_switchToButton, QDialogButtonBox::AcceptRole);
|
||||
connect(m_switchToButton, &QPushButton::clicked, this, [this] { m_usedSwitchTo = true; });
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
m_okButton->setEnabled(false);
|
||||
m_switchToButton->setEnabled(false);
|
||||
|
||||
connect(m_newWorkspaceLineEdit, &QLineEdit::textChanged, this, [this](const QString &) {
|
||||
m_okButton->setEnabled(m_newWorkspaceLineEdit->hasAcceptableInput());
|
||||
m_switchToButton->setEnabled(m_newWorkspaceLineEdit->hasAcceptableInput());
|
||||
});
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
Column {
|
||||
label,
|
||||
m_newWorkspaceLineEdit,
|
||||
buttons
|
||||
}.attachTo(this);
|
||||
}
|
||||
|
||||
void WorkspaceNameInputDialog::setActionText(const QString &actionText,
|
||||
const QString &openActionText)
|
||||
{
|
||||
m_okButton->setText(actionText);
|
||||
m_switchToButton->setText(openActionText);
|
||||
}
|
||||
|
||||
void WorkspaceNameInputDialog::setValue(const QString &value)
|
||||
{
|
||||
m_newWorkspaceLineEdit->setText(value);
|
||||
}
|
||||
|
||||
QString WorkspaceNameInputDialog::value() const
|
||||
{
|
||||
return m_newWorkspaceLineEdit->text();
|
||||
}
|
||||
|
||||
bool WorkspaceNameInputDialog::isSwitchToRequested() const
|
||||
{
|
||||
return m_usedSwitchTo;
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
38
src/libs/advanceddockingsystem/workspaceinputdialog.h
Normal file
38
src/libs/advanceddockingsystem/workspaceinputdialog.h
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-2.1-or-later OR GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace ADS {
|
||||
|
||||
class DockManager;
|
||||
|
||||
class WorkspaceNameInputDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WorkspaceNameInputDialog(DockManager *manager, QWidget *parent);
|
||||
|
||||
void setActionText(const QString &actionText, const QString &openActionText);
|
||||
void setValue(const QString &value);
|
||||
QString value() const;
|
||||
bool isSwitchToRequested() const;
|
||||
|
||||
private:
|
||||
QLineEdit *m_newWorkspaceLineEdit = nullptr;
|
||||
QPushButton *m_switchToButton = nullptr;
|
||||
QPushButton *m_okButton = nullptr;
|
||||
bool m_usedSwitchTo = false;
|
||||
|
||||
DockManager *m_manager;
|
||||
};
|
||||
|
||||
} // namespace ADS
|
||||
@@ -18,21 +18,21 @@ namespace ADS {
|
||||
WorkspaceModel::WorkspaceModel(DockManager *manager, QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
, m_manager(manager)
|
||||
, m_currentSortColumn(0)
|
||||
{
|
||||
m_sortedWorkspaces = m_manager->workspaces();
|
||||
sort(m_currentSortColumn, m_currentSortOrder);
|
||||
connect(m_manager, &DockManager::workspaceLoaded, this, &WorkspaceModel::resetWorkspaces);
|
||||
}
|
||||
|
||||
int WorkspaceModel::indexOfWorkspace(const QString &workspace)
|
||||
int WorkspaceModel::indexOfWorkspace(const QString &fileName)
|
||||
{
|
||||
return m_sortedWorkspaces.indexOf(workspace);
|
||||
return m_manager->workspaceIndex(fileName);
|
||||
}
|
||||
|
||||
QString WorkspaceModel::workspaceAt(int row) const
|
||||
{
|
||||
return m_sortedWorkspaces.value(row, QString());
|
||||
if (row >= rowCount() || row < 0)
|
||||
return {};
|
||||
|
||||
return m_manager->workspaces()[row].fileName();
|
||||
}
|
||||
|
||||
QVariant WorkspaceModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
@@ -46,6 +46,9 @@ QVariant WorkspaceModel::headerData(int section, Qt::Orientation orientation, in
|
||||
result = Tr::tr("Workspace");
|
||||
break;
|
||||
case 1:
|
||||
result = Tr::tr("File Name");
|
||||
break;
|
||||
case 2:
|
||||
result = Tr::tr("Last Modified");
|
||||
break;
|
||||
} // switch (section)
|
||||
@@ -59,7 +62,6 @@ int WorkspaceModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
static int sectionCount = 0;
|
||||
if (sectionCount == 0) {
|
||||
// headers sections defining possible columns
|
||||
while (!headerData(sectionCount, Qt::Horizontal, Qt::DisplayRole).isNull())
|
||||
sectionCount++;
|
||||
}
|
||||
@@ -69,183 +71,79 @@ int WorkspaceModel::columnCount(const QModelIndex &) const
|
||||
|
||||
int WorkspaceModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return m_sortedWorkspaces.count();
|
||||
}
|
||||
|
||||
QStringList pathsToBaseNames(const QStringList &paths)
|
||||
{
|
||||
return Utils::transform(paths,
|
||||
[](const QString &path) { return QFileInfo(path).completeBaseName(); });
|
||||
return m_manager->workspaces().count();
|
||||
}
|
||||
|
||||
QVariant WorkspaceModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QVariant result;
|
||||
if (index.isValid()) {
|
||||
QString workspaceName = m_sortedWorkspaces.at(index.row());
|
||||
if (!index.isValid() || index.row() >= rowCount())
|
||||
return QVariant();
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
result = workspaceName;
|
||||
break;
|
||||
case 1:
|
||||
result = m_manager->workspaceDateTime(workspaceName);
|
||||
break;
|
||||
} // switch (section)
|
||||
Workspace *workspace = m_manager->workspace(index.row());
|
||||
if (!workspace)
|
||||
return QVariant();
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
return workspace->name();
|
||||
case 1:
|
||||
return workspace->fileName();
|
||||
case 2:
|
||||
return workspace->lastModified();
|
||||
default:
|
||||
qWarning("data: invalid display value column %d", index.column());
|
||||
break;
|
||||
case Qt::FontRole: {
|
||||
QFont font;
|
||||
if (m_manager->isWorkspacePreset(workspaceName))
|
||||
font.setItalic(true);
|
||||
else
|
||||
font.setItalic(false);
|
||||
if (m_manager->activeWorkspace() == workspaceName)
|
||||
font.setBold(true);
|
||||
else
|
||||
font.setBold(false);
|
||||
result = font;
|
||||
} break;
|
||||
case PresetWorkspaceRole:
|
||||
result = m_manager->isWorkspacePreset(workspaceName);
|
||||
break;
|
||||
case LastWorkspaceRole:
|
||||
result = m_manager->lastWorkspace() == workspaceName;
|
||||
break;
|
||||
case ActiveWorkspaceRole:
|
||||
result = m_manager->activeWorkspace() == workspaceName;
|
||||
break;
|
||||
} // switch (role)
|
||||
}
|
||||
break;
|
||||
case Qt::FontRole: {
|
||||
QFont font;
|
||||
font.setItalic(workspace->isPreset());
|
||||
font.setBold(*m_manager->activeWorkspace() == *workspace);
|
||||
return font;
|
||||
}
|
||||
|
||||
return result;
|
||||
case WorkspacePreset:
|
||||
return workspace->isPreset();
|
||||
case WorkspaceStartup:
|
||||
return m_manager->startupWorkspace() == workspace->fileName();
|
||||
case WorkspaceActive:
|
||||
return *m_manager->activeWorkspace() == *workspace;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> WorkspaceModel::roleNames() const
|
||||
{
|
||||
static QHash<int, QByteArray> extraRoles{{Qt::DisplayRole, "workspaceName"},
|
||||
{PresetWorkspaceRole, "presetWorkspace"},
|
||||
{LastWorkspaceRole, "activeWorkspace"},
|
||||
{ActiveWorkspaceRole, "lastWorkspace"}};
|
||||
{WorkspacePreset, "presetWorkspace"},
|
||||
{WorkspaceStartup, "lastWorkspace"},
|
||||
{WorkspaceActive, "activeWorkspace"}};
|
||||
|
||||
auto defaultRoles = QAbstractTableModel::roleNames();
|
||||
defaultRoles.insert(extraRoles);
|
||||
return defaultRoles;
|
||||
}
|
||||
|
||||
void WorkspaceModel::sort(int column, Qt::SortOrder order)
|
||||
Qt::DropActions WorkspaceModel::supportedDropActions() const
|
||||
{
|
||||
m_currentSortColumn = column;
|
||||
m_currentSortOrder = order;
|
||||
return Qt::MoveAction;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
const auto cmp = [this, column, order](const QString &s1, const QString &s2) {
|
||||
bool isLess;
|
||||
if (column == 0)
|
||||
isLess = s1 < s2;
|
||||
else
|
||||
isLess = m_manager->workspaceDateTime(s1) < m_manager->workspaceDateTime(s2);
|
||||
if (order == Qt::DescendingOrder)
|
||||
isLess = !isLess;
|
||||
return isLess;
|
||||
};
|
||||
Utils::sort(m_sortedWorkspaces, cmp);
|
||||
endResetModel();
|
||||
Qt::ItemFlags WorkspaceModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags defaultFlags = QAbstractTableModel::flags(index);
|
||||
|
||||
if (index.isValid())
|
||||
return Qt::ItemIsDragEnabled | defaultFlags;
|
||||
|
||||
return Qt::ItemIsDropEnabled | defaultFlags;
|
||||
}
|
||||
|
||||
void WorkspaceModel::resetWorkspaces()
|
||||
{
|
||||
m_sortedWorkspaces = m_manager->workspaces();
|
||||
sort(m_currentSortColumn, m_currentSortOrder);
|
||||
}
|
||||
|
||||
void WorkspaceModel::newWorkspace(QWidget *parent)
|
||||
{
|
||||
WorkspaceNameInputDialog workspaceInputDialog(m_manager, parent);
|
||||
workspaceInputDialog.setWindowTitle(Tr::tr("New Workspace Name"));
|
||||
workspaceInputDialog.setActionText(Tr::tr("&Create"), Tr::tr("Create and &Open"));
|
||||
|
||||
runWorkspaceNameInputDialog(&workspaceInputDialog, [this](const QString &newName) {
|
||||
m_manager->createWorkspace(newName);
|
||||
});
|
||||
}
|
||||
|
||||
void WorkspaceModel::cloneWorkspace(QWidget *parent, const QString &workspace)
|
||||
{
|
||||
WorkspaceNameInputDialog workspaceInputDialog(m_manager, parent);
|
||||
workspaceInputDialog.setWindowTitle(Tr::tr("New Workspace Name"));
|
||||
workspaceInputDialog.setActionText(Tr::tr("&Clone"), Tr::tr("Clone and &Open"));
|
||||
workspaceInputDialog.setValue(workspace + " (2)");
|
||||
|
||||
runWorkspaceNameInputDialog(&workspaceInputDialog, [this, workspace](const QString &newName) {
|
||||
m_manager->cloneWorkspace(workspace, newName);
|
||||
});
|
||||
}
|
||||
|
||||
void WorkspaceModel::deleteWorkspaces(const QStringList &workspaces)
|
||||
{
|
||||
if (!m_manager->confirmWorkspaceDelete(workspaces))
|
||||
return;
|
||||
|
||||
m_manager->deleteWorkspaces(workspaces);
|
||||
m_sortedWorkspaces = m_manager->workspaces();
|
||||
sort(m_currentSortColumn, m_currentSortOrder);
|
||||
}
|
||||
|
||||
void WorkspaceModel::renameWorkspace(QWidget *parent, const QString &workspace)
|
||||
{
|
||||
WorkspaceNameInputDialog workspaceInputDialog(m_manager, parent);
|
||||
workspaceInputDialog.setWindowTitle(Tr::tr("Rename Workspace"));
|
||||
workspaceInputDialog.setActionText(Tr::tr("&Rename"), Tr::tr("Rename and &Open"));
|
||||
workspaceInputDialog.setValue(workspace);
|
||||
|
||||
runWorkspaceNameInputDialog(&workspaceInputDialog, [this, workspace](const QString &newName) {
|
||||
m_manager->renameWorkspace(workspace, newName);
|
||||
});
|
||||
}
|
||||
|
||||
void WorkspaceModel::resetWorkspace(const QString &workspace)
|
||||
{
|
||||
if (m_manager->resetWorkspacePreset(workspace) && workspace == m_manager->activeWorkspace())
|
||||
m_manager->reloadActiveWorkspace();
|
||||
}
|
||||
|
||||
void WorkspaceModel::switchToWorkspace(const QString &workspace)
|
||||
{
|
||||
m_manager->openWorkspace(workspace);
|
||||
emit workspaceSwitched();
|
||||
}
|
||||
|
||||
void WorkspaceModel::importWorkspace(const QString &workspace)
|
||||
{
|
||||
m_manager->importWorkspace(workspace);
|
||||
m_sortedWorkspaces = m_manager->workspaces();
|
||||
sort(m_currentSortColumn, m_currentSortOrder);
|
||||
}
|
||||
|
||||
void WorkspaceModel::exportWorkspace(const QString &target, const QString &workspace)
|
||||
{
|
||||
m_manager->exportWorkspace(target, workspace);
|
||||
}
|
||||
|
||||
void WorkspaceModel::runWorkspaceNameInputDialog(WorkspaceNameInputDialog *workspaceInputDialog,
|
||||
std::function<void(const QString &)> createWorkspace)
|
||||
{
|
||||
if (workspaceInputDialog->exec() == QDialog::Accepted) {
|
||||
QString newWorkspace = workspaceInputDialog->value();
|
||||
if (newWorkspace.isEmpty() || m_manager->workspaces().contains(newWorkspace))
|
||||
return;
|
||||
|
||||
createWorkspace(newWorkspace);
|
||||
m_sortedWorkspaces = m_manager->workspaces();
|
||||
sort(m_currentSortColumn, m_currentSortOrder);
|
||||
|
||||
if (workspaceInputDialog->isSwitchToRequested())
|
||||
switchToWorkspace(newWorkspace);
|
||||
|
||||
emit workspaceCreated(newWorkspace);
|
||||
}
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
|
||||
@@ -17,45 +17,27 @@ class WorkspaceModel final : public QAbstractTableModel
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum { PresetWorkspaceRole = Qt::UserRole + 1, LastWorkspaceRole, ActiveWorkspaceRole };
|
||||
enum { WorkspaceFileName = Qt::UserRole, WorkspacePreset, WorkspaceStartup, WorkspaceActive };
|
||||
|
||||
explicit WorkspaceModel(DockManager *manager, QObject *parent = nullptr);
|
||||
|
||||
int indexOfWorkspace(const QString &workspace);
|
||||
int indexOfWorkspace(const QString &fileName);
|
||||
QString workspaceAt(int row) const;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override;
|
||||
|
||||
signals:
|
||||
void workspaceSwitched();
|
||||
void workspaceCreated(const QString &workspaceName);
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
public:
|
||||
void resetWorkspaces();
|
||||
void newWorkspace(QWidget *parent);
|
||||
void cloneWorkspace(QWidget *parent, const QString &workspace);
|
||||
void deleteWorkspaces(const QStringList &workspaces);
|
||||
void renameWorkspace(QWidget *parent, const QString &workspace);
|
||||
void resetWorkspace(const QString &workspace);
|
||||
void switchToWorkspace(const QString &workspace);
|
||||
|
||||
void importWorkspace(const QString &workspace);
|
||||
void exportWorkspace(const QString &target, const QString &workspace);
|
||||
|
||||
private:
|
||||
void runWorkspaceNameInputDialog(WorkspaceNameInputDialog *workspaceInputDialog,
|
||||
std::function<void(const QString &)> createWorkspace);
|
||||
|
||||
QStringList m_sortedWorkspaces;
|
||||
DockManager *m_manager;
|
||||
int m_currentSortColumn;
|
||||
Qt::SortOrder m_currentSortOrder = Qt::AscendingOrder;
|
||||
};
|
||||
|
||||
} // namespace ADS
|
||||
|
||||
@@ -3,14 +3,16 @@
|
||||
|
||||
#include "workspaceview.h"
|
||||
|
||||
#include "dockmanager.h"
|
||||
#include "advanceddockingsystemtr.h"
|
||||
#include "dockmanager.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QHeaderView>
|
||||
#include <QItemSelection>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
#include <QStringList>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
@@ -49,13 +51,15 @@ WorkspaceView::WorkspaceView(DockManager *manager, QWidget *parent)
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
setWordWrap(false);
|
||||
setRootIsDecorated(false);
|
||||
setSortingEnabled(true);
|
||||
setSortingEnabled(false);
|
||||
setDragEnabled(true);
|
||||
setAcceptDrops(true);
|
||||
setDropIndicatorShown(true);
|
||||
setDragDropMode(QAbstractItemView::InternalMove);
|
||||
|
||||
setModel(&m_workspaceModel);
|
||||
sortByColumn(0, Qt::AscendingOrder);
|
||||
|
||||
// Ensure that the full workspace name is visible.
|
||||
header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
header()->setDefaultSectionSize(150);
|
||||
|
||||
QItemSelection firstRow(m_workspaceModel.index(0, 0),
|
||||
m_workspaceModel.index(0, m_workspaceModel.columnCount() - 1));
|
||||
@@ -68,17 +72,94 @@ WorkspaceView::WorkspaceView(DockManager *manager, QWidget *parent)
|
||||
emit workspacesSelected(selectedWorkspaces());
|
||||
});
|
||||
|
||||
connect(&m_workspaceModel, &WorkspaceModel::workspaceSwitched,
|
||||
this, &WorkspaceView::workspaceSwitched);
|
||||
connect(&m_workspaceModel, &WorkspaceModel::modelReset,
|
||||
this, &WorkspaceView::selectActiveWorkspace);
|
||||
connect(&m_workspaceModel, &WorkspaceModel::workspaceCreated,
|
||||
this, &WorkspaceView::selectWorkspace);
|
||||
connect(&m_workspaceModel,
|
||||
&WorkspaceModel::modelReset,
|
||||
this,
|
||||
&WorkspaceView::selectActiveWorkspace);
|
||||
}
|
||||
|
||||
void WorkspaceView::createNewWorkspace()
|
||||
{
|
||||
m_workspaceModel.newWorkspace(this);
|
||||
WorkspaceNameInputDialog workspaceInputDialog(m_manager, this);
|
||||
workspaceInputDialog.setWindowTitle(Tr::tr("New Workspace Name"));
|
||||
workspaceInputDialog.setActionText(Tr::tr("&Create"), Tr::tr("Create and &Open"));
|
||||
|
||||
runWorkspaceNameInputDialog(&workspaceInputDialog, [this](const QString &newName) {
|
||||
Utils::expected_str<QString> result = m_manager->createWorkspace(newName);
|
||||
|
||||
if (!result)
|
||||
QMessageBox::warning(this, Tr::tr("Cannot Create Workspace"), result.error());
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
void WorkspaceView::cloneCurrentWorkspace()
|
||||
{
|
||||
const QString fileName = currentWorkspace();
|
||||
|
||||
QString displayName = "Unknown";
|
||||
Workspace *workspace = m_manager->workspace(fileName);
|
||||
if (workspace)
|
||||
displayName = workspace->name();
|
||||
|
||||
WorkspaceNameInputDialog workspaceInputDialog(m_manager, this);
|
||||
workspaceInputDialog.setWindowTitle(Tr::tr("New Workspace Name"));
|
||||
workspaceInputDialog.setActionText(Tr::tr("&Clone"), Tr::tr("Clone and &Open"));
|
||||
workspaceInputDialog.setValue(Tr::tr("%1 Copy").arg(displayName));
|
||||
|
||||
runWorkspaceNameInputDialog(&workspaceInputDialog, [this, fileName](const QString &newName) {
|
||||
Utils::expected_str<QString> result = m_manager->cloneWorkspace(fileName, newName);
|
||||
|
||||
if (!result)
|
||||
QMessageBox::warning(this, Tr::tr("Cannot Clone Workspace"), result.error());
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
void WorkspaceView::renameCurrentWorkspace()
|
||||
{
|
||||
const QString fileName = currentWorkspace();
|
||||
|
||||
QString displayName = "Unknown";
|
||||
Workspace *workspace = m_manager->workspace(fileName);
|
||||
if (workspace)
|
||||
displayName = workspace->name();
|
||||
|
||||
WorkspaceNameInputDialog workspaceInputDialog(m_manager, this);
|
||||
workspaceInputDialog.setWindowTitle(Tr::tr("Rename Workspace"));
|
||||
workspaceInputDialog.setActionText(Tr::tr("&Rename"), Tr::tr("Rename and &Open"));
|
||||
workspaceInputDialog.setValue(displayName);
|
||||
|
||||
runWorkspaceNameInputDialog(&workspaceInputDialog, [this, fileName](const QString &newName) {
|
||||
Utils::expected_str<QString> result = m_manager->renameWorkspace(fileName, newName);
|
||||
|
||||
if (!result)
|
||||
QMessageBox::warning(this, Tr::tr("Cannot Rename Workspace"), result.error());
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
void WorkspaceView::resetCurrentWorkspace()
|
||||
{
|
||||
const QString fileName = currentWorkspace();
|
||||
|
||||
if (m_manager->resetWorkspacePreset(fileName) && fileName == *m_manager->activeWorkspace()) {
|
||||
if (m_manager->reloadActiveWorkspace())
|
||||
m_workspaceModel.resetWorkspaces();
|
||||
}
|
||||
}
|
||||
|
||||
void WorkspaceView::switchToCurrentWorkspace()
|
||||
{
|
||||
Utils::expected_str<void> result = m_manager->openWorkspace(currentWorkspace());
|
||||
|
||||
if (!result)
|
||||
QMessageBox::warning(this, Tr::tr("Cannot Switch Workspace"), result.error());
|
||||
|
||||
emit workspaceSwitched();
|
||||
}
|
||||
|
||||
void WorkspaceView::deleteSelectedWorkspaces()
|
||||
@@ -86,61 +167,72 @@ void WorkspaceView::deleteSelectedWorkspaces()
|
||||
deleteWorkspaces(selectedWorkspaces());
|
||||
}
|
||||
|
||||
void WorkspaceView::deleteWorkspaces(const QStringList &workspaces)
|
||||
{
|
||||
m_workspaceModel.deleteWorkspaces(workspaces);
|
||||
}
|
||||
|
||||
void WorkspaceView::importWorkspace()
|
||||
{
|
||||
static QString lastDir;
|
||||
const QString currentDir = lastDir.isEmpty() ? "" : lastDir;
|
||||
const auto fileName = QFileDialog::getOpenFileName(this,
|
||||
Tr::tr("Import Workspace"),
|
||||
currentDir,
|
||||
"Workspaces (*" + m_manager->workspaceFileExtension() + ")");
|
||||
static QString previousDirectory;
|
||||
const QString currentDirectory = previousDirectory.isEmpty() ? "" : previousDirectory;
|
||||
const auto filePath
|
||||
= QFileDialog::getOpenFileName(this,
|
||||
Tr::tr("Import Workspace"),
|
||||
currentDirectory,
|
||||
QString("Workspaces (*.%1)").arg(workspaceFileExtension));
|
||||
|
||||
if (!fileName.isEmpty())
|
||||
lastDir = QFileInfo(fileName).absolutePath();
|
||||
// If the user presses Cancel, it returns a null string
|
||||
if (filePath.isEmpty())
|
||||
return;
|
||||
|
||||
m_workspaceModel.importWorkspace(fileName);
|
||||
previousDirectory = QFileInfo(filePath).absolutePath();
|
||||
|
||||
const Utils::expected_str<QString> newFileName = m_manager->importWorkspace(filePath);
|
||||
if (newFileName)
|
||||
m_workspaceModel.resetWorkspaces();
|
||||
else
|
||||
QMessageBox::warning(this, Tr::tr("Cannot Import Workspace"), newFileName.error());
|
||||
}
|
||||
|
||||
void WorkspaceView::exportCurrentWorkspace()
|
||||
{
|
||||
static QString lastDir;
|
||||
const QString currentDir = lastDir.isEmpty() ? "" : lastDir;
|
||||
QFileInfo fileInfo(currentDir, m_manager->workspaceNameToFileName(currentWorkspace()));
|
||||
static QString previousDirectory;
|
||||
const QString currentDirectory = previousDirectory.isEmpty() ? "" : previousDirectory;
|
||||
QFileInfo fileInfo(currentDirectory, currentWorkspace());
|
||||
|
||||
const auto fileName = QFileDialog::getSaveFileName(this,
|
||||
Tr::tr("Export Workspace"),
|
||||
fileInfo.absoluteFilePath(),
|
||||
"Workspaces (*" + m_manager->workspaceFileExtension() + ")");
|
||||
const auto filePath
|
||||
= QFileDialog::getSaveFileName(this,
|
||||
Tr::tr("Export Workspace"),
|
||||
fileInfo.absoluteFilePath(),
|
||||
QString("Workspaces (*.%1)").arg(workspaceFileExtension));
|
||||
|
||||
if (!fileName.isEmpty())
|
||||
lastDir = QFileInfo(fileName).absolutePath();
|
||||
// If the user presses Cancel, it returns a null string
|
||||
if (filePath.isEmpty())
|
||||
return;
|
||||
|
||||
m_workspaceModel.exportWorkspace(fileName, currentWorkspace());
|
||||
previousDirectory = QFileInfo(filePath).absolutePath();
|
||||
|
||||
const Utils::expected_str<QString> result = m_manager->exportWorkspace(filePath,
|
||||
currentWorkspace());
|
||||
|
||||
if (!result)
|
||||
QMessageBox::warning(this, Tr::tr("Cannot Export Workspace"), result.error());
|
||||
}
|
||||
|
||||
void WorkspaceView::cloneCurrentWorkspace()
|
||||
void WorkspaceView::moveWorkspaceUp()
|
||||
{
|
||||
m_workspaceModel.cloneWorkspace(this, currentWorkspace());
|
||||
const QString w = currentWorkspace();
|
||||
bool hasMoved = m_manager->moveWorkspaceUp(w);
|
||||
if (hasMoved) {
|
||||
m_workspaceModel.resetWorkspaces();
|
||||
selectWorkspace(w);
|
||||
}
|
||||
}
|
||||
|
||||
void WorkspaceView::renameCurrentWorkspace()
|
||||
void WorkspaceView::moveWorkspaceDown()
|
||||
{
|
||||
m_workspaceModel.renameWorkspace(this, currentWorkspace());
|
||||
}
|
||||
|
||||
void WorkspaceView::resetCurrentWorkspace()
|
||||
{
|
||||
m_workspaceModel.resetWorkspace(currentWorkspace());
|
||||
}
|
||||
|
||||
void WorkspaceView::switchToCurrentWorkspace()
|
||||
{
|
||||
m_workspaceModel.switchToWorkspace(currentWorkspace());
|
||||
const QString w = currentWorkspace();
|
||||
bool hasMoved = m_manager->moveWorkspaceDown(w);
|
||||
if (hasMoved) {
|
||||
m_workspaceModel.resetWorkspaces();
|
||||
selectWorkspace(w);
|
||||
}
|
||||
}
|
||||
|
||||
QString WorkspaceView::currentWorkspace()
|
||||
@@ -155,17 +247,24 @@ WorkspaceModel *WorkspaceView::workspaceModel()
|
||||
|
||||
void WorkspaceView::selectActiveWorkspace()
|
||||
{
|
||||
selectWorkspace(m_manager->activeWorkspace());
|
||||
selectWorkspace(m_manager->activeWorkspace()->fileName());
|
||||
}
|
||||
|
||||
void WorkspaceView::selectWorkspace(const QString &workspaceName)
|
||||
void WorkspaceView::selectWorkspace(const QString &fileName)
|
||||
{
|
||||
int row = m_workspaceModel.indexOfWorkspace(workspaceName);
|
||||
int row = m_workspaceModel.indexOfWorkspace(fileName);
|
||||
selectionModel()->setCurrentIndex(model()->index(row, 0),
|
||||
QItemSelectionModel::ClearAndSelect
|
||||
| QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
QStringList WorkspaceView::selectedWorkspaces() const
|
||||
{
|
||||
return Utils::transform(selectionModel()->selectedRows(), [this](const QModelIndex &index) {
|
||||
return m_workspaceModel.workspaceAt(index.row());
|
||||
});
|
||||
}
|
||||
|
||||
void WorkspaceView::showEvent(QShowEvent *event)
|
||||
{
|
||||
Utils::TreeView::showEvent(event);
|
||||
@@ -179,19 +278,83 @@ void WorkspaceView::keyPressEvent(QKeyEvent *event)
|
||||
TreeView::keyPressEvent(event);
|
||||
return;
|
||||
}
|
||||
const QStringList workspaces = selectedWorkspaces();
|
||||
if (!Utils::anyOf(workspaces, [this](const QString &workspace) {
|
||||
return workspace == m_manager->activeWorkspace();
|
||||
const QStringList fileNames = selectedWorkspaces();
|
||||
if (!Utils::anyOf(fileNames, [this](const QString &fileName) {
|
||||
return fileName == *m_manager->activeWorkspace();
|
||||
})) {
|
||||
deleteWorkspaces(workspaces);
|
||||
deleteWorkspaces(fileNames);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList WorkspaceView::selectedWorkspaces() const
|
||||
void WorkspaceView::dropEvent(QDropEvent *event)
|
||||
{
|
||||
return Utils::transform(selectionModel()->selectedRows(), [this](const QModelIndex &index) {
|
||||
return m_workspaceModel.workspaceAt(index.row());
|
||||
});
|
||||
const QModelIndex dropIndex = indexAt(event->pos());
|
||||
const DropIndicatorPosition dropIndicator = dropIndicatorPosition();
|
||||
|
||||
const auto droppedWorkspaces = selectedWorkspaces();
|
||||
int from = m_manager->workspaceIndex(droppedWorkspaces.first());
|
||||
int to = dropIndex.row();
|
||||
|
||||
if (dropIndicator == QAbstractItemView::AboveItem && from < to)
|
||||
--to;
|
||||
if (dropIndicator == QAbstractItemView::BelowItem && from > to)
|
||||
++to;
|
||||
|
||||
bool hasMoved = m_manager->moveWorkspace(from, to);
|
||||
|
||||
if (hasMoved) {
|
||||
m_workspaceModel.resetWorkspaces();
|
||||
selectionModel()->setCurrentIndex(model()->index(to, 0),
|
||||
QItemSelectionModel::ClearAndSelect
|
||||
| QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void WorkspaceView::deleteWorkspaces(const QStringList &fileNames)
|
||||
{
|
||||
if (!confirmWorkspaceDelete(fileNames))
|
||||
return;
|
||||
|
||||
m_manager->deleteWorkspaces(fileNames);
|
||||
m_workspaceModel.resetWorkspaces();
|
||||
}
|
||||
|
||||
bool WorkspaceView::confirmWorkspaceDelete(const QStringList &fileNames)
|
||||
{
|
||||
const QString title = fileNames.size() == 1 ? Tr::tr("Delete Workspace")
|
||||
: Tr::tr("Delete Workspaces");
|
||||
const QString question
|
||||
= fileNames.size() == 1
|
||||
? Tr::tr("Delete workspace %1?").arg(fileNames.first())
|
||||
: Tr::tr("Delete these workspaces?\n %1").arg(fileNames.join("\n "));
|
||||
return QMessageBox::question(parentWidget(), title, question, QMessageBox::Yes | QMessageBox::No)
|
||||
== QMessageBox::Yes;
|
||||
}
|
||||
|
||||
void WorkspaceView::runWorkspaceNameInputDialog(
|
||||
WorkspaceNameInputDialog *workspaceInputDialog,
|
||||
std::function<Utils::expected_str<QString>(const QString &)> callback)
|
||||
{
|
||||
if (workspaceInputDialog->exec() == QDialog::Accepted) {
|
||||
const QString newWorkspace = workspaceInputDialog->value();
|
||||
if (newWorkspace.isEmpty() || m_manager->workspaces().contains(newWorkspace))
|
||||
return;
|
||||
|
||||
const Utils::expected_str<QString> fileName = callback(newWorkspace);
|
||||
if (!fileName)
|
||||
return;
|
||||
|
||||
m_workspaceModel.resetWorkspaces();
|
||||
|
||||
if (workspaceInputDialog->isSwitchToRequested()) {
|
||||
m_manager->openWorkspace(*fileName);
|
||||
emit workspaceSwitched();
|
||||
}
|
||||
|
||||
selectWorkspace(*fileName);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ADS
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "workspaceinputdialog.h"
|
||||
#include "workspacemodel.h"
|
||||
|
||||
#include <utils/expected.h>
|
||||
#include <utils/itemviews.h>
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
namespace ADS {
|
||||
|
||||
class DockManager;
|
||||
@@ -22,32 +22,42 @@ public:
|
||||
explicit WorkspaceView(DockManager *manager, QWidget *parent = nullptr);
|
||||
|
||||
void createNewWorkspace();
|
||||
void deleteSelectedWorkspaces();
|
||||
void cloneCurrentWorkspace();
|
||||
void renameCurrentWorkspace();
|
||||
void resetCurrentWorkspace();
|
||||
void switchToCurrentWorkspace();
|
||||
void deleteSelectedWorkspaces();
|
||||
|
||||
void importWorkspace();
|
||||
void exportCurrentWorkspace();
|
||||
|
||||
void moveWorkspaceUp();
|
||||
void moveWorkspaceDown();
|
||||
|
||||
QString currentWorkspace();
|
||||
WorkspaceModel *workspaceModel();
|
||||
void selectActiveWorkspace();
|
||||
void selectWorkspace(const QString &workspaceName);
|
||||
void selectWorkspace(const QString &fileName);
|
||||
|
||||
QStringList selectedWorkspaces() const;
|
||||
|
||||
signals:
|
||||
void workspaceActivated(const QString &workspace);
|
||||
void workspacesSelected(const QStringList &workspaces);
|
||||
void workspaceActivated(const QString &fileName);
|
||||
void workspacesSelected(const QStringList &fileNames);
|
||||
void workspaceSwitched();
|
||||
|
||||
private:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
|
||||
void deleteWorkspaces(const QStringList &workspaces);
|
||||
void deleteWorkspaces(const QStringList &fileNames);
|
||||
|
||||
bool confirmWorkspaceDelete(const QStringList &fileNames);
|
||||
|
||||
void runWorkspaceNameInputDialog(
|
||||
WorkspaceNameInputDialog *workspaceInputDialog,
|
||||
std::function<Utils::expected_str<QString>(const QString &)> callback);
|
||||
|
||||
DockManager *m_manager;
|
||||
WorkspaceModel m_workspaceModel;
|
||||
|
||||
@@ -19,7 +19,11 @@ public:
|
||||
RenderModelNodePreviewImage,
|
||||
Import3DSupport,
|
||||
NodeAtPos,
|
||||
None };
|
||||
BakeLightsProgress,
|
||||
BakeLightsFinished,
|
||||
BakeLightsAborted,
|
||||
None
|
||||
};
|
||||
|
||||
PuppetToCreatorCommand(Type type, const QVariant &data);
|
||||
PuppetToCreatorCommand() = default;
|
||||
|
||||
@@ -48,7 +48,8 @@ enum class View3DActionType {
|
||||
SelectGridColor,
|
||||
ResetBackgroundColor,
|
||||
SyncBackgroundColor,
|
||||
GetNodeAtPos
|
||||
GetNodeAtPos,
|
||||
SetBakeLightsView3D
|
||||
};
|
||||
|
||||
constexpr bool isNanotraceEnabled()
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
return first.id - second.id;
|
||||
}
|
||||
|
||||
constexpr bool isValid() const { return id >= 0; }
|
||||
constexpr bool isValid() const { return id > 0; }
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
[[noreturn, deprecated]] InternalIntegerType operator&() const { throw std::exception{}; }
|
||||
|
||||
private:
|
||||
InternalIntegerType id = -1;
|
||||
InternalIntegerType id = 0;
|
||||
};
|
||||
|
||||
template<typename Container>
|
||||
|
||||
@@ -17,7 +17,7 @@ LibraryInitializer::LibraryInitializer()
|
||||
DatabaseBackend::initializeSqliteLibrary();
|
||||
}
|
||||
|
||||
LibraryInitializer::~LibraryInitializer()
|
||||
LibraryInitializer::~LibraryInitializer() noexcept(false)
|
||||
{
|
||||
DatabaseBackend::shutdownSqliteLibrary();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
|
||||
private:
|
||||
LibraryInitializer();
|
||||
~LibraryInitializer();
|
||||
~LibraryInitializer() noexcept(false);
|
||||
};
|
||||
|
||||
} // namespace Sqlite
|
||||
|
||||
@@ -34,57 +34,39 @@ public:
|
||||
template<typename ResultType, typename... QueryTypes>
|
||||
auto valueWithTransaction(const QueryTypes &...queryValues)
|
||||
{
|
||||
DeferredTransaction transaction{Base::database()};
|
||||
|
||||
auto resultValue = Base::template value<ResultType>(queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
return resultValue;
|
||||
return withDeferredTransaction(Base::database(), [&] {
|
||||
return Base::template value<ResultType>(queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename ResultType, typename... QueryTypes>
|
||||
auto optionalValueWithTransaction(const QueryTypes &...queryValues)
|
||||
{
|
||||
DeferredTransaction transaction{Base::database()};
|
||||
|
||||
auto resultValue = Base::template optionalValue<ResultType>(queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
return resultValue;
|
||||
return withDeferredTransaction(Base::database(), [&] {
|
||||
return Base::template optionalValue<ResultType>(queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename ResultType, typename... QueryTypes>
|
||||
auto valuesWithTransaction(std::size_t reserveSize, const QueryTypes &...queryValues)
|
||||
{
|
||||
DeferredTransaction transaction{Base::database()};
|
||||
|
||||
auto resultValues = Base::template values<ResultType>(reserveSize, queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
return resultValues;
|
||||
return withDeferredTransaction(Base::database(), [&] {
|
||||
return Base::template values<ResultType>(reserveSize, queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Callable, typename... QueryTypes>
|
||||
void readCallbackWithTransaction(Callable &&callable, const QueryTypes &...queryValues)
|
||||
{
|
||||
DeferredTransaction transaction{Base::database()};
|
||||
|
||||
Base::readCallback(std::forward<Callable>(callable), queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
withDeferredTransaction(Base::database(), [&] {
|
||||
Base::readCallback(std::forward<Callable>(callable), queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Container, typename... QueryTypes>
|
||||
void readToWithTransaction(Container &container, const QueryTypes &...queryValues)
|
||||
{
|
||||
DeferredTransaction transaction{Base::database()};
|
||||
|
||||
Base::readTo(container, queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
withDeferredTransaction(Base::database(), [&] { Base::readTo(container, queryValues...); });
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -34,66 +34,48 @@ public:
|
||||
template<typename ResultType, typename... QueryTypes>
|
||||
auto valueWithTransaction(const QueryTypes &...queryValues)
|
||||
{
|
||||
ImmediateTransaction transaction{Base::database()};
|
||||
|
||||
auto resultValue = Base::template value<ResultType>(queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
return resultValue;
|
||||
return withImmediateTransaction(Base::database(), [&] {
|
||||
return Base::template value<ResultType>(queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename ResultType, typename... QueryTypes>
|
||||
auto optionalValueWithTransaction(const QueryTypes &...queryValues)
|
||||
{
|
||||
ImmediateTransaction transaction{Base::database()};
|
||||
|
||||
auto resultValue = Base::template optionalValue<ResultType>(queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
return resultValue;
|
||||
return withImmediateTransaction(Base::database(), [&] {
|
||||
return Base::template optionalValue<ResultType>(queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename ResultType, typename... QueryTypes>
|
||||
auto valuesWithTransaction(std::size_t reserveSize, const QueryTypes &...queryValues)
|
||||
{
|
||||
ImmediateTransaction transaction{Base::database()};
|
||||
|
||||
auto resultValues = Base::template values<ResultType>(reserveSize, queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
return resultValues;
|
||||
return withImmediateTransaction(Base::database(), [&] {
|
||||
return Base::template values<ResultType>(reserveSize, queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Callable, typename... QueryTypes>
|
||||
void readCallbackWithTransaction(Callable &&callable, const QueryTypes &...queryValues)
|
||||
{
|
||||
ImmediateTransaction transaction{Base::database()};
|
||||
|
||||
Base::readCallback(std::forward<Callable>(callable), queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
withImmediateTransaction(Base::database(), [&] {
|
||||
Base::readCallback(std::forward<Callable>(callable), queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Container, typename... QueryTypes>
|
||||
void readToWithTransaction(Container &container, const QueryTypes &...queryValues)
|
||||
{
|
||||
ImmediateTransaction transaction{Base::database()};
|
||||
|
||||
Base::readTo(container, queryValues...);
|
||||
|
||||
transaction.commit();
|
||||
withImmediateTransaction(Base::database(), [&] {
|
||||
Base::readTo(container, queryValues...);
|
||||
});
|
||||
}
|
||||
|
||||
void executeWithTransaction()
|
||||
{
|
||||
ImmediateTransaction transaction{Base::database()};
|
||||
|
||||
Base::execute();
|
||||
|
||||
transaction.commit();
|
||||
withImmediateTransaction(Base::database(), [&] {
|
||||
Base::execute();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ void Sessions::create()
|
||||
{
|
||||
sqlite3_session *newSession = nullptr;
|
||||
int resultCode = sqlite3session_create(database.backend().sqliteDatabaseHandle(),
|
||||
std::string(databaseName.data()).c_str(),
|
||||
std::string(databaseName).c_str(),
|
||||
&newSession);
|
||||
session.reset(newSession);
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ protected:
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
TransactionInterface &m_interface;
|
||||
std::unique_lock<TransactionInterface> m_locker{m_interface};
|
||||
@@ -183,6 +182,38 @@ public:
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename Transaction, typename TransactionInterface, typename Callable>
|
||||
auto withTransaction(TransactionInterface &transactionInterface, Callable &&callable)
|
||||
-> std::invoke_result_t<Callable>
|
||||
{
|
||||
Transaction transaction{transactionInterface};
|
||||
|
||||
if constexpr (std::is_void_v<std::invoke_result_t<Callable>>) {
|
||||
callable();
|
||||
|
||||
transaction.commit();
|
||||
} else {
|
||||
auto results = callable();
|
||||
|
||||
transaction.commit();
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TransactionInterface, typename Callable>
|
||||
auto withDeferredTransaction(TransactionInterface &transactionInterface, Callable &&callable)
|
||||
{
|
||||
if constexpr (std::is_void_v<std::invoke_result_t<Callable>>) {
|
||||
withTransaction<DeferredTransaction<TransactionInterface>>(transactionInterface,
|
||||
std::forward<Callable>(callable));
|
||||
} else {
|
||||
return withTransaction<DeferredTransaction<TransactionInterface>>(transactionInterface,
|
||||
std::forward<Callable>(
|
||||
callable));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TransactionInterface>
|
||||
DeferredTransaction(TransactionInterface &) -> DeferredTransaction<TransactionInterface>;
|
||||
|
||||
@@ -226,6 +257,20 @@ public:
|
||||
using Base::Base;
|
||||
};
|
||||
|
||||
template<typename TransactionInterface, typename Callable>
|
||||
auto withImmediateTransaction(TransactionInterface &transactionInterface, Callable &&callable)
|
||||
{
|
||||
if constexpr (std::is_void_v<std::invoke_result_t<Callable>>) {
|
||||
withTransaction<ImmediateTransaction<TransactionInterface>>(transactionInterface,
|
||||
std::forward<Callable>(
|
||||
callable));
|
||||
} else {
|
||||
return withTransaction<ImmediateTransaction<TransactionInterface>>(transactionInterface,
|
||||
std::forward<Callable>(
|
||||
callable));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TransactionInterface>
|
||||
ImmediateTransaction(TransactionInterface &) -> ImmediateTransaction<TransactionInterface>;
|
||||
|
||||
|
||||
@@ -186,9 +186,11 @@ add_qtc_library(Utils
|
||||
tooltip/tips.cpp tooltip/tips.h
|
||||
tooltip/tooltip.cpp tooltip/tooltip.h
|
||||
touchbar/touchbar.h
|
||||
transientscroll.cpp transientscroll.h
|
||||
treemodel.cpp treemodel.h
|
||||
treeviewcombobox.cpp treeviewcombobox.h
|
||||
uncommentselection.cpp uncommentselection.h
|
||||
uniqueobjectptr.h
|
||||
unixutils.cpp unixutils.h
|
||||
url.cpp url.h
|
||||
utils.qrc
|
||||
|
||||
@@ -92,9 +92,11 @@ public:
|
||||
/*!
|
||||
Constructs a BaseAspect.
|
||||
*/
|
||||
BaseAspect::BaseAspect()
|
||||
BaseAspect::BaseAspect(AspectContainer *container)
|
||||
: d(new Internal::BaseAspectPrivate)
|
||||
{
|
||||
if (container)
|
||||
container->registerAspect(this);
|
||||
addDataExtractor(this, &BaseAspect::value, &Data::value);
|
||||
}
|
||||
|
||||
@@ -766,8 +768,8 @@ public:
|
||||
Constructs a StringAspect.
|
||||
*/
|
||||
|
||||
StringAspect::StringAspect()
|
||||
: d(new Internal::StringAspectPrivate)
|
||||
StringAspect::StringAspect(AspectContainer *container)
|
||||
: BaseAspect(container), d(new Internal::StringAspectPrivate)
|
||||
{
|
||||
setDefaultValue(QString());
|
||||
setSpan(2, 1); // Default: Label + something
|
||||
@@ -1134,7 +1136,7 @@ void StringAspect::addToLayout(LayoutItem &parent)
|
||||
if (d->m_blockAutoApply)
|
||||
return;
|
||||
d->m_blockAutoApply = true;
|
||||
setValue(d->m_pathChooserDisplay->filePath().toString());
|
||||
setValueQuietly(d->m_pathChooserDisplay->filePath().toString());
|
||||
d->m_blockAutoApply = false;
|
||||
};
|
||||
connect(d->m_pathChooserDisplay, &PathChooser::editingFinished, this, setPathChooserValue);
|
||||
@@ -1142,7 +1144,7 @@ void StringAspect::addToLayout(LayoutItem &parent)
|
||||
} else {
|
||||
connect(d->m_pathChooserDisplay, &PathChooser::textChanged,
|
||||
this, [this](const QString &path) {
|
||||
setValue(path);
|
||||
setValueQuietly(path);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1359,8 +1361,8 @@ FilePathAspect::FilePathAspect()
|
||||
The color aspect is displayed using a QtColorButton.
|
||||
*/
|
||||
|
||||
ColorAspect::ColorAspect()
|
||||
: d(new Internal::ColorAspectPrivate)
|
||||
ColorAspect::ColorAspect(AspectContainer *container)
|
||||
: BaseAspect(container), d(new Internal::ColorAspectPrivate)
|
||||
{
|
||||
setDefaultValue(QColor::fromRgb(0, 0, 0));
|
||||
setSpan(1, 1);
|
||||
@@ -1426,8 +1428,8 @@ void ColorAspect::setVolatileValue(const QVariant &val)
|
||||
*/
|
||||
|
||||
|
||||
BoolAspect::BoolAspect()
|
||||
: d(new Internal::BoolAspectPrivate)
|
||||
BoolAspect::BoolAspect(AspectContainer *container)
|
||||
: BaseAspect(container), d(new Internal::BoolAspectPrivate)
|
||||
{
|
||||
setDefaultValue(false);
|
||||
setSpan(2, 1);
|
||||
@@ -1605,8 +1607,8 @@ CheckableDecider BoolAspect::checkableDecider()
|
||||
QRadioButtons in a QButtonGroup.
|
||||
*/
|
||||
|
||||
SelectionAspect::SelectionAspect()
|
||||
: d(new Internal::SelectionAspectPrivate)
|
||||
SelectionAspect::SelectionAspect(AspectContainer *container)
|
||||
: BaseAspect(container), d(new Internal::SelectionAspectPrivate)
|
||||
{
|
||||
setSpan(2, 1);
|
||||
}
|
||||
@@ -1808,8 +1810,8 @@ QVariant SelectionAspect::itemValueForIndex(int index) const
|
||||
checkable items.
|
||||
*/
|
||||
|
||||
MultiSelectionAspect::MultiSelectionAspect()
|
||||
: d(new Internal::MultiSelectionAspectPrivate(this))
|
||||
MultiSelectionAspect::MultiSelectionAspect(AspectContainer *container)
|
||||
: BaseAspect(container), d(new Internal::MultiSelectionAspectPrivate(this))
|
||||
{
|
||||
setDefaultValue(QStringList());
|
||||
setSpan(2, 1);
|
||||
@@ -1915,8 +1917,8 @@ void MultiSelectionAspect::setValue(const QStringList &value)
|
||||
|
||||
// IntegerAspect
|
||||
|
||||
IntegerAspect::IntegerAspect()
|
||||
: d(new Internal::IntegerAspectPrivate)
|
||||
IntegerAspect::IntegerAspect(AspectContainer *container)
|
||||
: BaseAspect(container), d(new Internal::IntegerAspectPrivate)
|
||||
{
|
||||
setDefaultValue(qint64(0));
|
||||
setSpan(2, 1);
|
||||
@@ -2051,8 +2053,8 @@ void IntegerAspect::setSingleStep(qint64 step)
|
||||
the display of the spin box.
|
||||
*/
|
||||
|
||||
DoubleAspect::DoubleAspect()
|
||||
: d(new Internal::DoubleAspectPrivate)
|
||||
DoubleAspect::DoubleAspect(AspectContainer *container)
|
||||
: BaseAspect(container), d(new Internal::DoubleAspectPrivate)
|
||||
{
|
||||
setDefaultValue(double(0));
|
||||
setSpan(2, 1);
|
||||
@@ -2206,8 +2208,8 @@ TriState TriState::fromVariant(const QVariant &variant)
|
||||
that is a list of strings.
|
||||
*/
|
||||
|
||||
StringListAspect::StringListAspect()
|
||||
: d(new Internal::StringListAspectPrivate)
|
||||
StringListAspect::StringListAspect(AspectContainer *container)
|
||||
: BaseAspect(container), d(new Internal::StringListAspectPrivate)
|
||||
{
|
||||
setDefaultValue(QStringList());
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class QTCREATOR_UTILS_EXPORT BaseAspect : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BaseAspect();
|
||||
BaseAspect(AspectContainer *container = nullptr);
|
||||
~BaseAspect() override;
|
||||
|
||||
Id id() const;
|
||||
@@ -213,7 +213,7 @@ class QTCREATOR_UTILS_EXPORT BoolAspect : public BaseAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BoolAspect();
|
||||
BoolAspect(AspectContainer *container = nullptr);
|
||||
~BoolAspect() override;
|
||||
|
||||
struct Data : BaseAspect::Data
|
||||
@@ -257,7 +257,7 @@ class QTCREATOR_UTILS_EXPORT ColorAspect : public BaseAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ColorAspect();
|
||||
ColorAspect(AspectContainer *container = nullptr);
|
||||
~ColorAspect() override;
|
||||
|
||||
struct Data : BaseAspect::Data
|
||||
@@ -282,7 +282,7 @@ class QTCREATOR_UTILS_EXPORT SelectionAspect : public BaseAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SelectionAspect();
|
||||
SelectionAspect(AspectContainer *container = nullptr);
|
||||
~SelectionAspect() override;
|
||||
|
||||
void addToLayout(Layouting::LayoutItem &parent) override;
|
||||
@@ -336,7 +336,7 @@ class QTCREATOR_UTILS_EXPORT MultiSelectionAspect : public BaseAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MultiSelectionAspect();
|
||||
MultiSelectionAspect(AspectContainer *container = nullptr);
|
||||
~MultiSelectionAspect() override;
|
||||
|
||||
void addToLayout(Layouting::LayoutItem &parent) override;
|
||||
@@ -359,7 +359,7 @@ class QTCREATOR_UTILS_EXPORT StringAspect : public BaseAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
StringAspect();
|
||||
StringAspect(AspectContainer *container = nullptr);
|
||||
~StringAspect() override;
|
||||
|
||||
struct Data : BaseAspect::Data
|
||||
@@ -456,7 +456,7 @@ class QTCREATOR_UTILS_EXPORT IntegerAspect : public BaseAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IntegerAspect();
|
||||
IntegerAspect(AspectContainer *container = nullptr);
|
||||
~IntegerAspect() override;
|
||||
|
||||
void addToLayout(Layouting::LayoutItem &parent) override;
|
||||
@@ -494,7 +494,7 @@ class QTCREATOR_UTILS_EXPORT DoubleAspect : public BaseAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DoubleAspect();
|
||||
DoubleAspect(AspectContainer *container = nullptr);
|
||||
~DoubleAspect() override;
|
||||
|
||||
void addToLayout(Layouting::LayoutItem &parent) override;
|
||||
@@ -563,7 +563,7 @@ class QTCREATOR_UTILS_EXPORT StringListAspect : public BaseAspect
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
StringListAspect();
|
||||
StringListAspect(AspectContainer *container = nullptr);
|
||||
~StringListAspect() override;
|
||||
|
||||
void addToLayout(Layouting::LayoutItem &parent) override;
|
||||
|
||||
@@ -116,6 +116,7 @@ public:
|
||||
|
||||
const QColor m_okTextColor;
|
||||
const QColor m_errorTextColor;
|
||||
const QColor m_placeholderTextColor;
|
||||
QString m_errorMessage;
|
||||
};
|
||||
|
||||
@@ -124,7 +125,9 @@ FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
|
||||
m_lineEdit(parent),
|
||||
m_completionShortcut(completionShortcut()->key(), parent),
|
||||
m_okTextColor(creatorTheme()->color(Theme::TextColorNormal)),
|
||||
m_errorTextColor(creatorTheme()->color(Theme::TextColorError))
|
||||
m_errorTextColor(creatorTheme()->color(Theme::TextColorError)),
|
||||
m_placeholderTextColor(creatorTheme()->color(Theme::PalettePlaceholderText))
|
||||
|
||||
{
|
||||
m_completionShortcut.setContext(Qt::WidgetShortcut);
|
||||
connect(completionShortcut(), &CompletionShortcut::keyChanged,
|
||||
@@ -486,15 +489,18 @@ void FancyLineEdit::validate()
|
||||
setToolTip(d->m_errorMessage);
|
||||
d->m_toolTipSet = true;
|
||||
}
|
||||
// Changed..figure out if valid changed. DisplayingPlaceholderText is not valid,
|
||||
// but should not show error color. Also trigger on the first change.
|
||||
// Changed..figure out if valid changed. Also trigger on the first change.
|
||||
// Invalid DisplayingPlaceholderText shows also error color.
|
||||
if (newState != d->m_state || d->m_firstChange) {
|
||||
const bool validHasChanged = (d->m_state == Valid) != (newState == Valid);
|
||||
d->m_state = newState;
|
||||
d->m_firstChange = false;
|
||||
|
||||
QPalette p = palette();
|
||||
p.setColor(QPalette::Active, QPalette::Text, newState == Invalid ? d->m_errorTextColor : d->m_okTextColor);
|
||||
p.setColor(QPalette::Active, QPalette::Text,
|
||||
newState == Invalid ? d->m_errorTextColor : d->m_okTextColor);
|
||||
p.setColor(QPalette::Active, QPalette::PlaceholderText,
|
||||
validates ? d->m_placeholderTextColor : d->m_errorTextColor);
|
||||
setPalette(p);
|
||||
|
||||
if (validHasChanged)
|
||||
|
||||
@@ -278,11 +278,6 @@ public:
|
||||
return Q_LIKELY(isShortString()) ? m_data.shortString : m_data.reference.pointer;
|
||||
}
|
||||
|
||||
const char *constData() const noexcept
|
||||
{
|
||||
return data();
|
||||
}
|
||||
|
||||
iterator begin() noexcept
|
||||
{
|
||||
return data();
|
||||
@@ -315,7 +310,7 @@ public:
|
||||
|
||||
const_iterator begin() const noexcept
|
||||
{
|
||||
return constData();
|
||||
return data();
|
||||
}
|
||||
|
||||
const_iterator end() const noexcept
|
||||
|
||||
222
src/libs/utils/transientscroll.cpp
Normal file
222
src/libs/utils/transientscroll.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "transientscroll.h"
|
||||
|
||||
#include <QAbstractScrollArea>
|
||||
#include <QMouseEvent>
|
||||
#include <QPointer>
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
static constexpr char transientScrollAreaSupportName[] = "transientScrollAreSupport";
|
||||
|
||||
class Utils::ScrollAreaPrivate
|
||||
{
|
||||
public:
|
||||
ScrollAreaPrivate(QAbstractScrollArea *area)
|
||||
: area(area)
|
||||
{
|
||||
verticalScrollBar = new ScrollBar(area);
|
||||
area->setVerticalScrollBar(verticalScrollBar);
|
||||
|
||||
horizontalScrollBar = new ScrollBar(area);
|
||||
area->setHorizontalScrollBar(horizontalScrollBar);
|
||||
|
||||
area->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
}
|
||||
|
||||
inline QRect scrollBarRect(ScrollBar *scrollBar)
|
||||
{
|
||||
QRect rect = viewPort ? viewPort->rect() : area->rect();
|
||||
if (scrollBar->orientation() == Qt::Vertical) {
|
||||
int mDiff = rect.width() - scrollBar->sizeHint().width();
|
||||
return rect.adjusted(mDiff, 0, mDiff, 0);
|
||||
} else {
|
||||
int mDiff = rect.height() - scrollBar->sizeHint().height();
|
||||
return rect.adjusted(0, mDiff, 0, mDiff);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool checkToFlashScroll(QPointer<ScrollBar> scrollBar, const QPoint &pos)
|
||||
{
|
||||
if (scrollBar.isNull())
|
||||
return false;
|
||||
|
||||
if (!scrollBar->style()->styleHint(
|
||||
QStyle::SH_ScrollBar_Transient,
|
||||
nullptr, scrollBar))
|
||||
return false;
|
||||
|
||||
if (scrollBarRect(scrollBar).contains(pos)) {
|
||||
scrollBar->flash();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool checkToFlashScroll(const QPoint &pos)
|
||||
{
|
||||
bool coversScroll = checkToFlashScroll(verticalScrollBar, pos);
|
||||
if (!coversScroll)
|
||||
coversScroll |= checkToFlashScroll(horizontalScrollBar, pos);
|
||||
|
||||
return coversScroll;
|
||||
}
|
||||
|
||||
inline void installViewPort(QObject *eventHandler) {
|
||||
QWidget *viewPort = area->viewport();
|
||||
if (viewPort
|
||||
&& viewPort != this->viewPort
|
||||
&& viewPort->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, viewPort)
|
||||
&& (area->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff
|
||||
|| area->horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) {
|
||||
viewPort->installEventFilter(eventHandler);
|
||||
this->viewPort = viewPort;
|
||||
}
|
||||
}
|
||||
|
||||
inline void uninstallViewPort(QObject *eventHandler) {
|
||||
if (viewPort) {
|
||||
viewPort->removeEventFilter(eventHandler);
|
||||
this->viewPort = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QAbstractScrollArea *area = nullptr;
|
||||
QPointer<QWidget> viewPort = nullptr;
|
||||
QPointer<ScrollBar> verticalScrollBar;
|
||||
QPointer<ScrollBar> horizontalScrollBar;
|
||||
};
|
||||
|
||||
TransientScrollAreaSupport::TransientScrollAreaSupport(QAbstractScrollArea *scrollArea)
|
||||
: QObject(scrollArea)
|
||||
, d(new ScrollAreaPrivate(scrollArea))
|
||||
{
|
||||
scrollArea->installEventFilter(this);
|
||||
}
|
||||
|
||||
void TransientScrollAreaSupport::support(QAbstractScrollArea *scrollArea)
|
||||
{
|
||||
QObject *prevSupport = scrollArea->property(transientScrollAreaSupportName)
|
||||
.value<QObject *>();
|
||||
if (!prevSupport)
|
||||
scrollArea->setProperty(transientScrollAreaSupportName,
|
||||
QVariant::fromValue(
|
||||
new TransientScrollAreaSupport(scrollArea))
|
||||
);
|
||||
}
|
||||
|
||||
TransientScrollAreaSupport::~TransientScrollAreaSupport()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool TransientScrollAreaSupport::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::Enter: {
|
||||
if (watched == d->area)
|
||||
d->installViewPort(this);
|
||||
}
|
||||
break;
|
||||
case QEvent::Leave: {
|
||||
if (watched == d->area)
|
||||
d->uninstallViewPort(this);
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseMove: {
|
||||
if (watched == d->viewPort){
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent) {
|
||||
if (d->checkToFlashScroll(mouseEvent->pos()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
class Utils::ScrollBarPrivate {
|
||||
public:
|
||||
bool flashed = false;
|
||||
int flashTimer = 0;
|
||||
};
|
||||
|
||||
ScrollBar::ScrollBar(QWidget *parent)
|
||||
: QScrollBar(parent)
|
||||
, d(new ScrollBarPrivate)
|
||||
{
|
||||
}
|
||||
|
||||
ScrollBar::~ScrollBar()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
QSize ScrollBar::sizeHint() const
|
||||
{
|
||||
QSize sh = QScrollBar::sizeHint();
|
||||
if (style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this)) {
|
||||
constexpr int thickness = 10;
|
||||
if (orientation() == Qt::Horizontal)
|
||||
sh.setHeight(thickness);
|
||||
else
|
||||
sh.setWidth(thickness);
|
||||
} else {
|
||||
constexpr int thickness = 12;
|
||||
if (orientation() == Qt::Horizontal)
|
||||
sh.setHeight(thickness);
|
||||
else
|
||||
sh.setWidth(thickness);
|
||||
}
|
||||
return sh;
|
||||
}
|
||||
|
||||
void ScrollBar::flash()
|
||||
{
|
||||
if (!d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this)) {
|
||||
d->flashed = true;
|
||||
if (!isVisible())
|
||||
show();
|
||||
else
|
||||
update();
|
||||
}
|
||||
if (!d->flashTimer)
|
||||
d->flashTimer = startTimer(0);
|
||||
}
|
||||
|
||||
void ScrollBar::initStyleOption(QStyleOptionSlider *option) const
|
||||
{
|
||||
QScrollBar::initStyleOption(option);
|
||||
|
||||
if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this))
|
||||
option->state |= QStyle::State_On;
|
||||
}
|
||||
|
||||
bool ScrollBar::event(QEvent *event)
|
||||
{
|
||||
switch (event->type()) {
|
||||
case QEvent::Timer:
|
||||
if (static_cast<QTimerEvent *>(event)->timerId() == d->flashTimer) {
|
||||
if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this)) {
|
||||
d->flashed = false;
|
||||
update();
|
||||
}
|
||||
killTimer(d->flashTimer);
|
||||
d->flashTimer = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QScrollBar::event(event);
|
||||
}
|
||||
51
src/libs/utils/transientscroll.h
Normal file
51
src/libs/utils/transientscroll.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utils_global.h"
|
||||
|
||||
#include <QScrollBar>
|
||||
|
||||
class QAbstractScrollArea;
|
||||
|
||||
namespace Utils {
|
||||
class ScrollAreaPrivate;
|
||||
class ScrollBarPrivate;
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT TransientScrollAreaSupport : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static void support(QAbstractScrollArea *scrollArea);
|
||||
virtual ~TransientScrollAreaSupport();
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
|
||||
private:
|
||||
explicit TransientScrollAreaSupport(QAbstractScrollArea *scrollArea);
|
||||
|
||||
ScrollAreaPrivate *d = nullptr;
|
||||
};
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT ScrollBar : public QScrollBar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScrollBar(QWidget *parent = nullptr);
|
||||
virtual ~ScrollBar();
|
||||
|
||||
QSize sizeHint() const override;
|
||||
|
||||
virtual void flash();
|
||||
|
||||
protected:
|
||||
virtual void initStyleOption(QStyleOptionSlider *option) const override;
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
private:
|
||||
ScrollBarPrivate *d = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
86
src/libs/utils/uniqueobjectptr.h
Normal file
86
src/libs/utils/uniqueobjectptr.h
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
#include <memory.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
template<typename Type>
|
||||
class UniqueObjectInternalPointer : public QPointer<Type>
|
||||
{
|
||||
public:
|
||||
using QPointer<Type>::QPointer;
|
||||
|
||||
template<typename UpType,
|
||||
typename = std::enable_if_t<std::is_convertible_v<UpType *, Type *>
|
||||
&& !std::is_same_v<std::decay_t<UpType>, std::decay_t<Type>>>>
|
||||
UniqueObjectInternalPointer(const UniqueObjectInternalPointer<UpType> &p) noexcept
|
||||
: QPointer<Type>{p.data()}
|
||||
{}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
struct UniqueObjectPtrDeleter
|
||||
{
|
||||
using pointer = UniqueObjectInternalPointer<Type>;
|
||||
|
||||
constexpr UniqueObjectPtrDeleter() noexcept = default;
|
||||
template<typename UpType, typename = std::enable_if_t<std::is_convertible_v<UpType *, Type *>>>
|
||||
constexpr UniqueObjectPtrDeleter(const UniqueObjectPtrDeleter<UpType> &) noexcept
|
||||
{}
|
||||
|
||||
constexpr void operator()(pointer p) const
|
||||
{
|
||||
static_assert(!std::is_void_v<Type>, "can't delete pointer to incomplete type");
|
||||
static_assert(sizeof(Type) > 0, "can't delete pointer to incomplete type");
|
||||
|
||||
delete p.data();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
struct UniqueObjectPtrLateDeleter
|
||||
{
|
||||
using pointer = UniqueObjectInternalPointer<Type>;
|
||||
|
||||
constexpr UniqueObjectPtrLateDeleter() noexcept = default;
|
||||
template<typename UpType, typename = std::enable_if_t<std::is_convertible_v<UpType *, Type *>>>
|
||||
constexpr UniqueObjectPtrLateDeleter(const UniqueObjectPtrLateDeleter<UpType> &) noexcept
|
||||
{}
|
||||
|
||||
constexpr void operator()(pointer p) const
|
||||
{
|
||||
static_assert(!std::is_void_v<Type>, "can't delete pointer to incomplete type");
|
||||
static_assert(sizeof(Type) > 0, "can't delete pointer to incomplete type");
|
||||
|
||||
p->deleteLater();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
template<typename Type>
|
||||
using UniqueObjectPtr = std::unique_ptr<Type, Internal::UniqueObjectPtrDeleter<Type>>;
|
||||
|
||||
template<typename Type, typename... Arguments>
|
||||
auto makeUniqueObjectPtr(Arguments &&...arguments)
|
||||
{
|
||||
return UniqueObjectPtr<Type>{new Type(std::forward<Arguments>(arguments)...)};
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
using UniqueObjectLatePtr = std::unique_ptr<Type, Internal::UniqueObjectPtrLateDeleter<Type>>;
|
||||
|
||||
template<typename Type, typename... Arguments>
|
||||
auto makeUniqueObjectLatePtr(Arguments &&...arguments)
|
||||
{
|
||||
return UniqueObjectLatePtr<Type>{new Type(std::forward<Arguments>(arguments)...)};
|
||||
}
|
||||
} // namespace Utils
|
||||
@@ -337,6 +337,7 @@ Project {
|
||||
"headerviewstretcher.h",
|
||||
"uncommentselection.cpp",
|
||||
"uncommentselection.h",
|
||||
"uniqueobjectptr.h",
|
||||
"unixutils.cpp",
|
||||
"unixutils.h",
|
||||
"url.cpp",
|
||||
|
||||
@@ -58,15 +58,18 @@ add_subdirectory(scxmleditor)
|
||||
add_subdirectory(subversion)
|
||||
add_subdirectory(compilationdatabaseprojectmanager)
|
||||
add_subdirectory(languageclient)
|
||||
add_subdirectory(qmldesignerbase)
|
||||
|
||||
if (WITH_QMLDESIGNER)
|
||||
add_subdirectory(qmldesignerbase)
|
||||
endif()
|
||||
|
||||
# Level 6:
|
||||
add_subdirectory(cmakeprojectmanager)
|
||||
add_subdirectory(debugger)
|
||||
add_subdirectory(coco)
|
||||
add_subdirectory(gitlab)
|
||||
add_subdirectory(qmlprojectmanager)
|
||||
if (WITH_QMLDESIGNER)
|
||||
add_subdirectory(qmlprojectmanager)
|
||||
endif()
|
||||
|
||||
# Level 7:
|
||||
add_subdirectory(android)
|
||||
@@ -91,14 +94,17 @@ add_subdirectory(squish)
|
||||
|
||||
# Level 8:
|
||||
add_subdirectory(boot2qt)
|
||||
unset(qmldesigner_builddir)
|
||||
if (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# Workaround for @CMakeFiles\QmlDesigner.rsp ld.lld.exe: The filename or extension is too long.
|
||||
# Clang on Windows is having problems with QmlDesigner.rsp which is bigger than 32KiB
|
||||
set(qmldesigner_builddir ${PROJECT_BINARY_DIR}/qmldsgnr)
|
||||
if (WITH_QMLDESIGNER)
|
||||
unset(qmldesigner_builddir)
|
||||
if (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# Workaround for @CMakeFiles\QmlDesigner.rsp ld.lld.exe: The filename or extension is too long.
|
||||
# Clang on Windows is having problems with QmlDesigner.rsp which is bigger than 32KiB
|
||||
set(qmldesigner_builddir ${PROJECT_BINARY_DIR}/qmldsgnr)
|
||||
endif()
|
||||
add_subdirectory(qmldesigner ${qmldesigner_builddir})
|
||||
add_subdirectory(studiowelcome)
|
||||
add_subdirectory(insight)
|
||||
endif()
|
||||
add_subdirectory(qmldesigner ${qmldesigner_builddir})
|
||||
add_subdirectory(studiowelcome)
|
||||
add_subdirectory(qnx)
|
||||
add_subdirectory(webassembly)
|
||||
add_subdirectory(mcusupport)
|
||||
|
||||
@@ -361,6 +361,14 @@ Abi AndroidManager::androidAbi2Abi(const QString &androidAbi)
|
||||
|
||||
bool AndroidManager::skipInstallationAndPackageSteps(const Target *target)
|
||||
{
|
||||
// For projects using Qt 5.15 and Qt 6, the deployment settings file
|
||||
// is generated by CMake/qmake and not Qt Creator, so if such file doesn't exist
|
||||
// or it's been generated by Qt Creator, we can assume the project is not
|
||||
// an android app.
|
||||
const FilePath inputFile = AndroidQtVersion::androidDeploymentSettings(target);
|
||||
if (!inputFile.exists() || AndroidManager::isQtCreatorGenerated(inputFile))
|
||||
return true;
|
||||
|
||||
const Project *p = target->project();
|
||||
|
||||
const Core::Context cmakeCtx = Core::Context(CMakeProjectManager::Constants::CMAKE_PROJECT_ID);
|
||||
|
||||
@@ -5,7 +5,6 @@ add_qtc_plugin(Beautifier
|
||||
abstractsettings.cpp abstractsettings.h
|
||||
artisticstyle/artisticstyle.cpp artisticstyle/artisticstyle.h
|
||||
artisticstyle/artisticstyleconstants.h
|
||||
artisticstyle/artisticstyleoptionspage.cpp artisticstyle/artisticstyleoptionspage.h
|
||||
artisticstyle/artisticstylesettings.cpp artisticstyle/artisticstylesettings.h
|
||||
beautifier.qrc
|
||||
beautifierabstracttool.h
|
||||
@@ -14,7 +13,6 @@ add_qtc_plugin(Beautifier
|
||||
beautifiertr.h
|
||||
clangformat/clangformat.cpp clangformat/clangformat.h
|
||||
clangformat/clangformatconstants.h
|
||||
clangformat/clangformatoptionspage.cpp clangformat/clangformatoptionspage.h
|
||||
clangformat/clangformatsettings.cpp clangformat/clangformatsettings.h
|
||||
configurationdialog.cpp configurationdialog.h
|
||||
configurationeditor.cpp configurationeditor.h
|
||||
@@ -22,6 +20,5 @@ add_qtc_plugin(Beautifier
|
||||
generalsettings.cpp generalsettings.h
|
||||
uncrustify/uncrustify.cpp uncrustify/uncrustify.h
|
||||
uncrustify/uncrustifyconstants.h
|
||||
uncrustify/uncrustifyoptionspage.cpp uncrustify/uncrustifyoptionspage.h
|
||||
uncrustify/uncrustifysettings.cpp uncrustify/uncrustifysettings.h
|
||||
)
|
||||
|
||||
@@ -26,9 +26,6 @@ using namespace Utils;
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
const char COMMAND[] = "command";
|
||||
const char SUPPORTED_MIME[] = "supportedMime";
|
||||
|
||||
class VersionUpdater
|
||||
{
|
||||
public:
|
||||
@@ -86,9 +83,40 @@ AbstractSettings::AbstractSettings(const QString &name, const QString &ending)
|
||||
, m_styleDir(Core::ICore::userResourcePath(Beautifier::Constants::SETTINGS_DIRNAME)
|
||||
.pathAppended(name)
|
||||
.toString())
|
||||
, m_name(name)
|
||||
, m_versionUpdater(new VersionUpdater)
|
||||
{
|
||||
setSettingsGroups(Utils::Constants::BEAUTIFIER_SETTINGS_GROUP, name);
|
||||
|
||||
registerAspect(&command);
|
||||
command.setSettingsKey("command");
|
||||
command.setExpectedKind(Utils::PathChooser::ExistingCommand);
|
||||
command.setCommandVersionArguments({"--version"});
|
||||
command.setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle("Clang Format"));
|
||||
|
||||
registerAspect(&supportedMimeTypes);
|
||||
supportedMimeTypes.setDisplayStyle(StringAspect::LineEditDisplay);
|
||||
supportedMimeTypes.setSettingsKey("supportedMime");
|
||||
supportedMimeTypes.setLabelText(Tr::tr("Restrict to MIME types:"));
|
||||
supportedMimeTypes.setDefaultValue("text/x-c++src; text/x-c++hdr; text/x-csrc;text/x-chdr; "
|
||||
"text/x-objcsrc; text/x-objc++src");
|
||||
|
||||
supportedMimeTypes.setValueAcceptor([](const QString &, const QString &value) -> std::optional<QString> {
|
||||
const QStringList stringTypes = value.split(';');
|
||||
QStringList types;
|
||||
for (const QString &type : stringTypes) {
|
||||
const MimeType mime = mimeTypeForName(type.trimmed());
|
||||
if (!mime.isValid())
|
||||
continue;
|
||||
const QString canonicalName = mime.name();
|
||||
if (!types.contains(canonicalName))
|
||||
types << canonicalName;
|
||||
}
|
||||
return types.join("; ");
|
||||
});
|
||||
|
||||
connect(&command, &BaseAspect::changed, this, [this] {
|
||||
m_versionUpdater->update(command());
|
||||
});
|
||||
}
|
||||
|
||||
AbstractSettings::~AbstractSettings() = default;
|
||||
@@ -157,20 +185,6 @@ QString AbstractSettings::styleFileName(const QString &key) const
|
||||
return m_styleDir.absoluteFilePath(key + m_ending);
|
||||
}
|
||||
|
||||
FilePath AbstractSettings::command() const
|
||||
{
|
||||
return m_command;
|
||||
}
|
||||
|
||||
void AbstractSettings::setCommand(const FilePath &cmd)
|
||||
{
|
||||
if (cmd == m_command)
|
||||
return;
|
||||
|
||||
m_command = cmd;
|
||||
m_versionUpdater->update(command());
|
||||
}
|
||||
|
||||
QVersionNumber AbstractSettings::version() const
|
||||
{
|
||||
return m_versionUpdater->version();
|
||||
@@ -181,30 +195,6 @@ void AbstractSettings::setVersionRegExp(const QRegularExpression &versionRegExp)
|
||||
m_versionUpdater->setVersionRegExp(versionRegExp);
|
||||
}
|
||||
|
||||
QString AbstractSettings::supportedMimeTypesAsString() const
|
||||
{
|
||||
return m_supportedMimeTypes.join("; ");
|
||||
}
|
||||
|
||||
void AbstractSettings::setSupportedMimeTypes(const QString &mimes)
|
||||
{
|
||||
const QStringList stringTypes = mimes.split(';');
|
||||
QStringList types;
|
||||
for (const QString &type : stringTypes) {
|
||||
const MimeType mime = mimeTypeForName(type.trimmed());
|
||||
if (!mime.isValid())
|
||||
continue;
|
||||
const QString canonicalName = mime.name();
|
||||
if (!types.contains(canonicalName))
|
||||
types << canonicalName;
|
||||
}
|
||||
|
||||
if (m_supportedMimeTypes != types) {
|
||||
m_supportedMimeTypes = types;
|
||||
emit supportedMimeTypesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool AbstractSettings::isApplicable(const Core::IDocument *document) const
|
||||
{
|
||||
if (!document)
|
||||
@@ -240,17 +230,8 @@ void AbstractSettings::save()
|
||||
{
|
||||
// Save settings, except styles
|
||||
QSettings *s = Core::ICore::settings();
|
||||
s->beginGroup(Utils::Constants::BEAUTIFIER_SETTINGS_GROUP);
|
||||
s->beginGroup(m_name);
|
||||
QMap<QString, QVariant>::const_iterator iSettings = m_settings.constBegin();
|
||||
while (iSettings != m_settings.constEnd()) {
|
||||
s->setValue(iSettings.key(), iSettings.value());
|
||||
++iSettings;
|
||||
}
|
||||
s->setValue(COMMAND, m_command.toSettings());
|
||||
s->setValue(SUPPORTED_MIME, supportedMimeTypesAsString());
|
||||
s->endGroup();
|
||||
s->endGroup();
|
||||
|
||||
AspectContainer::writeSettings(s);
|
||||
|
||||
// Save styles
|
||||
if (m_stylesToRemove.isEmpty() && m_styles.isEmpty())
|
||||
@@ -306,27 +287,9 @@ void AbstractSettings::createDocumentationFile() const
|
||||
|
||||
void AbstractSettings::read()
|
||||
{
|
||||
// Set default values
|
||||
setSupportedMimeTypes("text/x-c++src;text/x-c++hdr;text/x-csrc;text/x-chdr;text/x-objcsrc;"
|
||||
"text/x-objc++src");
|
||||
|
||||
// Read settings, except styles
|
||||
QSettings *s = Core::ICore::settings();
|
||||
s->beginGroup(Utils::Constants::BEAUTIFIER_SETTINGS_GROUP);
|
||||
s->beginGroup(m_name);
|
||||
const QStringList keys = s->allKeys();
|
||||
for (const QString &key : keys) {
|
||||
if (key == COMMAND)
|
||||
setCommand(FilePath::fromSettings(s->value(key)));
|
||||
else if (key == SUPPORTED_MIME)
|
||||
setSupportedMimeTypes(s->value(key).toString());
|
||||
else if (m_settings.contains(key))
|
||||
m_settings[key] = s->value(key);
|
||||
else
|
||||
s->remove(key);
|
||||
}
|
||||
s->endGroup();
|
||||
s->endGroup();
|
||||
AspectContainer::readSettings(s);
|
||||
|
||||
m_styles.clear();
|
||||
m_changedStyles.clear();
|
||||
@@ -336,18 +299,19 @@ void AbstractSettings::read()
|
||||
|
||||
void AbstractSettings::readDocumentation()
|
||||
{
|
||||
const QString filename = documentationFilePath();
|
||||
const FilePath filename = documentationFilePath();
|
||||
if (filename.isEmpty()) {
|
||||
BeautifierPlugin::showError(Tr::tr("No documentation file specified."));
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(filename);
|
||||
QFile file(filename.toFSPathString());
|
||||
if (!file.exists())
|
||||
createDocumentationFile();
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
BeautifierPlugin::showError(Tr::tr("Cannot open documentation file \"%1\".").arg(filename));
|
||||
BeautifierPlugin::showError(Tr::tr("Cannot open documentation file \"%1\".")
|
||||
.arg(filename.toUserOutput()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -356,7 +320,7 @@ void AbstractSettings::readDocumentation()
|
||||
return;
|
||||
if (xml.name() != QLatin1String(Constants::DOCUMENTATION_XMLROOT)) {
|
||||
BeautifierPlugin::showError(Tr::tr("The file \"%1\" is not a valid documentation file.")
|
||||
.arg(filename));
|
||||
.arg(filename.toUserOutput()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -387,7 +351,7 @@ void AbstractSettings::readDocumentation()
|
||||
|
||||
if (xml.hasError()) {
|
||||
BeautifierPlugin::showError(Tr::tr("Cannot read documentation file \"%1\": %2.")
|
||||
.arg(filename).arg(xml.errorString()));
|
||||
.arg(filename.toUserOutput()).arg(xml.errorString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/dialogs/ioptionspage.h>
|
||||
|
||||
#include <utils/aspects.h>
|
||||
#include <utils/filepath.h>
|
||||
|
||||
@@ -40,7 +42,6 @@ public:
|
||||
void read();
|
||||
void save();
|
||||
|
||||
virtual QString documentationFilePath() const = 0;
|
||||
virtual void createDocumentationFile() const;
|
||||
virtual QStringList completerWords();
|
||||
|
||||
@@ -53,25 +54,21 @@ public:
|
||||
void replaceStyle(const QString &oldKey, const QString &newKey, const QString &value);
|
||||
virtual QString styleFileName(const QString &key) const;
|
||||
|
||||
Utils::FilePath command() const;
|
||||
void setCommand(const Utils::FilePath &cmd);
|
||||
Utils::FilePathAspect command;
|
||||
Utils::StringAspect supportedMimeTypes;
|
||||
Utils::FilePathAspect documentationFilePath;
|
||||
|
||||
QVersionNumber version() const;
|
||||
|
||||
QString supportedMimeTypesAsString() const;
|
||||
void setSupportedMimeTypes(const QString &mimes);
|
||||
bool isApplicable(const Core::IDocument *document) const;
|
||||
|
||||
QStringList options();
|
||||
QString documentation(const QString &option) const;
|
||||
|
||||
signals:
|
||||
void supportedMimeTypesChanged();
|
||||
|
||||
protected:
|
||||
void setVersionRegExp(const QRegularExpression &versionRegExp);
|
||||
|
||||
QMap<QString, QString> m_styles;
|
||||
QMap<QString, QVariant> m_settings;
|
||||
QString m_ending;
|
||||
QDir m_styleDir;
|
||||
|
||||
@@ -79,11 +76,9 @@ protected:
|
||||
virtual void readStyles();
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
std::unique_ptr<VersionUpdater> m_versionUpdater;
|
||||
QStringList m_stylesToRemove;
|
||||
QSet<QString> m_changedStyles;
|
||||
Utils::FilePath m_command;
|
||||
QHash<QString, int> m_options;
|
||||
QStringList m_docu;
|
||||
QStringList m_supportedMimeTypes;
|
||||
|
||||
@@ -48,7 +48,7 @@ ArtisticStyle::ArtisticStyle()
|
||||
|
||||
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
|
||||
|
||||
connect(&m_settings, &ArtisticStyleSettings::supportedMimeTypesChanged,
|
||||
connect(&m_settings.supportedMimeTypes, &Utils::BaseAspect::changed,
|
||||
this, [this] { updateActions(Core::EditorManager::currentEditor()); });
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "../beautifierabstracttool.h"
|
||||
|
||||
#include "artisticstyleoptionspage.h"
|
||||
#include "artisticstylesettings.h"
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
// Copyright (C) 2016 Lorenz Haas
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "artisticstyleoptionspage.h"
|
||||
|
||||
#include "artisticstyleconstants.h"
|
||||
#include "artisticstylesettings.h"
|
||||
|
||||
#include "../beautifierconstants.h"
|
||||
#include "../beautifierplugin.h"
|
||||
#include "../beautifiertr.h"
|
||||
#include "../configurationpanel.h"
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
class ArtisticStyleOptionsPageWidget : public Core::IOptionsPageWidget
|
||||
{
|
||||
public:
|
||||
explicit ArtisticStyleOptionsPageWidget(ArtisticStyleSettings *settings);
|
||||
|
||||
void apply() final;
|
||||
|
||||
private:
|
||||
ArtisticStyleSettings *m_settings;
|
||||
|
||||
Utils::PathChooser *m_command;
|
||||
QLineEdit *m_mime;
|
||||
QCheckBox *m_useOtherFiles;
|
||||
QCheckBox *m_useSpecificConfigFile;
|
||||
Utils::PathChooser *m_specificConfigFile;
|
||||
QCheckBox *m_useHomeFile;
|
||||
QCheckBox *m_useCustomStyle;
|
||||
Beautifier::Internal::ConfigurationPanel *m_configurations;
|
||||
};
|
||||
|
||||
ArtisticStyleOptionsPageWidget::ArtisticStyleOptionsPageWidget(ArtisticStyleSettings *settings)
|
||||
: m_settings(settings)
|
||||
{
|
||||
m_command = new Utils::PathChooser;
|
||||
|
||||
m_mime = new QLineEdit(m_settings->supportedMimeTypesAsString());
|
||||
|
||||
auto options = new QGroupBox(Tr::tr("Options"));
|
||||
|
||||
m_useOtherFiles = new QCheckBox(Tr::tr("Use file *.astylerc defined in project files"));
|
||||
m_useOtherFiles->setChecked(m_settings->useOtherFiles());
|
||||
|
||||
m_useSpecificConfigFile = new QCheckBox(Tr::tr("Use specific config file:"));
|
||||
m_useSpecificConfigFile->setChecked(m_settings->useSpecificConfigFile());
|
||||
|
||||
m_specificConfigFile = new Utils::PathChooser;
|
||||
m_specificConfigFile->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
m_specificConfigFile->setExpectedKind(Utils::PathChooser::File);
|
||||
m_specificConfigFile->setPromptDialogFilter(Tr::tr("AStyle (*.astylerc)"));
|
||||
m_specificConfigFile->setFilePath(m_settings->specificConfigFile());
|
||||
|
||||
m_useHomeFile = new QCheckBox(
|
||||
Tr::tr("Use file .astylerc or astylerc in HOME").
|
||||
replace("HOME", QDir::toNativeSeparators(QDir::home().absolutePath())));
|
||||
m_useHomeFile->setChecked(m_settings->useHomeFile());
|
||||
|
||||
m_useCustomStyle = new QCheckBox(Tr::tr("Use customized style:"));
|
||||
m_useCustomStyle->setChecked(m_settings->useCustomStyle());
|
||||
|
||||
m_configurations = new ConfigurationPanel(options);
|
||||
m_configurations->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
m_configurations->setSettings(m_settings);
|
||||
m_configurations->setCurrentConfiguration(m_settings->customStyle());
|
||||
|
||||
m_command->setExpectedKind(Utils::PathChooser::ExistingCommand);
|
||||
m_command->setCommandVersionArguments({"--version"});
|
||||
m_command->setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle(
|
||||
Tr::tr(Constants::ARTISTICSTYLE_DISPLAY_NAME)));
|
||||
m_command->setFilePath(m_settings->command());
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
Column {
|
||||
m_useOtherFiles,
|
||||
Row { m_useSpecificConfigFile, m_specificConfigFile },
|
||||
m_useHomeFile,
|
||||
Row { m_useCustomStyle, m_configurations },
|
||||
noMargin,
|
||||
}.attachTo(options);
|
||||
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Configuration")),
|
||||
Form {
|
||||
Tr::tr("Artistic Style command:"), m_command, br,
|
||||
Tr::tr("Restrict to MIME types:"), m_mime
|
||||
}
|
||||
},
|
||||
options,
|
||||
st
|
||||
}.attachTo(this);
|
||||
|
||||
connect(m_command, &Utils::PathChooser::validChanged, options, &QWidget::setEnabled);
|
||||
}
|
||||
|
||||
void ArtisticStyleOptionsPageWidget::apply()
|
||||
{
|
||||
m_settings->setCommand(m_command->filePath());
|
||||
m_settings->setSupportedMimeTypes(m_mime->text());
|
||||
m_settings->setUseOtherFiles(m_useOtherFiles->isChecked());
|
||||
m_settings->setUseSpecificConfigFile(m_useSpecificConfigFile->isChecked());
|
||||
m_settings->setSpecificConfigFile(m_specificConfigFile->filePath());
|
||||
m_settings->setUseHomeFile(m_useHomeFile->isChecked());
|
||||
m_settings->setUseCustomStyle(m_useCustomStyle->isChecked());
|
||||
m_settings->setCustomStyle(m_configurations->currentConfiguration());
|
||||
m_settings->save();
|
||||
|
||||
// update since not all MIME types are accepted (invalids or duplicates)
|
||||
m_mime->setText(m_settings->supportedMimeTypesAsString());
|
||||
}
|
||||
|
||||
ArtisticStyleOptionsPage::ArtisticStyleOptionsPage(ArtisticStyleSettings *settings)
|
||||
{
|
||||
setId("ArtisticStyle");
|
||||
setDisplayName(Tr::tr("Artistic Style"));
|
||||
setCategory(Constants::OPTION_CATEGORY);
|
||||
setWidgetCreator([settings] { return new ArtisticStyleOptionsPageWidget(settings); });
|
||||
}
|
||||
|
||||
} // Beautifier::Internal
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (C) 2016 Lorenz Haas
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/dialogs/ioptionspage.h>
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
class ArtisticStyleSettings;
|
||||
|
||||
class ArtisticStyleOptionsPage final : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
explicit ArtisticStyleOptionsPage(ArtisticStyleSettings *settings);
|
||||
};
|
||||
|
||||
} // Beautifier::Internal
|
||||
@@ -3,16 +3,24 @@
|
||||
|
||||
#include "artisticstylesettings.h"
|
||||
|
||||
#include "artisticstyleconstants.h"
|
||||
#include "../beautifierconstants.h"
|
||||
#include "../beautifierplugin.h"
|
||||
#include "../beautifiertr.h"
|
||||
#include "../configurationpanel.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/process.h>
|
||||
#include <utils/stringutils.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QGroupBox>
|
||||
#include <QRegularExpression>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
@@ -20,96 +28,52 @@ using namespace Utils;
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
const char USE_OTHER_FILES[] = "useOtherFiles";
|
||||
const char USE_SPECIFIC_CONFIG_FILE[] = "useSpecificConfigFile";
|
||||
const char SPECIFIC_CONFIG_FILE[] = "specificConfigFile";
|
||||
const char USE_HOME_FILE[] = "useHomeFile";
|
||||
const char USE_CUSTOM_STYLE[] = "useCustomStyle";
|
||||
const char CUSTOM_STYLE[] = "customStyle";
|
||||
const char SETTINGS_NAME[] = "artisticstyle";
|
||||
|
||||
ArtisticStyleSettings::ArtisticStyleSettings() :
|
||||
AbstractSettings(SETTINGS_NAME, ".astyle")
|
||||
ArtisticStyleSettings::ArtisticStyleSettings()
|
||||
: AbstractSettings(SETTINGS_NAME, ".astyle")
|
||||
{
|
||||
setVersionRegExp(QRegularExpression("([2-9]{1})\\.([0-9]{1,2})(\\.[1-9]{1})?$"));
|
||||
setCommand("astyle");
|
||||
m_settings.insert(USE_OTHER_FILES, QVariant(true));
|
||||
m_settings.insert(USE_SPECIFIC_CONFIG_FILE, QVariant(false));
|
||||
m_settings.insert(SPECIFIC_CONFIG_FILE, QVariant());
|
||||
m_settings.insert(USE_HOME_FILE, QVariant(false));
|
||||
m_settings.insert(USE_CUSTOM_STYLE, QVariant(false));
|
||||
m_settings.insert(CUSTOM_STYLE, QVariant());
|
||||
command.setLabelText(Tr::tr("Artistic Style command:"));
|
||||
command.setDefaultValue("astyle");
|
||||
command.setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle(
|
||||
Tr::tr(Constants::ARTISTICSTYLE_DISPLAY_NAME)));
|
||||
|
||||
registerAspect(&useOtherFiles);
|
||||
useOtherFiles.setSettingsKey("useOtherFiles");
|
||||
useOtherFiles.setLabelText(Tr::tr("Use file *.astylerc defined in project files"));
|
||||
useOtherFiles.setDefaultValue(true);
|
||||
|
||||
registerAspect(&useSpecificConfigFile);
|
||||
useSpecificConfigFile.setSettingsKey("useSpecificConfigFile");
|
||||
useSpecificConfigFile.setLabelText(Tr::tr("Use specific config file:"));
|
||||
|
||||
registerAspect(&specificConfigFile);
|
||||
specificConfigFile.setSettingsKey("specificConfigFile");
|
||||
specificConfigFile.setExpectedKind(PathChooser::File);
|
||||
specificConfigFile.setPromptDialogFilter(Tr::tr("AStyle (*.astylerc)"));
|
||||
|
||||
registerAspect(&useHomeFile);
|
||||
useHomeFile.setSettingsKey("useHomeFile");
|
||||
useHomeFile.setLabelText(Tr::tr("Use file .astylerc or astylerc in HOME").
|
||||
replace("HOME", QDir::toNativeSeparators(QDir::home().absolutePath())));
|
||||
|
||||
registerAspect(&useCustomStyle);
|
||||
useCustomStyle.setSettingsKey("useCustomStyle");
|
||||
useCustomStyle.setLabelText(Tr::tr("Use customized style:"));
|
||||
|
||||
registerAspect(&customStyle);
|
||||
customStyle.setSettingsKey("customStyle");
|
||||
|
||||
documentationFilePath.setFilePath(
|
||||
Core::ICore::userResourcePath(Beautifier::Constants::SETTINGS_DIRNAME)
|
||||
.pathAppended(Beautifier::Constants::DOCUMENTATION_DIRNAME)
|
||||
.pathAppended(SETTINGS_NAME)
|
||||
.stringAppended(".xml"));
|
||||
|
||||
read();
|
||||
}
|
||||
|
||||
bool ArtisticStyleSettings::useOtherFiles() const
|
||||
{
|
||||
return m_settings.value(USE_OTHER_FILES).toBool();
|
||||
}
|
||||
|
||||
void ArtisticStyleSettings::setUseOtherFiles(bool useOtherFiles)
|
||||
{
|
||||
m_settings.insert(USE_OTHER_FILES, QVariant(useOtherFiles));
|
||||
}
|
||||
|
||||
bool ArtisticStyleSettings::useSpecificConfigFile() const
|
||||
{
|
||||
return m_settings.value(USE_SPECIFIC_CONFIG_FILE).toBool();
|
||||
}
|
||||
|
||||
void ArtisticStyleSettings::setUseSpecificConfigFile(bool useSpecificConfigFile)
|
||||
{
|
||||
m_settings.insert(USE_SPECIFIC_CONFIG_FILE, QVariant(useSpecificConfigFile));
|
||||
}
|
||||
|
||||
FilePath ArtisticStyleSettings::specificConfigFile() const
|
||||
{
|
||||
return FilePath::fromString(m_settings.value(SPECIFIC_CONFIG_FILE).toString());
|
||||
}
|
||||
|
||||
void ArtisticStyleSettings::setSpecificConfigFile(const FilePath &specificConfigFile)
|
||||
{
|
||||
m_settings.insert(SPECIFIC_CONFIG_FILE, QVariant(specificConfigFile.toString()));
|
||||
}
|
||||
|
||||
bool ArtisticStyleSettings::useHomeFile() const
|
||||
{
|
||||
return m_settings.value(USE_HOME_FILE).toBool();
|
||||
}
|
||||
|
||||
void ArtisticStyleSettings::setUseHomeFile(bool useHomeFile)
|
||||
{
|
||||
m_settings.insert(USE_HOME_FILE, QVariant(useHomeFile));
|
||||
}
|
||||
|
||||
bool ArtisticStyleSettings::useCustomStyle() const
|
||||
{
|
||||
return m_settings.value(USE_CUSTOM_STYLE).toBool();
|
||||
}
|
||||
|
||||
void ArtisticStyleSettings::setUseCustomStyle(bool useCustomStyle)
|
||||
{
|
||||
m_settings.insert(USE_CUSTOM_STYLE, QVariant(useCustomStyle));
|
||||
}
|
||||
|
||||
QString ArtisticStyleSettings::customStyle() const
|
||||
{
|
||||
return m_settings.value(CUSTOM_STYLE).toString();
|
||||
}
|
||||
|
||||
void ArtisticStyleSettings::setCustomStyle(const QString &customStyle)
|
||||
{
|
||||
m_settings.insert(CUSTOM_STYLE, QVariant(customStyle));
|
||||
}
|
||||
|
||||
QString ArtisticStyleSettings::documentationFilePath() const
|
||||
{
|
||||
return (Core::ICore::userResourcePath(Beautifier::Constants::SETTINGS_DIRNAME)
|
||||
/ Beautifier::Constants::DOCUMENTATION_DIRNAME / SETTINGS_NAME)
|
||||
.stringAppended(".xml")
|
||||
.toString();
|
||||
}
|
||||
|
||||
void ArtisticStyleSettings::createDocumentationFile() const
|
||||
{
|
||||
Process process;
|
||||
@@ -119,7 +83,7 @@ void ArtisticStyleSettings::createDocumentationFile() const
|
||||
if (process.result() != ProcessResult::FinishedWithSuccess)
|
||||
return;
|
||||
|
||||
QFile file(documentationFilePath());
|
||||
QFile file(documentationFilePath().toFSPathString());
|
||||
const QFileInfo fi(file);
|
||||
if (!fi.exists())
|
||||
fi.dir().mkpath(fi.absolutePath());
|
||||
@@ -183,4 +147,61 @@ void ArtisticStyleSettings::createDocumentationFile() const
|
||||
}
|
||||
}
|
||||
|
||||
class ArtisticStyleOptionsPageWidget : public Core::IOptionsPageWidget
|
||||
{
|
||||
public:
|
||||
explicit ArtisticStyleOptionsPageWidget(ArtisticStyleSettings *settings)
|
||||
{
|
||||
QGroupBox *options = nullptr;
|
||||
|
||||
auto configurations = new ConfigurationPanel(this);
|
||||
configurations->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
configurations->setSettings(settings);
|
||||
configurations->setCurrentConfiguration(settings->customStyle());
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
ArtisticStyleSettings &s = *settings;
|
||||
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Configuration")),
|
||||
Form {
|
||||
s.command, br,
|
||||
s.supportedMimeTypes
|
||||
}
|
||||
},
|
||||
Group {
|
||||
title(Tr::tr("Options")),
|
||||
bindTo(&options),
|
||||
Column {
|
||||
s.useOtherFiles,
|
||||
Row { s.useSpecificConfigFile, s.specificConfigFile },
|
||||
s.useHomeFile,
|
||||
Row { s.useCustomStyle, configurations },
|
||||
}
|
||||
},
|
||||
st
|
||||
}.attachTo(this);
|
||||
|
||||
setOnApply([&s, configurations] {
|
||||
s.customStyle.setValue(configurations->currentConfiguration());
|
||||
s.save();
|
||||
});
|
||||
|
||||
s.read();
|
||||
|
||||
connect(s.command.pathChooser(), &PathChooser::validChanged, options, &QWidget::setEnabled);
|
||||
options->setEnabled(s.command.pathChooser()->isValid());
|
||||
}
|
||||
};
|
||||
|
||||
ArtisticStyleOptionsPage::ArtisticStyleOptionsPage(ArtisticStyleSettings *settings)
|
||||
{
|
||||
setId("ArtisticStyle");
|
||||
setDisplayName(Tr::tr("Artistic Style"));
|
||||
setCategory(Constants::OPTION_CATEGORY);
|
||||
setWidgetCreator([settings] { return new ArtisticStyleOptionsPageWidget(settings); });
|
||||
}
|
||||
|
||||
} // Beautifier::Internal
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include "../abstractsettings.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
class ArtisticStyleSettings : public AbstractSettings
|
||||
@@ -14,26 +12,20 @@ class ArtisticStyleSettings : public AbstractSettings
|
||||
public:
|
||||
ArtisticStyleSettings();
|
||||
|
||||
bool useOtherFiles() const;
|
||||
void setUseOtherFiles(bool useOtherFiles);
|
||||
Utils::BoolAspect useOtherFiles;
|
||||
Utils::BoolAspect useSpecificConfigFile;
|
||||
Utils::FilePathAspect specificConfigFile;
|
||||
Utils::BoolAspect useHomeFile;
|
||||
Utils::BoolAspect useCustomStyle;
|
||||
Utils::StringAspect customStyle;
|
||||
|
||||
bool useSpecificConfigFile() const;
|
||||
void setUseSpecificConfigFile(bool useSpecificConfigFile);
|
||||
|
||||
Utils::FilePath specificConfigFile() const;
|
||||
void setSpecificConfigFile(const Utils::FilePath &specificConfigFile);
|
||||
|
||||
bool useHomeFile() const;
|
||||
void setUseHomeFile(bool useHomeFile);
|
||||
|
||||
bool useCustomStyle() const;
|
||||
void setUseCustomStyle(bool useCustomStyle);
|
||||
|
||||
QString customStyle() const;
|
||||
void setCustomStyle(const QString &customStyle);
|
||||
|
||||
QString documentationFilePath() const override;
|
||||
void createDocumentationFile() const override;
|
||||
};
|
||||
|
||||
class ArtisticStyleOptionsPage final : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
explicit ArtisticStyleOptionsPage(ArtisticStyleSettings *settings);
|
||||
};
|
||||
|
||||
} // Beautifier::Internal
|
||||
|
||||
@@ -36,8 +36,6 @@ QtcPlugin {
|
||||
"artisticstyle.cpp",
|
||||
"artisticstyle.h",
|
||||
"artisticstyleconstants.h",
|
||||
"artisticstyleoptionspage.cpp",
|
||||
"artisticstyleoptionspage.h",
|
||||
"artisticstylesettings.cpp",
|
||||
"artisticstylesettings.h"
|
||||
]
|
||||
@@ -50,8 +48,6 @@ QtcPlugin {
|
||||
"clangformat.cpp",
|
||||
"clangformat.h",
|
||||
"clangformatconstants.h",
|
||||
"clangformatoptionspage.cpp",
|
||||
"clangformatoptionspage.h",
|
||||
"clangformatsettings.cpp",
|
||||
"clangformatsettings.h"
|
||||
]
|
||||
@@ -64,8 +60,6 @@ QtcPlugin {
|
||||
"uncrustify.cpp",
|
||||
"uncrustify.h",
|
||||
"uncrustifyconstants.h",
|
||||
"uncrustifyoptionspage.cpp",
|
||||
"uncrustifyoptionspage.h",
|
||||
"uncrustifysettings.cpp",
|
||||
"uncrustifysettings.h"
|
||||
]
|
||||
|
||||
@@ -64,7 +64,7 @@ ClangFormat::ClangFormat()
|
||||
|
||||
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
|
||||
|
||||
connect(&m_settings, &ClangFormatSettings::supportedMimeTypesChanged,
|
||||
connect(&m_settings.supportedMimeTypes, &Utils::BaseAspect::changed,
|
||||
this, [this] { updateActions(Core::EditorManager::currentEditor()); });
|
||||
}
|
||||
|
||||
@@ -191,10 +191,10 @@ Command ClangFormat::command() const
|
||||
command.setProcessing(Command::PipeProcessing);
|
||||
|
||||
if (m_settings.usePredefinedStyle()) {
|
||||
const QString predefinedStyle = m_settings.predefinedStyle();
|
||||
const QString predefinedStyle = m_settings.predefinedStyle.stringValue();
|
||||
command.addOption("-style=" + predefinedStyle);
|
||||
if (predefinedStyle == "File") {
|
||||
const QString fallbackStyle = m_settings.fallbackStyle();
|
||||
const QString fallbackStyle = m_settings.fallbackStyle.stringValue();
|
||||
if (fallbackStyle != "Default")
|
||||
command.addOption("-fallback-style=" + fallbackStyle);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "../beautifierabstracttool.h"
|
||||
|
||||
#include "clangformatoptionspage.h"
|
||||
#include "clangformatsettings.h"
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
// Copyright (C) 2016 Lorenz Haas
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "clangformatoptionspage.h"
|
||||
|
||||
#include "clangformatsettings.h"
|
||||
|
||||
#include "../beautifierconstants.h"
|
||||
#include "../beautifierplugin.h"
|
||||
#include "../beautifiertr.h"
|
||||
#include "../configurationpanel.h"
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QComboBox>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QRadioButton>
|
||||
#include <QSpacerItem>
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
class ClangFormatOptionsPageWidget : public Core::IOptionsPageWidget
|
||||
{
|
||||
public:
|
||||
explicit ClangFormatOptionsPageWidget(ClangFormatSettings *settings);
|
||||
|
||||
void apply() final;
|
||||
|
||||
private:
|
||||
ClangFormatSettings *m_settings;
|
||||
ConfigurationPanel *m_configurations;
|
||||
QRadioButton *m_usePredefinedStyle;
|
||||
QComboBox *m_predefinedStyle;
|
||||
QComboBox *m_fallbackStyle;
|
||||
Utils::PathChooser *m_command;
|
||||
QLineEdit *m_mime;
|
||||
};
|
||||
|
||||
ClangFormatOptionsPageWidget::ClangFormatOptionsPageWidget(ClangFormatSettings *settings)
|
||||
: m_settings(settings)
|
||||
{
|
||||
auto options = new QGroupBox(Tr::tr("Options"));
|
||||
options->setEnabled(false);
|
||||
|
||||
auto styleButtonGroup = new QButtonGroup(this);
|
||||
|
||||
auto useCustomizedStyle = new QRadioButton(Tr::tr("Use customized style:"));
|
||||
styleButtonGroup->addButton(useCustomizedStyle);
|
||||
|
||||
m_configurations = new ConfigurationPanel;
|
||||
m_configurations->setSettings(m_settings);
|
||||
m_configurations->setCurrentConfiguration(m_settings->customStyle());
|
||||
|
||||
m_usePredefinedStyle = new QRadioButton(Tr::tr("Use predefined style:"));
|
||||
|
||||
m_usePredefinedStyle->setChecked(true);
|
||||
styleButtonGroup->addButton(m_usePredefinedStyle);
|
||||
|
||||
m_predefinedStyle = new QComboBox;
|
||||
m_predefinedStyle->addItems(m_settings->predefinedStyles());
|
||||
const int predefinedStyleIndex = m_predefinedStyle->findText(m_settings->predefinedStyle());
|
||||
if (predefinedStyleIndex != -1)
|
||||
m_predefinedStyle->setCurrentIndex(predefinedStyleIndex);
|
||||
|
||||
m_fallbackStyle = new QComboBox;
|
||||
m_fallbackStyle->addItems(m_settings->fallbackStyles());
|
||||
m_fallbackStyle->setEnabled(false);
|
||||
const int fallbackStyleIndex = m_fallbackStyle->findText(m_settings->fallbackStyle());
|
||||
if (fallbackStyleIndex != -1)
|
||||
m_fallbackStyle->setCurrentIndex(fallbackStyleIndex);
|
||||
|
||||
m_mime = new QLineEdit(m_settings->supportedMimeTypesAsString());
|
||||
|
||||
m_command = new Utils::PathChooser;
|
||||
m_command->setExpectedKind(Utils::PathChooser::ExistingCommand);
|
||||
m_command->setCommandVersionArguments({"--version"});
|
||||
m_command->setPromptDialogTitle(
|
||||
BeautifierPlugin::msgCommandPromptDialogTitle("Clang Format"));
|
||||
|
||||
if (m_settings->usePredefinedStyle())
|
||||
m_usePredefinedStyle->setChecked(true);
|
||||
else
|
||||
useCustomizedStyle->setChecked(true);
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
Form {
|
||||
m_usePredefinedStyle, m_predefinedStyle, br,
|
||||
empty, Row { Tr::tr("Fallback style:"), m_fallbackStyle }, br,
|
||||
useCustomizedStyle, m_configurations, br,
|
||||
}.attachTo(options);
|
||||
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Configuration")),
|
||||
Form {
|
||||
Tr::tr("Clang Format command:"), m_command, br,
|
||||
Tr::tr("Restrict to MIME types:"), m_mime
|
||||
}
|
||||
},
|
||||
options,
|
||||
st
|
||||
}.attachTo(this);
|
||||
|
||||
connect(m_command, &Utils::PathChooser::validChanged, options, &QWidget::setEnabled);
|
||||
connect(m_predefinedStyle, &QComboBox::currentTextChanged, this, [this](const QString &item) {
|
||||
m_fallbackStyle->setEnabled(item == "File");
|
||||
});
|
||||
connect(m_usePredefinedStyle, &QRadioButton::toggled, this, [this](bool checked) {
|
||||
m_fallbackStyle->setEnabled(checked && m_predefinedStyle->currentText() == "File");
|
||||
m_predefinedStyle->setEnabled(checked);
|
||||
});
|
||||
|
||||
// might trigger PathChooser::validChanged, so so after the connect above
|
||||
m_command->setFilePath(m_settings->command());
|
||||
}
|
||||
|
||||
void ClangFormatOptionsPageWidget::apply()
|
||||
{
|
||||
m_settings->setCommand(m_command->filePath());
|
||||
m_settings->setSupportedMimeTypes(m_mime->text());
|
||||
m_settings->setUsePredefinedStyle(m_usePredefinedStyle->isChecked());
|
||||
m_settings->setPredefinedStyle(m_predefinedStyle->currentText());
|
||||
m_settings->setFallbackStyle(m_fallbackStyle->currentText());
|
||||
m_settings->setCustomStyle(m_configurations->currentConfiguration());
|
||||
m_settings->save();
|
||||
|
||||
// update since not all MIME types are accepted (invalids or duplicates)
|
||||
m_mime->setText(m_settings->supportedMimeTypesAsString());
|
||||
}
|
||||
|
||||
ClangFormatOptionsPage::ClangFormatOptionsPage(ClangFormatSettings *settings)
|
||||
{
|
||||
setId("ClangFormat");
|
||||
setDisplayName(Tr::tr("Clang Format"));
|
||||
setCategory(Constants::OPTION_CATEGORY);
|
||||
setWidgetCreator([settings] { return new ClangFormatOptionsPageWidget(settings); });
|
||||
}
|
||||
|
||||
} // Beautifier::Internal
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (C) 2016 Lorenz Haas
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/dialogs/ioptionspage.h>
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
class ClangFormatSettings;
|
||||
|
||||
class ClangFormatOptionsPage final : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
explicit ClangFormatOptionsPage(ClangFormatSettings *settings);
|
||||
};
|
||||
|
||||
} // Beautifier::Internal
|
||||
@@ -4,43 +4,80 @@
|
||||
#include "clangformatsettings.h"
|
||||
|
||||
#include "../beautifierconstants.h"
|
||||
#include "../beautifierplugin.h"
|
||||
#include "../beautifiertr.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QXmlStreamWriter>
|
||||
#include "../configurationpanel.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QButtonGroup>
|
||||
#include <QComboBox>
|
||||
#include <QGroupBox>
|
||||
#include <QRadioButton>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
const char USE_PREDEFINED_STYLE[] = "usePredefinedStyle";
|
||||
const char PREDEFINED_STYLE[] = "predefinedStyle";
|
||||
const char FALLBACK_STYLE[] = "fallbackStyle";
|
||||
const char CUSTOM_STYLE[] = "customStyle";
|
||||
const char SETTINGS_NAME[] = "clangformat";
|
||||
|
||||
ClangFormatSettings::ClangFormatSettings() :
|
||||
AbstractSettings(SETTINGS_NAME, ".clang-format")
|
||||
ClangFormatSettings::ClangFormatSettings()
|
||||
: AbstractSettings(SETTINGS_NAME, ".clang-format")
|
||||
{
|
||||
setCommand("clang-format");
|
||||
m_settings.insert(USE_PREDEFINED_STYLE, QVariant(true));
|
||||
m_settings.insert(PREDEFINED_STYLE, "LLVM");
|
||||
m_settings.insert(FALLBACK_STYLE, "Default");
|
||||
m_settings.insert(CUSTOM_STYLE, QVariant());
|
||||
read();
|
||||
}
|
||||
command.setDefaultValue("clang-format");
|
||||
command.setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle("Clang Format"));
|
||||
command.setLabelText(Tr::tr("Clang Format command:"));
|
||||
|
||||
QString ClangFormatSettings::documentationFilePath() const
|
||||
{
|
||||
return (Core::ICore::userResourcePath() / Beautifier::Constants::SETTINGS_DIRNAME
|
||||
/ Beautifier::Constants::DOCUMENTATION_DIRNAME / SETTINGS_NAME)
|
||||
.stringAppended(".xml")
|
||||
.toString();
|
||||
registerAspect(&usePredefinedStyle);
|
||||
usePredefinedStyle.setSettingsKey("usePredefinedStyle");
|
||||
usePredefinedStyle.setLabelText(Tr::tr("Use predefined style:"));
|
||||
usePredefinedStyle.setDefaultValue(true);
|
||||
|
||||
registerAspect(&predefinedStyle);
|
||||
predefinedStyle.setSettingsKey("predefinedStyle");
|
||||
predefinedStyle.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
|
||||
predefinedStyle.addOption("LLVM");
|
||||
predefinedStyle.addOption("Google");
|
||||
predefinedStyle.addOption("Chromium");
|
||||
predefinedStyle.addOption("Mozilla");
|
||||
predefinedStyle.addOption("WebKit");
|
||||
predefinedStyle.addOption("File");
|
||||
predefinedStyle.setDefaultValue("LLVM");
|
||||
|
||||
registerAspect(&fallbackStyle);
|
||||
fallbackStyle.setSettingsKey("fallbackStyle");
|
||||
fallbackStyle.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
|
||||
fallbackStyle.addOption("Default");
|
||||
fallbackStyle.addOption("None");
|
||||
fallbackStyle.addOption("LLVM");
|
||||
fallbackStyle.addOption("Google");
|
||||
fallbackStyle.addOption("Chromium");
|
||||
fallbackStyle.addOption("Mozilla");
|
||||
fallbackStyle.addOption("WebKit");
|
||||
fallbackStyle.setDefaultValue("Default");
|
||||
|
||||
registerAspect(&predefinedStyle);
|
||||
predefinedStyle.setSettingsKey("predefinedStyle");
|
||||
predefinedStyle.setDefaultValue("LLVM");
|
||||
|
||||
registerAspect(&customStyle);
|
||||
customStyle.setSettingsKey("customStyle");
|
||||
|
||||
documentationFilePath.setFilePath(Core::ICore::userResourcePath(Constants::SETTINGS_DIRNAME)
|
||||
.pathAppended(Constants::DOCUMENTATION_DIRNAME)
|
||||
.pathAppended(SETTINGS_NAME).stringAppended(".xml"));
|
||||
|
||||
read();
|
||||
}
|
||||
|
||||
void ClangFormatSettings::createDocumentationFile() const
|
||||
{
|
||||
QFile file(documentationFilePath());
|
||||
QFile file(documentationFilePath().toFSPathString());
|
||||
const QFileInfo fi(file);
|
||||
if (!fi.exists())
|
||||
fi.dir().mkpath(fi.absolutePath());
|
||||
@@ -144,60 +181,6 @@ QStringList ClangFormatSettings::completerWords()
|
||||
};
|
||||
}
|
||||
|
||||
bool ClangFormatSettings::usePredefinedStyle() const
|
||||
{
|
||||
return m_settings.value(USE_PREDEFINED_STYLE).toBool();
|
||||
}
|
||||
|
||||
void ClangFormatSettings::setUsePredefinedStyle(bool usePredefinedStyle)
|
||||
{
|
||||
m_settings.insert(USE_PREDEFINED_STYLE, QVariant(usePredefinedStyle));
|
||||
}
|
||||
|
||||
QString ClangFormatSettings::predefinedStyle() const
|
||||
{
|
||||
return m_settings.value(PREDEFINED_STYLE).toString();
|
||||
}
|
||||
|
||||
void ClangFormatSettings::setPredefinedStyle(const QString &predefinedStyle)
|
||||
{
|
||||
const QStringList test = predefinedStyles();
|
||||
if (test.contains(predefinedStyle))
|
||||
m_settings.insert(PREDEFINED_STYLE, QVariant(predefinedStyle));
|
||||
}
|
||||
|
||||
QString ClangFormatSettings::fallbackStyle() const
|
||||
{
|
||||
return m_settings.value(FALLBACK_STYLE).toString();
|
||||
}
|
||||
|
||||
void ClangFormatSettings::setFallbackStyle(const QString &fallbackStyle)
|
||||
{
|
||||
const QStringList test = fallbackStyles();
|
||||
if (test.contains(fallbackStyle))
|
||||
m_settings.insert(FALLBACK_STYLE, QVariant(fallbackStyle));
|
||||
}
|
||||
|
||||
QString ClangFormatSettings::customStyle() const
|
||||
{
|
||||
return m_settings.value(CUSTOM_STYLE).toString();
|
||||
}
|
||||
|
||||
void ClangFormatSettings::setCustomStyle(const QString &customStyle)
|
||||
{
|
||||
m_settings.insert(CUSTOM_STYLE, QVariant(customStyle));
|
||||
}
|
||||
|
||||
QStringList ClangFormatSettings::predefinedStyles() const
|
||||
{
|
||||
return {"LLVM", "Google", "Chromium", "Mozilla", "WebKit", "File"};
|
||||
}
|
||||
|
||||
QStringList ClangFormatSettings::fallbackStyles() const
|
||||
{
|
||||
return {"Default", "None", "LLVM", "Google", "Chromium", "Mozilla", "WebKit"};
|
||||
}
|
||||
|
||||
QString ClangFormatSettings::styleFileName(const QString &key) const
|
||||
{
|
||||
return m_styleDir.absolutePath() + '/' + key + '/' + m_ending;
|
||||
@@ -213,4 +196,86 @@ void ClangFormatSettings::readStyles()
|
||||
}
|
||||
}
|
||||
|
||||
class ClangFormatOptionsPageWidget : public Core::IOptionsPageWidget
|
||||
{
|
||||
public:
|
||||
explicit ClangFormatOptionsPageWidget(ClangFormatSettings *settings)
|
||||
{
|
||||
ClangFormatSettings &s = *settings;
|
||||
QGroupBox *options = nullptr;
|
||||
|
||||
auto predefinedStyleButton = new QRadioButton;
|
||||
s.usePredefinedStyle.adoptButton(predefinedStyleButton);
|
||||
|
||||
auto customizedStyleButton = new QRadioButton(Tr::tr("Use customized style:"));
|
||||
|
||||
auto styleButtonGroup = new QButtonGroup;
|
||||
styleButtonGroup->addButton(predefinedStyleButton);
|
||||
styleButtonGroup->addButton(customizedStyleButton);
|
||||
|
||||
auto configurations = new ConfigurationPanel(this);
|
||||
configurations->setSettings(&s);
|
||||
configurations->setCurrentConfiguration(s.customStyle());
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
auto fallbackBlob = Row { noMargin, Tr::tr("Fallback style:"), s.fallbackStyle }.emerge();
|
||||
|
||||
auto predefinedBlob = Column { noMargin, s.predefinedStyle, fallbackBlob }.emerge();
|
||||
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Configuration")),
|
||||
Form {
|
||||
s.command, br,
|
||||
s.supportedMimeTypes
|
||||
}
|
||||
},
|
||||
Group {
|
||||
title(Tr::tr("Options")),
|
||||
bindTo(&options),
|
||||
Form {
|
||||
s.usePredefinedStyle, predefinedBlob, br,
|
||||
customizedStyleButton, configurations,
|
||||
},
|
||||
},
|
||||
st
|
||||
}.attachTo(this);
|
||||
|
||||
if (s.usePredefinedStyle.value())
|
||||
predefinedStyleButton->click();
|
||||
else
|
||||
customizedStyleButton->click();
|
||||
|
||||
const auto updateEnabled = [&s, styleButtonGroup, predefinedBlob, fallbackBlob,
|
||||
configurations, predefinedStyleButton] {
|
||||
const bool predefSelected = styleButtonGroup->checkedButton() == predefinedStyleButton;
|
||||
predefinedBlob->setEnabled(predefSelected);
|
||||
fallbackBlob->setEnabled(predefSelected && s.predefinedStyle.volatileValue().toInt() == 5); // File
|
||||
configurations->setEnabled(!predefSelected);
|
||||
};
|
||||
updateEnabled();
|
||||
connect(styleButtonGroup, &QButtonGroup::buttonClicked, this, updateEnabled);
|
||||
connect(&s.predefinedStyle, &SelectionAspect::volatileValueChanged, this, updateEnabled);
|
||||
|
||||
setOnApply([settings, configurations] {
|
||||
settings->customStyle.setValue(configurations->currentConfiguration());
|
||||
settings->save();
|
||||
});
|
||||
|
||||
s.read();
|
||||
|
||||
connect(s.command.pathChooser(), &PathChooser::validChanged, options, &QWidget::setEnabled);
|
||||
options->setEnabled(s.command.pathChooser()->isValid());
|
||||
}
|
||||
};
|
||||
|
||||
ClangFormatOptionsPage::ClangFormatOptionsPage(ClangFormatSettings *settings)
|
||||
{
|
||||
setId("ClangFormat");
|
||||
setDisplayName(Tr::tr("Clang Format"));
|
||||
setCategory(Constants::OPTION_CATEGORY);
|
||||
setWidgetCreator([settings] { return new ClangFormatOptionsPageWidget(settings); });
|
||||
}
|
||||
|
||||
} // Beautifier::Internal
|
||||
|
||||
@@ -12,24 +12,14 @@ class ClangFormatSettings : public AbstractSettings
|
||||
public:
|
||||
explicit ClangFormatSettings();
|
||||
|
||||
QString documentationFilePath() const override;
|
||||
void createDocumentationFile() const override;
|
||||
|
||||
QStringList completerWords() override;
|
||||
|
||||
bool usePredefinedStyle() const;
|
||||
void setUsePredefinedStyle(bool usePredefinedStyle);
|
||||
|
||||
QString predefinedStyle() const;
|
||||
void setPredefinedStyle(const QString &predefinedStyle);
|
||||
|
||||
QString fallbackStyle() const;
|
||||
void setFallbackStyle(const QString &fallbackStyle);
|
||||
|
||||
QString customStyle() const;
|
||||
void setCustomStyle(const QString &customStyle);
|
||||
|
||||
QStringList predefinedStyles() const;
|
||||
QStringList fallbackStyles() const;
|
||||
Utils::BoolAspect usePredefinedStyle;
|
||||
Utils::SelectionAspect predefinedStyle;
|
||||
Utils::SelectionAspect fallbackStyle;
|
||||
Utils::StringAspect customStyle;
|
||||
|
||||
QString styleFileName(const QString &key) const override;
|
||||
|
||||
@@ -37,4 +27,10 @@ private:
|
||||
void readStyles() override;
|
||||
};
|
||||
|
||||
class ClangFormatOptionsPage final : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
explicit ClangFormatOptionsPage(ClangFormatSettings *settings);
|
||||
};
|
||||
|
||||
} // Beautifier::Internal
|
||||
|
||||
@@ -54,7 +54,7 @@ Uncrustify::Uncrustify()
|
||||
|
||||
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
|
||||
|
||||
connect(&m_settings, &UncrustifySettings::supportedMimeTypesChanged,
|
||||
connect(&m_settings.supportedMimeTypes, &Utils::BaseAspect::changed,
|
||||
this, [this] { updateActions(Core::EditorManager::currentEditor()); });
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "../beautifierabstracttool.h"
|
||||
|
||||
#include "uncrustifyoptionspage.h"
|
||||
#include "uncrustifysettings.h"
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
// Copyright (C) 2016 Lorenz Haas
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "uncrustifyoptionspage.h"
|
||||
|
||||
#include "uncrustifyconstants.h"
|
||||
#include "uncrustifysettings.h"
|
||||
|
||||
#include "../beautifierconstants.h"
|
||||
#include "../beautifierplugin.h"
|
||||
#include "../beautifiertr.h"
|
||||
#include "../configurationpanel.h"
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/pathchooser.h>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
class UncrustifyOptionsPageWidget : public Core::IOptionsPageWidget
|
||||
{
|
||||
public:
|
||||
explicit UncrustifyOptionsPageWidget(UncrustifySettings *settings);
|
||||
|
||||
void apply() final;
|
||||
|
||||
private:
|
||||
UncrustifySettings *m_settings;
|
||||
|
||||
Utils::PathChooser *m_command;
|
||||
QLineEdit *m_mime;
|
||||
QCheckBox *m_useOtherFiles;
|
||||
QCheckBox *m_useSpecificFile;
|
||||
Utils::PathChooser *m_uncrusifyFilePath;
|
||||
QCheckBox *m_useHomeFile;
|
||||
QCheckBox *m_useCustomStyle;
|
||||
ConfigurationPanel *m_configurations;
|
||||
QCheckBox *m_formatEntireFileFallback;
|
||||
};
|
||||
|
||||
UncrustifyOptionsPageWidget::UncrustifyOptionsPageWidget(UncrustifySettings *settings)
|
||||
: m_settings(settings)
|
||||
{
|
||||
m_command = new Utils::PathChooser;
|
||||
|
||||
m_mime = new QLineEdit(m_settings->supportedMimeTypesAsString());
|
||||
|
||||
m_useOtherFiles = new QCheckBox(Tr::tr("Use file uncrustify.cfg defined in project files"));
|
||||
m_useOtherFiles->setChecked(m_settings->useOtherFiles());
|
||||
|
||||
m_useSpecificFile = new QCheckBox(Tr::tr("Use file specific uncrustify.cfg"));
|
||||
m_useSpecificFile->setChecked(m_settings->useSpecificConfigFile());
|
||||
|
||||
m_uncrusifyFilePath = new Utils::PathChooser;
|
||||
m_uncrusifyFilePath->setExpectedKind(Utils::PathChooser::File);
|
||||
m_uncrusifyFilePath->setPromptDialogFilter(Tr::tr("Uncrustify file (*.cfg)"));
|
||||
m_uncrusifyFilePath->setFilePath(m_settings->specificConfigFile());
|
||||
|
||||
m_useHomeFile = new QCheckBox(Tr::tr("Use file uncrustify.cfg in HOME")
|
||||
.replace( "HOME", QDir::toNativeSeparators(QDir::home().absolutePath())));
|
||||
m_useHomeFile->setChecked(m_settings->useHomeFile());
|
||||
|
||||
m_useCustomStyle = new QCheckBox(Tr::tr("Use customized style:"));
|
||||
m_useCustomStyle->setChecked(m_settings->useCustomStyle());
|
||||
|
||||
m_configurations = new ConfigurationPanel;
|
||||
m_configurations->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
m_configurations->setSettings(m_settings);
|
||||
m_configurations->setCurrentConfiguration(m_settings->customStyle());
|
||||
|
||||
m_formatEntireFileFallback = new QCheckBox(Tr::tr("Format entire file if no text was selected"));
|
||||
m_formatEntireFileFallback->setToolTip(Tr::tr("For action Format Selected Text"));
|
||||
m_formatEntireFileFallback->setChecked(m_settings->formatEntireFileFallback());
|
||||
|
||||
m_command->setExpectedKind(Utils::PathChooser::ExistingCommand);
|
||||
m_command->setCommandVersionArguments({"--version"});
|
||||
m_command->setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle(
|
||||
Tr::tr(Constants::UNCRUSTIFY_DISPLAY_NAME)));
|
||||
m_command->setFilePath(m_settings->command());
|
||||
|
||||
auto options = new QGroupBox(Tr::tr("Options"));
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
Column {
|
||||
m_useOtherFiles,
|
||||
Row { m_useSpecificFile, m_uncrusifyFilePath },
|
||||
m_useHomeFile,
|
||||
Row { m_useCustomStyle, m_configurations },
|
||||
m_formatEntireFileFallback
|
||||
}.attachTo(options);
|
||||
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Configuration")),
|
||||
Form {
|
||||
Tr::tr("Uncrustify command:"), m_command, br,
|
||||
Tr::tr("Restrict to MIME types:"), m_mime
|
||||
}
|
||||
},
|
||||
options,
|
||||
st
|
||||
}.attachTo(this);
|
||||
|
||||
connect(m_command, &Utils::PathChooser::validChanged, options, &QWidget::setEnabled);
|
||||
}
|
||||
|
||||
void UncrustifyOptionsPageWidget::apply()
|
||||
{
|
||||
m_settings->setCommand(m_command->filePath());
|
||||
m_settings->setSupportedMimeTypes(m_mime->text());
|
||||
m_settings->setUseOtherFiles(m_useOtherFiles->isChecked());
|
||||
m_settings->setUseHomeFile(m_useHomeFile->isChecked());
|
||||
m_settings->setUseSpecificConfigFile(m_useSpecificFile->isChecked());
|
||||
m_settings->setSpecificConfigFile(m_uncrusifyFilePath->filePath());
|
||||
m_settings->setUseCustomStyle(m_useCustomStyle->isChecked());
|
||||
m_settings->setCustomStyle(m_configurations->currentConfiguration());
|
||||
m_settings->setFormatEntireFileFallback(m_formatEntireFileFallback->isChecked());
|
||||
m_settings->save();
|
||||
|
||||
// update since not all MIME types are accepted (invalids or duplicates)
|
||||
m_mime->setText(m_settings->supportedMimeTypesAsString());
|
||||
}
|
||||
|
||||
UncrustifyOptionsPage::UncrustifyOptionsPage(UncrustifySettings *settings)
|
||||
{
|
||||
setId("Uncrustify");
|
||||
setDisplayName(Tr::tr("Uncrustify"));
|
||||
setCategory(Constants::OPTION_CATEGORY);
|
||||
setWidgetCreator([settings] { return new UncrustifyOptionsPageWidget(settings); });
|
||||
}
|
||||
|
||||
} // Beautifier::Internal
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (C) 2016 Lorenz Haas
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/dialogs/ioptionspage.h>
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
class UncrustifySettings;
|
||||
|
||||
class UncrustifyOptionsPage final : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
explicit UncrustifyOptionsPage(UncrustifySettings *settings);
|
||||
};
|
||||
|
||||
} // Beautifier::Internal
|
||||
@@ -3,14 +3,25 @@
|
||||
|
||||
#include "uncrustifysettings.h"
|
||||
|
||||
#include "uncrustifyconstants.h"
|
||||
#include "../beautifierconstants.h"
|
||||
#include "../beautifierplugin.h"
|
||||
#include "../beautifiertr.h"
|
||||
#include "../configurationpanel.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/process.h>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QRegularExpression>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
@@ -18,110 +29,57 @@ using namespace Utils;
|
||||
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
const char USE_OTHER_FILES[] = "useOtherFiles";
|
||||
const char USE_HOME_FILE[] = "useHomeFile";
|
||||
const char USE_SPECIFIC_CONFIG_FILE_PATH[] = "useSpecificConfigFile";
|
||||
const char SPECIFIC_CONFIG_FILE_PATH[] = "specificConfigFile";
|
||||
const char USE_CUSTOM_STYLE[] = "useCustomStyle";
|
||||
const char CUSTOM_STYLE[] = "customStyle";
|
||||
const char FORMAT_ENTIRE_FILE_FALLBACK[] = "formatEntireFileFallback";
|
||||
const char SETTINGS_NAME[] = "uncrustify";
|
||||
const char SETTINGS_NAME[] = "uncrustify";
|
||||
|
||||
UncrustifySettings::UncrustifySettings() :
|
||||
AbstractSettings(SETTINGS_NAME, ".cfg")
|
||||
UncrustifySettings::UncrustifySettings()
|
||||
: AbstractSettings(SETTINGS_NAME, ".cfg")
|
||||
{
|
||||
setVersionRegExp(QRegularExpression("([0-9]{1})\\.([0-9]{2})"));
|
||||
setCommand("uncrustify");
|
||||
m_settings.insert(USE_OTHER_FILES, QVariant(true));
|
||||
m_settings.insert(USE_HOME_FILE, QVariant(false));
|
||||
m_settings.insert(USE_CUSTOM_STYLE, QVariant(false));
|
||||
m_settings.insert(USE_SPECIFIC_CONFIG_FILE_PATH, QVariant(false));
|
||||
m_settings.insert(CUSTOM_STYLE, QVariant());
|
||||
m_settings.insert(FORMAT_ENTIRE_FILE_FALLBACK, QVariant(true));
|
||||
m_settings.insert(SPECIFIC_CONFIG_FILE_PATH, QVariant());
|
||||
|
||||
command.setDefaultValue("uncrustify");
|
||||
command.setLabelText(Tr::tr("Uncrustify command:"));
|
||||
command.setPromptDialogTitle(BeautifierPlugin::msgCommandPromptDialogTitle(
|
||||
Tr::tr(Constants::UNCRUSTIFY_DISPLAY_NAME)));
|
||||
|
||||
registerAspect(&useOtherFiles);
|
||||
useOtherFiles.setSettingsKey("useOtherFiles");
|
||||
useOtherFiles.setDefaultValue(true);
|
||||
useOtherFiles.setLabelText(Tr::tr("Use file uncrustify.cfg defined in project files"));
|
||||
|
||||
registerAspect(&useHomeFile);
|
||||
useHomeFile.setSettingsKey("useHomeFile");
|
||||
useHomeFile.setLabelText(Tr::tr("Use file uncrustify.cfg in HOME")
|
||||
.replace( "HOME", QDir::toNativeSeparators(QDir::home().absolutePath())));
|
||||
|
||||
registerAspect(&useCustomStyle);
|
||||
useCustomStyle.setSettingsKey("useCustomStyle");
|
||||
useCustomStyle.setLabelText(Tr::tr("Use customized style:"));
|
||||
|
||||
registerAspect(&useSpecificConfigFile);
|
||||
useSpecificConfigFile.setSettingsKey("useSpecificConfigFile");
|
||||
useSpecificConfigFile.setLabelText(Tr::tr("Use file specific uncrustify.cfg"));
|
||||
|
||||
registerAspect(&customStyle);
|
||||
customStyle.setSettingsKey("customStyle");
|
||||
|
||||
registerAspect(&formatEntireFileFallback);
|
||||
formatEntireFileFallback.setSettingsKey("formatEntireFileFallback");
|
||||
formatEntireFileFallback.setDefaultValue(true);
|
||||
formatEntireFileFallback.setLabelText(Tr::tr("Format entire file if no text was selected"));
|
||||
formatEntireFileFallback.setToolTip(Tr::tr("For action Format Selected Text"));
|
||||
|
||||
registerAspect(&specificConfigFile);
|
||||
specificConfigFile.setSettingsKey("specificConfigFile");
|
||||
specificConfigFile.setExpectedKind(Utils::PathChooser::File);
|
||||
specificConfigFile.setPromptDialogFilter(Tr::tr("Uncrustify file (*.cfg)"));
|
||||
|
||||
documentationFilePath.setFilePath(Core::ICore::userResourcePath(Constants::SETTINGS_DIRNAME)
|
||||
.pathAppended(Constants::DOCUMENTATION_DIRNAME)
|
||||
.pathAppended(SETTINGS_NAME).stringAppended(".xml"));
|
||||
|
||||
read();
|
||||
}
|
||||
|
||||
UncrustifySettings::~UncrustifySettings() = default;
|
||||
|
||||
bool UncrustifySettings::useOtherFiles() const
|
||||
{
|
||||
return m_settings.value(USE_OTHER_FILES).toBool();
|
||||
}
|
||||
|
||||
void UncrustifySettings::setUseOtherFiles(bool useOtherFiles)
|
||||
{
|
||||
m_settings.insert(USE_OTHER_FILES, QVariant(useOtherFiles));
|
||||
}
|
||||
|
||||
bool UncrustifySettings::useHomeFile() const
|
||||
{
|
||||
return m_settings.value(USE_HOME_FILE).toBool();
|
||||
}
|
||||
|
||||
void UncrustifySettings::setUseHomeFile(bool useHomeFile)
|
||||
{
|
||||
m_settings.insert(USE_HOME_FILE, QVariant(useHomeFile));
|
||||
}
|
||||
|
||||
FilePath UncrustifySettings::specificConfigFile() const
|
||||
{
|
||||
return FilePath::fromString(m_settings.value(SPECIFIC_CONFIG_FILE_PATH).toString());
|
||||
}
|
||||
|
||||
void UncrustifySettings::setSpecificConfigFile(const FilePath &filePath)
|
||||
{
|
||||
m_settings.insert(SPECIFIC_CONFIG_FILE_PATH, QVariant(filePath.toString()));
|
||||
}
|
||||
|
||||
bool UncrustifySettings::useSpecificConfigFile() const
|
||||
{
|
||||
return m_settings.value(USE_SPECIFIC_CONFIG_FILE_PATH).toBool();
|
||||
}
|
||||
|
||||
void UncrustifySettings::setUseSpecificConfigFile(bool useConfigFile)
|
||||
{
|
||||
m_settings.insert(USE_SPECIFIC_CONFIG_FILE_PATH, QVariant(useConfigFile));
|
||||
}
|
||||
|
||||
bool UncrustifySettings::useCustomStyle() const
|
||||
{
|
||||
return m_settings.value(USE_CUSTOM_STYLE).toBool();
|
||||
}
|
||||
|
||||
void UncrustifySettings::setUseCustomStyle(bool useCustomStyle)
|
||||
{
|
||||
m_settings.insert(USE_CUSTOM_STYLE, QVariant(useCustomStyle));
|
||||
}
|
||||
|
||||
QString UncrustifySettings::customStyle() const
|
||||
{
|
||||
return m_settings.value(CUSTOM_STYLE).toString();
|
||||
}
|
||||
|
||||
void UncrustifySettings::setCustomStyle(const QString &customStyle)
|
||||
{
|
||||
m_settings.insert(CUSTOM_STYLE, QVariant(customStyle));
|
||||
}
|
||||
|
||||
bool UncrustifySettings::formatEntireFileFallback() const
|
||||
{
|
||||
return m_settings.value(FORMAT_ENTIRE_FILE_FALLBACK).toBool();
|
||||
}
|
||||
|
||||
void UncrustifySettings::setFormatEntireFileFallback(bool formatEntireFileFallback)
|
||||
{
|
||||
m_settings.insert(FORMAT_ENTIRE_FILE_FALLBACK, QVariant(formatEntireFileFallback));
|
||||
}
|
||||
|
||||
QString UncrustifySettings::documentationFilePath() const
|
||||
{
|
||||
return (Core::ICore::userResourcePath() / Beautifier::Constants::SETTINGS_DIRNAME
|
||||
/ Beautifier::Constants::DOCUMENTATION_DIRNAME / SETTINGS_NAME)
|
||||
.stringAppended(".xml")
|
||||
.toString();
|
||||
}
|
||||
|
||||
void UncrustifySettings::createDocumentationFile() const
|
||||
{
|
||||
Process process;
|
||||
@@ -131,7 +89,7 @@ void UncrustifySettings::createDocumentationFile() const
|
||||
if (process.result() != ProcessResult::FinishedWithSuccess)
|
||||
return;
|
||||
|
||||
QFile file(documentationFilePath());
|
||||
QFile file(documentationFilePath().toFSPathString());
|
||||
const QFileInfo fi(file);
|
||||
if (!fi.exists())
|
||||
fi.dir().mkpath(fi.absolutePath());
|
||||
@@ -185,4 +143,62 @@ void UncrustifySettings::createDocumentationFile() const
|
||||
}
|
||||
}
|
||||
|
||||
class UncrustifyOptionsPageWidget : public Core::IOptionsPageWidget
|
||||
{
|
||||
public:
|
||||
explicit UncrustifyOptionsPageWidget(UncrustifySettings *settings)
|
||||
{
|
||||
UncrustifySettings &s = *settings;
|
||||
|
||||
auto configurations = new ConfigurationPanel(this);
|
||||
configurations->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
configurations->setSettings(settings);
|
||||
configurations->setCurrentConfiguration(settings->customStyle());
|
||||
|
||||
QGroupBox *options = nullptr;
|
||||
|
||||
using namespace Layouting;
|
||||
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Configuration")),
|
||||
Form {
|
||||
s.command, br,
|
||||
s.supportedMimeTypes,
|
||||
}
|
||||
},
|
||||
Group {
|
||||
title(Tr::tr("Options")),
|
||||
bindTo(&options),
|
||||
Column {
|
||||
s.useOtherFiles,
|
||||
Row { s.useSpecificConfigFile, s.specificConfigFile },
|
||||
s.useHomeFile,
|
||||
Row { s.useCustomStyle, configurations },
|
||||
s.formatEntireFileFallback
|
||||
},
|
||||
},
|
||||
st
|
||||
}.attachTo(this);
|
||||
|
||||
s.read();
|
||||
|
||||
connect(s.command.pathChooser(), &PathChooser::validChanged, options, &QWidget::setEnabled);
|
||||
options->setEnabled(s.command.pathChooser()->isValid());
|
||||
|
||||
setOnApply([&s, configurations] {
|
||||
s.customStyle.setValue(configurations->currentConfiguration());
|
||||
s.save();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
UncrustifyOptionsPage::UncrustifyOptionsPage(UncrustifySettings *settings)
|
||||
{
|
||||
setId("Uncrustify");
|
||||
setDisplayName(Tr::tr("Uncrustify"));
|
||||
setCategory(Constants::OPTION_CATEGORY);
|
||||
setWidgetCreator([settings] { return new UncrustifyOptionsPageWidget(settings); });
|
||||
}
|
||||
|
||||
} // Beautifier::Internal
|
||||
|
||||
@@ -5,41 +5,30 @@
|
||||
|
||||
#include "../abstractsettings.h"
|
||||
|
||||
namespace Beautifier {
|
||||
namespace Internal {
|
||||
namespace Beautifier::Internal {
|
||||
|
||||
class UncrustifySettings : public AbstractSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
UncrustifySettings();
|
||||
~UncrustifySettings() override;
|
||||
|
||||
bool useOtherFiles() const;
|
||||
void setUseOtherFiles(bool useOtherFiles);
|
||||
|
||||
bool useHomeFile() const;
|
||||
void setUseHomeFile(bool useHomeFile);
|
||||
|
||||
bool useCustomStyle() const;
|
||||
void setUseCustomStyle(bool useCustomStyle);
|
||||
|
||||
QString customStyle() const;
|
||||
void setCustomStyle(const QString &customStyle);
|
||||
|
||||
bool formatEntireFileFallback() const;
|
||||
void setFormatEntireFileFallback(bool formatEntireFileFallback);
|
||||
|
||||
QString documentationFilePath() const override;
|
||||
void createDocumentationFile() const override;
|
||||
|
||||
Utils::FilePath specificConfigFile() const;
|
||||
void setSpecificConfigFile(const Utils::FilePath &filePath);
|
||||
Utils::BoolAspect useOtherFiles;
|
||||
Utils::BoolAspect useHomeFile;
|
||||
Utils::BoolAspect useCustomStyle;
|
||||
|
||||
bool useSpecificConfigFile() const;
|
||||
void setUseSpecificConfigFile(bool useConfigFile);
|
||||
Utils::StringAspect customStyle;
|
||||
Utils::BoolAspect formatEntireFileFallback;
|
||||
|
||||
Utils::FilePathAspect specificConfigFile;
|
||||
Utils::BoolAspect useSpecificConfigFile;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Beautifier
|
||||
class UncrustifyOptionsPage final : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
explicit UncrustifyOptionsPage(UncrustifySettings *settings);
|
||||
};
|
||||
|
||||
} // Beautifier::Internal
|
||||
|
||||
@@ -174,6 +174,8 @@ static bool buildAndRunOnSameDevice(Kit *kit)
|
||||
{
|
||||
IDeviceConstPtr runDevice = DeviceKitAspect::device(kit);
|
||||
IDeviceConstPtr buildDevice = BuildDeviceKitAspect::device(kit);
|
||||
QTC_ASSERT(runDevice, return false);
|
||||
QTC_ASSERT(buildDevice, return false);
|
||||
return runDevice->id() == buildDevice->id();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,26 +16,78 @@ class CORE_EXPORT ManhattanStyle : public QProxyStyle
|
||||
public:
|
||||
explicit ManhattanStyle(const QString &baseStyleName);
|
||||
|
||||
~ManhattanStyle() override;
|
||||
virtual ~ManhattanStyle() override;
|
||||
|
||||
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) const override;
|
||||
void drawPrimitive(
|
||||
PrimitiveElement element,
|
||||
const QStyleOption *option,
|
||||
QPainter *painter,
|
||||
const QWidget *widget = nullptr) const override;
|
||||
|
||||
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override;
|
||||
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override;
|
||||
QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc, const QWidget *widget) const override;
|
||||
void drawControl(
|
||||
ControlElement element,
|
||||
const QStyleOption *option,
|
||||
QPainter *painter,
|
||||
const QWidget *widget = nullptr) const override;
|
||||
|
||||
SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, const QPoint &pos, const QWidget *widget = nullptr) const override;
|
||||
QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget = nullptr) const override;
|
||||
QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override;
|
||||
int styleHint(StyleHint hint, const QStyleOption *option = nullptr, const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override;
|
||||
QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *opt) const override;
|
||||
void drawComplexControl(
|
||||
ComplexControl control,
|
||||
const QStyleOptionComplex *option,
|
||||
QPainter *painter,
|
||||
const QWidget *widget = nullptr) const override;
|
||||
|
||||
int pixelMetric(PixelMetric metric, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override;
|
||||
QSize sizeFromContents(
|
||||
ContentsType type,
|
||||
const QStyleOption *option,
|
||||
const QSize &size,
|
||||
const QWidget *widget) const override;
|
||||
|
||||
QRect subElementRect(
|
||||
SubElement element,
|
||||
const QStyleOption *option,
|
||||
const QWidget *widget) const override;
|
||||
|
||||
QRect subControlRect(
|
||||
ComplexControl control,
|
||||
const QStyleOptionComplex *option,
|
||||
SubControl subControl,
|
||||
const QWidget *widget) const override;
|
||||
|
||||
int styleHint(
|
||||
StyleHint hint,
|
||||
const QStyleOption *option = nullptr,
|
||||
const QWidget *widget = nullptr,
|
||||
QStyleHintReturn *returnData = nullptr) const override;
|
||||
|
||||
int pixelMetric(
|
||||
PixelMetric metric,
|
||||
const QStyleOption *option = nullptr,
|
||||
const QWidget *widget = nullptr) const override;
|
||||
|
||||
QPalette standardPalette() const override;
|
||||
|
||||
|
||||
QIcon standardIcon(
|
||||
StandardPixmap standardIcon,
|
||||
const QStyleOption *option = nullptr,
|
||||
const QWidget *widget = nullptr) const override;
|
||||
|
||||
SubControl hitTestComplexControl(
|
||||
ComplexControl control,
|
||||
const QStyleOptionComplex *option,
|
||||
const QPoint &pos,
|
||||
const QWidget *widget = nullptr) const override;
|
||||
|
||||
QPixmap standardPixmap(
|
||||
StandardPixmap standardPixmap,
|
||||
const QStyleOption *opt,
|
||||
const QWidget *widget = nullptr) const override;
|
||||
|
||||
QPixmap generatedIconPixmap(
|
||||
QIcon::Mode iconMode,
|
||||
const QPixmap &pixmap,
|
||||
const QStyleOption *opt) const override;
|
||||
|
||||
void polish(QWidget *widget) override;
|
||||
void polish(QPalette &pal) override;
|
||||
void polish(QApplication *app) override;
|
||||
@@ -44,28 +96,16 @@ public:
|
||||
void unpolish(QApplication *app) override;
|
||||
|
||||
private:
|
||||
void drawPrimitiveForPanelWidget(PrimitiveElement element,
|
||||
const QStyleOption *option,
|
||||
QPainter *painter,
|
||||
const QWidget *widget) const;
|
||||
void drawPrimitiveForPanelWidget(
|
||||
PrimitiveElement element,
|
||||
const QStyleOption *option,
|
||||
QPainter *painter,
|
||||
const QWidget *widget) const;
|
||||
|
||||
void drawPrimitiveForQmlEditor(PrimitiveElement element,
|
||||
const QStyleOption *option,
|
||||
QPainter *painter,
|
||||
const QWidget *widget) const;
|
||||
static void drawButtonSeparator(
|
||||
QPainter *painter,
|
||||
const QRect &rect,
|
||||
bool reverse);
|
||||
|
||||
void drawControlForQmlEditor(ControlElement element,
|
||||
const QStyleOption *option,
|
||||
QPainter *painter,
|
||||
const QWidget *widget = nullptr) const;
|
||||
|
||||
void drawQmlEditorIcon(PrimitiveElement element,
|
||||
const QStyleOption *option,
|
||||
const char *propertyName,
|
||||
QPainter *painter,
|
||||
const QWidget *widget = nullptr) const;
|
||||
|
||||
static void drawButtonSeparator(QPainter *painter, const QRect &rect, bool reverse);
|
||||
|
||||
ManhattanStylePrivate *d;
|
||||
ManhattanStylePrivate *d = nullptr;
|
||||
};
|
||||
|
||||
@@ -183,6 +183,10 @@ void OutputPanePlaceHolder::showEvent(QShowEvent *)
|
||||
d->m_initialized = true;
|
||||
setHeight(Internal::OutputPaneManager::outputPaneHeightSetting());
|
||||
}
|
||||
if (OutputPanePlaceHolderPrivate::m_current == this) {
|
||||
Internal::OutputPaneManager *om = Internal::OutputPaneManager::instance();
|
||||
om->updateStatusButtons(true);
|
||||
}
|
||||
}
|
||||
|
||||
OutputPanePlaceHolder *OutputPanePlaceHolder::getCurrent()
|
||||
|
||||
@@ -497,6 +497,9 @@ void OutputPaneManager::initialize()
|
||||
m_instance->m_titleLabel->setMinimumWidth(
|
||||
minTitleWidth + m_instance->m_titleLabel->contentsMargins().left()
|
||||
+ m_instance->m_titleLabel->contentsMargins().right());
|
||||
const int currentIdx = m_instance->currentIndex();
|
||||
if (QTC_GUARD(currentIdx >= 0 && currentIdx < g_outputPanes.size()))
|
||||
m_instance->m_titleLabel->setText(g_outputPanes[currentIdx].pane->displayName());
|
||||
m_instance->m_buttonsWidget->layout()->addWidget(m_instance->m_manageButton);
|
||||
connect(m_instance->m_manageButton,
|
||||
&QAbstractButton::clicked,
|
||||
@@ -575,7 +578,12 @@ void OutputPaneManager::readSettings()
|
||||
}
|
||||
settings->endArray();
|
||||
|
||||
m_outputPaneHeightSetting = settings->value(QLatin1String("OutputPanePlaceHolder/Height"), 0).toInt();
|
||||
m_outputPaneHeightSetting
|
||||
= settings->value(QLatin1String("OutputPanePlaceHolder/Height"), 0).toInt();
|
||||
const int currentIdx
|
||||
= settings->value(QLatin1String("OutputPanePlaceHolder/CurrentIndex"), 0).toInt();
|
||||
if (QTC_GUARD(currentIdx >= 0 && currentIdx < g_outputPanes.size()))
|
||||
setCurrentIndex(currentIdx);
|
||||
}
|
||||
|
||||
void OutputPaneManager::slotNext()
|
||||
@@ -682,7 +690,8 @@ void OutputPaneManager::setCurrentIndex(int idx)
|
||||
OutputPaneData &data = g_outputPanes[idx];
|
||||
IOutputPane *pane = data.pane;
|
||||
data.button->show();
|
||||
pane->visibilityChanged(true);
|
||||
if (OutputPanePlaceHolder::isCurrentVisible())
|
||||
pane->visibilityChanged(true);
|
||||
|
||||
bool canNavigate = pane->canNavigate();
|
||||
m_prevAction->setEnabled(canNavigate && pane->canPrevious());
|
||||
@@ -737,6 +746,7 @@ void OutputPaneManager::saveSettings() const
|
||||
if (OutputPanePlaceHolder *curr = OutputPanePlaceHolder::getCurrent())
|
||||
heightSetting = curr->nonMaximizedSize();
|
||||
settings->setValue(QLatin1String("OutputPanePlaceHolder/Height"), heightSetting);
|
||||
settings->setValue(QLatin1String("OutputPanePlaceHolder/CurrentIndex"), currentIndex());
|
||||
}
|
||||
|
||||
void OutputPaneManager::clearPage()
|
||||
|
||||
@@ -586,7 +586,7 @@ bool FossilClient::synchronousCreateRepository(const FilePath &workingDirectory,
|
||||
// use the configured default user for admin
|
||||
|
||||
const QString repoName = workingDirectory.fileName().simplified();
|
||||
const QString repoPath = settings().defaultRepoPath.value();
|
||||
const FilePath repoPath = settings().defaultRepoPath();
|
||||
const QString adminUser = settings().userName.value();
|
||||
|
||||
if (repoName.isEmpty() || repoPath.isEmpty())
|
||||
@@ -596,8 +596,7 @@ bool FossilClient::synchronousCreateRepository(const FilePath &workingDirectory,
|
||||
// @TODO: what about --template options?
|
||||
|
||||
const FilePath fullRepoName = FilePath::fromStringWithExtension(repoName, Constants::FOSSIL_FILE_SUFFIX);
|
||||
const FilePath repoFilePath = FilePath::fromString(repoPath)
|
||||
.pathAppended(fullRepoName.toString());
|
||||
const FilePath repoFilePath = repoPath.pathAppended(fullRepoName.toString());
|
||||
QStringList args(vcsCommandString(CreateRepositoryCommand));
|
||||
if (!adminUser.isEmpty())
|
||||
args << "--admin-user" << adminUser;
|
||||
|
||||
@@ -592,7 +592,7 @@ bool FossilPluginPrivate::pullOrPush(FossilPluginPrivate::SyncMode mode)
|
||||
QTC_ASSERT(state.hasTopLevel(), return false);
|
||||
|
||||
PullOrPushDialog dialog(pullOrPushMode, Core::ICore::dialogParent());
|
||||
dialog.setLocalBaseDirectory(m_client.settings().defaultRepoPath.value());
|
||||
dialog.setLocalBaseDirectory(m_client.settings().defaultRepoPath());
|
||||
const QString defaultURL(m_client.synchronousGetRepositoryURL(state.topLevel()));
|
||||
dialog.setDefaultRemoteLocation(defaultURL);
|
||||
if (dialog.exec() != QDialog::Accepted)
|
||||
@@ -868,24 +868,19 @@ bool FossilPluginPrivate::managesFile(const FilePath &workingDirectory, const QS
|
||||
|
||||
bool FossilPluginPrivate::isConfigured() const
|
||||
{
|
||||
const Utils::FilePath binary = m_client.vcsBinary();
|
||||
const FilePath binary = m_client.vcsBinary();
|
||||
if (binary.isEmpty())
|
||||
return false;
|
||||
|
||||
const QFileInfo fi = binary.toFileInfo();
|
||||
if ( !(fi.exists() && fi.isFile() && fi.isExecutable()) )
|
||||
if (!binary.isExecutableFile())
|
||||
return false;
|
||||
|
||||
// Local repositories default path must be set and exist
|
||||
const QString repoPath = m_client.settings().defaultRepoPath.value();
|
||||
const FilePath repoPath = m_client.settings().defaultRepoPath();
|
||||
if (repoPath.isEmpty())
|
||||
return false;
|
||||
|
||||
const QDir dir(repoPath);
|
||||
if (!dir.exists())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return repoPath.isReadableDir();
|
||||
}
|
||||
|
||||
bool FossilPluginPrivate::supportsOperation(Operation operation) const
|
||||
|
||||
@@ -42,7 +42,6 @@ FossilSettings::FossilSettings()
|
||||
|
||||
registerAspect(&defaultRepoPath);
|
||||
defaultRepoPath.setSettingsKey("defaultRepoPath");
|
||||
defaultRepoPath.setDisplayStyle(StringAspect::PathChooserDisplay);
|
||||
defaultRepoPath.setExpectedKind(PathChooser::Directory);
|
||||
defaultRepoPath.setDisplayName(Tr::tr("Fossil Repositories"));
|
||||
defaultRepoPath.setLabelText(Tr::tr("Default path:"));
|
||||
@@ -55,7 +54,6 @@ FossilSettings::FossilSettings()
|
||||
|
||||
registerAspect(&sslIdentityFile);
|
||||
sslIdentityFile.setSettingsKey("sslIdentityFile");
|
||||
sslIdentityFile.setDisplayStyle(StringAspect::PathChooserDisplay);
|
||||
sslIdentityFile.setExpectedKind(PathChooser::File);
|
||||
sslIdentityFile.setDisplayName(Tr::tr("SSL/TLS Identity Key"));
|
||||
sslIdentityFile.setLabelText(Tr::tr("SSL/TLS identity:"));
|
||||
|
||||
@@ -12,8 +12,8 @@ class FossilSettings : public VcsBase::VcsBaseSettings
|
||||
public:
|
||||
FossilSettings();
|
||||
|
||||
Utils::StringAspect defaultRepoPath;
|
||||
Utils::StringAspect sslIdentityFile;
|
||||
Utils::FilePathAspect defaultRepoPath;
|
||||
Utils::FilePathAspect sslIdentityFile;
|
||||
Utils::BoolAspect diffIgnoreAllWhiteSpace;
|
||||
Utils::BoolAspect diffStripTrailingCR;
|
||||
Utils::BoolAspect annotateShowCommitters;
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
#include <QLineEdit>
|
||||
#include <QRadioButton>
|
||||
|
||||
namespace Fossil {
|
||||
namespace Internal {
|
||||
namespace Fossil::Internal {
|
||||
|
||||
PullOrPushDialog::PullOrPushDialog(Mode mode, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
@@ -106,10 +105,9 @@ void PullOrPushDialog::setDefaultRemoteLocation(const QString &url)
|
||||
m_urlLineEdit->setText(url);
|
||||
}
|
||||
|
||||
void PullOrPushDialog::setLocalBaseDirectory(const QString &dir)
|
||||
void PullOrPushDialog::setLocalBaseDirectory(const Utils::FilePath &dir)
|
||||
{
|
||||
m_localPathChooser->setBaseDirectory(Utils::FilePath::fromString(dir));
|
||||
m_localPathChooser->setBaseDirectory(dir);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Fossil
|
||||
} // Fossil::Internal
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -13,13 +15,10 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace Utils { class PathChooser; }
|
||||
|
||||
namespace Fossil {
|
||||
namespace Internal {
|
||||
namespace Fossil::Internal {
|
||||
|
||||
class PullOrPushDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Mode {
|
||||
PullMode,
|
||||
@@ -33,7 +32,7 @@ public:
|
||||
bool isRememberOptionEnabled() const;
|
||||
bool isPrivateOptionEnabled() const;
|
||||
void setDefaultRemoteLocation(const QString &url);
|
||||
void setLocalBaseDirectory(const QString &dir);
|
||||
void setLocalBaseDirectory(const Utils::FilePath &dir);
|
||||
// Pull-specific options
|
||||
// Push-specific options
|
||||
|
||||
@@ -47,5 +46,4 @@ private:
|
||||
QCheckBox *m_privateCheckBox;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Fossil
|
||||
} // Fossil::Internal
|
||||
|
||||
14
src/plugins/insight/CMakeLists.txt
Normal file
14
src/plugins/insight/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
add_qtc_plugin(Insight
|
||||
CONDITION TARGET QtCreator::QmlDesigner
|
||||
PLUGIN_DEPENDS
|
||||
QtCreator::Core QtCreator::QtSupport QtCreator::QmlDesigner QtCreator::QmlProjectManager QtCreator::ProjectExplorer
|
||||
DEPENDS
|
||||
QtCreator::Utils
|
||||
Qt6::Core Qt6::CorePrivate Qt6::Widgets
|
||||
Qt6::Qml Qt6::QmlPrivate Qt6::Quick Qt6::QuickWidgets
|
||||
SOURCES
|
||||
insightplugin.cpp insightplugin.h
|
||||
insightmodel.cpp insightmodel.h
|
||||
insightview.cpp insightview.h
|
||||
insightwidget.cpp insightwidget.h
|
||||
)
|
||||
21
src/plugins/insight/Insight.json.in
Normal file
21
src/plugins/insight/Insight.json.in
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
\"Name\" : \"Insight\",
|
||||
\"Version\" : \"$$QTCREATOR_VERSION\",
|
||||
\"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
|
||||
\"Revision\" : \"$$QTC_PLUGIN_REVISION\",
|
||||
\"Vendor\" : \"The Qt Company Ltd\",
|
||||
\"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
|
||||
\"License\" : [ \"Commercial Usage\",
|
||||
\"\",
|
||||
\"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and The Qt Company.\",
|
||||
\"\",
|
||||
\"GNU General Public License Usage\",
|
||||
\"\",
|
||||
\"Alternatively, this plugin may be used under the terms of the GNU General Public License version 3 as published by the Free Software Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT included in the packaging of this plugin. Please review the following information to ensure the GNU General Public License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html.\"
|
||||
],
|
||||
\"Category\" : \"Qt Quick\",
|
||||
\"Description\" : \"Qt Insight Support for Design Studio.\",
|
||||
\"DisabledByDefault\" : true,
|
||||
\"Url\" : \"http://www.qt.io\",
|
||||
$$dependencyList
|
||||
}
|
||||
860
src/plugins/insight/insightmodel.cpp
Normal file
860
src/plugins/insight/insightmodel.cpp
Normal file
@@ -0,0 +1,860 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "insightmodel.h"
|
||||
#include "insightview.h"
|
||||
|
||||
#include <auxiliarydataproperties.h>
|
||||
#include <externaldependenciesinterface.h>
|
||||
#include <plaintexteditmodifier.h>
|
||||
#include <rewriterview.h>
|
||||
#include <signalhandlerproperty.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr QStringView insightConfFile{u"qtinsight.conf"};
|
||||
constexpr QStringView qtdsConfFile{u"qtdsinsight.conf"};
|
||||
constexpr QStringView dataFolder{u"qtinsight"};
|
||||
|
||||
constexpr QStringView insightImport{u"QtInsightTracker"};
|
||||
constexpr QStringView signalHandler{u"Component.onCompleted"};
|
||||
constexpr QStringView regExp{u"InsightTracker\\.enabled\\s*=\\s*(true|false)"};
|
||||
|
||||
constexpr std::string_view defaultColor{"#000000"};
|
||||
constexpr std::string_view predefinedStr{"predefined"};
|
||||
constexpr std::string_view customStr{"custom"};
|
||||
|
||||
constexpr QStringView defaultCategoryName{u"New Category"};
|
||||
|
||||
// JSON attribut names
|
||||
constexpr std::string_view categoriesAtt{"categories"};
|
||||
constexpr std::string_view tokenAtt{"token"};
|
||||
constexpr std::string_view syncAtt{"sync"};
|
||||
constexpr std::string_view intervalAtt{"interval"};
|
||||
constexpr std::string_view secondsAtt{"seconds"};
|
||||
constexpr std::string_view minutesAtt{"minutes"};
|
||||
|
||||
constexpr std::string_view nameAtt{"name"};
|
||||
constexpr std::string_view typeAtt{"type"};
|
||||
constexpr std::string_view colorAtt{"color"};
|
||||
|
||||
QByteArray fileToByteArray(const QString &filePath)
|
||||
{
|
||||
QFile file(filePath);
|
||||
|
||||
if (!file.exists()) {
|
||||
qWarning() << "File does not exist" << filePath;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qWarning() << "Could not open" << filePath << file.error() << file.errorString();
|
||||
return {};
|
||||
}
|
||||
|
||||
return file.readAll();
|
||||
}
|
||||
|
||||
QString fileToString(const QString &filePath)
|
||||
{
|
||||
return QString::fromUtf8(fileToByteArray(filePath));
|
||||
}
|
||||
|
||||
bool isNodeEnabled(const ModelNode &node)
|
||||
{
|
||||
SignalHandlerProperty property = node.signalHandlerProperty(signalHandler.toUtf8());
|
||||
|
||||
QString src = property.source();
|
||||
const QRegularExpression re(regExp.toString());
|
||||
QRegularExpressionMatch match = re.match(src);
|
||||
|
||||
if (match.hasMatch() && !match.capturedView(1).isEmpty())
|
||||
return QVariant(match.captured(1)).toBool();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void setNodeEnabled(const ModelNode &node, bool value)
|
||||
{
|
||||
const QString valueAsStr = QVariant(value).toString();
|
||||
|
||||
if (node.hasSignalHandlerProperty(signalHandler.toUtf8())) {
|
||||
SignalHandlerProperty property = node.signalHandlerProperty(signalHandler.toUtf8());
|
||||
|
||||
QString src = property.source();
|
||||
const QRegularExpression re(regExp.toString());
|
||||
QRegularExpressionMatch match = re.match(src);
|
||||
|
||||
if (match.hasMatch() && !match.capturedView(1).isEmpty())
|
||||
src.replace(match.capturedStart(1), match.capturedLength(1), valueAsStr);
|
||||
|
||||
property.setSource(src);
|
||||
} else {
|
||||
SignalHandlerProperty property = node.signalHandlerProperty(signalHandler.toUtf8());
|
||||
property.setSource("InsightTracker.enabled = " + valueAsStr);
|
||||
}
|
||||
}
|
||||
|
||||
json readJSON(const QString &filePath)
|
||||
{
|
||||
const QByteArray data = fileToByteArray(filePath);
|
||||
if (data.isEmpty()) {
|
||||
qWarning() << "File is empty" << filePath;
|
||||
return {};
|
||||
}
|
||||
|
||||
json document;
|
||||
|
||||
try {
|
||||
document = json::parse(data.data());
|
||||
} catch (json::parse_error &e) {
|
||||
qWarning() << "JSON parse error" << e.what();
|
||||
return {};
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
bool writeJSON(const QString &filePath, const json &document)
|
||||
{
|
||||
QFile file(filePath);
|
||||
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
qWarning() << "Could not open file" << filePath << file.error() << file.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = file.write(document.dump(4).c_str());
|
||||
|
||||
if (result == -1)
|
||||
qWarning() << "Could not write file" << filePath << file.error() << file.errorString();
|
||||
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
json createCategory(std::string_view name,
|
||||
std::string_view type = customStr,
|
||||
std::string_view color = defaultColor)
|
||||
{
|
||||
return json::object({{nameAtt, name}, {typeAtt, type}, {colorAtt, color}});
|
||||
}
|
||||
|
||||
// Checks if a is fully, partially or not at all contained in b.
|
||||
Qt::CheckState checkState(const std::vector<std::string> &a, const std::vector<std::string> &b)
|
||||
{
|
||||
unsigned count = 0;
|
||||
std::for_each(a.begin(), a.end(), [&](const std::string &s) {
|
||||
if (std::find(b.begin(), b.end(), s) != b.end())
|
||||
++count;
|
||||
});
|
||||
|
||||
if (count == 0)
|
||||
return Qt::Unchecked;
|
||||
else if (count == a.size())
|
||||
return Qt::Checked;
|
||||
|
||||
return Qt::PartiallyChecked;
|
||||
}
|
||||
|
||||
struct ModelBuilder
|
||||
{
|
||||
ModelBuilder(const QString &filePath, ExternalDependenciesInterface &externalDependencies)
|
||||
{
|
||||
const QString fileContent = fileToString(filePath);
|
||||
if (fileContent.isEmpty()) {
|
||||
qWarning() << "File is empty" << filePath;
|
||||
return;
|
||||
}
|
||||
|
||||
document = std::make_unique<QTextDocument>(fileContent);
|
||||
modifier = std::make_unique<NotIndentingTextEditModifier>(document.get(),
|
||||
QTextCursor{document.get()});
|
||||
|
||||
rewriter = std::make_unique<RewriterView>(externalDependencies, RewriterView::Amend);
|
||||
rewriter->setCheckSemanticErrors(false);
|
||||
rewriter->setCheckLinkErrors(false);
|
||||
rewriter->setTextModifier(modifier.get());
|
||||
|
||||
model = QmlDesigner::Model::create("QtQuick.Item", 2, 1);
|
||||
model->setRewriterView(rewriter.get());
|
||||
}
|
||||
|
||||
std::unique_ptr<QTextDocument> document;
|
||||
std::unique_ptr<NotIndentingTextEditModifier> modifier;
|
||||
std::unique_ptr<RewriterView> rewriter;
|
||||
ModelPointer model;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
InsightModel::InsightModel(InsightView *view, ExternalDependenciesInterface &externalDependencies)
|
||||
: m_insightView(view)
|
||||
, m_externalDependencies(externalDependencies)
|
||||
, m_fileSystemWatcher(new Utils::FileSystemWatcher(this))
|
||||
{
|
||||
QObject::connect(ProjectExplorer::ProjectManager::instance(),
|
||||
&ProjectExplorer::ProjectManager::startupProjectChanged,
|
||||
this,
|
||||
[&](ProjectExplorer::Project *project) {
|
||||
if (project)
|
||||
m_initialized = false;
|
||||
});
|
||||
|
||||
QObject::connect(m_fileSystemWatcher,
|
||||
&Utils::FileSystemWatcher::fileChanged,
|
||||
this,
|
||||
&InsightModel::handleFileChange);
|
||||
}
|
||||
|
||||
int InsightModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return m_qtdsConfig.empty() ? 0 : m_qtdsConfig.size();
|
||||
}
|
||||
|
||||
QVariant InsightModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= rowCount() || m_qtdsConfig.empty())
|
||||
return QVariant();
|
||||
|
||||
json::json_pointer ptr;
|
||||
ptr.push_back(std::to_string(index.row()));
|
||||
|
||||
if (!m_qtdsConfig.contains(ptr))
|
||||
return QVariant();
|
||||
|
||||
auto element = m_qtdsConfig[ptr];
|
||||
|
||||
switch (role) {
|
||||
case CategoryName:
|
||||
return QString::fromStdString(element.value(nameAtt, ""));
|
||||
case CategoryColor:
|
||||
return QString::fromStdString(element.value(colorAtt, ""));
|
||||
case CategoryType:
|
||||
return QString::fromStdString(element.value(typeAtt, ""));
|
||||
case CategoryActive: {
|
||||
auto categories = activeCategories();
|
||||
auto category = element.value(nameAtt, "");
|
||||
return std::find(std::begin(categories), std::end(categories), category)
|
||||
!= std::end(categories);
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> InsightModel::roleNames() const
|
||||
{
|
||||
static QHash<int, QByteArray> roleNames{{CategoryName, "categoryName"},
|
||||
{CategoryColor, "categoryColor"},
|
||||
{CategoryType, "categoryType"},
|
||||
{CategoryActive, "categoryActive"}};
|
||||
return roleNames;
|
||||
}
|
||||
|
||||
void InsightModel::setup()
|
||||
{
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
const QString projectUrl = m_externalDependencies.projectUrl().toLocalFile();
|
||||
|
||||
m_mainQmlInfo = QFileInfo(projectUrl + "/main.qml");
|
||||
m_configInfo = QFileInfo(projectUrl + "/" + insightConfFile);
|
||||
m_qtdsConfigInfo = QFileInfo(projectUrl + "/" + qtdsConfFile);
|
||||
|
||||
parseMainQml();
|
||||
parseDefaultConfig();
|
||||
parseConfig();
|
||||
parseQtdsConfig();
|
||||
|
||||
beginResetModel();
|
||||
|
||||
if (m_qtdsConfig.empty())
|
||||
createQtdsConfig();
|
||||
else
|
||||
updateQtdsConfig();
|
||||
|
||||
endResetModel();
|
||||
|
||||
updateCheckState();
|
||||
|
||||
if (m_enabled) {
|
||||
// Flush config files and start listening to modifications
|
||||
writeJSON(m_configInfo.absoluteFilePath(), m_config);
|
||||
writeJSON(m_qtdsConfigInfo.absoluteFilePath(), m_qtdsConfig);
|
||||
}
|
||||
|
||||
m_fileSystemWatcher->addFile(m_mainQmlInfo.absoluteFilePath(),
|
||||
Utils::FileSystemWatcher::WatchModifiedDate);
|
||||
m_fileSystemWatcher->addFile(m_configInfo.absoluteFilePath(),
|
||||
Utils::FileSystemWatcher::WatchModifiedDate);
|
||||
m_fileSystemWatcher->addFile(m_qtdsConfigInfo.absoluteFilePath(),
|
||||
Utils::FileSystemWatcher::WatchModifiedDate);
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
void InsightModel::addCategory()
|
||||
{
|
||||
int counter = 0;
|
||||
QString newCategory = defaultCategoryName.toString();
|
||||
|
||||
while (hasCategory(newCategory)) {
|
||||
++counter;
|
||||
newCategory = QString(QStringLiteral("%1%2")).arg(defaultCategoryName).arg(counter);
|
||||
}
|
||||
|
||||
json tmp = m_qtdsConfig;
|
||||
tmp.push_back(createCategory(newCategory.toStdString()));
|
||||
writeJSON(m_qtdsConfigInfo.absoluteFilePath(), tmp);
|
||||
}
|
||||
|
||||
void InsightModel::removeCateogry(int idx)
|
||||
{
|
||||
json::json_pointer ptr;
|
||||
ptr.push_back(std::to_string(idx));
|
||||
ptr.push_back(std::string(nameAtt));
|
||||
|
||||
// Check if category is active and remove it there as well
|
||||
auto active = activeCategories();
|
||||
auto category = m_qtdsConfig.contains(ptr) ? m_qtdsConfig[ptr].get<std::string>() : "";
|
||||
auto it = std::find(std::begin(active), std::end(active), category);
|
||||
if (it != std::end(active)) {
|
||||
active.erase(it);
|
||||
|
||||
json tmp = m_config;
|
||||
tmp[categoriesAtt] = active;
|
||||
writeJSON(m_configInfo.absoluteFilePath(), tmp);
|
||||
}
|
||||
|
||||
json tmp = m_qtdsConfig;
|
||||
tmp.erase(idx);
|
||||
writeJSON(m_qtdsConfigInfo.absoluteFilePath(), tmp);
|
||||
}
|
||||
|
||||
bool InsightModel::renameCategory(int idx, const QString &name)
|
||||
{
|
||||
if (hasCategory(name))
|
||||
return false;
|
||||
|
||||
json::json_pointer ptr;
|
||||
ptr.push_back(std::to_string(idx));
|
||||
ptr.push_back(std::string(nameAtt));
|
||||
|
||||
// Check if category is active and rename it there as well
|
||||
auto active = activeCategories();
|
||||
auto category = m_qtdsConfig.contains(ptr) ? m_qtdsConfig[ptr].get<std::string>() : "";
|
||||
auto it = std::find(std::begin(active), std::end(active), category);
|
||||
if (it != std::end(active)) {
|
||||
*it = name.toStdString();
|
||||
|
||||
json tmp = m_config;
|
||||
tmp[categoriesAtt] = active;
|
||||
writeJSON(m_configInfo.absoluteFilePath(), tmp);
|
||||
}
|
||||
|
||||
json tmp = m_qtdsConfig;
|
||||
tmp[ptr] = name.toStdString();
|
||||
writeJSON(m_qtdsConfigInfo.absoluteFilePath(), tmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void InsightModel::setCategoryActive(int idx, bool value)
|
||||
{
|
||||
json::json_pointer ptr;
|
||||
ptr.push_back(std::to_string(idx));
|
||||
ptr.push_back(std::string(nameAtt));
|
||||
|
||||
auto categoryName = m_qtdsConfig.contains(ptr) ? m_qtdsConfig[ptr].get<std::string>() : "";
|
||||
auto categories = activeCategories();
|
||||
|
||||
if (value) { // active = true
|
||||
if (std::find(std::begin(categories), std::end(categories), categoryName)
|
||||
== std::end(categories))
|
||||
categories.push_back(categoryName);
|
||||
} else { // active = false
|
||||
categories.erase(std::remove(categories.begin(), categories.end(), categoryName),
|
||||
categories.end());
|
||||
}
|
||||
|
||||
json tmp = m_config;
|
||||
tmp[categoriesAtt] = categories;
|
||||
writeJSON(m_configInfo.absoluteFilePath(), tmp);
|
||||
}
|
||||
|
||||
bool InsightModel::enabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void InsightModel::setEnabled(bool value)
|
||||
{
|
||||
if (!m_mainQmlInfo.exists()) {
|
||||
qWarning() << "File does not exist" << m_mainQmlInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
ModelBuilder builder(m_mainQmlInfo.absoluteFilePath(), m_externalDependencies);
|
||||
|
||||
if (!builder.model) {
|
||||
qWarning() << "Could not create model" << m_mainQmlInfo.absoluteFilePath();
|
||||
return;
|
||||
}
|
||||
|
||||
// Add import if it does not exist yet
|
||||
Import import = Import::createLibraryImport(insightImport.toString(), "1.0");
|
||||
if (!builder.model->hasImport(import, true, true) && value) {
|
||||
builder.model->changeImports({import}, {});
|
||||
}
|
||||
|
||||
bool insightEnabled = isNodeEnabled(builder.rewriter->rootModelNode());
|
||||
if (insightEnabled == value)
|
||||
return;
|
||||
|
||||
setNodeEnabled(builder.rewriter->rootModelNode(), value);
|
||||
|
||||
QFile file(m_mainQmlInfo.absoluteFilePath());
|
||||
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
qWarning() << "Could not open" << m_mainQmlInfo.absoluteFilePath() << file.error()
|
||||
<< file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
auto result = file.write(builder.rewriter->textModifierContent().toUtf8());
|
||||
|
||||
if (result == -1)
|
||||
qWarning() << "Could not write file" << m_mainQmlInfo.absoluteFilePath() << file.error()
|
||||
<< file.errorString();
|
||||
|
||||
// If enabled and config files do not exist yet, write them
|
||||
if (value) {
|
||||
if (!m_configInfo.exists())
|
||||
writeJSON(m_configInfo.absoluteFilePath(), m_config);
|
||||
if (!m_qtdsConfigInfo.exists())
|
||||
writeJSON(m_qtdsConfigInfo.absoluteFilePath(), m_qtdsConfig);
|
||||
}
|
||||
|
||||
m_enabled = value;
|
||||
setAuxiliaryEnabled(m_enabled);
|
||||
|
||||
QmlDesignerPlugin::instance()->viewManager().resetPropertyEditorView();
|
||||
}
|
||||
|
||||
QString InsightModel::token() const
|
||||
{
|
||||
if (m_config.empty())
|
||||
return {};
|
||||
|
||||
return QString::fromStdString(m_config.value(tokenAtt, ""));
|
||||
}
|
||||
|
||||
void InsightModel::setToken(const QString &value)
|
||||
{
|
||||
writeConfigValue(json::json_pointer("/" + std::string(tokenAtt)), value.toStdString());
|
||||
}
|
||||
|
||||
int InsightModel::minutes() const
|
||||
{
|
||||
if (m_config.empty())
|
||||
return {};
|
||||
|
||||
json::json_pointer ptr;
|
||||
ptr.push_back(std::string(syncAtt));
|
||||
ptr.push_back(std::string(intervalAtt));
|
||||
ptr.push_back(std::string(minutesAtt));
|
||||
|
||||
return m_config.value(ptr, 0);
|
||||
}
|
||||
|
||||
void InsightModel::setMinutes(int value)
|
||||
{
|
||||
json::json_pointer ptr;
|
||||
ptr.push_back(std::string(syncAtt));
|
||||
ptr.push_back(std::string(intervalAtt));
|
||||
ptr.push_back(std::string(minutesAtt));
|
||||
|
||||
writeConfigValue(ptr, value);
|
||||
}
|
||||
|
||||
void InsightModel::selectAllPredefined()
|
||||
{
|
||||
selectAll(predefinedCategories(), m_predefinedCheckState);
|
||||
}
|
||||
|
||||
void InsightModel::selectAllCustom()
|
||||
{
|
||||
selectAll(customCategories(), m_customCheckState);
|
||||
}
|
||||
|
||||
void InsightModel::handleFileChange(const QString &path)
|
||||
{
|
||||
if (m_mainQmlInfo.absoluteFilePath() == path)
|
||||
parseMainQml();
|
||||
else if (m_configInfo.absoluteFilePath() == path)
|
||||
parseConfig();
|
||||
else if (m_qtdsConfigInfo.absoluteFilePath() == path) {
|
||||
beginResetModel();
|
||||
parseQtdsConfig();
|
||||
endResetModel();
|
||||
}
|
||||
}
|
||||
|
||||
void InsightModel::setAuxiliaryEnabled(bool value)
|
||||
{
|
||||
ModelNode root = m_insightView->rootModelNode();
|
||||
if (root.isValid())
|
||||
root.setAuxiliaryData(insightEnabledProperty, value);
|
||||
}
|
||||
|
||||
void InsightModel::setAuxiliaryCategories(const std::vector<std::string> &categories)
|
||||
{
|
||||
ModelNode root = m_insightView->rootModelNode();
|
||||
if (root.isValid()) {
|
||||
QStringList c;
|
||||
std::for_each(categories.begin(), categories.end(), [&](const std::string &s) {
|
||||
c.append(QString::fromStdString(s));
|
||||
});
|
||||
|
||||
root.setAuxiliaryData(insightCategoriesProperty, c);
|
||||
}
|
||||
}
|
||||
|
||||
void InsightModel::hideCursor()
|
||||
{
|
||||
if (QApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
|
||||
|
||||
if (QWidget *w = QApplication::activeWindow())
|
||||
m_lastPos = QCursor::pos(w->screen());
|
||||
}
|
||||
|
||||
void InsightModel::restoreCursor()
|
||||
{
|
||||
if (!QApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
if (QWidget *w = QApplication::activeWindow())
|
||||
QCursor::setPos(w->screen(), m_lastPos);
|
||||
}
|
||||
|
||||
void InsightModel::holdCursorInPlace()
|
||||
{
|
||||
if (!QApplication::overrideCursor())
|
||||
return;
|
||||
|
||||
if (QWidget *w = QApplication::activeWindow())
|
||||
QCursor::setPos(w->screen(), m_lastPos);
|
||||
}
|
||||
|
||||
int InsightModel::devicePixelRatio()
|
||||
{
|
||||
if (QWidget *w = QApplication::activeWindow())
|
||||
return w->devicePixelRatio();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void InsightModel::parseMainQml()
|
||||
{
|
||||
ModelBuilder builder(m_mainQmlInfo.absoluteFilePath(), m_externalDependencies);
|
||||
|
||||
if (!builder.model)
|
||||
return;
|
||||
|
||||
Import import = Import::createLibraryImport(insightImport.toString(), "1.0");
|
||||
if (!builder.model->hasImport(import, true, true))
|
||||
return;
|
||||
|
||||
bool insightEnabled = isNodeEnabled(builder.rewriter->rootModelNode());
|
||||
|
||||
if (m_enabled != insightEnabled) {
|
||||
m_enabled = insightEnabled;
|
||||
emit enabledChanged();
|
||||
|
||||
setAuxiliaryEnabled(m_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void InsightModel::parseDefaultConfig()
|
||||
{
|
||||
// Load default insight config from plugin
|
||||
const ProjectExplorer::Target *target = ProjectExplorer::ProjectTree::currentTarget();
|
||||
if (target) {
|
||||
const QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
|
||||
m_defaultConfig = readJSON(qtVersion->dataPath().toString() + "/" + dataFolder + "/"
|
||||
+ insightConfFile);
|
||||
}
|
||||
}
|
||||
|
||||
void InsightModel::parseConfig()
|
||||
{
|
||||
json target = readJSON(m_configInfo.absoluteFilePath());
|
||||
|
||||
if (target.empty()) {
|
||||
if (m_defaultConfig.empty()) {
|
||||
qWarning() << "Could not find default or user insight config.";
|
||||
return;
|
||||
}
|
||||
// Copy default config
|
||||
m_config = m_defaultConfig;
|
||||
|
||||
// Try to overwrite seconds entry in config as it is set in the default config to 60,
|
||||
// but currently not supported in QtDS.
|
||||
json::json_pointer ptr;
|
||||
ptr.push_back(std::string(syncAtt));
|
||||
ptr.push_back(std::string(intervalAtt));
|
||||
|
||||
if (m_config.contains(ptr))
|
||||
m_config[ptr][secondsAtt] = 0;
|
||||
} else {
|
||||
bool resetModel = false;
|
||||
|
||||
if (m_config.empty()) {
|
||||
m_config = target;
|
||||
|
||||
emit tokenChanged();
|
||||
emit minutesChanged();
|
||||
resetModel = true;
|
||||
} else {
|
||||
json patch = json::diff(m_config, target);
|
||||
|
||||
m_config = target;
|
||||
for (auto it : patch) {
|
||||
if (!it.contains("path"))
|
||||
continue;
|
||||
|
||||
json::json_pointer tmp(it["path"].get<std::string>());
|
||||
|
||||
if (tmp.back() == tokenAtt)
|
||||
emit tokenChanged();
|
||||
|
||||
if (tmp.back() == minutesAtt)
|
||||
emit minutesChanged();
|
||||
|
||||
if (!tmp.to_string().compare(1, categoriesAtt.size(), categoriesAtt))
|
||||
resetModel = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (resetModel) {
|
||||
updateCheckState();
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InsightModel::parseQtdsConfig()
|
||||
{
|
||||
m_qtdsConfig = readJSON(m_qtdsConfigInfo.absoluteFilePath());
|
||||
updateCheckState();
|
||||
setAuxiliaryCategories(customCategories());
|
||||
}
|
||||
|
||||
// Create new QtDS Insight configuration
|
||||
void InsightModel::createQtdsConfig()
|
||||
{
|
||||
json categories = json::array();
|
||||
|
||||
auto active = activeCategories();
|
||||
auto predefined = predefinedCategories();
|
||||
|
||||
std::vector<std::string> custom;
|
||||
|
||||
std::set_difference(std::make_move_iterator(active.begin()),
|
||||
std::make_move_iterator(active.end()),
|
||||
std::make_move_iterator(predefined.begin()),
|
||||
std::make_move_iterator(predefined.end()),
|
||||
std::back_inserter(custom));
|
||||
|
||||
for (const auto &c : predefined)
|
||||
categories.push_back(createCategory(c, predefinedStr));
|
||||
|
||||
for (const auto &c : custom)
|
||||
categories.push_back(createCategory(c));
|
||||
|
||||
m_qtdsConfig = categories;
|
||||
}
|
||||
|
||||
// Update existing QtDS Insight configuration
|
||||
void InsightModel::updateQtdsConfig()
|
||||
{
|
||||
auto contains = [&](const json &arr, const std::string &val) {
|
||||
for (auto it : arr) {
|
||||
if (val == it[nameAtt].get<std::string>())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto active = activeCategories();
|
||||
auto predefined = predefinedCategories();
|
||||
std::vector<std::string> custom;
|
||||
|
||||
std::set_difference(std::make_move_iterator(active.begin()),
|
||||
std::make_move_iterator(active.end()),
|
||||
std::make_move_iterator(predefined.begin()),
|
||||
std::make_move_iterator(predefined.end()),
|
||||
std::back_inserter(custom));
|
||||
|
||||
for (const auto &c : predefined) {
|
||||
if (!contains(m_qtdsConfig, c))
|
||||
m_qtdsConfig.push_back(createCategory(c, predefinedStr));
|
||||
}
|
||||
|
||||
for (const auto &c : custom) {
|
||||
if (!contains(m_qtdsConfig, c))
|
||||
m_qtdsConfig.push_back(createCategory(c));
|
||||
}
|
||||
}
|
||||
|
||||
void InsightModel::selectAll(const std::vector<std::string> &categories, Qt::CheckState checkState)
|
||||
{
|
||||
auto active = activeCategories();
|
||||
|
||||
if (checkState == Qt::Unchecked || checkState == Qt::PartiallyChecked) {
|
||||
// Select all
|
||||
std::for_each(categories.begin(), categories.end(), [&](const std::string &s) {
|
||||
if (std::find(active.begin(), active.end(), s) == active.end())
|
||||
active.push_back(s);
|
||||
});
|
||||
} else {
|
||||
// Unselect all
|
||||
std::vector<std::string> diff;
|
||||
|
||||
std::set_difference(active.begin(),
|
||||
active.end(),
|
||||
categories.begin(),
|
||||
categories.end(),
|
||||
std::inserter(diff, diff.begin()));
|
||||
active = diff;
|
||||
}
|
||||
|
||||
json tmp = m_config;
|
||||
tmp[categoriesAtt] = active;
|
||||
writeJSON(m_configInfo.absoluteFilePath(), tmp);
|
||||
}
|
||||
|
||||
std::vector<std::string> InsightModel::predefinedCategories() const
|
||||
{
|
||||
std::vector<std::string> categories;
|
||||
if (!m_defaultConfig.empty() && m_defaultConfig.contains(categoriesAtt))
|
||||
categories = m_defaultConfig[categoriesAtt].get<std::vector<std::string>>();
|
||||
|
||||
std::sort(categories.begin(), categories.end());
|
||||
categories.erase(std::unique(categories.begin(), categories.end()), categories.end());
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
std::vector<std::string> InsightModel::activeCategories() const
|
||||
{
|
||||
std::vector<std::string> categories;
|
||||
if (!m_config.empty() && m_config.contains(categoriesAtt))
|
||||
categories = m_config[categoriesAtt].get<std::vector<std::string>>();
|
||||
|
||||
std::sort(categories.begin(), categories.end());
|
||||
categories.erase(std::unique(categories.begin(), categories.end()), categories.end());
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
std::vector<std::string> InsightModel::customCategories() const
|
||||
{
|
||||
std::vector<std::string> categories;
|
||||
if (!m_qtdsConfig.empty()) {
|
||||
for (auto it : m_qtdsConfig) {
|
||||
if (it.contains(typeAtt) && it.contains(nameAtt)
|
||||
&& it[typeAtt].get<std::string>() == customStr)
|
||||
categories.push_back(it[nameAtt].get<std::string>());
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(categories.begin(), categories.end());
|
||||
categories.erase(std::unique(categories.begin(), categories.end()), categories.end());
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
std::vector<std::string> InsightModel::categories() const
|
||||
{
|
||||
std::vector<std::string> categories;
|
||||
if (!m_qtdsConfig.empty()) {
|
||||
for (auto it : m_qtdsConfig) {
|
||||
if (it.contains(nameAtt))
|
||||
categories.push_back(it[nameAtt].get<std::string>());
|
||||
}
|
||||
}
|
||||
|
||||
return categories;
|
||||
}
|
||||
|
||||
bool InsightModel::hasCategory(const QString &name) const
|
||||
{
|
||||
auto c = categories();
|
||||
return std::find(std::begin(c), std::end(c), name.toStdString()) != std::end(c);
|
||||
}
|
||||
|
||||
void InsightModel::updateCheckState()
|
||||
{
|
||||
auto active = activeCategories();
|
||||
auto predefined = predefinedCategories();
|
||||
auto custom = customCategories();
|
||||
|
||||
Qt::CheckState predefinedCheckState = checkState(predefined, active);
|
||||
Qt::CheckState customCheckState = checkState(custom, active);
|
||||
|
||||
if (m_predefinedCheckState != predefinedCheckState) {
|
||||
m_predefinedCheckState = predefinedCheckState;
|
||||
emit predefinedSelectStateChanged();
|
||||
}
|
||||
|
||||
if (m_customCheckState != customCheckState) {
|
||||
m_customCheckState = customCheckState;
|
||||
emit customSelectStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void InsightModel::writeConfigValue(const json::json_pointer &ptr, T value)
|
||||
{
|
||||
T configValue{};
|
||||
|
||||
if (!m_config.empty())
|
||||
configValue = m_config.value(ptr, configValue);
|
||||
|
||||
if (configValue == value)
|
||||
return;
|
||||
|
||||
json tmp = m_config;
|
||||
tmp[ptr] = value;
|
||||
|
||||
writeJSON(m_configInfo.absoluteFilePath(), tmp);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
132
src/plugins/insight/insightmodel.h
Normal file
132
src/plugins/insight/insightmodel.h
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <model.h>
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QFileInfo>
|
||||
#include <QPointer>
|
||||
#include <QPoint>
|
||||
|
||||
#include <utils/filesystemwatcher.h>
|
||||
|
||||
#include <3rdparty/json/json.hpp>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class InsightView;
|
||||
|
||||
typedef nlohmann::json json;
|
||||
|
||||
class InsightModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool enabled READ enabled NOTIFY enabledChanged)
|
||||
Q_PROPERTY(QString token READ token NOTIFY tokenChanged)
|
||||
Q_PROPERTY(int minutes READ minutes NOTIFY minutesChanged)
|
||||
Q_PROPERTY(Qt::CheckState predefinedSelectState MEMBER m_predefinedCheckState NOTIFY
|
||||
predefinedSelectStateChanged)
|
||||
Q_PROPERTY(Qt::CheckState customSelectState MEMBER m_customCheckState NOTIFY customSelectStateChanged)
|
||||
|
||||
enum {
|
||||
CategoryName = Qt::DisplayRole,
|
||||
CategoryColor = Qt::UserRole,
|
||||
CategoryType,
|
||||
CategoryActive
|
||||
};
|
||||
|
||||
public:
|
||||
InsightModel(InsightView *view, class ExternalDependenciesInterface &externalDependencies);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void setup();
|
||||
|
||||
Q_INVOKABLE void addCategory();
|
||||
Q_INVOKABLE void removeCateogry(int idx);
|
||||
Q_INVOKABLE bool renameCategory(int idx, const QString &name);
|
||||
|
||||
Q_INVOKABLE void setCategoryActive(int idx, bool value);
|
||||
|
||||
bool enabled() const;
|
||||
Q_INVOKABLE void setEnabled(bool value);
|
||||
|
||||
QString token() const;
|
||||
Q_INVOKABLE void setToken(const QString &value);
|
||||
|
||||
int minutes() const;
|
||||
Q_INVOKABLE void setMinutes(int value);
|
||||
|
||||
Q_INVOKABLE void selectAllPredefined();
|
||||
Q_INVOKABLE void selectAllCustom();
|
||||
|
||||
void handleFileChange(const QString &path);
|
||||
|
||||
void setAuxiliaryEnabled(bool value);
|
||||
void setAuxiliaryCategories(const std::vector<std::string> &categories);
|
||||
|
||||
Q_INVOKABLE void hideCursor();
|
||||
Q_INVOKABLE void restoreCursor();
|
||||
Q_INVOKABLE void holdCursorInPlace();
|
||||
|
||||
Q_INVOKABLE int devicePixelRatio();
|
||||
|
||||
signals:
|
||||
void enabledChanged();
|
||||
void tokenChanged();
|
||||
void minutesChanged();
|
||||
|
||||
void predefinedSelectStateChanged();
|
||||
void customSelectStateChanged();
|
||||
|
||||
private:
|
||||
void parseMainQml();
|
||||
void parseDefaultConfig();
|
||||
void parseConfig();
|
||||
void parseQtdsConfig();
|
||||
|
||||
void createQtdsConfig();
|
||||
void updateQtdsConfig();
|
||||
|
||||
void selectAll(const std::vector<std::string> &categories, Qt::CheckState checkState);
|
||||
|
||||
std::vector<std::string> predefinedCategories() const;
|
||||
std::vector<std::string> activeCategories() const;
|
||||
std::vector<std::string> customCategories() const;
|
||||
std::vector<std::string> categories() const;
|
||||
|
||||
bool hasCategory(const QString &name) const;
|
||||
void updateCheckState();
|
||||
|
||||
template<typename T>
|
||||
void writeConfigValue(const json::json_pointer &ptr, T value);
|
||||
|
||||
private:
|
||||
QPointer<InsightView> m_insightView;
|
||||
ExternalDependenciesInterface &m_externalDependencies;
|
||||
|
||||
Utils::FileSystemWatcher *m_fileSystemWatcher;
|
||||
|
||||
bool m_enabled = false;
|
||||
bool m_initialized = false;
|
||||
|
||||
QFileInfo m_mainQmlInfo;
|
||||
QFileInfo m_configInfo;
|
||||
QFileInfo m_qtdsConfigInfo;
|
||||
|
||||
json m_defaultConfig;
|
||||
json m_config;
|
||||
json m_qtdsConfig;
|
||||
|
||||
Qt::CheckState m_predefinedCheckState;
|
||||
Qt::CheckState m_customCheckState;
|
||||
|
||||
QPoint m_lastPos;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
31
src/plugins/insight/insightplugin.cpp
Normal file
31
src/plugins/insight/insightplugin.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "insightplugin.h"
|
||||
|
||||
#include "insightview.h"
|
||||
|
||||
#include <qmldesigner/dynamiclicensecheck.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
InsightPlugin::InsightPlugin() = default;
|
||||
InsightPlugin::~InsightPlugin() = default;
|
||||
|
||||
bool InsightPlugin::initialize(const QStringList & /*arguments*/, QString * /*errorMessage*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsightPlugin::delayedInitialize()
|
||||
{
|
||||
auto *designerPlugin = QmlDesignerPlugin::instance();
|
||||
auto &viewManager = designerPlugin->viewManager();
|
||||
viewManager.registerView(std::make_unique<InsightView>(
|
||||
QmlDesignerPlugin::externalDependenciesForPluginInitializationOnly()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
22
src/plugins/insight/insightplugin.h
Normal file
22
src/plugins/insight/insightplugin.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class InsightPlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Insight.json")
|
||||
public:
|
||||
InsightPlugin();
|
||||
~InsightPlugin();
|
||||
|
||||
bool initialize(const QStringList &arguments, QString *errorMessage);
|
||||
bool delayedInitialize();
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
57
src/plugins/insight/insightview.cpp
Normal file
57
src/plugins/insight/insightview.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "insightview.h"
|
||||
#include "insightmodel.h"
|
||||
#include "insightwidget.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QTextDocument>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
InsightView::InsightView(ExternalDependenciesInterface &externalDependencies)
|
||||
: AbstractView(externalDependencies)
|
||||
, m_insightModel(std::make_unique<InsightModel>(this, externalDependencies))
|
||||
{
|
||||
Q_ASSERT(m_insightModel);
|
||||
}
|
||||
|
||||
InsightView::~InsightView()
|
||||
{
|
||||
delete m_insightWidget.data();
|
||||
}
|
||||
|
||||
void InsightView::modelAttached(Model *model)
|
||||
{
|
||||
if (model == AbstractView::model())
|
||||
return;
|
||||
|
||||
QTC_ASSERT(model, return );
|
||||
AbstractView::modelAttached(model);
|
||||
|
||||
m_insightModel->setup();
|
||||
}
|
||||
|
||||
WidgetInfo InsightView::widgetInfo()
|
||||
{
|
||||
if (!m_insightWidget)
|
||||
m_insightWidget = new InsightWidget(this, m_insightModel.get());
|
||||
|
||||
return createWidgetInfo(m_insightWidget.data(),
|
||||
"QtInsight",
|
||||
WidgetInfo::RightPane,
|
||||
0,
|
||||
tr("Qt Insight"));
|
||||
}
|
||||
|
||||
bool InsightView::hasWidget() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
40
src/plugins/insight/insightview.h
Normal file
40
src/plugins/insight/insightview.h
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <abstractview.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <3rdparty/json/json.hpp>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class InsightModel;
|
||||
class InsightWidget;
|
||||
|
||||
class InsightView : public AbstractView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InsightView(ExternalDependenciesInterface &externalDependencies);
|
||||
~InsightView() override;
|
||||
|
||||
// AbstractView
|
||||
void modelAttached(Model *model) override;
|
||||
|
||||
WidgetInfo widgetInfo() override;
|
||||
bool hasWidget() const override;
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
std::unique_ptr<InsightModel> m_insightModel;
|
||||
QPointer<InsightWidget> m_insightWidget;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
123
src/plugins/insight/insightwidget.cpp
Normal file
123
src/plugins/insight/insightwidget.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "insightwidget.h"
|
||||
#include "insightmodel.h"
|
||||
#include "insightview.h"
|
||||
|
||||
#include <componentcore/theme.h>
|
||||
#include <designersettings.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
#include <invalidqmlsourceexception.h>
|
||||
|
||||
#include <coreplugin/messagebox.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFileInfo>
|
||||
#include <QShortcut>
|
||||
#include <QBoxLayout>
|
||||
#include <QKeySequence>
|
||||
|
||||
#include <QQmlContext>
|
||||
#include <QQmlEngine>
|
||||
#include <QQuickItem>
|
||||
|
||||
enum {
|
||||
debug = false
|
||||
};
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
static QString propertyEditorResourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||
}
|
||||
|
||||
InsightWidget::InsightWidget(InsightView *insightView, InsightModel *insightModel)
|
||||
: m_insightView(insightView)
|
||||
, m_qmlSourceUpdateShortcut(nullptr)
|
||||
{
|
||||
engine()->addImportPath(qmlSourcesPath());
|
||||
engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||
engine()->addImportPath(qmlSourcesPath() + "/imports");
|
||||
|
||||
m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F11), this);
|
||||
connect(m_qmlSourceUpdateShortcut,
|
||||
&QShortcut::activated,
|
||||
this,
|
||||
&InsightWidget::reloadQmlSource);
|
||||
|
||||
setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
rootContext()->setContextProperties({{"insightModel", QVariant::fromValue(insightModel)}});
|
||||
|
||||
Theme::setupTheme(engine());
|
||||
|
||||
setWindowTitle(tr("Qt Insight", "Title of the widget"));
|
||||
setMinimumWidth(195);
|
||||
setMinimumHeight(195);
|
||||
|
||||
// init the first load of the QML UI elements
|
||||
reloadQmlSource();
|
||||
}
|
||||
|
||||
InsightWidget::~InsightWidget() = default;
|
||||
|
||||
QString InsightWidget::qmlSourcesPath()
|
||||
{
|
||||
#ifdef SHARE_QML_PATH
|
||||
if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||
return QLatin1String(SHARE_QML_PATH) + "/insight";
|
||||
#endif
|
||||
return Core::ICore::resourcePath("qmldesigner/insight").toString();
|
||||
}
|
||||
|
||||
void InsightWidget::showEvent(QShowEvent *event)
|
||||
{
|
||||
QQuickWidget::showEvent(event);
|
||||
update();
|
||||
}
|
||||
|
||||
void InsightWidget::focusOutEvent(QFocusEvent *focusEvent)
|
||||
{
|
||||
QmlDesignerPlugin::emitUsageStatisticsTime(Constants::EVENT_INSIGHT_TIME, m_usageTimer.elapsed());
|
||||
QQuickWidget::focusOutEvent(focusEvent);
|
||||
}
|
||||
|
||||
void InsightWidget::focusInEvent(QFocusEvent *focusEvent)
|
||||
{
|
||||
m_usageTimer.restart();
|
||||
QQuickWidget::focusInEvent(focusEvent);
|
||||
}
|
||||
|
||||
void InsightWidget::reloadQmlSource()
|
||||
{
|
||||
QString statesListQmlFilePath = qmlSourcesPath() + QStringLiteral("/Main.qml");
|
||||
QTC_ASSERT(QFileInfo::exists(statesListQmlFilePath), return );
|
||||
engine()->clearComponentCache();
|
||||
setSource(QUrl::fromLocalFile(statesListQmlFilePath));
|
||||
|
||||
if (!rootObject()) {
|
||||
QString errorString;
|
||||
for (const QQmlError &error : errors())
|
||||
errorString += "\n" + error.toString();
|
||||
|
||||
Core::AsynchronousMessageBox::warning(tr("Cannot Create QtQuick View"),
|
||||
tr("InsightWidget: %1 cannot be created.%2")
|
||||
.arg(qmlSourcesPath(), errorString));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
45
src/plugins/insight/insightwidget.h
Normal file
45
src/plugins/insight/insightwidget.h
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QPointer>
|
||||
#include <QQmlPropertyMap>
|
||||
#include <QQuickWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QShortcut;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class NodeInstanceView;
|
||||
class InsightModel;
|
||||
class InsightView;
|
||||
|
||||
class InsightWidget : public QQuickWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InsightWidget(InsightView *insightView, InsightModel *insightModel);
|
||||
~InsightWidget() override;
|
||||
|
||||
static QString qmlSourcesPath();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *) override;
|
||||
void focusOutEvent(QFocusEvent *focusEvent) override;
|
||||
void focusInEvent(QFocusEvent *focusEvent) override;
|
||||
|
||||
private:
|
||||
void reloadQmlSource();
|
||||
|
||||
private:
|
||||
QPointer<InsightView> m_insightView;
|
||||
QShortcut *m_qmlSourceUpdateShortcut;
|
||||
QElapsedTimer m_usageTimer;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
@@ -23,6 +23,7 @@ add_qtc_plugin(McuSupport
|
||||
mcuhelpers.cpp mcuhelpers.h
|
||||
settingshandler.cpp settingshandler.h
|
||||
mcuqmlprojectnode.cpp mcuqmlprojectnode.h
|
||||
mcubuildstep.cpp mcubuildstep.h
|
||||
)
|
||||
|
||||
add_subdirectory(test)
|
||||
|
||||
171
src/plugins/mcusupport/mcubuildstep.cpp
Normal file
171
src/plugins/mcusupport/mcubuildstep.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "mcubuildstep.h"
|
||||
#include "mcukitmanager.h"
|
||||
#include "mculegacyconstants.h"
|
||||
#include "mcusupportconstants.h"
|
||||
|
||||
#include <cmakeprojectmanager/cmakekitinformation.h>
|
||||
|
||||
#include <projectexplorer/buildstep.h>
|
||||
#include <projectexplorer/buildsteplist.h>
|
||||
#include <projectexplorer/buildsystem.h>
|
||||
#include <projectexplorer/deployconfiguration.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
#include <projectexplorer/kitmanager.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/task.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
|
||||
#include <qmlprojectmanager/qmlprojectmanagertr.h>
|
||||
|
||||
#include <qtsupport/qtsupportconstants.h>
|
||||
|
||||
#include <utils/aspects.h>
|
||||
#include <utils/filepath.h>
|
||||
|
||||
#include <QVersionNumber>
|
||||
|
||||
namespace McuSupport::Internal {
|
||||
|
||||
const Utils::Id DeployMcuProcessStep::id = "QmlProject.Mcu.DeployStep";
|
||||
|
||||
void DeployMcuProcessStep::showError(const QString &text)
|
||||
{
|
||||
ProjectExplorer::DeploymentTask task(ProjectExplorer::Task::Error, text);
|
||||
ProjectExplorer::TaskHub::addTask(task);
|
||||
}
|
||||
|
||||
DeployMcuProcessStep::DeployMcuProcessStep(ProjectExplorer::BuildStepList *bc, Utils::Id id)
|
||||
: AbstractProcessStep(bc, id)
|
||||
, m_tmpDir()
|
||||
{
|
||||
if (!buildSystem()) {
|
||||
showError(QmlProjectManager::Tr::tr("Failed to find valid build system"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_tmpDir.isValid()) {
|
||||
showError(QmlProjectManager::Tr::tr("Failed to create valid build directory"));
|
||||
return;
|
||||
}
|
||||
|
||||
ProjectExplorer::Kit *kit = MCUBuildStepFactory::findMostRecentQulKit();
|
||||
if (!kit)
|
||||
return;
|
||||
|
||||
QString root = findKitInformation(kit, Internal::Legacy::Constants::QUL_CMAKE_VAR);
|
||||
auto rootPath = Utils::FilePath::fromString(root);
|
||||
|
||||
auto cmd = addAspect<Utils::StringAspect>();
|
||||
cmd->setSettingsKey("QmlProject.Mcu.ProcessStep.Command");
|
||||
cmd->setDisplayStyle(Utils::StringAspect::PathChooserDisplay);
|
||||
cmd->setExpectedKind(Utils::PathChooser::Command);
|
||||
cmd->setLabelText(QmlProjectManager::Tr::tr("Command:"));
|
||||
cmd->setFilePath(rootPath.pathAppended("/bin/qmlprojectexporter"));
|
||||
|
||||
const char *importPathConstant = QtSupport::Constants::KIT_QML_IMPORT_PATH;
|
||||
Utils::FilePath projectDir = buildSystem()->projectDirectory();
|
||||
Utils::FilePath qulIncludeDir = Utils::FilePath::fromVariant(kit->value(importPathConstant));
|
||||
QStringList includeDirs {
|
||||
Utils::ProcessArgs::quoteArg(qulIncludeDir.toString()),
|
||||
Utils::ProcessArgs::quoteArg(qulIncludeDir.pathAppended("Timeline").toString())
|
||||
};
|
||||
|
||||
const char *toolChainConstant = Internal::Constants::KIT_MCUTARGET_TOOLCHAIN_KEY;
|
||||
QStringList arguments = {
|
||||
Utils::ProcessArgs::quoteArg(buildSystem()->projectFilePath().toString()),
|
||||
"--platform", findKitInformation(kit, "QUL_PLATFORM"),
|
||||
"--toolchain", kit->value(toolChainConstant).toString(),
|
||||
"--include-dirs", includeDirs.join(","),
|
||||
};
|
||||
|
||||
auto args = addAspect<Utils::StringAspect>();
|
||||
args->setSettingsKey("QmlProject.Mcu.ProcessStep.Arguments");
|
||||
args->setDisplayStyle(Utils::StringAspect::LineEditDisplay);
|
||||
args->setLabelText(QmlProjectManager::Tr::tr("Arguments:"));
|
||||
args->setValue(Utils::ProcessArgs::joinArgs(arguments));
|
||||
|
||||
auto outDir = addAspect<Utils::StringAspect>();
|
||||
outDir->setSettingsKey("QmlProject.Mcu.ProcessStep.BuildDirectory");
|
||||
outDir->setDisplayStyle(Utils::StringAspect::PathChooserDisplay);
|
||||
outDir->setExpectedKind(Utils::PathChooser::Directory);
|
||||
outDir->setLabelText(QmlProjectManager::Tr::tr("Build directory:"));
|
||||
outDir->setPlaceHolderText(m_tmpDir.path());
|
||||
|
||||
setCommandLineProvider([this, cmd, args, outDir]() -> Utils::CommandLine {
|
||||
auto directory = outDir->value();
|
||||
if (directory.isEmpty())
|
||||
directory = m_tmpDir.path();
|
||||
|
||||
Utils::CommandLine cmdLine(cmd->filePath());
|
||||
cmdLine.addArgs(args->value(), Utils::CommandLine::Raw);
|
||||
cmdLine.addArg("--outdir");
|
||||
cmdLine.addArg(directory);
|
||||
return cmdLine;
|
||||
});
|
||||
}
|
||||
|
||||
QString DeployMcuProcessStep::findKitInformation(ProjectExplorer::Kit *kit, const QString &key)
|
||||
{
|
||||
using namespace CMakeProjectManager;
|
||||
const auto config = CMakeConfigurationKitAspect::configuration(kit).toList();
|
||||
const auto keyName = key.toUtf8();
|
||||
for (const CMakeProjectManager::CMakeConfigItem &configItem : config) {
|
||||
if (configItem.key == keyName)
|
||||
return QString::fromUtf8(configItem.value);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
MCUBuildStepFactory::MCUBuildStepFactory()
|
||||
: BuildStepFactory()
|
||||
{
|
||||
setDisplayName(QmlProjectManager::Tr::tr("Qt for MCUs Deploy Step"));
|
||||
registerStep<DeployMcuProcessStep>(DeployMcuProcessStep::id);
|
||||
}
|
||||
|
||||
ProjectExplorer::Kit *MCUBuildStepFactory::findMostRecentQulKit()
|
||||
{
|
||||
ProjectExplorer::Kit *mcuKit = nullptr;
|
||||
for (auto availableKit : ProjectExplorer::KitManager::kits()) {
|
||||
if (!availableKit)
|
||||
continue;
|
||||
|
||||
auto qulVersion = McuKitManager::kitQulVersion(availableKit);
|
||||
if (qulVersion.isNull())
|
||||
continue;
|
||||
|
||||
if (!mcuKit)
|
||||
mcuKit = availableKit;
|
||||
|
||||
if (qulVersion > McuKitManager::kitQulVersion(mcuKit))
|
||||
mcuKit = availableKit;
|
||||
}
|
||||
return mcuKit;
|
||||
}
|
||||
|
||||
void MCUBuildStepFactory::updateDeployStep(ProjectExplorer::Target *target, bool enabled)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
ProjectExplorer::DeployConfiguration *deployConfiguration = target->activeDeployConfiguration();
|
||||
ProjectExplorer::BuildStepList *stepList = deployConfiguration->stepList();
|
||||
ProjectExplorer::BuildStep *step = stepList->firstStepWithId(DeployMcuProcessStep::id);
|
||||
if (!step && enabled) {
|
||||
if (findMostRecentQulKit()) {
|
||||
stepList->appendStep(DeployMcuProcessStep::id);
|
||||
} else {
|
||||
DeployMcuProcessStep::showError(
|
||||
QmlProjectManager::Tr::tr("Failed to find valid Qt for MCUs kit"));
|
||||
}
|
||||
} else {
|
||||
if (!step)
|
||||
return;
|
||||
step->setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace McuSupport::Internal
|
||||
37
src/plugins/mcusupport/mcubuildstep.h
Normal file
37
src/plugins/mcusupport/mcubuildstep.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||
#pragma once
|
||||
|
||||
#include <projectexplorer/abstractprocessstep.h>
|
||||
#include <projectexplorer/buildstep.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
#include <projectexplorer/project.h>
|
||||
|
||||
#include <utils/id.h>
|
||||
|
||||
#include <QTemporaryDir>
|
||||
|
||||
namespace McuSupport::Internal {
|
||||
|
||||
class DeployMcuProcessStep : public ProjectExplorer::AbstractProcessStep
|
||||
{
|
||||
public:
|
||||
static const Utils::Id id;
|
||||
static void showError(const QString &text);
|
||||
|
||||
DeployMcuProcessStep(ProjectExplorer::BuildStepList *bc, Utils::Id id);
|
||||
|
||||
private:
|
||||
QString findKitInformation(ProjectExplorer::Kit *kit, const QString &key);
|
||||
QTemporaryDir m_tmpDir;
|
||||
};
|
||||
|
||||
class MCUBuildStepFactory : public ProjectExplorer::BuildStepFactory
|
||||
{
|
||||
public:
|
||||
MCUBuildStepFactory();
|
||||
static ProjectExplorer::Kit *findMostRecentQulKit();
|
||||
static void updateDeployStep(ProjectExplorer::Target *target, bool enabled);
|
||||
};
|
||||
|
||||
} // namespace McuSupport::Internal
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "mcusupportplugin.h"
|
||||
|
||||
#include "mcubuildstep.h"
|
||||
#include "mcukitinformation.h"
|
||||
#include "mcukitmanager.h"
|
||||
#include "mcuqmlprojectnode.h"
|
||||
@@ -98,6 +99,7 @@ public:
|
||||
McuSupportOptions m_options{m_settingsHandler};
|
||||
McuSupportOptionsPage optionsPage{m_options, m_settingsHandler};
|
||||
McuDependenciesKitAspect environmentPathsKitAspect;
|
||||
MCUBuildStepFactory mcuBuildStepFactory;
|
||||
}; // class McuSupportPluginPrivate
|
||||
|
||||
static McuSupportPluginPrivate *dd{nullptr};
|
||||
@@ -219,4 +221,9 @@ void McuSupportPlugin::askUserAboutRemovingUninstalledTargetsKits()
|
||||
ICore::infoBar()->addInfo(info);
|
||||
}
|
||||
|
||||
void McuSupportPlugin::updateDeployStep(ProjectExplorer::Target *target, bool enabled)
|
||||
{
|
||||
MCUBuildStepFactory::updateDeployStep(target, enabled);
|
||||
}
|
||||
|
||||
} // namespace McuSupport::Internal
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
namespace McuSupport::Internal {
|
||||
|
||||
void printMessage(const QString &message, bool important);
|
||||
@@ -25,6 +27,8 @@ public:
|
||||
void askUserAboutMcuSupportKitsSetup();
|
||||
static void askUserAboutMcuSupportKitsUpgrade(const SettingsHandler::Ptr &settingsHandler);
|
||||
static void askUserAboutRemovingUninstalledTargetsKits();
|
||||
|
||||
Q_INVOKABLE static void updateDeployStep(ProjectExplorer::Target *target, bool enabled);
|
||||
};
|
||||
|
||||
} // McuSupport::Internal
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <coreplugin/modemanager.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QCollator>
|
||||
#include <QGuiApplication>
|
||||
#include <QItemDelegate>
|
||||
#include <QKeyEvent>
|
||||
@@ -141,8 +142,15 @@ private:
|
||||
|
||||
static bool compareItems(const TreeItem *ti1, const TreeItem *ti2)
|
||||
{
|
||||
const int result = caseFriendlyCompare(static_cast<const GenericItem *>(ti1)->rawDisplayName(),
|
||||
static_cast<const GenericItem *>(ti2)->rawDisplayName());
|
||||
static const QCollator collator = [] {
|
||||
QCollator collator;
|
||||
collator.setNumericMode(true);
|
||||
collator.setCaseSensitivity(Qt::CaseInsensitive);
|
||||
return collator;
|
||||
}();
|
||||
|
||||
const int result = collator.compare(static_cast<const GenericItem *>(ti1)->rawDisplayName(),
|
||||
static_cast<const GenericItem *>(ti2)->rawDisplayName());
|
||||
if (result != 0)
|
||||
return result < 0;
|
||||
return ti1 < ti2;
|
||||
@@ -389,6 +397,12 @@ private:
|
||||
TreeView::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void showEvent(QShowEvent* event) override
|
||||
{
|
||||
scrollTo(currentIndex());
|
||||
TreeView::showEvent(event);
|
||||
}
|
||||
|
||||
QObject *objectAt(const QModelIndex &index) const
|
||||
{
|
||||
return theModel()->itemForIndex(index)->object();
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
#only if the plugin is requested by qtc_plugin_enabled continue if not stop as early as possible
|
||||
add_qtc_plugin(QmlDesigner
|
||||
PLUGIN_RECOMMENDS QmlPreview
|
||||
CONDITION Qt6_VERSION VERSION_GREATER_EQUAL 6.2.0 AND TARGET Qt::QuickWidgets AND TARGET Qt::Svg
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
PLUGIN_DEPENDS
|
||||
Core ProjectExplorer QmlDesignerBase QmlJSEditor QmakeProjectManager QmlProjectManager
|
||||
QtSupport
|
||||
)
|
||||
qtc_plugin_enabled(_qmlDesignerEnabled QmlDesigner)
|
||||
if (NOT _qmlDesignerEnabled)
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
find_package(Qt6 COMPONENTS QmlDomPrivate QmlCompilerPrivate)
|
||||
|
||||
@@ -19,13 +8,10 @@ if (APPLE)
|
||||
set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/QmlDesigner")
|
||||
endif()
|
||||
|
||||
|
||||
env_with_default("QDS_USE_PROJECTSTORAGE" ENV_QDS_USE_PROJECTSTORAGE OFF)
|
||||
option(USE_PROJECTSTORAGE "Use ProjectStorage" ${ENV_QDS_USE_PROJECTSTORAGE})
|
||||
add_feature_info("ProjectStorage" ${USE_PROJECTSTORAGE} "")
|
||||
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,Clang>:-Wno-error=maybe-uninitialized>")
|
||||
add_compile_options("$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-error=maybe-uninitialized>")
|
||||
|
||||
add_qtc_library(QmlDesignerUtils STATIC
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
DEPENDS
|
||||
Qt::Gui Utils Qt::QmlPrivate
|
||||
DEFINES QMLDESIGNERUTILS_LIBRARY
|
||||
@@ -44,8 +30,15 @@ add_qtc_library(QmlDesignerUtils STATIC
|
||||
qmldesignerutils_global.h
|
||||
)
|
||||
|
||||
extend_qtc_library(QmlDesignerUtils
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
add_qtc_library(QmlDesignerCore STATIC
|
||||
CONDITION Qt6_VERSION VERSION_GREATER_EQUAL 6.4.3 AND TARGET Qt6::QmlPrivate AND TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate
|
||||
EXCLUDE_FROM_INSTALL
|
||||
PROPERTIES SKIP_AUTOUIC ON
|
||||
DEPENDS
|
||||
Threads::Threads
|
||||
Qt::CorePrivate
|
||||
@@ -53,6 +46,9 @@ add_qtc_library(QmlDesignerCore STATIC
|
||||
Utils
|
||||
Qt::Widgets
|
||||
Qt::Qml
|
||||
Qt::QmlPrivate
|
||||
Qt6::QmlDomPrivate
|
||||
Qt6::QmlCompilerPrivate
|
||||
Core
|
||||
ProjectExplorer
|
||||
QmakeProjectManager
|
||||
@@ -79,26 +75,28 @@ add_qtc_library(QmlDesignerCore STATIC
|
||||
rewritertransaction.h
|
||||
)
|
||||
|
||||
extend_qtc_library(QmlDesignerCore
|
||||
CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0
|
||||
|
||||
DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate
|
||||
DEFINES QDS_HAS_QMLDOM
|
||||
if(TARGET QmlDesignerCore)
|
||||
env_with_default("QDS_USE_PROJECTSTORAGE" ENV_QDS_USE_PROJECTSTORAGE OFF)
|
||||
option(USE_PROJECTSTORAGE "Use ProjectStorage" ${ENV_QDS_USE_PROJECTSTORAGE})
|
||||
add_feature_info("ProjectStorage" ${USE_PROJECTSTORAGE} "")
|
||||
endif()
|
||||
|
||||
|
||||
extend_qtc_library(QmlDesignerCore
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
extend_qtc_library(QmlDesignerCore
|
||||
CONDITION Qt6_VERSION VERSION_GREATER_EQUAL 6.5.0 AND Qt6_VERSION VERSION_LESS 6.6.0
|
||||
PUBLIC_DEFINES QDS_BUILD_QMLPARSER
|
||||
)
|
||||
extend_qtc_library(QmlDesignerCore
|
||||
CONDITION UNIX AND NOT APPLE
|
||||
PUBLIC_DEPENDS rt
|
||||
)
|
||||
|
||||
extend_qtc_library(QmlDesignerCore
|
||||
INCLUDES ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES
|
||||
${UI_SOURCES}
|
||||
${UI_FILES}
|
||||
)
|
||||
set_source_files_properties(${UI_FILES} PROPERTIES SKIP_AUTOUIC ON)
|
||||
|
||||
extend_qtc_library(QmlDesignerCore
|
||||
INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/exceptions
|
||||
SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/exceptions
|
||||
@@ -221,6 +219,7 @@ extend_qtc_library(QmlDesignerCore
|
||||
metainfo.h
|
||||
metainforeader.h
|
||||
model.h
|
||||
modelfwd.h
|
||||
modelmerger.h
|
||||
modelnode.h
|
||||
modelnodepositionstorage.h
|
||||
@@ -241,6 +240,7 @@ extend_qtc_library(QmlDesignerCore
|
||||
qmlchangeset.h
|
||||
qmlconnections.h
|
||||
qmldesignercorelib_global.h
|
||||
qmldesignercorelib_exports.h
|
||||
qmlitemnode.h
|
||||
qmlmodelnodefacade.h
|
||||
qmlobjectnode.h
|
||||
@@ -262,6 +262,7 @@ extend_qtc_library(QmlDesignerCore
|
||||
INCLUDES
|
||||
${CMAKE_CURRENT_LIST_DIR}/designercore/metainfo
|
||||
SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/metainfo
|
||||
DEFINES SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner"
|
||||
SOURCES
|
||||
itemlibraryinfo.cpp
|
||||
metainfo.cpp
|
||||
@@ -326,8 +327,11 @@ extend_qtc_library(QmlDesignerCore
|
||||
modelnodepositionrecalculator.cpp
|
||||
modelnodepositionrecalculator.h
|
||||
modelnodepositionstorage.cpp
|
||||
modelresourcemanagementinterface.h
|
||||
modeltotextmerger.cpp
|
||||
modeltotextmerger.h
|
||||
modelutils.cpp
|
||||
modelutils.h
|
||||
nodeabstractproperty.cpp
|
||||
nodelistproperty.cpp
|
||||
nodeproperty.cpp
|
||||
@@ -354,6 +358,7 @@ extend_qtc_library(QmlDesignerCore
|
||||
rewriteactioncompressor.h
|
||||
rewriterview.cpp
|
||||
signalhandlerproperty.cpp
|
||||
skipiterator.h
|
||||
stylesheetmerger.cpp
|
||||
textmodifier.cpp
|
||||
texttomodelmerger.cpp
|
||||
@@ -374,6 +379,7 @@ extend_qtc_library(QmlDesignerCore
|
||||
extend_qtc_library(QmlDesignerCore
|
||||
SOURCES_PREFIX designercore/projectstorage
|
||||
PUBLIC_INCLUDES designercore/projectstorage
|
||||
SOURCES_PROPERTIES SKIP_AUTOMOC ON
|
||||
SOURCES
|
||||
commontypecache.h
|
||||
directorypathcompressor.h
|
||||
@@ -381,6 +387,7 @@ extend_qtc_library(QmlDesignerCore
|
||||
filesystem.cpp filesystem.h
|
||||
filestatus.h
|
||||
filestatuscache.cpp filestatuscache.h
|
||||
modulescanner.cpp modulescanner.h
|
||||
nonlockingmutex.h
|
||||
projectstorageexceptions.cpp projectstorageexceptions.h
|
||||
projectstorageinterface.h
|
||||
@@ -409,18 +416,17 @@ extend_qtc_library(QmlDesignerCore
|
||||
qmldocumentparser.cpp qmldocumentparser.h
|
||||
)
|
||||
|
||||
file(GLOB PROJECTSTORAGE_EXCLUDED_SOURCES designercore/projectstorage/*.cpp)
|
||||
set_property(SOURCE ${PROJECTSTORAGE_EXCLUDED_SOURCES} PROPERTY SKIP_AUTOMOC ON)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
PUBLIC_DEPENDS
|
||||
QmlDesignerUtils
|
||||
QmlDesignerBase
|
||||
QmlPuppetCommunication
|
||||
add_qtc_plugin(QmlDesigner
|
||||
PLUGIN_RECOMMENDS QmlPreview
|
||||
CONDITION Qt6_VERSION VERSION_GREATER_EQUAL 6.4.3 AND TARGET QmlDesignerCore AND TARGET Qt::QuickWidgets AND TARGET Qt::Svg
|
||||
PLUGIN_DEPENDS
|
||||
Core ProjectExplorer QmlDesignerBase QmlJSEditor QmakeProjectManager QmlProjectManager
|
||||
QtSupport
|
||||
DEPENDS
|
||||
QmlDesignerCore
|
||||
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem Sqlite
|
||||
Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg
|
||||
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
|
||||
Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg QmlDesignerCore Sqlite
|
||||
PUBLIC_DEPENDS
|
||||
QmlDesignerUtils QmlPuppetCommunication QmlDesignerBase
|
||||
DEFINES
|
||||
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
|
||||
SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner"
|
||||
@@ -474,6 +480,11 @@ extend_qtc_plugin(QmlDesigner
|
||||
QMLDESIGNER_PLUGIN_PATH "${QmlDesignerPluginInstallPrefix}"
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
function(get_and_add_as_subdirectory name repository git_tag build_dir source_dir source_subdir)
|
||||
# make the configuration in the build dir
|
||||
file(MAKE_DIRECTORY ${build_dir}/${name})
|
||||
@@ -521,67 +532,6 @@ if (QTC_STATIC_BUILD AND TARGET QmlDesigner)
|
||||
extend_qtc_target(QmlDesigner PUBLIC_DEPENDS TextEditor)
|
||||
endif()
|
||||
|
||||
add_qtc_plugin(assetexporterplugin
|
||||
PLUGIN_CLASS AssetExporterPlugin
|
||||
CONDITION TARGET QmlDesigner
|
||||
DEPENDS Core ProjectExplorer QmlDesigner Utils Qt::Qml Qt::QuickPrivate
|
||||
PUBLIC_INCLUDES assetexporterplugin
|
||||
SOURCES
|
||||
assetexporterplugin/assetexportdialog.h assetexporterplugin/assetexportdialog.cpp assetexporterplugin/assetexportdialog.ui
|
||||
assetexporterplugin/assetexporter.h assetexporterplugin/assetexporter.cpp
|
||||
assetexporterplugin/assetexporterplugin.h assetexporterplugin/assetexporterplugin.cpp
|
||||
assetexporterplugin/assetexporterview.h assetexporterplugin/assetexporterview.cpp
|
||||
assetexporterplugin/assetexportpluginconstants.h
|
||||
assetexporterplugin/componentexporter.h assetexporterplugin/componentexporter.cpp
|
||||
assetexporterplugin/exportnotification.h assetexporterplugin/exportnotification.cpp
|
||||
assetexporterplugin/filepathmodel.h assetexporterplugin/filepathmodel.cpp
|
||||
assetexporterplugin/dumpers/assetnodedumper.h assetexporterplugin/dumpers/assetnodedumper.cpp
|
||||
assetexporterplugin/dumpers/itemnodedumper.h assetexporterplugin/dumpers/itemnodedumper.cpp
|
||||
assetexporterplugin/dumpers/nodedumper.h assetexporterplugin/dumpers/nodedumper.cpp
|
||||
assetexporterplugin/dumpers/textnodedumper.h assetexporterplugin/dumpers/textnodedumper.cpp
|
||||
assetexporterplugin/assetexporterplugin.qrc
|
||||
PLUGIN_PATH ${QmlDesignerPluginInstallPrefix}
|
||||
)
|
||||
|
||||
add_qtc_plugin(componentsplugin
|
||||
PLUGIN_CLASS ComponentsPlugin
|
||||
CONDITION TARGET QmlDesigner
|
||||
DEPENDS Core QmlDesigner Utils Qt::Qml
|
||||
DEFINES COMPONENTS_LIBRARY
|
||||
SOURCES
|
||||
componentsplugin/addtabdesigneraction.cpp componentsplugin/addtabdesigneraction.h
|
||||
componentsplugin/addtabtotabviewdialog.cpp componentsplugin/addtabtotabviewdialog.h
|
||||
componentsplugin/addtabtotabviewdialog.ui
|
||||
componentsplugin/componentsplugin.cpp componentsplugin/componentsplugin.h
|
||||
componentsplugin/componentsplugin.qrc
|
||||
componentsplugin/entertabdesigneraction.cpp componentsplugin/entertabdesigneraction.h
|
||||
componentsplugin/tabviewindexmodel.cpp componentsplugin/tabviewindexmodel.h
|
||||
PLUGIN_PATH ${QmlDesignerPluginInstallPrefix}
|
||||
)
|
||||
|
||||
add_qtc_plugin(qmlpreviewplugin
|
||||
PLUGIN_CLASS QmlPreviewWidgetPlugin
|
||||
CONDITION TARGET QmlDesigner
|
||||
DEPENDS Core ProjectExplorer QmlDesigner Utils Qt::Qml
|
||||
SOURCES
|
||||
qmlpreviewplugin/qmlpreviewactions.cpp qmlpreviewplugin/qmlpreviewactions.h
|
||||
qmlpreviewplugin/qmlpreviewplugin.cpp qmlpreviewplugin/qmlpreviewplugin.h
|
||||
qmlpreviewplugin/qmlpreviewplugin.qrc
|
||||
PLUGIN_PATH ${QmlDesignerPluginInstallPrefix}
|
||||
)
|
||||
|
||||
add_qtc_plugin(qtquickplugin
|
||||
PLUGIN_CLASS QtQuickPlugin
|
||||
CONDITION TARGET QmlDesigner
|
||||
DEPENDS Core QmlDesigner Utils Qt::Qml
|
||||
DEFINES QTQUICK_LIBRARY
|
||||
SOURCES
|
||||
qtquickplugin/qtquickplugin.cpp qtquickplugin/qtquickplugin.h
|
||||
qtquickplugin/qtquickplugin.qrc
|
||||
PLUGIN_PATH ${QmlDesignerPluginInstallPrefix}
|
||||
)
|
||||
|
||||
add_subdirectory(studioplugin)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components
|
||||
@@ -643,6 +593,9 @@ extend_qtc_plugin(QmlDesigner
|
||||
edit3dactions.cpp edit3dactions.h
|
||||
edit3dvisibilitytogglesmenu.cpp edit3dvisibilitytogglesmenu.h
|
||||
backgroundcolorselection.cpp backgroundcolorselection.h
|
||||
bakelights.cpp bakelights.h
|
||||
bakelightsdatamodel.cpp bakelightsdatamodel.h
|
||||
bakelightsconnectionmanager.cpp bakelightsconnectionmanager.h
|
||||
edit3d.qrc
|
||||
)
|
||||
|
||||
@@ -1129,3 +1082,106 @@ extend_qtc_plugin(QmlDesigner
|
||||
CONDITION TARGET Nanotrace
|
||||
DEPENDS Nanotrace
|
||||
)
|
||||
|
||||
add_qtc_plugin(assetexporterplugin
|
||||
PLUGIN_CLASS AssetExporterPlugin
|
||||
CONDITION TARGET QmlDesigner
|
||||
PLUGIN_DEPENDS
|
||||
Core ProjectExplorer QmlDesigner
|
||||
DEPENDS Utils Qt::Qml Qt::QuickPrivate
|
||||
PUBLIC_INCLUDES assetexporterplugin
|
||||
PLUGIN_PATH ${QmlDesignerPluginInstallPrefix}
|
||||
)
|
||||
|
||||
extend_qtc_plugin(assetexporterplugin
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
extend_qtc_plugin(assetexporterplugin
|
||||
SOURCES_PREFIX assetexporterplugin
|
||||
SOURCES
|
||||
assetexportdialog.h assetexportdialog.cpp assetexportdialog.ui
|
||||
assetexporter.h assetexporter.cpp
|
||||
assetexporterplugin.h assetexporterplugin.cpp
|
||||
assetexporterview.h assetexporterview.cpp
|
||||
assetexportpluginconstants.h
|
||||
componentexporter.h componentexporter.cpp
|
||||
exportnotification.h exportnotification.cpp
|
||||
filepathmodel.h filepathmodel.cpp
|
||||
dumpers/assetnodedumper.h dumpers/assetnodedumper.cpp
|
||||
dumpers/itemnodedumper.h dumpers/itemnodedumper.cpp
|
||||
dumpers/nodedumper.h dumpers/nodedumper.cpp
|
||||
dumpers/textnodedumper.h dumpers/textnodedumper.cpp
|
||||
assetexporterplugin.qrc
|
||||
)
|
||||
|
||||
add_qtc_plugin(componentsplugin
|
||||
PLUGIN_CLASS ComponentsPlugin
|
||||
CONDITION TARGET QmlDesigner
|
||||
PLUGIN_DEPENDS Core QmlDesigner
|
||||
DEPENDS Utils Qt::Qml
|
||||
DEFINES COMPONENTS_LIBRARY
|
||||
|
||||
PLUGIN_PATH ${QmlDesignerPluginInstallPrefix}
|
||||
)
|
||||
|
||||
extend_qtc_plugin(componentsplugin
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
extend_qtc_plugin(componentsplugin
|
||||
SOURCES_PREFIX componentsplugin
|
||||
SOURCES
|
||||
addtabdesigneraction.cpp addtabdesigneraction.h
|
||||
addtabtotabviewdialog.cpp addtabtotabviewdialog.h
|
||||
addtabtotabviewdialog.ui
|
||||
componentsplugin.cpp componentsplugin.h
|
||||
componentsplugin.qrc
|
||||
entertabdesigneraction.cpp entertabdesigneraction.h
|
||||
tabviewindexmodel.cpp tabviewindexmodel.h
|
||||
)
|
||||
|
||||
add_qtc_plugin(qmlpreviewplugin
|
||||
PLUGIN_CLASS QmlPreviewWidgetPlugin
|
||||
CONDITION TARGET QmlDesigner
|
||||
PLUGIN_DEPENDS Core ProjectExplorer QmlDesigner
|
||||
DEPENDS Utils Qt::Qml
|
||||
PLUGIN_PATH ${QmlDesignerPluginInstallPrefix}
|
||||
)
|
||||
|
||||
extend_qtc_plugin(qmlpreviewplugin
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
extend_qtc_plugin(qmlpreviewplugin
|
||||
SOURCES_PREFIX qmlpreviewplugin
|
||||
SOURCES
|
||||
qmlpreviewactions.cpp qmlpreviewactions.h
|
||||
qmlpreviewplugin.cpp qmlpreviewplugin.h
|
||||
qmlpreviewplugin.qrc
|
||||
)
|
||||
|
||||
add_qtc_plugin(qtquickplugin
|
||||
PLUGIN_CLASS QtQuickPlugin
|
||||
CONDITION TARGET QmlDesigner
|
||||
PLUGIN_DEPENDS Core QmlDesigner
|
||||
DEPENDS Utils Qt::Qml
|
||||
DEFINES QTQUICK_LIBRARY
|
||||
PLUGIN_PATH ${QmlDesignerPluginInstallPrefix}
|
||||
)
|
||||
|
||||
extend_qtc_plugin(qtquickplugin
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
extend_qtc_plugin(qtquickplugin
|
||||
SOURCES_PREFIX qtquickplugin
|
||||
SOURCES
|
||||
qtquickplugin.cpp qtquickplugin.h
|
||||
qtquickplugin.qrc
|
||||
)
|
||||
add_subdirectory(studioplugin)
|
||||
|
||||
@@ -136,7 +136,7 @@ bool AssetsLibraryModel::renameFolder(const QString &folderPath, const QString &
|
||||
return dir.rename(oldName, newName);
|
||||
}
|
||||
|
||||
bool AssetsLibraryModel::addNewFolder(const QString &folderPath)
|
||||
QString AssetsLibraryModel::addNewFolder(const QString &folderPath)
|
||||
{
|
||||
QString iterPath = folderPath;
|
||||
QDir dir{folderPath};
|
||||
@@ -147,7 +147,7 @@ bool AssetsLibraryModel::addNewFolder(const QString &folderPath)
|
||||
dir.setPath(iterPath);
|
||||
}
|
||||
|
||||
return dir.mkpath(iterPath);
|
||||
return dir.mkpath(iterPath) ? iterPath : "";
|
||||
}
|
||||
|
||||
bool AssetsLibraryModel::urlPathExistsInModel(const QUrl &url) const
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
Q_INVOKABLE bool requestDeleteFiles(const QStringList &filePaths);
|
||||
Q_INVOKABLE void deleteFiles(const QStringList &filePaths, bool dontAskAgain);
|
||||
Q_INVOKABLE bool renameFolder(const QString &folderPath, const QString &newName);
|
||||
Q_INVOKABLE bool addNewFolder(const QString &folderPath);
|
||||
Q_INVOKABLE QString addNewFolder(const QString &folderPath);
|
||||
Q_INVOKABLE bool deleteFolderRecursively(const QModelIndex &folderIndex);
|
||||
Q_INVOKABLE bool allFilePathsAreTextures(const QStringList &filePaths) const;
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ void BindingEditor::setBackendValue(const QVariant &backendValue)
|
||||
m_backendValueTypeName = node.metaInfo()
|
||||
.property(propertyEditorValue->name())
|
||||
.propertyType()
|
||||
.typeName();
|
||||
.simplifiedTypeName();
|
||||
|
||||
QString nodeId = node.id();
|
||||
if (nodeId.isEmpty())
|
||||
@@ -187,7 +187,7 @@ void BindingEditor::prepareBindings()
|
||||
for (const auto &objnode : allNodes) {
|
||||
BindingEditorDialog::BindingOption binding;
|
||||
for (const auto &property : objnode.metaInfo().properties()) {
|
||||
const TypeName &propertyTypeName = property.propertyType().typeName();
|
||||
const TypeName &propertyTypeName = property.propertyType().simplifiedTypeName();
|
||||
|
||||
if (skipTypeFiltering
|
||||
|| (m_backendValueTypeName == propertyTypeName)
|
||||
|
||||
@@ -95,7 +95,7 @@ void DesignerActionManagerView::nodeOrderChanged(const NodeListProperty &)
|
||||
setupContext(SelectionContext::UpdateMode::NodeHierachy);
|
||||
}
|
||||
|
||||
void DesignerActionManagerView::importsChanged(const QList<Import> &, const QList<Import> &)
|
||||
void DesignerActionManagerView::importsChanged(const Imports &, const Imports &)
|
||||
{
|
||||
setupContext();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
void selectedNodesChanged(const QList<ModelNode> &,
|
||||
const QList<ModelNode> &) override;
|
||||
void nodeOrderChanged(const NodeListProperty &) override;
|
||||
void importsChanged(const QList<Import> &, const QList<Import> &) override;
|
||||
void importsChanged(const Imports &, const Imports &) override;
|
||||
void signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &/*propertyList*/, PropertyChangeFlags /*propertyChange*/) override;
|
||||
void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override;
|
||||
void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChangeFlag) override;
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
AnchorsIcon,
|
||||
AnnotationIcon,
|
||||
ArrangeIcon,
|
||||
BackspaceIcon,
|
||||
CameraIcon,
|
||||
CameraOrthographicIcon,
|
||||
CameraPerspectiveIcon,
|
||||
|
||||
@@ -1650,7 +1650,11 @@ void openEffectMaker(const QString &filePath)
|
||||
|
||||
const QtSupport::QtVersion *baseQtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
|
||||
if (baseQtVersion) {
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
|
||||
auto effectMakerPath = baseQtVersion->binPath().pathAppended("qqem").withExecutableSuffix();
|
||||
if (!effectMakerPath.exists() && env.osType() == Utils::OsTypeMac)
|
||||
effectMakerPath = baseQtVersion->binPath().pathAppended("qqem.app/Contents/MacOS/qqem");
|
||||
if (!effectMakerPath.exists()) {
|
||||
qWarning() << __FUNCTION__ << "Cannot find EffectMaker app";
|
||||
return;
|
||||
@@ -1663,7 +1667,6 @@ void openEffectMaker(const QString &filePath)
|
||||
arguments << "--create";
|
||||
arguments << "--exportpath" << effectResPath.toString();
|
||||
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
if (env.osType() == Utils::OsTypeMac)
|
||||
env.appendOrSet("QSG_RHI_BACKEND", "metal");
|
||||
|
||||
|
||||
@@ -149,4 +149,6 @@ QmlEditorStyleObject::QmlEditorStyleObject()
|
||||
QmlEditorMenuPrivate::cascadeRight = DesignerIcons::rotateIcon(downIcon, -90);
|
||||
QmlEditorMenuPrivate::tick = DesignerActionManager::instance()
|
||||
.contextIcon(DesignerIcons::SimpleCheckIcon);
|
||||
QmlEditorMenuPrivate::backspaceIcon = DesignerActionManager::instance()
|
||||
.contextIcon(DesignerIcons::BackspaceIcon);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
void disableWidgets();
|
||||
void enableWidgets();
|
||||
|
||||
void pushFileOnCrumbleBar(const Utils::FilePath &fileName);
|
||||
void pushFileOnCrumbleBar(const ::Utils::FilePath &fileName);
|
||||
void pushInFileComponentOnCrumbleBar(const ModelNode &modelNode);
|
||||
void nextFileIsCalledInternally();
|
||||
|
||||
|
||||
@@ -38,10 +38,7 @@ QStringList propertyNameListToStringList(const QmlDesigner::PropertyNameList &pr
|
||||
|
||||
bool isConnection(const QmlDesigner::ModelNode &modelNode)
|
||||
{
|
||||
return (modelNode.type() == "Connections"
|
||||
|| modelNode.type() == "QtQuick.Connections"
|
||||
|| modelNode.type() == "Qt.Connections"
|
||||
|| modelNode.type() == "QtQml.Connections");
|
||||
return (modelNode.metaInfo().simplifiedTypeName() == "Connections");
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
@@ -183,7 +183,7 @@ void ConnectionView::auxiliaryDataChanged([[maybe_unused]] const ModelNode &node
|
||||
selectionModel->clearSelection();
|
||||
}
|
||||
|
||||
void ConnectionView::importsChanged(const QList<Import> & /*addedImports*/, const QList<Import> & /*removedImports*/)
|
||||
void ConnectionView::importsChanged(const Imports & /*addedImports*/, const Imports & /*removedImports*/)
|
||||
{
|
||||
backendModel()->resetModel();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user