diff options
Diffstat (limited to 'src/corelib')
20 files changed, 1605 insertions, 14 deletions
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index 539ad753ca6..e50838730cb 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -1533,6 +1533,7 @@ qt_internal_extend_target(Core CONDITION WASM platform/wasm/qstdweb.cpp platform/wasm/qstdweb_p.h platform/wasm/qwasmsocket.cpp platform/wasm/qwasmsocket_p.h platform/wasm/qwasmsuspendresumecontrol.cpp platform/wasm/qwasmsuspendresumecontrol_p.h + platform/wasm/qwasmlocalfileengine.cpp platform/wasm/qwasmlocalfileengine_p.h kernel/qeventdispatcher_wasm.cpp kernel/qeventdispatcher_wasm_p.h ) diff --git a/src/corelib/configure.cmake b/src/corelib/configure.cmake index 7274b51cc0a..0f717ff2ae0 100644 --- a/src/corelib/configure.cmake +++ b/src/corelib/configure.cmake @@ -812,7 +812,7 @@ qt_feature("winsdkicu" PRIVATE ) qt_feature("windows-ioring" PRIVATE LABEL "Windows I/O Ring" - AUTODETECT WIN32 AND CMAKE_HOST_SYSTEM_VERSION VERSION_GREATER_EQUAL 10.0.22000 + AUTODETECT WIN32 CONDITION TEST_windows_ioring ) qt_feature("inotify" PUBLIC PRIVATE diff --git a/src/corelib/doc/images/modelview-begin-append-columns.svg b/src/corelib/doc/images/modelview-begin-append-columns.svg new file mode 100644 index 00000000000..937a2c03206 --- /dev/null +++ b/src/corelib/doc/images/modelview-begin-append-columns.svg @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="291" + height="166" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } +</style> + +<path d="m 10.5,10.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="20" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 40.5,10.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="50" y="32" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 70.5,10.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="80" y="32" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 100.5,10.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="110" y="32" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 130.5,10.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="140" y="32" font-family="arial" font-size="20px" class="text-style">4</text> +<path d="m 160.5,10.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="170" y="32" font-family="arial" font-size="20px" class="text-style">5</text> + +<path d="m 190.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="200" y="90" font-family="arial" font-size="20px" class="high-text-style">6</text> +<path d="m 220.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="230" y="90" font-family="arial" font-size="20px" class="high-text-style">7</text> +<path d="m 250.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="260" y="90" font-family="arial" font-size="20px" class="high-text-style">8</text> + +<path d="m 10.5,125.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="20" y="147" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 40.5,125.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="50" y="147" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 70.5,125.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="80" y="147" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 100.5,125.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="110" y="147" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 130.5,125.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="140" y="147" font-family="arial" font-size="20px" class="text-style">4</text> +<path d="m 160.5,125.5 h 30 v 30 h -30 v -30" class="box-style" /> +<text x="170" y="147" font-family="arial" font-size="20px" class="text-style">5</text> +<path d="m 190.5,125.5 h 30 v 30 h -30 v -30" class="highlighted-style" /> +<text x="200" y="147" font-family="arial" font-size="20px" class="high-text-style">6</text> +<path d="m 220.5,125.5 h 30 v 30 h -30 v -30" class="highlighted-style" /> +<text x="230" y="147" font-family="arial" font-size="20px" class="high-text-style">7</text> +<path d="m 250.5,125.5 h 30 v 30 h -30 v -30" class="highlighted-style" /> +<text x="260" y="147" font-family="arial" font-size="20px" class="high-text-style">8</text> + +<path d="m 190.5,65.5 v -20" class="line-style" /> +<path d="M 190.5 42.5 l 5,10 l -10,0 z" class="fill-style" /> +</svg> diff --git a/src/corelib/doc/images/modelview-begin-append-rows.svg b/src/corelib/doc/images/modelview-begin-append-rows.svg new file mode 100644 index 00000000000..7e66d0d8756 --- /dev/null +++ b/src/corelib/doc/images/modelview-begin-append-rows.svg @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="165" + height="200" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } +</style> + +<path d="m 10.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 10.5,40.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="62" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 10.5,70.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="92" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 10.5,100.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="122" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 68.5,130.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="77" y="152" font-family="arial" font-size="20px" class="high-text-style">4</text> +<path d="m 68.5,160.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="77" y="182" font-family="arial" font-size="20px" class="high-text-style">5</text> + +<path d="m 125.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 125.5,40.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="62" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 125.5,70.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="92" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 125.5,100.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="122" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 125.5,130.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="135" y="152" font-family="arial" font-size="20px" class="high-text-style">4</text> +<path d="m 125.5,160.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="135" y="182" font-family="arial" font-size="20px" class="high-text-style">5</text> + +<path d="m 65.5,130.5 h -20" class="line-style" /> +<path d="M 42.5,130.5 l 10,-5 l 0,10 z" class="fill-style" /> +</svg> diff --git a/src/corelib/doc/images/modelview-begin-insert-columns.svg b/src/corelib/doc/images/modelview-begin-insert-columns.svg new file mode 100644 index 00000000000..51664b80568 --- /dev/null +++ b/src/corelib/doc/images/modelview-begin-insert-columns.svg @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="290" + height="165" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + svg .faded-text-style { font: 20px arial; fill: #808080 } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + svg.dark .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="dark"] svg .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .faded-text-style { font: 20px arial; fill: #808080 } +</style> + +<path d="m 10.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 40.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="50" y="32" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 70.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="80" y="32" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 100.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="110" y="32" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 130.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="140" y="32" font-family="arial" font-size="20px" class="text-style">4</text> +<path d="m 160.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="170" y="32" font-family="arial" font-size="20px" class="text-style">5</text> +<path d="m 190.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="200" y="32" font-family="arial" font-size="20px" class="text-style">6</text> +<path d="m 220.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="230" y="32" font-family="arial" font-size="20px" class="text-style">7</text> +<path d="m 250.5,10.5 h 30 v 30 h -30 z" class="line-style" + stroke-dasharray="5, 5" /> + +<path d="m 130.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="140" y="90" font-family="arial" font-size="20px" class="high-text-style">4</text> +<path d="m 160.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="170" y="90" font-family="arial" font-size="20px" class="high-text-style">5</text> +<path d="m 190.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="200" y="90" font-family="arial" font-size="20px" class="high-text-style">6</text> + +<path d="m 10.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="147" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 40.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="50" y="147" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 70.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="80" y="147" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 100.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="110" y="147" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 130.5,125.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="140" y="147" font-family="arial" font-size="20px" class="high-text-style">4</text> +<path d="m 160.5,125.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="170" y="147" font-family="arial" font-size="20px" class="high-text-style">5</text> +<path d="m 190.5,125.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="200" y="147" font-family="arial" font-size="20px" class="high-text-style">6</text> +<path d="m 220.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="230" y="147" font-family="arial" font-size="20px" fill="#808080" class="faded-text-style">4</text> +<path d="m 250.5,125.5 h 30 v 30 h -30 z" class="line-style" + stroke-dasharray="5, 5" /> + + +<path d="m 130.5,65.5 v -20" class="line-style" /> +<path d="M 130.5,42.5 l 5,10 l -10,0 z" class="fill-style" /> +</svg> diff --git a/src/corelib/doc/images/modelview-begin-insert-rows.svg b/src/corelib/doc/images/modelview-begin-insert-rows.svg new file mode 100644 index 00000000000..fd6641218ed --- /dev/null +++ b/src/corelib/doc/images/modelview-begin-insert-rows.svg @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="165" + height="230" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + svg .faded-text-style { font: 20px arial; fill: #808080 } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + svg.dark .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="dark"] svg .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .faded-text-style { font: 20px arial; fill: #808080 } +</style> + +<path d="m 10.5,190.5 h 30 v 30 h -30 z" class="box-style" + stroke-dasharray="5, 5" /> +<path d="m 125.5,190.5 h 30 v 30 h -30 z" class="box-style" + stroke-dasharray="5, 5" /> +<path d="m 10.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 10.5,40.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="62" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 10.5,70.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="92" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 10.5,100.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="122" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 10.5,130.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="152" font-family="arial" font-size="20px" class="text-style">4</text> +<path d="m 10.5,160.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="182" font-family="arial" font-size="20px" class="text-style">5</text> + +<path d="m 68.5,70.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="77" y="92" font-family="arial" font-size="20px" class="high-text-style">2</text> +<path d="m 68.5,100.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="77" y="122" font-family="arial" font-size="20px" class="high-text-style">3</text> +<path d="m 68.5,130.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="77" y="152" font-family="arial" font-size="20px" class="high-text-style">4</text> + +<path d="m 125.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 125.5,40.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="62" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 125.5,70.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="135" y="92" font-family="arial" font-size="20px" class="high-text-style">2</text> +<path d="m 125.5,100.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="135" y="122" font-family="arial" font-size="20px" class="high-text-style">3</text> +<path d="m 125.5,130.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="135" y="152" font-family="arial" font-size="20px" class="high-text-style">4</text> +<path d="m 125.5,160.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="182" font-family="arial" font-size="20px" fill="#808080" class="faded-text-style">2</text> + +<path d="m 65.5,70.5 h -20" class="line-style" /> +<path d="M 42.5,70.5 l 10,-5 l 0,10 z" class="fill-style" /> +</svg> diff --git a/src/corelib/doc/images/modelview-begin-remove-columns.svg b/src/corelib/doc/images/modelview-begin-remove-columns.svg new file mode 100644 index 00000000000..a221bfda9fc --- /dev/null +++ b/src/corelib/doc/images/modelview-begin-remove-columns.svg @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="290" + height="165" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + svg .faded-text-style { font: 20px arial; fill: #808080 } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + svg.dark .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="dark"] svg .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .faded-text-style { font: 20px arial; fill: #808080 } +</style> + +<path d="m 10.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 40.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="50" y="32" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 70.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="80" y="32" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 100.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="110" y="32" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 130.5,10.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="140" y="32" font-family="arial" font-size="20px" class="high-text-style">4</text> +<path d="m 160.5,10.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="170" y="32" font-family="arial" font-size="20px" class="high-text-style">5</text> +<path d="m 190.5,10.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="200" y="32" font-family="arial" font-size="20px" class="high-text-style">6</text> +<path d="m 220.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="230" y="32" font-family="arial" font-size="20px" class="text-style">7</text> +<path d="m 250.5,10.5 h 30 v 30 h -30 z" class="box-style" + stroke-dasharray="5, 5" /> + +<path d="m 130.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="140" y="89" font-family="arial" font-size="20px" class="high-text-style">4</text> +<path d="m 160.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="170" y="89" font-family="arial" font-size="20px" class="high-text-style">5</text> +<path d="m 190.5,68.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="200" y="89" font-family="arial" font-size="20px" class="high-text-style">6</text> + +<path d="m 10.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="147" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 40.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="50" y="147" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 70.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="80" y="147" font-family="arial" font-size="20px" class="text-style">2</text> +<path d="m 100.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="110" y="147" font-family="arial" font-size="20px" class="text-style">3</text> +<path d="m 130.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="140" y="147" font-family="arial" font-size="20px" fill="#808080" class="faded-text-style">7</text> +<path d="m 160.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="170" y="147" font-family="arial" font-size="20px" fill="#808080" class="faded-text-style">8</text> +<path d="m 190.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="200" y="147" font-family="arial" font-size="20px" fill="#808080" class="faded-text-style">9</text> +<path d="m 220.5,125.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="224" y="147" font-family="arial" font-size="20px" fill="#808080" class="faded-text-style">10</text> +<path d="m 250.5,125.5 h 30 v 30 h -30 z" class="box-style" + stroke-dasharray="5, 5" /> + +<path d="M 130.5,63 V 43" class="line-style" /> +<path d="M 130.5,66 l -5,-10 l 10,0 z" class="fill-style" /> + +</svg> diff --git a/src/corelib/doc/images/modelview-begin-remove-rows.svg b/src/corelib/doc/images/modelview-begin-remove-rows.svg new file mode 100644 index 00000000000..0c67b1b6404 --- /dev/null +++ b/src/corelib/doc/images/modelview-begin-remove-rows.svg @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="165" + height="230" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + svg .faded-text-style { font: 20px arial; fill: #808080 } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + svg.dark .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="dark"] svg .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .faded-text-style { font: 20px arial; fill: #808080 } +</style> + +<path d="m 10.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 10.5,40.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="62" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 10.5,70.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="20" y="92" font-family="arial" font-size="20px" class="high-text-style">2</text> +<path d="m 10.5,100.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="20" y="122" font-family="arial" font-size="20px" class="high-text-style">3</text> +<path d="m 10.5,130.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="152" font-family="arial" font-size="20px" class="text-style">4</text> +<path d="m 10.5,160.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="20" y="182" font-family="arial" font-size="20px" class="text-style">5</text> +<path d="m 10.5,190.5 h 30 v 30 h -30 z" class="box-style" + stroke-dasharray="5, 5" /> + +<path d="m 125.5,10.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="32" font-family="arial" font-size="20px" class="text-style">0</text> +<path d="m 125.5,40.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="62" font-family="arial" font-size="20px" class="text-style">1</text> +<path d="m 125.5,70.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="92" font-family="arial" font-size="20px" fill="#808080" class="faded-text-style">4</text> +<path d="m 125.5,100.5 h 30 v 30 h -30 z" class="box-style" /> +<text x="135" y="122" font-family="arial" font-size="20px" fill="#808080" class="faded-text-style">5</text> +<path d="m 125.5,130.5 h 30 v 30 h -30 z" class="box-style" + stroke-dasharray="5, 5" /> + +<path d="m 68.5,70.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="77" y="92" font-family="arial" font-size="20px" class="high-text-style">2</text> +<path d="m 68.5,100.5 h 30 v 30 h -30 z" class="highlighted-style" /> +<text x="77" y="122" font-family="arial" font-size="20px" class="high-text-style">3</text> + +<path d="M 63,70.5 H 43" class="line-style" /> +<path d="M 66,70.5 l -10,-5 l 0,10 z" class="fill-style" /> +</svg> diff --git a/src/corelib/doc/images/modelview-move-rows-1.svg b/src/corelib/doc/images/modelview-move-rows-1.svg new file mode 100644 index 00000000000..1c90c42f730 --- /dev/null +++ b/src/corelib/doc/images/modelview-move-rows-1.svg @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="200" + height="440" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + svg .faded-text-style { font: 20px arial; fill: #808080 } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + svg.dark .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="dark"] svg .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .faded-text-style { font: 20px arial; fill: #808080 } +</style> + +<g transform="translate(10,10)"> +<path d="m 0.5,0.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="22" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 0.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="52" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 0.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="82" font-family="arial" font-size="20px" + class="text-style">2</text> +<path d="m 0.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="112" font-family="arial" font-size="20px" + class="text-style">3</text> +<path d="m 0.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="142" font-family="arial" font-size="20px" + class="text-style">4</text> +<path d="m 0.5,180.5 h 30 v 30 h -30 z" stroke="black" fill="white" + stroke-dasharray="5, 5" + class="box-style" /> +<path d="m 0.5,150.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="172" font-family="arial" font-size="20px" + class="text-style">5</text> + +<path d="m 0.5,240.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="262" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 0.5,270.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="292" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 0.5,300.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="10" y="322" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 0.5,330.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="10" y="352" font-family="arial" font-size="20px" + class="high-text-style">3</text> +<path d="m 0.5,360.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="10" y="382" font-family="arial" font-size="20px" + class="high-text-style">4</text> +<path d="m 0.5,390.5 h 30 V 420.5 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="412" font-family="arial" font-size="20px" + class="text-style">5</text> + +<path d="m 58.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="67" y="82" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 58.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="67" y="112" font-family="arial" font-size="20px" + class="high-text-style">3</text> +<path d="m 58.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="67" y="142" font-family="arial" font-size="20px" + class="high-text-style">4</text> + +<path d="m 145.5,0.5 h 30 v 30.956 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="22" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 145.5,31.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="52" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 145.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="155" y="82" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 145.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="155" y="112" font-family="arial" font-size="20px" + class="high-text-style">3</text> +<path d="m 145.5,180.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="202" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">3</text> +<path d="m 145.5,210.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="232" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">4</text> +<path d="m 145.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="155" y="142" font-family="arial" font-size="20px" + class="high-text-style">4</text> +<path d="m 145.5,150.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="172" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">2</text> +<path d="m 145.5,240.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="262" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">5</text> + +<path d="m 145.5,330.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="352" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 145.5,360.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="382" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 145.5,390.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="412" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">5</text> + +<path d="M 58.5,60.5 h -25" stroke="black" + class="line-style" /> +<path d="M 31.5,60.5 l 10,-5 l 0,10 z" stroke="none" fill="black" + class="fill-style" /> +<path d="M 31.5,315.5 h 42 v -163" stroke="black" fill="none" + class="line-style" /> +<path d="M 73.5,151.5 l -5,10 l 10,0 z" stroke="none" fill="black" + class="fill-style" /> +</g> +</svg> diff --git a/src/corelib/doc/images/modelview-move-rows-2.svg b/src/corelib/doc/images/modelview-move-rows-2.svg new file mode 100644 index 00000000000..12ebfc43a16 --- /dev/null +++ b/src/corelib/doc/images/modelview-move-rows-2.svg @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="200" + height="440" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + svg .faded-text-style { font: 20px arial; fill: #808080 } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + svg.dark .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="dark"] svg .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .faded-text-style { font: 20px arial; fill: #808080 } +</style> + +<g transform="translate(10,10)"> +<path d="m 0.5,0.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="22" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 0.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="52" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 0.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="82" font-family="arial" font-size="20px" + class="text-style">2</text> +<path d="m 0.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="112" font-family="arial" font-size="20px" + class="text-style">3</text> +<path d="m 0.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="142" font-family="arial" font-size="20px" + class="text-style">4</text> +<path d="m 0.5,180.5 h 30 v 30 h -30 z" stroke="black" fill="white" + stroke-dasharray="5, 5" + class="box-style" /> +<path d="m 0.5,150.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="172" font-family="arial" font-size="20px" + class="text-style">5</text> + +<path d="m 0.5,240.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="262" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 0.5,270.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="292" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 0.5,300.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="10" y="322" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 0.5,330.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="10" y="352" font-family="arial" font-size="20px" + class="high-text-style">3</text> +<path d="m 0.5,360.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="10" y="382" font-family="arial" font-size="20px" + class="high-text-style">4</text> +<path d="m 0.5,390.5 h 30 V 420.5 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="412" font-family="arial" font-size="20px" + class="text-style">5</text> + +<path d="m 58.5,180.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="67" y="202" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 58.5,210.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="67" y="232" font-family="arial" font-size="20px" + class="high-text-style">3</text> +<path d="m 58.5,240.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="67" y="262" font-family="arial" font-size="20px" + class="high-text-style">4</text> + +<path d="m 145.5,0.5 h 30 v 30.956 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="22" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 145.5,31.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="52" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 145.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="82" font-family="arial" font-size="20px" + class="text-style">2</text> +<path d="m 145.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="112" font-family="arial" font-size="20px" + class="text-style">3</text> +<path d="m 145.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="142" font-family="arial" font-size="20px" + class="text-style">4</text> +<path d="m 145.5,150.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="172" font-family="arial" font-size="20px" + class="text-style">5</text> +<path d="m 145.5,180.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="155" y="202" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 145.5,210.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="155" y="232" font-family="arial" font-size="20px" + class="high-text-style">3</text> +<path d="m 145.5,240.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="155" y="262" font-family="arial" font-size="20px" + class="high-text-style">4</text> + +<path d="m 145.5,330.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="352" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 145.5,360.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="382" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 145.5,390.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="412" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">5</text> + +<path d="M 58.5,180.5 h -25" stroke="black" + class="line-style" /> +<path d="M 31.5,180.5 l 10,-5 l 0,10 z" stroke="none" fill="black" + class="fill-style" /> +<path d="M 31.5,315.5 h 42 v -43" stroke="black" fill="none" + class="line-style" /> +<path d="M 73.5,271.5 l -5,10 l 10,0 z" stroke="none" fill="black" + class="fill-style" /> +</g> +</svg> diff --git a/src/corelib/doc/images/modelview-move-rows-3.svg b/src/corelib/doc/images/modelview-move-rows-3.svg new file mode 100644 index 00000000000..21d9803eb91 --- /dev/null +++ b/src/corelib/doc/images/modelview-move-rows-3.svg @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="200" + height="200" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + svg .faded-text-style { font: 20px arial; fill: #808080 } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + svg.dark .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="dark"] svg .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .faded-text-style { font: 20px arial; fill: #808080 } +</style> + +<g transform="translate(10,10)"> +<path d="m 0.5,0.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="22" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 0.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="52" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 0.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="10" y="82" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 0.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="112" font-family="arial" font-size="20px" + class="text-style">3</text> +<path d="m 0.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="142" font-family="arial" font-size="20px" + class="text-style">4</text> +<path d="m 0.5,150.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="172" font-family="arial" font-size="20px" + class="text-style">5</text> + +<path d="m 58.5,0.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="67" y="22" font-family="arial" font-size="20px" + class="high-text-style">2</text> + +<path d="m 145.5,0.5 h 30 v 30.956 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="155" y="22" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 145.5,31.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="52" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">0</text> +<path d="m 145.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="82" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">1</text> +<path d="m 145.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="112" font-family="arial" font-size="20px" + class="text-style">3</text> +<path d="m 145.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="142" font-family="arial" font-size="20px" + class="text-style">4</text> +<path d="m 145.5,150.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="172" font-family="arial" font-size="20px" + class="text-style">5</text> + +<path d="M 58.5,0.5 h -25" stroke="black" fill="none" + class="line-style" /> +<path d="M 31.5,0.5 l 10,-5 l 0,10 z" stroke="none" fill="black" + class="fill-style" /> +<path d="M 31.5,75.5 h 42 v -43" stroke="black" fill="none" + class="line-style" /> +<path d="M 73.5,31.5 l -5,10 l 10,0 z" stroke="black" fill="black" + class="fill-style" /> +</g> +</svg> diff --git a/src/corelib/doc/images/modelview-move-rows-4.svg b/src/corelib/doc/images/modelview-move-rows-4.svg new file mode 100644 index 00000000000..708eb71f440 --- /dev/null +++ b/src/corelib/doc/images/modelview-move-rows-4.svg @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + version="1.1" + width="200" + height="200" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + +<style> + svg .box-style { stroke: black; fill: white } + svg .highlighted-style { stroke: black; fill: #c0ffc0 } + svg .fill-style { stroke: none; fill: black } + svg .line-style { stroke: black; fill: none } + svg .text-style { font: 20px arial; fill: black } + svg .high-text-style { font: 20px arial; fill: black } + svg .faded-text-style { font: 20px arial; fill: #808080 } + + svg.dark .box-style { stroke: #f2f2f2; fill: black } + svg.dark .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + svg.dark .fill-style { stroke: none; fill: #f2f2f2 } + svg.dark .line-style { stroke: #f2f2f2; fill: none } + svg.dark .text-style { font: 20px arial; fill: #f2f2f2 } + svg.dark .high-text-style { font: 20px arial; fill: black } + svg.dark .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black } + [data-theme="dark"] svg .highlighted-style { stroke: #f2f2f2; fill: #c0ffc0 } + [data-theme="dark"] svg .fill-style { stroke: none; fill: #f2f2f2 } + [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none } + [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 } + [data-theme="dark"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="dark"] svg .faded-text-style { font: 20px arial; fill: #808080 } + + [data-theme="light"] svg .box-style { stroke: black; fill: white } + [data-theme="light"] svg .highlighted-style { stroke: black; fill: #c0ffc0 } + [data-theme="light"] svg .fill-style { stroke: none; fill: black } + [data-theme="light"] svg .line-style { stroke: black; fill: none } + [data-theme="light"] svg .text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .high-text-style { font: 20px arial; fill: black } + [data-theme="light"] svg .faded-text-style { font: 20px arial; fill: #808080 } +</style> + +<g transform="translate(10,10)"> +<path d="m 0.5,0.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="22" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 0.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="52" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 0.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="10" y="82" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 0.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="112" font-family="arial" font-size="20px" + class="text-style">3</text> +<path d="m 0.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="142" font-family="arial" font-size="20px" + class="text-style">4</text> +<path d="m 0.5,150.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="10" y="172" font-family="arial" font-size="20px" + class="text-style">5</text> + +<path d="m 58.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="67" y="142" font-family="arial" font-size="20px" + class="high-text-style">2</text> + +<path d="m 145.5,0.5 h 30 v 30.956 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="22" font-family="arial" font-size="20px" + class="text-style">0</text> +<path d="m 145.5,31.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="52" font-family="arial" font-size="20px" + class="text-style">1</text> +<path d="m 145.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="82" font-family="arial" font-size="20px" fill="#808080" + class="faded-text-style">3</text> +<path d="m 145.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="#c0ffc0" + class="highlighted-style" /> +<text x="155" y="112" font-family="arial" font-size="20px" + class="high-text-style">2</text> +<path d="m 145.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="142" font-family="arial" font-size="20px" + class="text-style">4</text> +<path d="m 145.5,150.5 h 30 v 30 h -30 z" stroke="black" fill="white" + class="box-style" /> +<text x="155" y="172" font-family="arial" font-size="20px" + class="text-style">5</text> + +<path d="M 58.5,120.5 h -25" stroke="black" fill="none" + class="line-style" /> +<path d="M 31.5,120.5 l 10,-5 l 0,10 z" stroke="black" fill="black" + class="fill-style" /> +<path d="M 31.5,75.5 h 42 v 43" stroke="black" fill="none" + class="line-style" /> +<path d="M 73.5,119.5 l -5,-10 l 10,0 z" stroke="black" fill="black" + class="fill-style" /> +</g> +</svg> diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index c960e11f6bb..58a057009ff 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -2867,7 +2867,7 @@ bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &pare \table 80% \row - \li \inlineimage modelview-begin-insert-rows.png Inserting rows + \li \inlineimage modelview-begin-insert-rows.svg Inserting rows \li Specify the first and last row numbers for the span of rows you want to insert into an item in a model. @@ -2878,7 +2878,7 @@ bool QAbstractItemModel::decodeData(int row, int column, const QModelIndex &pare This inserts the three new rows as rows 2, 3, and 4. \row - \li \inlineimage modelview-begin-append-rows.png Appending rows + \li \inlineimage modelview-begin-append-rows.svg Appending rows \li To append rows, insert them after the last row. For example, as shown in the diagram, we append two rows to a @@ -2934,7 +2934,7 @@ void QAbstractItemModel::endInsertRows() \table 80% \row - \li \inlineimage modelview-begin-remove-rows.png Removing rows + \li \inlineimage modelview-begin-remove-rows.svg Removing rows \li Specify the first and last row numbers for the span of rows you want to remove from an item in a model. @@ -3055,7 +3055,7 @@ void QAbstractItemModelPrivate::executePendingOperations() const { } \table 80% \row - \li \inlineimage modelview-move-rows-1.png Moving rows to another parent + \li \inlineimage modelview-move-rows-1.svg Moving rows to another parent \li Specify the first and last row numbers for the span of rows in the source parent you want to move in the model. Also specify the row in the destination parent to move the span to. @@ -3069,7 +3069,7 @@ void QAbstractItemModelPrivate::executePendingOperations() const { } This moves the three rows rows 2, 3, and 4 in the source to become 2, 3 and 4 in the destination. Other affected siblings are displaced accordingly. \row - \li \inlineimage modelview-move-rows-2.png Moving rows to append to another parent + \li \inlineimage modelview-move-rows-2.svg Moving rows to append to another parent \li To append rows to another parent, move them to after the last row. For example, as shown in the diagram, we move three rows to a @@ -3079,7 +3079,7 @@ void QAbstractItemModelPrivate::executePendingOperations() const { } This moves the target rows to the end of the target parent as 6, 7 and 8. \row - \li \inlineimage modelview-move-rows-3.png Moving rows in the same parent up + \li \inlineimage modelview-move-rows-3.svg Moving rows in the same parent up \li To move rows within the same parent, specify the row to move them to. For example, as shown in the diagram, we move one item from row 2 to row 0, @@ -3094,7 +3094,7 @@ void QAbstractItemModelPrivate::executePendingOperations() const { } it is already) \row - \li \inlineimage modelview-move-rows-4.png Moving rows in the same parent down + \li \inlineimage modelview-move-rows-4.svg Moving rows in the same parent down \li To move rows within the same parent, specify the row to move them to. For example, as shown in the diagram, we move one item from row 2 to row 4, @@ -3176,7 +3176,7 @@ void QAbstractItemModel::endMoveRows() \table 80% \row - \li \inlineimage modelview-begin-insert-columns.png Inserting columns + \li \inlineimage modelview-begin-insert-columns.svg Inserting columns \li Specify the first and last column numbers for the span of columns you want to insert into an item in a model. @@ -3187,7 +3187,7 @@ void QAbstractItemModel::endMoveRows() This inserts the three new columns as columns 4, 5, and 6. \row - \li \inlineimage modelview-begin-append-columns.png Appending columns + \li \inlineimage modelview-begin-append-columns.svg Appending columns \li To append columns, insert them after the last column. For example, as shown in the diagram, we append three columns to a @@ -3245,7 +3245,7 @@ void QAbstractItemModel::endInsertColumns() \table 80% \row - \li \inlineimage modelview-begin-remove-columns.png Removing columns + \li \inlineimage modelview-begin-remove-columns.svg Removing columns \li Specify the first and last column numbers for the span of columns you want to remove from an item in a model. diff --git a/src/corelib/kernel/qeventdispatcher_wasm.cpp b/src/corelib/kernel/qeventdispatcher_wasm.cpp index f7edf3285f8..25a27a0c22b 100644 --- a/src/corelib/kernel/qeventdispatcher_wasm.cpp +++ b/src/corelib/kernel/qeventdispatcher_wasm.cpp @@ -150,6 +150,18 @@ bool QEventDispatcherWasm::isValidEventDispatcherPointer(QEventDispatcherWasm *e bool QEventDispatcherWasm::processEvents(QEventLoop::ProcessEventsFlags flags) { + // Accept the current event if event handling recurses / event loop is reentered, + // to prevent the browser from propagating it to other event handlers. + if (useAsyncify() && isMainThreadEventDispatcher()) { + auto control = QWasmSuspendResumeControl::get(); + auto currentEvent = control->currentEvent(); + if (!currentEvent.isUndefined() && currentEvent.instanceof(emscripten::val::global("Event"))) { + currentEvent.call<void>("preventDefault"); + currentEvent.call<void>("stopPropagation"); + control->setCurrentEvent(emscripten::val::undefined()); + } + } + emit awake(); if (!useAsyncify() && isMainThreadEventDispatcher()) diff --git a/src/corelib/kernel/qeventdispatcher_wasm_p.h b/src/corelib/kernel/qeventdispatcher_wasm_p.h index 674af85dac2..1946bf63ede 100644 --- a/src/corelib/kernel/qeventdispatcher_wasm_p.h +++ b/src/corelib/kernel/qeventdispatcher_wasm_p.h @@ -40,7 +40,6 @@ public: ~QEventDispatcherWasm(); bool processEvents(QEventLoop::ProcessEventsFlags flags) override; - bool sendAllEvents(QEventLoop::ProcessEventsFlags flag); void registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *object) override final; @@ -69,6 +68,7 @@ protected: virtual bool sendPostedEvents(); private: + bool sendAllEvents(QEventLoop::ProcessEventsFlags flag); bool isMainThreadEventDispatcher(); bool isSecondaryThreadEventDispatcher(); bool isValidEventDispatcher(); diff --git a/src/corelib/platform/wasm/qwasmlocalfileengine.cpp b/src/corelib/platform/wasm/qwasmlocalfileengine.cpp new file mode 100644 index 00000000000..58e662d5fde --- /dev/null +++ b/src/corelib/platform/wasm/qwasmlocalfileengine.cpp @@ -0,0 +1,422 @@ +// Copyright (C) 2025 Qt Group +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#include "qwasmlocalfileengine_p.h" +#include <QtCore/QDebug> +#include <QtCore/QUrl> + +QT_BEGIN_NAMESPACE + +using namespace Qt::StringLiterals; + +// Custom URL scheme for files handled by this file engine. A complete file URL can +// look like +// +// "weblocalfile:/n/file.ext" +// +// where n is a counter to ensure uniqueness, needed since web platform gives us the file name only +// and does not provide the file path. +// +// The scheme may be visible to end users if the application displays it, so +// we avoid using "wasm" and instead say "web", which should be more recognizable. +static constexpr QLatin1StringView wasmlocalfileScheme = "weblocalfile"_L1; + +// Instantiate the engine, the system will pick it up automatically +// Never destroy it to avoid problems with static destruction. +// The OS will reclaim the memory anyway, +// TODO: cleanup on QApplication destruction and re-init on QApplication re-creation. +static QWasmFileEngineHandler *singleton = new QWasmFileEngineHandler(); + +QWasmFileEngineHandler::QWasmFileEngineHandler() +{ +} + +QWasmFileEngineHandler::~QWasmFileEngineHandler() +{ +} + +std::unique_ptr<QAbstractFileEngine> QWasmFileEngineHandler::create(const QString &fileName) const +{ + if (!QWasmFileEngineHandler::isWasmFileName(fileName)) + return {}; + + // Check if it's a File or FileSystemFileHandle + if (singleton->m_files.contains(fileName)) { + qstdweb::File file = singleton->m_files.value(fileName); + return std::make_unique<QWasmFileEngine>(fileName, file); + } else if (singleton->m_fileSystemFiles.contains(fileName)) { + qstdweb::FileSystemFileHandle file = singleton->m_fileSystemFiles.value(fileName); + return std::make_unique<QWasmFileEngine>(fileName, file); + } + + // Not an error, this function will be called with partial paths like "weblocalfile:/1/" + return {}; +} + +// Check if this is a wasm filename by checking the URL scheme. +bool QWasmFileEngineHandler::isWasmFileName(const QString& fileName) +{ + return QUrl(fileName).scheme() == wasmlocalfileScheme; +} + +// Creates a wasm filename using the custom URL scheme and a counter. +QString QWasmFileEngineHandler::makeWasmFileName(const QString &nativeFileName) +{ + static std::atomic<uint64_t> sid = 0; + const uint64_t id = ++sid; + return wasmlocalfileScheme + QStringLiteral(":/%1/%2").arg(id).arg(nativeFileName); +} + +// Extracts the native filename from the custom URL (removes scheme and counter). +QString QWasmFileEngineHandler::nativeFileName(const QString &wasmFileName) +{ + QUrl url(wasmFileName); + if (url.scheme() == wasmlocalfileScheme) { + QString path = url.path(); + // Path is "/n/filename", find the second '/' and extract the filename + const qsizetype idx = path.indexOf(u'/', 1); + if (idx != -1) + return path.mid(idx + 1); + } + return wasmFileName; +} + +// Adds a File to the set of open files. Returns a prefixed wasm file name. +QString QWasmFileEngineHandler::addFile(qstdweb::File file) +{ + QString nativeFileName = QString::fromStdString(file.name()); + QString wasmFileName = makeWasmFileName(nativeFileName); + singleton->m_files.insert(wasmFileName, file); + return wasmFileName; +} + +// Adds a FileSystemFileHandle to the set of open files. Returns a prefixed wasm file name. +QString QWasmFileEngineHandler::addFile(qstdweb::FileSystemFileHandle file) +{ + QString nativeFileName = QString::fromStdString(file.name()); + QString wasmFileName = makeWasmFileName(nativeFileName); + singleton->m_fileSystemFiles.insert(wasmFileName, file); + return wasmFileName; +} + +// Removes a File or FileSystemFileHandle from the set of open file handlers +void QWasmFileEngineHandler::removeFile(const QString fileName) +{ + singleton->m_files.remove(fileName); + singleton->m_fileSystemFiles.remove(fileName); +} + +qstdweb::File QWasmFileEngineHandler::getFile(const QString fileName) +{ + return singleton->m_files.value(fileName); +} + +qstdweb::FileSystemFileHandle QWasmFileEngineHandler::getFileSystemFile(const QString fileName) +{ + return singleton->m_fileSystemFiles.value(fileName); +} + +/*! + \class QWasmFileEngine + \brief The QWasmFileEngine class provides a QAbstractFileEngine + for files that has the prefix ':weblocalfile/'. +*/ + +// Constructs a QWasmFileEngine with a File for read-only access +QWasmFileEngine::QWasmFileEngine(const QString &fileName, qstdweb::File file) + : m_fileName(fileName), + m_blobDevice(std::make_unique<qstdweb::BlobIODevice>(file.slice(0, file.size()))) +{ + // TODO use m_blobDevice in unbuffered mode? if there is already a buffer higher up. +} + +// Constructs a QWasmFileEngine with a FileSystemFileHandle for read-write access +QWasmFileEngine::QWasmFileEngine(const QString &fileName, qstdweb::FileSystemFileHandle file) + : m_fileName(fileName), + m_fileDevice(std::make_unique<qstdweb::FileSystemFileIODevice>(file)) +{ + +} + +QWasmFileEngine::~QWasmFileEngine() +{ + close(); +} + +bool QWasmFileEngine::open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) +{ + Q_UNUSED(permissions); + m_openMode = openMode; + + if (m_fileDevice) + return m_fileDevice->open(openMode); + else if (m_blobDevice) + return m_blobDevice->open(openMode); + + return false; +} + +bool QWasmFileEngine::close() +{ + if (m_openMode == QIODevice::NotOpen) + return false; + + bool success = true; + if (m_fileDevice) { + m_fileDevice->close(); + } + if (m_blobDevice) { + m_blobDevice->close(); + } + + m_openMode = QIODevice::NotOpen; + return success; +} + +bool QWasmFileEngine::flush() +{ + return true; +} + +bool QWasmFileEngine::syncToDisk() +{ + return true; +} + +qint64 QWasmFileEngine::size() const +{ + if (m_fileDevice) + return m_fileDevice->size(); + if (m_blobDevice) + return m_blobDevice->size(); + return 0; +} + +qint64 QWasmFileEngine::pos() const +{ + if (m_fileDevice) + return m_fileDevice->pos(); + if (m_blobDevice) + return m_blobDevice->pos(); + return 0; +} + +bool QWasmFileEngine::seek(qint64 pos) +{ + if (m_fileDevice) + return m_fileDevice->seek(pos); + if (m_blobDevice) + return m_blobDevice->seek(pos); + return false; +} + +bool QWasmFileEngine::isSequential() const +{ + return false; +} + +bool QWasmFileEngine::remove() +{ + return false; +} + +bool QWasmFileEngine::copy(const QString &newName) +{ + Q_UNUSED(newName); + return false; +} + +bool QWasmFileEngine::rename(const QString &newName) +{ + Q_UNUSED(newName); + return false; +} + +bool QWasmFileEngine::renameOverwrite(const QString &newName) +{ + Q_UNUSED(newName); + return false; +} + +bool QWasmFileEngine::link(const QString &newName) +{ + Q_UNUSED(newName); + return false; +} + +bool QWasmFileEngine::mkdir(const QString &dirName, bool createParentDirectories, + std::optional<QFile::Permissions> permissions) const +{ + Q_UNUSED(dirName); + Q_UNUSED(createParentDirectories); + Q_UNUSED(permissions); + return false; +} + +bool QWasmFileEngine::rmdir(const QString &dirName, bool recurseParentDirectories) const +{ + Q_UNUSED(dirName); + Q_UNUSED(recurseParentDirectories); + return false; +} + +bool QWasmFileEngine::setSize(qint64 size) +{ + Q_UNUSED(size); + return false; +} + +bool QWasmFileEngine::caseSensitive() const +{ + return true; +} + +bool QWasmFileEngine::isRelativePath() const +{ + return false; +} + + +QAbstractFileEngine::FileFlags QWasmFileEngine::fileFlags(FileFlags type) const +{ + return type & (QAbstractFileEngine::FileFlag::ExistsFlag | + QAbstractFileEngine::FileFlag::FileType | + QAbstractFileEngine::FileFlag::ReadOwnerPerm | + QAbstractFileEngine::FileFlag::WriteOwnerPerm); +} + +bool QWasmFileEngine::setPermissions(uint perms) +{ + Q_UNUSED(perms); + return false; +} + +QByteArray QWasmFileEngine::id() const +{ + return {}; +} + +QString QWasmFileEngine::fileName(FileName file) const +{ + switch (file) { + case DefaultName: + case AbsoluteName: + case CanonicalName: + return m_fileName; + case BaseName: { + QString native = QWasmFileEngineHandler::nativeFileName(m_fileName); + QFileInfo info(native); + return info.fileName(); + } + case PathName: + case AbsolutePathName: + case CanonicalPathName: { + QString native = QWasmFileEngineHandler::nativeFileName(m_fileName); + QFileInfo info(native); + QString path = info.path(); + return path.isEmpty() ? "."_L1 : path; + } + default: + return QString(); + } +} + +uint QWasmFileEngine::ownerId(FileOwner) const +{ + return 0; +} + +QString QWasmFileEngine::owner(FileOwner) const +{ + return {}; +} + +bool QWasmFileEngine::setFileTime(const QDateTime &newDate, QFile::FileTime time) +{ + Q_UNUSED(newDate); + Q_UNUSED(time); + return false; +} + +QDateTime QWasmFileEngine::fileTime(QFile::FileTime time) const +{ + Q_UNUSED(time); + return {}; +} + +void QWasmFileEngine::setFileName(const QString &file) +{ + if (m_fileName == file) + return; + close(); + m_fileName = file; +} + +int QWasmFileEngine::handle() const +{ + return -1; +} + +QAbstractFileEngine::TriStateResult QWasmFileEngine::cloneTo(QAbstractFileEngine *target) +{ + Q_UNUSED(target); + return QAbstractFileEngine::TriStateResult::NotSupported; +} + +QAbstractFileEngine::IteratorUniquePtr QWasmFileEngine::beginEntryList(const QString &path, QDirListing::IteratorFlags filters, + const QStringList &filterNames) +{ + Q_UNUSED(path); + Q_UNUSED(filters); + Q_UNUSED(filterNames); + return nullptr; +} + +qint64 QWasmFileEngine::read(char *data, qint64 maxlen) +{ + if (!(m_openMode & QIODevice::ReadOnly)) + return -1; + + if (m_fileDevice) + return m_fileDevice->read(data, maxlen); + if (m_blobDevice) + return m_blobDevice->read(data, maxlen); + return -1; +} + +qint64 QWasmFileEngine::readLine(char *data, qint64 maxlen) +{ + if (!(m_openMode & QIODevice::ReadOnly)) + return -1; + + if (m_fileDevice) + return m_fileDevice->readLine(data, maxlen); + if (m_blobDevice) + return m_blobDevice->readLine(data, maxlen); + return -1; +} + +qint64 QWasmFileEngine::write(const char *data, qint64 len) +{ + if (!(m_openMode & QIODevice::WriteOnly)) + return -1; + + if (m_fileDevice) + return m_fileDevice->write(data, len); + return -1; +} + +bool QWasmFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) +{ + Q_UNUSED(extension); + Q_UNUSED(option); + Q_UNUSED(output); + return false; +} + +bool QWasmFileEngine::supportsExtension(Extension extension) const +{ + Q_UNUSED(extension); + return false; +} + +QT_END_NAMESPACE diff --git a/src/corelib/platform/wasm/qwasmlocalfileengine_p.h b/src/corelib/platform/wasm/qwasmlocalfileengine_p.h new file mode 100644 index 00000000000..dd82788dd90 --- /dev/null +++ b/src/corelib/platform/wasm/qwasmlocalfileengine_p.h @@ -0,0 +1,102 @@ +// Copyright (C) 2024 Qt Group +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only +#ifndef QWASMLOCALFILEENGINE_P_H +#define QWASMLOCALFILEENGINE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/private/qabstractfileengine_p.h> +#include <QtCore/private/qstdweb_p.h> + +QT_BEGIN_NAMESPACE + +class QWasmFileEngine; + +class QWasmFileEngineHandler: public QAbstractFileEngineHandler +{ +public: + Q_DISABLE_COPY_MOVE(QWasmFileEngineHandler) + + QWasmFileEngineHandler(); + virtual ~QWasmFileEngineHandler() override; + virtual std::unique_ptr<QAbstractFileEngine> create(const QString &fileName) const override; + + static bool isWasmFileName(const QString& fileName); + static QString makeWasmFileName(const QString &fileName); + static QString nativeFileName(const QString &wasmFileName); + + static QString addFile(qstdweb::File file); + static QString addFile(qstdweb::FileSystemFileHandle file); + static void removeFile(const QString fileName); + qstdweb::File getFile(const QString fileName); + qstdweb::FileSystemFileHandle getFileSystemFile(const QString fileName); + +private: + QHash<QString, qstdweb::File> m_files; + QHash<QString, qstdweb::FileSystemFileHandle> m_fileSystemFiles; +}; + +class QWasmFileEngine: public QAbstractFileEngine +{ +public: + explicit QWasmFileEngine(const QString &fileName, qstdweb::File file); + explicit QWasmFileEngine(const QString &fileName, qstdweb::FileSystemFileHandle file); + ~QWasmFileEngine() override; + + virtual bool open(QIODevice::OpenMode openMode, std::optional<QFile::Permissions> permissions) override; + virtual bool close() override; + virtual bool flush() override; + virtual bool syncToDisk() override; + virtual qint64 size() const override; + virtual qint64 pos() const override; + virtual bool seek(qint64 pos) override; + virtual bool isSequential() const override; + virtual bool remove() override; + virtual bool copy(const QString &newName) override; + virtual bool rename(const QString &newName) override; + virtual bool renameOverwrite(const QString &newName) override; + virtual bool link(const QString &newName) override; + virtual bool mkdir(const QString &dirName, bool createParentDirectories, + std::optional<QFile::Permissions> permissions = std::nullopt) const override; + virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const override; + virtual bool setSize(qint64 size) override; + virtual bool caseSensitive() const override; + virtual bool isRelativePath() const override; + virtual FileFlags fileFlags(FileFlags type=FileInfoAll) const override; + virtual bool setPermissions(uint perms) override; + virtual QByteArray id() const override; + virtual QString fileName(FileName file = DefaultName) const override; + virtual uint ownerId(FileOwner) const override; + virtual QString owner(FileOwner) const override; + virtual bool setFileTime(const QDateTime &newDate, QFile::FileTime time) override; + virtual QDateTime fileTime(QFile::FileTime time) const override; + virtual void setFileName(const QString &file) override; + virtual int handle() const override; + virtual TriStateResult cloneTo(QAbstractFileEngine *target) override; + virtual IteratorUniquePtr beginEntryList(const QString &path, QDirListing::IteratorFlags filters, + const QStringList &filterNames) override; + virtual qint64 read(char *data, qint64 maxlen) override; + virtual qint64 readLine(char *data, qint64 maxlen) override; + virtual qint64 write(const char *data, qint64 len) override; + virtual bool extension(Extension extension, const ExtensionOption *option = nullptr, + ExtensionReturn *output = nullptr) override; + virtual bool supportsExtension(Extension extension) const override; + +private: + QString m_fileName; + QIODevice::OpenMode m_openMode = QIODevice::NotOpen; + std::unique_ptr<qstdweb::BlobIODevice> m_blobDevice; + std::unique_ptr<qstdweb::FileSystemFileIODevice> m_fileDevice; +}; + +QT_END_NAMESPACE +#endif // QWASMFILEENGINEHANDLER_H diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp index a4bc7843380..85358d1daf4 100644 --- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp +++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp @@ -225,8 +225,11 @@ int QWasmSuspendResumeControl::sendPendingEvents() pendingEvents.call<void>("splice", i, 1); auto it = m_eventHandlers.find(event["index"].as<int>()); - if (it != m_eventHandlers.end()) - it->second(event["arg"]); + if (it != m_eventHandlers.end()) { + setCurrentEvent(event["arg"]); + it->second(currentEvent()); + setCurrentEvent(emscripten::val::undefined()); + } ++count; } } diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h b/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h index ff97ff3d7ea..4e75d5674be 100644 --- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h +++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h @@ -42,12 +42,22 @@ public: void suspendExclusive(QList<uint32_t> eventHandlerIndices); int sendPendingEvents(); + emscripten::val currentEvent() const + { + return m_currentEvent; + } + void setCurrentEvent(emscripten::val currentEvent) + { + m_currentEvent = currentEvent; + } + private: friend void qtSendPendingEvents(); static QWasmSuspendResumeControl *s_suspendResumeControl; std::map<int, std::function<void(emscripten::val)>> m_eventHandlers; std::function<bool(int)> m_eventFilter = [](int) { return true; }; + emscripten::val m_currentEvent = emscripten::val::undefined(); }; class Q_CORE_EXPORT QWasmEventHandler diff --git a/src/corelib/text/qstringconverter_p.h b/src/corelib/text/qstringconverter_p.h index 3ac60ce8c70..3923c2f302f 100644 --- a/src/corelib/text/qstringconverter_p.h +++ b/src/corelib/text/qstringconverter_p.h @@ -334,6 +334,7 @@ struct QUtf8 static char16_t *convertToUnicode(char16_t *dst, QByteArrayView in, QStringConverter::State *state); + Q_CORE_EXPORT static char *convertFromUnicode(char *dst, QStringView in) noexcept; Q_CORE_EXPORT static QByteArray convertFromUnicode(QStringView in); Q_CORE_EXPORT static QByteArray convertFromUnicode(QStringView in, QStringConverter::State *state); |
