diff options
Diffstat (limited to 'src/quickdialogs2/quickdialogs2quickimpl')
108 files changed, 8602 insertions, 0 deletions
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt b/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt new file mode 100644 index 0000000000..caec15b097 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt @@ -0,0 +1,146 @@ +##################################################################### +## QuickDialogs2QuickImpl Module: +##################################################################### + +set(qml_files + "qml/FileDialog.qml" + "qml/FileDialogDelegate.qml" + "qml/FileDialogDelegateLabel.qml" + "qml/FolderBreadcrumbBar.qml" + "qml/FontDialog.qml" + "qml/FontDialogContent.qml" + "qml/+Fusion/FileDialog.qml" + "qml/+Fusion/FileDialogDelegate.qml" + "qml/+Fusion/FolderBreadcrumbBar.qml" + "qml/+Fusion/FontDialog.qml" + "qml/+Imagine/FileDialog.qml" + "qml/+Imagine/FileDialogDelegate.qml" + "qml/+Imagine/FolderBreadcrumbBar.qml" + "qml/+Imagine/FontDialog.qml" + "qml/+Material/FileDialog.qml" + "qml/+Material/FileDialogDelegate.qml" + "qml/+Material/FolderBreadcrumbBar.qml" + "qml/+Material/FontDialog.qml" + "qml/+Universal/FileDialog.qml" + "qml/+Universal/FileDialogDelegate.qml" + "qml/+Universal/FolderBreadcrumbBar.qml" + "qml/+Universal/FontDialog.qml" +) + +qt_internal_add_qml_module(QuickDialogs2QuickImpl + URI "QtQuick.Dialogs.quickimpl" + VERSION "${PROJECT_VERSION}" + CLASS_NAME QtQuickDialogs2QuickImplPlugin + PLUGIN_TARGET qtquickdialogs2quickimplplugin + DEPENDENCIES + QtQuick/auto + QtQuick.Templates/auto + SOURCES + qquickdialogimplfactory.cpp + qquickdialogimplfactory_p.h + qquickfiledialogdelegate.cpp + qquickfiledialogdelegate_p.h + qquickfiledialogimpl.cpp + qquickfiledialogimpl_p.h + qquickfiledialogimpl_p_p.h + qquickfolderbreadcrumbbar.cpp + qquickfolderbreadcrumbbar_p.h + qquickfolderbreadcrumbbar_p_p.h + qquickplatformfiledialog.cpp + qquickplatformfiledialog_p.h + qquickplatformfontdialog_p.h + qquickplatformfontdialog.cpp + qtquickdialogs2quickimplforeign_p.h + qtquickdialogs2quickimplglobal_p.h + qquickfontdialogimpl_p.h + qquickfontdialogimpl_p_p.h + qquickfontdialogimpl.cpp + QML_FILES + ${qml_files} + DEFINES + QT_BUILD_QUICKDIALOGS2QUICKIMPL_LIB + QT_NO_CAST_FROM_ASCII + QT_NO_CAST_TO_ASCII + INCLUDE_DIRECTORIES + ${CMAKE_CURRENT_SOURCE_DIR} + LIBRARIES + Qt::CorePrivate + Qt::GuiPrivate + Qt::QmlPrivate + Qt::QuickPrivate + Qt::QuickTemplates2 + Qt::QuickTemplates2Private + Qt::QuickDialogs2Utils + Qt::QuickDialogs2UtilsPrivate + PUBLIC_LIBRARIES + Qt::Core + Qt::Gui + Qt::Quick +) + +# Resources: +set(qtquickdialogs2quickimpl_resource_files + "images/crumb-separator-icon-round.png" + "images/crumb-separator-icon-round@2x.png" + "images/crumb-separator-icon-round@3x.png" + "images/crumb-separator-icon-round@4x.png" + "images/crumb-separator-icon-square.png" + "images/crumb-separator-icon-square@2x.png" + "images/crumb-separator-icon-square@3x.png" + "images/crumb-separator-icon-square@4x.png" + "images/file-icon-round.png" + "images/file-icon-round@2x.png" + "images/file-icon-round@3x.png" + "images/file-icon-round@4x.png" + "images/file-icon-square.png" + "images/file-icon-square@2x.png" + "images/file-icon-square@3x.png" + "images/file-icon-square@4x.png" + "images/folder-icon-round.png" + "images/folder-icon-round@2x.png" + "images/folder-icon-round@3x.png" + "images/folder-icon-round@4x.png" + "images/folder-icon-square.png" + "images/folder-icon-square@2x.png" + "images/folder-icon-square@3x.png" + "images/folder-icon-square@4x.png" + "images/imagine/filedialogdelegate-background@2x.9.png" + "images/imagine/filedialogdelegate-background@3x.9.png" + "images/imagine/filedialogdelegate-background@4x.9.png" + "images/imagine/filedialogdelegate-background.9.png" + "images/imagine/filedialogdelegate-background-disabled@2x.9.png" + "images/imagine/filedialogdelegate-background-disabled@3x.9.png" + "images/imagine/filedialogdelegate-background-disabled@4x.9.png" + "images/imagine/filedialogdelegate-background-disabled.9.png" + "images/imagine/filedialogdelegate-background-pressed@2x.9.png" + "images/imagine/filedialogdelegate-background-pressed@3x.9.png" + "images/imagine/filedialogdelegate-background-pressed@4x.9.png" + "images/imagine/filedialogdelegate-background-pressed.9.png" + "images/imagine/filedialogdelegate-background-focused@2x.9.png" + "images/imagine/filedialogdelegate-background-focused@3x.9.png" + "images/imagine/filedialogdelegate-background-focused@4x.9.png" + "images/imagine/filedialogdelegate-background-focused.9.png" + "images/imagine/filedialogdelegate-background-highlighted@2x.9.png" + "images/imagine/filedialogdelegate-background-highlighted@3x.9.png" + "images/imagine/filedialogdelegate-background-highlighted@4x.9.png" + "images/imagine/filedialogdelegate-background-highlighted.9.png" + "images/up-icon-round.png" + "images/up-icon-round@2x.png" + "images/up-icon-round@3x.png" + "images/up-icon-round@4x.png" + "images/up-icon-square.png" + "images/up-icon-square@2x.png" + "images/up-icon-square@3x.png" + "images/up-icon-square@4x.png" + "images/up-icon-thick-square.png" + "images/up-icon-thick-square@2x.png" + "images/up-icon-thick-square@3x.png" + "images/up-icon-thick-square@4x.png" +) + +qt_internal_add_resource(QuickDialogs2QuickImpl "QuickDialogs2QuickImpl" + PREFIX + "/qt-project.org/imports/QtQuick/Dialogs/quickimpl" + FILES + ${qtquickdialogs2quickimpl_resource_files} +) diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.png Binary files differnew file mode 100644 index 0000000000..aaa5a3e431 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.svg new file mode 100644 index 0000000000..013cedefa3 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round.svg @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="8" + height="8" + viewBox="0 0 8 8" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="crumb-separator-icon-round.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect3421" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1367" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1365" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="16.000001" + inkscape:cx="6.7812496" + inkscape:cy="15.031249" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0" + height="14px"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="crumb-separator-icon-round" + transform="translate(2.046,3.0914383)"> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect2017" + width="8" + height="8" + x="-2.046" + y="-3.0914383" /> + </g> + <path + id="rect858" + style="fill:#757575;stroke-width:2.43737;stroke-linejoin:round" + d="M 3.0219754,1.01117 6.416287,3.5317721 a 0.74259596,0.74259596 90 0 1 0,1.1923778 L 3.0219754,7.2447519 A 0.5029757,0.5029757 26.701285 0 1 2.2191312,6.8409408 l 0,-5.4259596 A 0.5029757,0.5029757 153.29872 0 1 3.0219754,1.01117 Z" + sodipodi:nodetypes="cccc" + inkscape:path-effect="#path-effect3421" + inkscape:original-d="m 2.2191312,0.41498117 5,3.71297983 -5,3.7129798 z" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1449" + width="8" + height="8" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@2x.png Binary files differnew file mode 100644 index 0000000000..3f66fe172b --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@3x.png Binary files differnew file mode 100644 index 0000000000..24d9f6a64e --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@4x.png Binary files differnew file mode 100644 index 0000000000..1dc83ef09f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-round@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.png Binary files differnew file mode 100644 index 0000000000..1f7ac63e7f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.svg new file mode 100644 index 0000000000..9663673470 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square.svg @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="8" + height="8" + viewBox="0 0 8 8" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="crumb-separator-icon-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect3421" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1367" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1365" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="90.509672" + inkscape:cx="4.43599" + inkscape:cy="3.3311357" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0" + height="14px"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="crumb-separator-icon-square" + transform="translate(2.046,3.0914383)"> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect2017" + width="8" + height="8" + x="-2.046" + y="-3.0914383" /> + <path + style="fill:#757575;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m -0.046,-2.0914383 4,3 -4,3 z" + id="path1065" + sodipodi:nodetypes="cccc" /> + </g> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1449" + width="8" + height="8" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@2x.png Binary files differnew file mode 100644 index 0000000000..524872c1e9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@3x.png Binary files differnew file mode 100644 index 0000000000..33bce847c8 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@4x.png Binary files differnew file mode 100644 index 0000000000..185c3eb7ae --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/crumb-separator-icon-square@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.png Binary files differnew file mode 100644 index 0000000000..c2a4928daf --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.svg new file mode 100644 index 0000000000..7ac6a23b5c --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round.svg @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="14" + height="18" + viewBox="0 0 14 18" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="file-icon-round.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.5003822,2.5063148 1.5000273,15.5 A 0.99997269,0.99997269 45.000782 0 0 2.5,16.5 h 9 a 1,1 135 0 0 1,-1 V 6.3440001 A 2.3479106,2.3479106 66.930332 0 0 11.778973,4.6510931 L 9.221027,2.192907 A 2.4805476,2.4805476 21.904486 0 0 7.5000004,1.5009022 l -4.9995913,0.00451 A 1.0009299,1.0009299 134.97494 0 0 1.5003822,2.5063148 Z" + id="path917" + sodipodi:nodetypes="cccccc" + inkscape:path-effect="#path-effect1367" + inkscape:original-d="M 1.5004095,1.5063148 1.5,16.5 h 11 V 5.3440001 L 8.5,1.5 Z" /> + <path + id="path921" + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 12.35,6.5 H 8.5 a 1,1 45 0 1 -1,-1 V 1.55" + inkscape:path-effect="#path-effect1365" + inkscape:original-d="M 12.35,6.5 H 7.5 V 1.55" + sodipodi:nodetypes="ccc" /> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1367" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1365" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="32.000001" + inkscape:cx="7.8906248" + inkscape:cy="9.7343747" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="file-icon-round" + transform="translate(2.046,3.0914383)" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect2270" + width="14" + height="18" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@2x.png Binary files differnew file mode 100644 index 0000000000..86af70d1cf --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@3x.png Binary files differnew file mode 100644 index 0000000000..06fea29ed0 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@4x.png Binary files differnew file mode 100644 index 0000000000..09f8787314 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-round@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.png Binary files differnew file mode 100644 index 0000000000..9e8f3ddd8f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.svg new file mode 100644 index 0000000000..107afa385e --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square.svg @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="14" + height="18" + viewBox="0 0 14 18" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="file-icon-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.5004095,1.5063148 1.5,16.5 h 11 V 5.3440001 L 8.5,1.5 Z" + id="path917" + sodipodi:nodetypes="cccccc" /> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 8.5,1.55 V 5.5" + id="path919" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 12.45,5.5 H 8.5" + id="path921" + sodipodi:nodetypes="cc" /> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="22.627417" + inkscape:cx="0.022097087" + inkscape:cy="8.1538251" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="file-icon-square" + transform="translate(2.046,3.0914383)" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1895" + width="14" + height="18" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@2x.png Binary files differnew file mode 100644 index 0000000000..8d33067744 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@3x.png Binary files differnew file mode 100644 index 0000000000..2987d2caed --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@4x.png Binary files differnew file mode 100644 index 0000000000..69d76176e9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/file-icon-square@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.png Binary files differnew file mode 100644 index 0000000000..60bc6c72c1 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.svg new file mode 100644 index 0000000000..ba6b627644 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round.svg @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="18" + height="14" + viewBox="0 0 18 14" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="folder-icon-round.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.5003723,2.5063148 1.5000372,11.5 A 0.99996275,0.99996275 45.001067 0 0 2.5,12.5 h 13 a 1,1 135 0 0 1,-1 v -7 a 1,1 45 0 0 -1,-1 h -5 A 2.4142136,2.4142136 22.5 0 1 8.7928932,2.7928932 L 8.2071068,2.2071068 A 2.4106245,2.4106245 22.469847 0 0 6.5000006,1.5010525 l -3.9995917,0.00421 A 1.0010904,1.0010904 134.97091 0 0 1.5003723,2.5063148 Z" + id="path917" + sodipodi:nodetypes="ccccccc" + inkscape:path-effect="#path-effect1132" + inkscape:original-d="M 1.5004095,1.5063148 1.5,12.5 h 15 v -9 h -7 l -2,-2 z" /> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8"> + <inkscape:path-effect + effect="fillet_chamfer" + id="path-effect1132" + is_visible="true" + lpeversion="1" + satellites_param="F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1 @ F,0,0,1,0,1,0,1" + unit="px" + method="auto" + mode="F" + radius="1" + chamfer_steps="1" + flexible="false" + use_knot_distance="true" + apply_no_radius="true" + apply_with_radius="true" + only_selected="false" + hide_knots="false" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="16" + inkscape:cx="-11.28125" + inkscape:cy="7.40625" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="folder-icon-round" + transform="translate(2.046,3.0914383)" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect2548" + width="18" + height="14" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@2x.png Binary files differnew file mode 100644 index 0000000000..e28734374f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@3x.png Binary files differnew file mode 100644 index 0000000000..5ee70a955e --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@4x.png Binary files differnew file mode 100644 index 0000000000..47d28a4b75 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-round@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.png Binary files differnew file mode 100644 index 0000000000..b84a90aecb --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.svg new file mode 100644 index 0000000000..0002b5ac8e --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square.svg @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="18" + height="14" + viewBox="0 0 18 14" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="folder-icon-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <path + style="fill:none;stroke:#757575;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 1.5004095,1.5063148 1.5,12.5 h 15 v -9 h -7 l -2,-2 z" + id="path917" + sodipodi:nodetypes="ccccccc" /> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="16" + inkscape:cx="-1.59375" + inkscape:cy="12.65625" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid856" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="folder-icon-square" + transform="translate(2.046,3.0914383)"> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1423" + width="18" + height="14" + x="-2.046" + y="-3.0914383" /> + </g> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@2x.png Binary files differnew file mode 100644 index 0000000000..9bf320bbf0 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@3x.png Binary files differnew file mode 100644 index 0000000000..9f12edb6ee --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@4x.png Binary files differnew file mode 100644 index 0000000000..9ec5b389bd --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/folder-icon-square@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled.9.png Binary files differnew file mode 100644 index 0000000000..ce48ee7422 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@2x.9.png Binary files differnew file mode 100644 index 0000000000..c7abb65c3f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@2x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@3x.9.png Binary files differnew file mode 100644 index 0000000000..46b84d7da4 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@3x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@4x.9.png Binary files differnew file mode 100644 index 0000000000..f4dfd338f9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-disabled@4x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused.9.png Binary files differnew file mode 100644 index 0000000000..39fa866442 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@2x.9.png Binary files differnew file mode 100644 index 0000000000..6b61562c14 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@2x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@3x.9.png Binary files differnew file mode 100644 index 0000000000..e46c0bf1d9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@3x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@4x.9.png Binary files differnew file mode 100644 index 0000000000..010444e8e1 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-focused@4x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted.9.png Binary files differnew file mode 100644 index 0000000000..6f565e8be2 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@2x.9.png Binary files differnew file mode 100644 index 0000000000..9fd0a434bb --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@2x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@3x.9.png Binary files differnew file mode 100644 index 0000000000..62b7435b84 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@3x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@4x.9.png Binary files differnew file mode 100644 index 0000000000..96444b8905 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-highlighted@4x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed.9.png Binary files differnew file mode 100644 index 0000000000..39fa866442 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@2x.9.png Binary files differnew file mode 100644 index 0000000000..6b61562c14 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@2x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@3x.9.png Binary files differnew file mode 100644 index 0000000000..e46c0bf1d9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@3x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@4x.9.png Binary files differnew file mode 100644 index 0000000000..010444e8e1 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background-pressed@4x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.9.png Binary files differnew file mode 100644 index 0000000000..cef1bafab3 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.svg new file mode 100644 index 0000000000..acecfcc9ac --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background.svg @@ -0,0 +1,358 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg5" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="filedialogdelegate-background.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata122"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + id="namedview7" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + objecttolerance="10.0" + gridtolerance="10.0" + guidetolerance="10.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:document-units="px" + showgrid="false" + inkscape:zoom="3.2715084" + inkscape:cx="24.912056" + inkscape:cy="54.867657" + inkscape:window-width="1848" + inkscape:window-height="1016" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="g1413" + showguides="true" + inkscape:guide-bbox="true" + inkscape:document-rotation="0"> + <sodipodi:guide + position="6.0854167,296.96676" + orientation="-1,0" + id="guide2310" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="3.363578,293.03125" + orientation="0,1" + id="guide2322" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="12.170833,297.68429" + orientation="-1,0" + id="guide2760" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="18.25625,297.91758" + orientation="-1,0" + id="guide949" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="24.341667,299.40187" + orientation="-1,0" + id="guide941" + inkscape:label="" + inkscape:locked="true" + inkscape:color="rgb(0,0,255)" /> + <sodipodi:guide + position="30.427083,299.08734" + orientation="-1,0" + id="guide1165" + inkscape:label="" + inkscape:locked="false" + inkscape:color="rgb(0,0,255)" /> + </sodipodi:namedview> + <defs + id="defs2" /> + <g + inkscape:label="[9] filedialogdelegate-background-highlighted" + inkscape:groupmode="layer" + id="g1413" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect1401" + width="6.0854168" + height="3.96875" + x="30.427084" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect1403" + width="0.26458332" + height="3.4395833" + x="30.427084" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect1405" + width="0.26458332" + height="5.5562401" + x="-0.26415125" + y="30.691679" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect1407" + width="0.26458332" + height="0.26458287" + x="-3.9588995" + y="33.337505" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect1409" + width="0.26458332" + height="0.26458287" + x="-2.1059568" + y="36.247913" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#4fc1e9;fill-opacity:1;fill-rule:evenodd;stroke-width:0.263352" + id="rect1411" + width="5.5562501" + height="3.4395833" + x="30.691668" + y="0.26458332" /> + </g> + <g + inkscape:label="[9] filedialogdelegate-background-focused" + inkscape:groupmode="layer" + id="g939" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect927" + width="6.0854168" + height="3.96875" + x="18.25625" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect929" + width="0.26458332" + height="3.4395833" + x="18.25625" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect931" + width="0.26458332" + height="5.5562401" + x="-0.26432261" + y="18.520845" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect933" + width="0.26458332" + height="0.26458287" + x="-3.9624968" + y="21.166674" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect935" + width="0.26458332" + height="0.26458287" + x="-2.1095541" + y="24.077082" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#e6e9ed;fill-opacity:1;fill-rule:evenodd;stroke-width:0.263352" + id="rect937" + width="5.5562501" + height="3.4395833" + x="18.520834" + y="0.26458332" /> + </g> + <g + inkscape:label="[9] filedialogdelegate-background-pressed" + inkscape:groupmode="layer" + id="g867" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect855" + width="6.0854168" + height="3.96875" + x="12.170834" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect857" + width="0.26458332" + height="3.4395833" + x="12.170834" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect859" + width="0.26458332" + height="5.5562401" + x="-0.26440823" + y="12.435429" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect861" + width="0.26458332" + height="0.26458287" + x="-3.9642947" + y="15.081257" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect863" + width="0.26458332" + height="0.26458287" + x="-2.111352" + y="17.991665" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#e6e9ed;fill-opacity:1;fill-rule:evenodd;stroke-width:0.263352" + id="rect865" + width="5.5562501" + height="3.4395833" + x="12.435416" + y="0.26458332" /> + </g> + <g + inkscape:label="[9] filedialogdelegate-background-disabled" + inkscape:groupmode="layer" + id="g2435" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect2425" + width="6.0854168" + height="3.96875" + x="6.0854168" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect2427" + width="0.26458332" + height="3.4395833" + x="6.0854168" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect2429" + width="0.26458332" + height="5.5562401" + x="-0.264494" + y="6.3500099" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect2431" + width="0.26458332" + height="0.26458287" + x="-3.9660921" + y="8.995841" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect2433" + width="0.26458332" + height="0.26458287" + x="-2.1131494" + y="11.906255" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#f5f7fa;fill-opacity:1;fill-rule:evenodd;stroke-width:0.263352" + id="rect124" + width="5.5562501" + height="3.4395833" + x="6.3499999" + y="0.26458332" /> + </g> + <g + inkscape:label="[9] filedialogdelegate-background" + inkscape:groupmode="layer" + id="layer1" + style="display:inline" + sodipodi:insensitive="true"> + <rect + style="fill:none;stroke-width:0.946642;stroke-linejoin:round" + id="rect846" + width="6.0854168" + height="3.96875" + x="0" + y="-6.9388939e-18" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:7.98967;stroke-linejoin:round" + id="rect1054" + width="0.26458332" + height="3.4395833" + x="0" + y="0.26458332" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:10.1547;stroke-linejoin:round" + id="rect1212" + width="0.26458332" + height="5.5562401" + x="-0.26457959" + y="0.26459303" + transform="matrix(3.6708238e-5,-1,1,1.4067378e-5,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect1505" + width="0.26458332" + height="0.26458287" + x="-3.9678898" + y="2.9104238" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.21594;stroke-linejoin:round" + id="rect1587" + width="0.26458332" + height="0.26458287" + x="-2.1149471" + y="5.8208375" + transform="matrix(1.7480114e-6,-1,0.99999996,2.9541491e-4,0,0)" /> + <rect + style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.0578;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect3108" + width="5.5562501" + height="3.4395833" + x="0.26458332" + y="0.26458332" /> + </g> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@2x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@2x.9.png Binary files differnew file mode 100644 index 0000000000..5a136a0ca9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@2x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@3x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@3x.9.png Binary files differnew file mode 100644 index 0000000000..f47a366b7b --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@3x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@4x.9.png b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@4x.9.png Binary files differnew file mode 100644 index 0000000000..9ecb680f20 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/imagine/filedialogdelegate-background@4x.9.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.png Binary files differnew file mode 100644 index 0000000000..a4b7bc0383 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.svg new file mode 100644 index 0000000000..fd05395798 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round.svg @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + viewBox="0 0 16 16" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="up-icon-round.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="16" + inkscape:cx="-1.96875" + inkscape:cy="10.65625" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid1497" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="up-icon-round" /> + <g + id="g1413" + transform="translate(0.3592822,-0.0034197)"> + <path + style="fill:none;fill-opacity:1;stroke:#757575;stroke-width:2.23721;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 7.6407178,2.1165354 3e-7,11.7737686" + id="path20" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-opacity:1;stroke:#757575;stroke-width:2.23721;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 7.6407178,2.1165354 2.6616436,7.0956099" + id="path950" + sodipodi:nodetypes="cc" /> + <path + style="fill:none;fill-opacity:1;stroke:#757575;stroke-width:2.23721;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 7.6407178,2.1165354 12.619792,7.0956096" + id="path952" + sodipodi:nodetypes="cc" /> + </g> + <rect + style="fill:none;stroke-width:5.33333;stroke-linejoin:round" + id="rect2897" + width="16" + height="16" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@2x.png Binary files differnew file mode 100644 index 0000000000..25ee970a17 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@3x.png Binary files differnew file mode 100644 index 0000000000..486f2f46a9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@4x.png Binary files differnew file mode 100644 index 0000000000..585402531c --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-round@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.png Binary files differnew file mode 100644 index 0000000000..f7d4151a5a --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.svg new file mode 100644 index 0000000000..93fc45bae4 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square.svg @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + viewBox="0 0 16 16" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="up-icon-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="11.313709" + inkscape:cx="-6.3197669" + inkscape:cy="28.416854" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid1497" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="up-icon-square" /> + <path + style="fill:#757575;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 8.000315,1 -6,6 L 3,8 8,3 13,8 14,7 Z" + id="path928" + sodipodi:nodetypes="ccccccc" /> + <rect + style="fill:none;stroke-width:5.33333;stroke-linejoin:round" + id="rect2897" + width="16" + height="16" + x="0" + y="0" /> + <rect + style="fill:#757575;fill-opacity:1;stroke:none;stroke-width:5.23075;stroke-linejoin:round" + id="rect4947" + width="1.5" + height="11" + x="7.2501574" + y="3" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@2x.png Binary files differnew file mode 100644 index 0000000000..2e2a3d94eb --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@3x.png Binary files differnew file mode 100644 index 0000000000..8965148c90 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@4x.png Binary files differnew file mode 100644 index 0000000000..0a56bbcc0a --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-square@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.png Binary files differnew file mode 100644 index 0000000000..3f9f87624a --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.svg b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.svg new file mode 100644 index 0000000000..dd20777be7 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square.svg @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + viewBox="0 0 16 16" + version="1.1" + id="svg2" + inkscape:version="1.1-alpha (b0f32e08fc, 2021-03-07)" + sodipodi:docname="up-icon-thick-square.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1848" + inkscape:window-height="1016" + id="namedview6" + showgrid="true" + inkscape:zoom="22.627417" + inkscape:cx="2.3201941" + inkscape:cy="10.00998" + inkscape:window-x="72" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + inkscape:document-rotation="0" + inkscape:pagecheckerboard="0"> + <inkscape:grid + type="xygrid" + id="grid1497" /> + </sodipodi:namedview> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="up-icon-thick-square" /> + <path + style="fill:#757575;fill-opacity:1;stroke:none;stroke-width:1.34164px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 2,8 6,-6 6,6 h -3 v 7 H 5 V 8 Z" + id="path1103" + sodipodi:nodetypes="cccccccc" /> + <rect + style="fill:none;stroke-width:4;stroke-linejoin:round" + id="rect1748" + width="16" + height="16" + x="0" + y="0" /> +</svg> diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@2x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@2x.png Binary files differnew file mode 100644 index 0000000000..b4efe13228 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@2x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@3x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@3x.png Binary files differnew file mode 100644 index 0000000000..2e8302b1f0 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@3x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@4x.png b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@4x.png Binary files differnew file mode 100644 index 0000000000..5cf05ab305 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/images/up-icon-thick-square@4x.png diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml new file mode 100644 index 0000000000..cf2a0a32c5 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialog.qml @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 6 + horizontalPadding: 12 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + /* + We use attached properties because we want to handle logic in C++, and: + - We can't assume the footer only contains a DialogButtonBox (which would allow us + to connect up to it in QQuickFileDialogImpl); it also needs to hold a ComboBox + and therefore the root footer item will be e.g. a layout item instead. + - We don't want to create our own "FileDialogButtonBox" (in order to be able to handle the logic + in C++) because we'd need to copy (and hence duplicate code in) DialogButtonBox.qml. + */ + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.mid + radius: 2 + + Rectangle { + z: -1 + x: 1 + y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + radius: 2 + } + } + + header: ColumnLayout { + spacing: 0 + + Label { + objectName: "dialogTitleBarLabel" + text: control.title + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + padding: 6 + + Layout.fillWidth: true + Layout.leftMargin: 12 + Layout.rightMargin: 12 + Layout.topMargin: control.title.length > 0 ? 0 : 12 + Layout.preferredHeight: control.title.length > 0 ? implicitHeight : 0 + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + fileDialog: control + + Layout.fillWidth: true + Layout.leftMargin: 12 + Layout.rightMargin: 12 + + KeyNavigation.tab: fileDialogListView + } + } + + contentItem: Frame { + padding: 0 + verticalPadding: 1 + + ListView { + id: fileDialogListView + objectName: "fileDialogListView" + anchors.fill: parent + clip: true + focus: true + boundsBehavior: Flickable.StopAtBounds + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + x: 1 + width: ListView.view.width - 2 + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + + KeyNavigation.backtab: breadcrumbBar + KeyNavigation.tab: nameFiltersComboBox + } + } + } + + footer: RowLayout { + id: rowLayout + spacing: 12 + + ComboBox { + // OK to use IDs here, since users shouldn't be overriding this stuff. + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 12 + Layout.fillWidth: true + Layout.bottomMargin: 12 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 6 + horizontalPadding: 0 + verticalPadding: 0 + background: null + + Layout.rightMargin: 12 + Layout.bottomMargin: 12 + } + } + + T.Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + T.Overlay.modeless: Rectangle { + color: Fusion.topShadow + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialogDelegate.qml new file mode 100644 index 0000000000..3c2b7b9c3c --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FileDialogDelegate.qml @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl as ControlsImpl +import QtQuick.Controls.Fusion +import QtQuick.Controls.Fusion.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 6 + spacing: 6 + + file: fileUrl + + icon.width: 16 + icon.height: 16 + icon.color: highlighted ? palette.highlightedText : palette.text + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-round.png" + + // We don't use index here, but in C++. Since we're using required + // properties, the index context property will not be injected, so we can't + // use its QQmlContext to access it. + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.highlighted ? Fusion.highlightedText(control.palette) : control.palette.text + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 20 + color: control.down ? Fusion.buttonColor(control.palette, false, true, true) + : control.highlighted ? Fusion.highlight(control.palette) : control.palette.base + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FolderBreadcrumbBar.qml new file mode 100644 index 0000000000..df8a466881 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FolderBreadcrumbBar.qml @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 6 + + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + + Rectangle { + anchors.fill: parent + color: control.palette.light + border.color: control.palette.mid + radius: 2 + z: -1 + } + } + buttonDelegate: Button { + id: buttonDelegateRoot + text: folderName + flat: true + + // The default of 100 is a bit too wide for short directory names. + Binding { + target: buttonDelegateRoot.background + property: "implicitWidth" + value: 24 + } + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-round.png" + sourceSize: Qt.size(8, 8) + width: 8 + 6 + height: control.contentItem.height + color: control.palette.dark + y: (control.height - height) / 2 + } + upButton: Button { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-round.png" + icon.width: 16 + icon.height: 16 + width: height + height: Math.max(implicitHeight, control.contentItem.height) + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml new file mode 100644 index 0000000000..dd75338f21 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(control.implicitBackgroundWidth + control.leftInset + control.rightInset, + control.contentWidth + control.leftPadding + control.rightPadding, + control.implicitHeaderWidth, + control.implicitFooterWidth) + implicitHeight: Math.max(control.implicitBackgroundHeight + control.topInset + control.bottomInset, + control.contentHeight + control.topPadding + control.bottomPadding + + (control.implicitHeaderHeight > 0 ? control.implicitHeaderHeight + control.spacing : 0) + + (control.implicitFooterHeight > 0 ? control.implicitFooterHeight + control.spacing : 0)) + + leftPadding: 20 + rightPadding: 20 + // Ensure that the background's border is visible. + leftInset: -1 + rightInset: -1 + topInset: -1 + bottomInset: -1 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.mid + radius: 2 + + Rectangle { + z: -1 + x: 1 + y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + radius: 2 + } + } + + Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + Overlay.modeless: Rectangle { + color: Fusion.topShadow + } + + header: Label { + text: control.title + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + padding: 6 + } + + contentItem: FontDialogContent { + id: content + } + + footer: RowLayout { + id: rowLayout + spacing: 12 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 12 + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 6 + horizontalPadding: 0 + verticalPadding: 0 + background: null + + Layout.rightMargin: 12 + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml new file mode 100644 index 0000000000..9509664df6 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialog.qml @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Templates as T +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + // Can't set implicitWidth of the NinePatchImage background, so we do it here. + implicitWidth: Math.max(600, + implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(400, + implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: NinePatchImage { + source: Imagine.url + "dialog-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + + header: ColumnLayout { + spacing: 12 + + Label { + text: control.title + elide: Label.ElideRight + font.bold: true + + Layout.leftMargin: 16 + Layout.rightMargin: 16 + Layout.topMargin: 12 + Layout.fillWidth: true + Layout.preferredHeight: control.title.length > 0 ? implicitHeight : 0 + + background: NinePatchImage { + width: parent.width + height: parent.height + + source: Imagine.url + "dialog-title" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + fileDialog: control + + Layout.leftMargin: 16 + Layout.rightMargin: 16 + Layout.fillWidth: true + Layout.maximumWidth: parent.width - 28 + } + } + + contentItem: ListView { + id: fileDialogListView + objectName: "fileDialogListView" + clip: true + boundsBehavior: Flickable.StopAtBounds + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + width: ListView.view.width + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + } + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + ComboBox { + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 16 + Layout.bottomMargin: 16 + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + + Layout.bottomMargin: 16 + Layout.rightMargin: 16 + } + } + + T.Overlay.modal: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + T.Overlay.modeless: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialogDelegate.qml new file mode 100644 index 0000000000..832f851cca --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FileDialogDelegate.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick.Controls +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl +import QtQuick.Controls.impl as ControlsImpl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + file: fileUrl + + icon.width: 16 + icon.height: 16 + icon.color: highlighted ? palette.highlightedText : palette.text + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-round.png" + + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.icon.color + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: NinePatchImage { + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/imagine/filedialogdelegate-background" + NinePatchImageSelector on source { + states: [ + { "disabled": !control.enabled }, + { "pressed": control.down }, + { "focused": control.visualFocus }, + { "highlighted": control.highlighted }, + { "mirrored": control.mirrored }, + { "hovered": control.enabled && control.hovered } + ] + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FolderBreadcrumbBar.qml new file mode 100644 index 0000000000..30e0586740 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FolderBreadcrumbBar.qml @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 20 + padding: 1 + + background: Rectangle {} + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + } + buttonDelegate: Button { + id: buttonDelegateRoot + text: folderName + flat: true + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-round.png" + sourceSize: Qt.size(8, 8) + width: 8 + height: control.contentItem.height + y: (control.height - height) / 2 + } + upButton: ToolButton { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-thick-square.png" + icon.width: 16 + icon.height: 16 + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml new file mode 100644 index 0000000000..47bd53dafc --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + // Can't set implicitWidth of the NinePatchImage background, so we do it here. + implicitWidth: Math.max(600, + implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(400, + implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: NinePatchImage { + source: Imagine.url + "dialog-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + + Overlay.modal: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + Overlay.modeless: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } + + header: Label { + text: control.title + elide: Label.ElideRight + font.bold: true + + leftPadding: 16 + rightPadding: 16 + topPadding: 12 + height: control.title.length > 0 ? implicitHeight : 0 + + background: NinePatchImage { + width: parent.width + height: parent.height + + source: Imagine.url + "dialog-title" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + } + + contentItem: FontDialogContent { + id: content + rowSpacing: 16 + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + Label { + text: qsTr("Writing System") + Layout.leftMargin: 20 + Layout.bottomMargin: 16 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.bottomMargin: 16 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + Layout.rightMargin: 20 + Layout.bottomMargin: 16 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml new file mode 100644 index 0000000000..de4a9d6f44 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialog.qml @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + leftPadding: 24 + rightPadding: 24 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + Material.elevation: 24 + + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + radius: 2 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + header: ColumnLayout { + spacing: 12 + + Label { + text: control.title + visible: control.title.length > 0 + elide: Label.ElideRight + font.bold: true + font.pixelSize: 16 + + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.topMargin: 24 + Layout.fillWidth: true + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + fileDialog: control + + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.fillWidth: true + Layout.maximumWidth: parent.width - 48 + } + } + + contentItem: ListView { + id: fileDialogListView + objectName: "fileDialogListView" + clip: true + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + width: ListView.view.width + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + } + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + ComboBox { + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 20 + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialogDelegate.qml new file mode 100644 index 0000000000..eb4bae9bfc --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FileDialogDelegate.qml @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 16 + verticalPadding: 8 + spacing: 16 + + icon.width: 16 + icon.height: 16 + icon.color: enabled ? Material.foreground : Material.hintTextColor + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-square.png" + + file: fileUrl + + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.Material.hintTextColor + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: Rectangle { + implicitHeight: control.Material.delegateHeight + + color: control.highlighted ? Color.transparent(control.Material.accentColor, 0.08) : "transparent" + + Ripple { + width: parent.width + height: parent.height + + clip: visible + pressed: control.pressed + anchor: control + active: control.down || control.visualFocus || control.hovered + color: control.highlighted ? control.Material.highlightedRippleColor : control.Material.rippleColor + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FolderBreadcrumbBar.qml new file mode 100644 index 0000000000..5ac638a07d --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FolderBreadcrumbBar.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 20 + padding: 1 + + background: Rectangle {} + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + } + buttonDelegate: Button { + id: buttonDelegateRoot + text: folderName + flat: true + font.capitalization: Font.MixedCase + + // The default of 100 is a bit too wide for short directory names. + Binding { + target: buttonDelegateRoot.background + property: "implicitWidth" + value: control.Material.buttonHeight + } + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-square.png" + sourceSize: Qt.size(8, 8) + // The image is 8x8, and add 2 px padding on each side. + width: 8 + 4 + height: control.contentItem.height + color: control.Material.hintTextColor + y: (control.height - height) / 2 + } + upButton: ToolButton { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-thick-square.png" + icon.width: 16 + icon.height: 16 + width: height + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml new file mode 100644 index 0000000000..5113468012 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + leftPadding: 24 + rightPadding: 24 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + Material.elevation: 24 + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + radius: 2 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } + + header: Label { + text: control.title + visible: control.title.length > 0 + elide: Label.ElideRight + font.bold: true + font.pixelSize: 16 + + leftPadding: 24 + rightPadding: 24 + topPadding: 24 + bottomPadding: 24 + } + + contentItem: FontDialogContent { + id: content + familyEdit.bottomPadding: 8 + styleEdit.bottomPadding: 8 + sizeEdit.bottomPadding: 8 + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 20 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml new file mode 100644 index 0000000000..7bcb4629d0 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialog.qml @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Universal +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 24 + verticalPadding: 18 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + + header: ColumnLayout { + spacing: 12 + + Label { + text: control.title + elide: Label.ElideRight + // TODO: QPlatformTheme::TitleBarFont + font.pixelSize: 20 + + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.topMargin: 18 + Layout.fillWidth: true + Layout.preferredHeight: control.title.length > 0 ? implicitHeight : 0 + + background: Rectangle { + x: 1; y: 1 // // FlyoutBorderThemeThickness + color: control.Universal.chromeMediumLowColor + width: parent.width - 2 + height: parent.height - 1 + } + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + fileDialog: control + + Layout.leftMargin: 24 + Layout.rightMargin: 24 + Layout.fillWidth: true + Layout.maximumWidth: parent.width - 48 + } + } + + contentItem: ListView { + id: fileDialogListView + objectName: "fileDialogListView" + clip: true + boundsBehavior: Flickable.StopAtBounds + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + width: ListView.view.width + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + } + } + + footer: RowLayout { + id: rowLayout + spacing: 24 + + ComboBox { + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 24 + Layout.fillWidth: true + Layout.topMargin: 6 + Layout.bottomMargin: 24 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + + Layout.rightMargin: 24 + } + } + + T.Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + T.Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialogDelegate.qml new file mode 100644 index 0000000000..d4322dc5fa --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FileDialogDelegate.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + spacing: 12 + + padding: 12 + topPadding: padding - 1 + bottomPadding: padding + 1 + + icon.width: 20 + icon.height: 20 + icon.color: Color.transparent(Universal.foreground, enabled ? 1.0 : 0.2) + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-square.png" + + file: fileUrl + + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.icon.color + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: Rectangle { + visible: control.down || control.highlighted || control.visualFocus || control.hovered + color: control.down ? control.Universal.listMediumColor : + control.hovered ? control.Universal.listLowColor : control.Universal.altMediumLowColor + + Rectangle { + width: parent.width + height: parent.height + visible: control.visualFocus || control.highlighted + color: control.Universal.accent + opacity: control.Universal.theme === Universal.Light ? 0.4 : 0.6 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FolderBreadcrumbBar.qml new file mode 100644 index 0000000000..1554b40a6f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FolderBreadcrumbBar.qml @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 20 + padding: 1 + + background: Rectangle {} + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + } + buttonDelegate: ToolButton { + id: buttonDelegateRoot + text: folderName + + // The default is a bit too wide for short directory names. + Binding { + target: buttonDelegateRoot.background + property: "implicitWidth" + value: 48 + } + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-square.png" + sourceSize: Qt.size(8, 8) + // The image is 8x8, and add 2 px padding on each side. + width: 8 + 4 + height: control.contentItem.height + color: Color.transparent(control.Universal.foreground, enabled ? 1.0 : 0.2) + y: (control.height - height) / 2 + } + upButton: ToolButton { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-square.png" + icon.width: 16 + icon.height: 16 + width: height + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml new file mode 100644 index 0000000000..1bd3092e6b --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 24 + verticalPadding: 18 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + + Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } + + header: Label { + text: control.title + elide: Label.ElideRight + // TODO: QPlatformTheme::TitleBarFont + font.pixelSize: 20 + + leftPadding: 24 + rightPadding: 24 + topPadding: 18 + height: control.title.length > 0 ? implicitHeight : 0 + + background: Rectangle { + x: 1; y: 1 // // FlyoutBorderThemeThickness + color: control.Universal.chromeMediumLowColor + width: parent.width - 2 + height: parent.height - 1 + } + } + + contentItem: FontDialogContent { + id: content + rowSpacing: 12 + } + + footer: RowLayout { + id: rowLayout + spacing: 24 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 24 + Layout.topMargin: 6 + Layout.bottomMargin: 24 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.topMargin: 6 + Layout.bottomMargin: 24 + + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + + Layout.rightMargin: 24 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml new file mode 100644 index 0000000000..5659190477 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialog.qml @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt.labs.folderlistmodel +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +import "." as DialogsImpl + +FileDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + leftPadding: 20 + rightPadding: 20 + // Ensure that the background's border is visible. + leftInset: -1 + rightInset: -1 + topInset: -1 + bottomInset: -1 + + standardButtons: T.Dialog.Open | T.Dialog.Cancel + + /* + We use attached properties because we want to handle logic in C++, and: + - We can't assume the footer only contains a DialogButtonBox (which would allow us + to connect up to it in QQuickFileDialogImpl); it also needs to hold a ComboBox + and therefore the root footer item will be e.g. a layout item instead. + - We don't want to create our own "FileDialogButtonBox" (in order to be able to handle the logic + in C++) because we'd need to copy (and hence duplicate code in) DialogButtonBox.qml. + */ + FileDialogImpl.buttonBox: buttonBox + FileDialogImpl.nameFiltersComboBox: nameFiltersComboBox + FileDialogImpl.fileDialogListView: fileDialogListView + FileDialogImpl.breadcrumbBar: breadcrumbBar + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.dark + } + + header: Pane { + palette.window: control.palette.light + padding: 20 + + contentItem: Column { + spacing: 12 + + Label { + objectName: "dialogTitleBarLabel" + width: parent.width + text: control.title + visible: control.title.length > 0 + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + } + + DialogsImpl.FolderBreadcrumbBar { + id: breadcrumbBar + width: parent.width + fileDialog: control + + KeyNavigation.tab: fileDialogListView + } + } + } + + contentItem: ListView { + id: fileDialogListView + objectName: "fileDialogListView" + clip: true + focus: true + boundsBehavior: Flickable.StopAtBounds + + ScrollBar.vertical: ScrollBar {} + + model: FolderListModel { + folder: control.currentFolder + nameFilters: control.selectedNameFilter.globs + showDirsFirst: true + sortCaseSensitive: false + } + delegate: DialogsImpl.FileDialogDelegate { + objectName: "fileDialogDelegate" + index + width: ListView.view.width + highlighted: ListView.isCurrentItem + fileDialog: control + fileDetailRowWidth: nameFiltersComboBox.width + + KeyNavigation.backtab: breadcrumbBar + KeyNavigation.tab: nameFiltersComboBox + } + } + + footer: Rectangle { + color: control.palette.light + implicitWidth: rowLayout.implicitWidth + implicitHeight: rowLayout.implicitHeight + + RowLayout { + id: rowLayout + width: parent.width + height: parent.height + spacing: 20 + + ComboBox { + // OK to use IDs here, since users shouldn't be overriding this stuff. + id: nameFiltersComboBox + model: control.nameFilters + + Layout.leftMargin: 20 + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + palette.window: control.palette.light + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegate.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegate.qml new file mode 100644 index 0000000000..03250faa7e --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegate.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl as ControlsImpl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FileDialogDelegate { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding, + implicitIndicatorHeight + topPadding + bottomPadding) + + padding: 12 + spacing: 8 + topPadding: 0 + bottomPadding: 0 + + file: fileUrl + + icon.width: 16 + icon.height: 16 + icon.color: highlighted ? palette.highlightedText : palette.text + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/" + + (fileIsDir ? "folder" : "file") + "-icon-round.png" + + // We don't use index here, but in C++. Since we're using required + // properties, the index context property will not be injected, so we can't + // use its QQmlContext to access it. + required property int index + required property string fileName + required property url fileUrl + required property int fileSize + required property date fileModified + required property bool fileIsDir + + required property int fileDetailRowWidth + + contentItem: FileDialogDelegateLabel { + delegate: control + fileDetailRowTextColor: control.icon.color + fileDetailRowWidth: control.fileDetailRowWidth + } + + background: Rectangle { + implicitWidth: 100 + implicitHeight: 40 + visible: control.down || control.highlighted || control.visualFocus + color: Color.blend(control.down ? control.palette.midlight : control.palette.light, + control.palette.highlight, control.highlighted ? 0.15 : 0.0) + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegateLabel.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegateLabel.qml new file mode 100644 index 0000000000..9768cd51f0 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FileDialogDelegateLabel.qml @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +/* + Most of the elements in here are the same between styles, so we + have a reusable component for it and provide some properties to enable style-specific tweaks. +*/ +Item { + id: root + implicitWidth: column.implicitWidth + implicitHeight: column.implicitHeight + + required property DialogsQuickImpl.FileDialogDelegate delegate + required property int fileDetailRowWidth + + property color fileDetailRowTextColor + + Column { + id: column + y: (parent.height - height) / 2 + + Row { + spacing: root.delegate.spacing + + IconImage { + id: iconImage + source: root.delegate.icon.source + sourceSize: Qt.size(root.delegate.icon.width, root.delegate.icon.height) + width: root.delegate.icon.width + height: root.delegate.icon.height + color: root.delegate.icon.color + y: (parent.height - height) / 2 + } + Label { + text: root.delegate.fileName + color: root.delegate.icon.color + y: (parent.height - height) / 2 + } + } + + Item { + id: fileDetailRow + x: iconImage.width + root.delegate.spacing + width: fileDetailRowWidth - x - root.delegate.leftPadding + implicitHeight: childrenRect.height + + Label { + text: locale.formattedDataSize(root.delegate.fileSize) + font.pixelSize: root.delegate.font.pixelSize * 0.75 + color: root.fileDetailRowTextColor + } + Label { + text: Qt.formatDateTime(root.delegate.fileModified) + font.pixelSize: root.delegate.font.pixelSize * 0.75 + color: root.fileDetailRowTextColor + x: parent.width - width + } + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FolderBreadcrumbBar.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FolderBreadcrumbBar.qml new file mode 100644 index 0000000000..a1697c8fe2 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FolderBreadcrumbBar.qml @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs.quickimpl as DialogsQuickImpl + +DialogsQuickImpl.FolderBreadcrumbBar { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + (upButton ? upButton.implicitWidth + upButtonSpacing : 0) + + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + upButtonSpacing: 20 + padding: 1 + + background: Rectangle { + border.color: control.palette.button + } + contentItem: ListView { + currentIndex: control.currentIndex + model: control.contentModel + orientation: ListView.Horizontal + snapMode: ListView.SnapToItem + highlightMoveDuration: 0 + interactive: false + clip: true + } + buttonDelegate: Button { + id: buttonDelegateRoot + text: folderName + flat: true + + // The default of 100 is a bit too wide for short directory names. + Binding { + target: buttonDelegateRoot.background + property: "implicitWidth" + value: 40 + } + + required property int index + required property string folderName + } + separatorDelegate: IconImage { + id: iconImage + source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/crumb-separator-icon-round.png" + sourceSize: Qt.size(8, 8) + width: 8 + height: control.contentItem.height + color: control.palette.button + y: (control.height - height) / 2 + } + upButton: ToolButton { + x: control.leftPadding + y: control.topPadding + icon.source: "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/images/up-icon-round.png" + icon.width: 16 + icon.height: 16 + width: height + focusPolicy: Qt.TabFocus + } + textField: TextField { + text: control.fileDialog.selectedFile + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml new file mode 100644 index 0000000000..e2caea4043 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(control.implicitBackgroundWidth + control.leftInset + control.rightInset, + control.contentWidth + control.leftPadding + control.rightPadding, + control.implicitHeaderWidth, + control.implicitFooterWidth) + implicitHeight: Math.max(control.implicitBackgroundHeight + control.topInset + control.bottomInset, + control.contentHeight + control.topPadding + control.bottomPadding + + (control.implicitHeaderHeight > 0 ? control.implicitHeaderHeight + control.spacing : 0) + + (control.implicitFooterHeight > 0 ? control.implicitFooterHeight + control.spacing : 0)) + + leftPadding: 20 + rightPadding: 20 + // Ensure that the background's border is visible. + leftInset: -1 + rightInset: -1 + topInset: -1 + bottomInset: -1 + + spacing: 12 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.dark + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } + + header: Pane { + palette.window: control.palette.light + padding: 20 + + contentItem: Label { + width: parent.width + text: control.title + visible: control.title.length > 0 + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + } + } + + contentItem: FontDialogContent { + id: content + } + + footer: Rectangle { + color: control.palette.light + implicitWidth: rowLayout.implicitWidth + implicitHeight: rowLayout.implicitHeight + + RowLayout { + id: rowLayout + width: parent.width + height: parent.height + spacing: 20 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 20 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + palette.window: control.palette.light + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml new file mode 100644 index 0000000000..f0d5020adf --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts + +GridLayout { + property alias familyListView: fontFamilyListView + property alias styleListView: fontStyleListView + property alias sizeListView: fontSizeListView + property alias sampleEdit: fontSample + property alias underline: fontUnderline + property alias strikeout: fontStrikeout + property alias familyEdit: fontFamilyEdit + property alias styleEdit: fontStyleEdit + property alias sizeEdit: fontSizeEdit + + columns: 3 + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 50 + + Label { + text: qsTr("Family") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontFamilyEdit + objectName: "familyEdit" + readOnly: true + Layout.fillWidth: true + focus: true + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + background: Rectangle { + color: "white" + } + ListView { + id: fontFamilyListView + objectName: "familyListView" + implicitHeight: 200 + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } + + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontFamilyListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 30 + + Label { + text: qsTr("Style") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontStyleEdit + objectName: "styleEdit" + readOnly: true + Layout.fillWidth: true + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + background: Rectangle { + color: "white" + } + ListView { + id: fontStyleListView + objectName: "styleListView" + implicitHeight: 200 + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar {} + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontStyleListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 20 + + Label { + text: qsTr("Size") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontSizeEdit + objectName: "sizeEdit" + Layout.fillWidth: true + validator: IntValidator { + bottom: 1 + top: 512 + } + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + + background: Rectangle { + color: "white" + } + ListView { + id: fontSizeListView + objectName: "sizeListView" + implicitHeight: 200 + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } + + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontSizeListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + Layout.preferredWidth: 80 + + GroupBox { + id: effectsGroupBox + title: qsTr("Effects") + + Layout.fillWidth: true + Layout.fillHeight: true + + label: Label { + anchors.left: effectsGroupBox.left + text: parent.title + } + + RowLayout { + anchors.fill: parent + CheckBox { + id: fontUnderline + objectName: "underlineEffect" + text: qsTr("Underline") + } + CheckBox{ + id: fontStrikeout + objectName: "strikeoutEffect" + text: qsTr("Strikeout") + } + } + } + } + + GroupBox { + id: sample + padding: label.implicitHeight + title: qsTr("Sample") + + Layout.fillWidth: true + Layout.preferredWidth: 80 + Layout.fillHeight: true + Layout.columnSpan: 2 + clip: true + + background: Rectangle { + y: sample.topPadding - sample.bottomPadding + width: sample.width - sample.leftPadding + sample.rightPadding + height: sample.height - sample.topPadding + sample.bottomPadding + radius: 3 + } + + label: Label { + anchors.left: sample.left + text: sample.title + } + + TextEdit { + id: fontSample + objectName: "sampleEdit" + anchors.centerIn: parent + readOnly: true + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp new file mode 100644 index 0000000000..da298432b4 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickdialogimplfactory_p.h" + +#include <QtCore/qloggingcategory.h> + +#include "qquickplatformfiledialog_p.h" +#include "qquickplatformfontdialog_p.h" + +QT_BEGIN_NAMESPACE + +/*! + \internal + + Creates concrete QML-based dialogs. +*/ + +Q_LOGGING_CATEGORY(lcQuickDialogImplFactory, "qt.quick.dialogs.quickdialogimplfactory") + +QPlatformDialogHelper *QQuickDialogImplFactory::createPlatformDialogHelper( + QPlatformTheme::DialogType type, QObject *parent) +{ + switch (type) { + case QPlatformTheme::FileDialog: { + auto dialog = new QQuickPlatformFileDialog(parent); + // If the QML file failed to load, we need to handle it gracefully. + if (!dialog->isValid()) { + delete dialog; + return nullptr; + } + + return dialog; + } + case QPlatformTheme::FontDialog: { + auto dialog = new QQuickPlatformFontDialog(parent); + + if (!dialog->isValid()) { + delete dialog; + return nullptr; + } + return dialog; + } + default: + break; + } + + return nullptr; +} + +QT_END_NAMESPACE diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory_p.h new file mode 100644 index 0000000000..54aa921f30 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory_p.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKQMLDIALOGFACTORY_P_H +#define QQUICKQMLDIALOGFACTORY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qobject.h> +#include <QtGui/qpa/qplatformtheme.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickDialogImplFactory +{ +public: + static QPlatformDialogHelper *createPlatformDialogHelper(QPlatformTheme::DialogType type, + QObject *parent); +}; + +QT_END_NAMESPACE + +#endif // QQUICKQMLDIALOGFACTORY_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate.cpp new file mode 100644 index 0000000000..b1d4477305 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate.cpp @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfiledialogdelegate_p.h" + +#include <QtCore/qfileinfo.h> +#include <QtGui/qpa/qplatformtheme.h> +#include <QtQml/QQmlFile> +#include <QtQml/qqmlexpression.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuickTemplates2/private/qquickitemdelegate_p_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileDialogDelegatePrivate : public QQuickItemDelegatePrivate +{ + Q_DECLARE_PUBLIC(QQuickFileDialogDelegate) + +public: + void highlightFile(); + void chooseFile(); + + bool acceptKeyClick(Qt::Key key) const override; + + QQuickFileDialogImpl *fileDialog = nullptr; + QUrl file; +}; + +void QQuickFileDialogDelegatePrivate::highlightFile() +{ + Q_Q(QQuickFileDialogDelegate); + QQuickListViewAttached *attached = static_cast<QQuickListViewAttached*>( + qmlAttachedPropertiesObject<QQuickListView>(q)); + if (!attached) + return; + + QQmlContext *delegateContext = qmlContext(q); + if (!delegateContext) + return; + + bool converted = false; + const int index = q->property("index").toInt(&converted); + if (converted) { + attached->view()->setCurrentIndex(index); + fileDialog->setCurrentFile(file); + } +} + +void QQuickFileDialogDelegatePrivate::chooseFile() +{ + const QFileInfo fileInfo(QQmlFile::urlToLocalFileOrQrc(file)); + if (fileInfo.isDir()) { + // If it's a directory, navigate to it. + fileDialog->setCurrentFolder(file); + } else { + // Otherwise it's a file, so select it and close the dialog. + fileDialog->setSelectedFile(file); + fileDialog->accept(); + } +} + +bool QQuickFileDialogDelegatePrivate::acceptKeyClick(Qt::Key key) const +{ + return key == Qt::Key_Return || key == Qt::Key_Enter; +} + +QQuickFileDialogDelegate::QQuickFileDialogDelegate(QQuickItem *parent) + : QQuickItemDelegate(*(new QQuickFileDialogDelegatePrivate), parent) +{ + Q_D(QQuickFileDialogDelegate); + // Clicking and tabbing should result in it getting focus, + // as e.g. Ubuntu and Windows both allow tabbing through file dialogs. + setFocusPolicy(Qt::StrongFocus); + setCheckable(true); + QObjectPrivate::connect(this, &QQuickFileDialogDelegate::clicked, + d, &QQuickFileDialogDelegatePrivate::highlightFile); + QObjectPrivate::connect(this, &QQuickFileDialogDelegate::doubleClicked, + d, &QQuickFileDialogDelegatePrivate::chooseFile); +} + +QQuickFileDialogImpl *QQuickFileDialogDelegate::fileDialog() const +{ + Q_D(const QQuickFileDialogDelegate); + return d->fileDialog; +} + +void QQuickFileDialogDelegate::setFileDialog(QQuickFileDialogImpl *fileDialog) +{ + Q_D(QQuickFileDialogDelegate); + if (fileDialog == d->fileDialog) + return; + + d->fileDialog = fileDialog; + emit fileDialogChanged(); +} + +QUrl QQuickFileDialogDelegate::file() const +{ + Q_D(const QQuickFileDialogDelegate); + return d->file; +} + +void QQuickFileDialogDelegate::setFile(const QUrl &file) +{ + Q_D(QQuickFileDialogDelegate); + if (file == d->file) + return; + + d->file = file; + emit fileChanged(); +} + +void QQuickFileDialogDelegate::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickFileDialogDelegate); + // We need to respond to being triggered by enter being pressed, + // but we can't use event->isAccepted() to check, because events are pre-accepted. + auto connection = QObjectPrivate::connect(this, &QQuickFileDialogDelegate::clicked, + d, &QQuickFileDialogDelegatePrivate::chooseFile); + + QQuickItemDelegate::keyReleaseEvent(event); + + disconnect(connection); +} + +QT_END_NAMESPACE + +#include "moc_qquickfiledialogdelegate_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate_p.h new file mode 100644 index 0000000000..093e27bdbd --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogdelegate_p.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFILEDIALOGDELEGATE_P_H +#define QQUICKFILEDIALOGDELEGATE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickitemdelegate_p.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileDialogImpl; +class QQuickFileDialogDelegatePrivate; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogDelegate : public QQuickItemDelegate +{ + Q_OBJECT + Q_PROPERTY(QQuickFileDialogImpl *fileDialog READ fileDialog WRITE setFileDialog NOTIFY fileDialogChanged) + Q_PROPERTY(QUrl file READ file WRITE setFile NOTIFY fileChanged) + QML_NAMED_ELEMENT(FileDialogDelegate) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFileDialogDelegate(QQuickItem *parent = nullptr); + + QQuickFileDialogImpl *fileDialog() const; + void setFileDialog(QQuickFileDialogImpl *fileDialog); + + QUrl file() const; + void setFile(const QUrl &file); + +Q_SIGNALS: + void fileDialogChanged(); + void fileChanged(); + +protected: + void keyReleaseEvent(QKeyEvent *event) override; + +private: + Q_DISABLE_COPY(QQuickFileDialogDelegate) + Q_DECLARE_PRIVATE(QQuickFileDialogDelegate) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFileDialogDelegate) + +#endif // QQUICKFILEDIALOGDELEGATE_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp new file mode 100644 index 0000000000..fd1ad44068 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl.cpp @@ -0,0 +1,574 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfiledialogimpl_p.h" +#include "qquickfiledialogimpl_p_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtQml/qqmlinfo.h> +#include <QtQml/qqmlfile.h> +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h> +#include <QtQuickTemplates2/private/qquickpopupitem_p_p.h> +#include "qquickfiledialogdelegate_p.h" +#include "qquickfolderbreadcrumbbar_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcCurrentFolder, "qt.quick.dialogs.quickfiledialogimpl.currentFolder") +Q_LOGGING_CATEGORY(lcOptions, "qt.quick.dialogs.quickfiledialogimpl.options") +Q_LOGGING_CATEGORY(lcNameFilters, "qt.quick.dialogs.quickfiledialogimpl.namefilters") +Q_LOGGING_CATEGORY(lcAttachedNameFilters, "qt.quick.dialogs.quickfiledialogimplattached.namefilters") + +QQuickFileDialogImplPrivate::QQuickFileDialogImplPrivate() +{ +} + +void QQuickFileDialogImplPrivate::setNameFilters(const QStringList &filters) +{ + Q_Q(QQuickFileDialogImpl); + if (filters == nameFilters) + return; + + nameFilters = filters; + emit q->nameFiltersChanged(); +} + +void QQuickFileDialogImplPrivate::updateEnabled() +{ + Q_Q(QQuickFileDialogImpl); + QQuickFileDialogImplAttached *attached = attachedOrWarn(); + if (!attached) + return; + + auto openButton = attached->buttonBox()->standardButton(QPlatformDialogHelper::Open); + if (!openButton) { + qmlWarning(q).nospace() << "Can't update Open button's enabled state because it wasn't found"; + return; + } + + openButton->setEnabled(!currentFile.isEmpty() && attached->breadcrumbBar() + && !attached->breadcrumbBar()->textField()->isVisible()); +} + +/*! + \internal + + Ensures that a file is always selected after a change in \c folder. + + \a oldFolderPath is the previous value of \c folder. +*/ +void QQuickFileDialogImplPrivate::updateCurrentFile(const QString &oldFolderPath) +{ + Q_Q(QQuickFileDialogImpl); + QQuickFileDialogImplAttached *attached = attachedOrWarn(); + if (!attached || !attached->fileDialogListView()) + return; + + QString newCurrentFilePath; + int newCurrentFileIndex = 0; + const QString newFolderPath = QQmlFile::urlToLocalFileOrQrc(currentFolder); + if (!oldFolderPath.isEmpty() && !newFolderPath.isEmpty()) { + // If the user went up a directory (or several), we should set + // currentFile to be the directory that we were in (or + // its closest ancestor that is a child of the new directory). + // E.g. if oldFolderPath is /foo/bar/baz/abc/xyz, and newFolderPath is /foo/bar, + // then we want to set currentFile to be /foo/bar/baz. + const int indexOfFolder = oldFolderPath.indexOf(newFolderPath); + if (indexOfFolder != -1) { + // [folder] + // [ oldFolderPath ] + // /foo/bar/baz/abc/xyz + // [rel...Paths] + QStringList relativePaths = oldFolderPath.mid(indexOfFolder + newFolderPath.size()).split(QLatin1Char('/'), Qt::SkipEmptyParts); + newCurrentFilePath = newFolderPath + QLatin1Char('/') + relativePaths.first(); + + // Now find the index of that directory so that we can set the ListView's currentIndex to it. + const QDir newFolderDir(newFolderPath); + // Just to be safe... + if (!newFolderDir.exists()) { + qmlWarning(q) << "Directory" << newCurrentFilePath << "doesn't exist; can't get a file entry list for it"; + return; + } + + const QFileInfoList dirs = newFolderDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::DirsFirst); + const QFileInfo newCurrentFileInfo(newCurrentFilePath); + // The directory can contain files, but since we put dirs first, that should never affect the indices. + newCurrentFileIndex = dirs.indexOf(newCurrentFileInfo); + } + } + + if (newCurrentFilePath.isEmpty()) { + // When entering into a directory that isn't a parent of the old one, the first + // file delegate should be selected. + // TODO: is there a cheaper way to do this? QDirIterator doesn't support sorting, + // so we can't use that. QQuickFolderListModel uses threads to fetch its data, + // so should be considered asynchronous. We might be able to use it, but it would + // complicate the code even more... + QDir newFolderDir(newFolderPath); + if (newFolderDir.exists()) { + const QFileInfoList files = newFolderDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::DirsFirst); + if (!files.isEmpty()) + newCurrentFilePath = files.first().absoluteFilePath(); + } + } + + if (!newCurrentFilePath.isEmpty()) { + q->setCurrentFile(QUrl::fromLocalFile(newCurrentFilePath)); + { + // Set the appropriate currentIndex for the selected file. We block signals from ListView + // because we don't want fileDialogListViewCurrentIndexChanged to be called, as the file + // it gets from the delegate will not be up-to-date (but most importantly because we already + // just set the selected file). + QSignalBlocker blocker(attached->fileDialogListView()); + attached->fileDialogListView()->setCurrentIndex(newCurrentFileIndex); + attached->fileDialogListView()->positionViewAtIndex(newCurrentFileIndex, QQuickListView::Center); + } + if (QQuickItem *currentItem = attached->fileDialogListView()->currentItem()) + currentItem->forceActiveFocus(); + } +} + +void QQuickFileDialogImplPrivate::handleAccept() +{ + // Let handleClick take care of calling accept(). +} + +void QQuickFileDialogImplPrivate::handleClick(QQuickAbstractButton *button) +{ + Q_Q(QQuickFileDialogImpl); + if (buttonRole(button) == QPlatformDialogHelper::AcceptRole && currentFile.isValid()) { + // The "Open" button was clicked, so we need to set the file to the current file, if any. + const QFileInfo fileInfo(currentFile.toLocalFile()); + if (fileInfo.isDir()) { + // If it's a directory, navigate to it. + q->setCurrentFolder(currentFile); + // Don't call accept(), because selecting a folder != accepting the dialog. + } else { + // Otherwise it's a file, so select it and close the dialog. + q->setSelectedFile(currentFile); + q->accept(); + QQuickDialogPrivate::handleClick(button); + emit q->fileSelected(currentFile); + } + } +} + +QQuickFileDialogImpl::QQuickFileDialogImpl(QObject *parent) + : QQuickDialog(*(new QQuickFileDialogImplPrivate), parent) +{ +} + +QQuickFileDialogImplAttached *QQuickFileDialogImpl::qmlAttachedProperties(QObject *object) +{ + return new QQuickFileDialogImplAttached(object); +} + +QUrl QQuickFileDialogImpl::currentFolder() const +{ + Q_D(const QQuickFileDialogImpl); + return d->currentFolder; +} + +void QQuickFileDialogImpl::setCurrentFolder(const QUrl ¤tFolder) +{ + qCDebug(lcCurrentFolder) << "setCurrentFolder called with" << currentFolder; + Q_D(QQuickFileDialogImpl); + if (currentFolder == d->currentFolder) + return; + + const QString oldFolderPath = QQmlFile::urlToLocalFileOrQrc(d->currentFolder); + + d->currentFolder = currentFolder; + // Since the directory changed, the old file can no longer be selected. + setCurrentFile(QUrl()); + d->updateCurrentFile(oldFolderPath); + emit currentFolderChanged(d->currentFolder); +} + +QUrl QQuickFileDialogImpl::selectedFile() const +{ + Q_D(const QQuickFileDialogImpl); + return d->selectedFile; +} + +void QQuickFileDialogImpl::setSelectedFile(const QUrl &selectedFile) +{ + Q_D(QQuickFileDialogImpl); + if (selectedFile == d->selectedFile) + return; + + d->selectedFile = selectedFile; + emit selectedFileChanged(); +} + +QUrl QQuickFileDialogImpl::currentFile() const +{ + Q_D(const QQuickFileDialogImpl); + return d->currentFile; +} + +void QQuickFileDialogImpl::setCurrentFile(const QUrl ¤tFile) +{ + Q_D(QQuickFileDialogImpl); + if (currentFile == d->currentFile) + return; + + d->currentFile = currentFile; + d->updateEnabled(); + emit currentFileChanged(d->currentFile); +} + +QSharedPointer<QFileDialogOptions> QQuickFileDialogImpl::options() const +{ + Q_D(const QQuickFileDialogImpl); + return d->options; +} + +void QQuickFileDialogImpl::setOptions(const QSharedPointer<QFileDialogOptions> &options) +{ + qCDebug(lcOptions).nospace() << "setOptions called with:" + << " acceptMode=" << options->acceptMode() + << " fileMode=" << options->fileMode() + << " initialDirectory=" << options->initialDirectory() + << " nameFilters=" << options->nameFilters() + << " initiallySelectedNameFilter=" << options->initiallySelectedNameFilter(); + + Q_D(QQuickFileDialogImpl); + d->options = options; + + if (d->options) { + d->selectedNameFilter->setOptions(options); + d->setNameFilters(options->nameFilters()); + } +} + +/*! + \internal + + The list of user-facing strings describing the available file filters. +*/ +QStringList QQuickFileDialogImpl::nameFilters() const +{ + Q_D(const QQuickFileDialogImpl); + return d->options ? d->options->nameFilters() : QStringList(); +} + +void QQuickFileDialogImpl::resetNameFilters() +{ + Q_D(QQuickFileDialogImpl); + d->setNameFilters(QStringList()); +} + +QQuickFileNameFilter *QQuickFileDialogImpl::selectedNameFilter() const +{ + Q_D(const QQuickFileDialogImpl); + if (!d->selectedNameFilter) { + QQuickFileDialogImpl *that = const_cast<QQuickFileDialogImpl *>(this); + d->selectedNameFilter = new QQuickFileNameFilter(that); + if (d->options) + d->selectedNameFilter->setOptions(d->options); + } + return d->selectedNameFilter; +} + +/*! + \internal + + These allow QQuickPlatformFileDialog::show() to set custom labels on the + dialog buttons without having to know about/go through QQuickFileDialogImplAttached + and QQuickDialogButtonBox. +*/ +void QQuickFileDialogImpl::setAcceptLabel(const QString &label) +{ + Q_D(QQuickFileDialogImpl); + d->acceptLabel = label; + QQuickFileDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + auto acceptButton = attached->buttonBox()->standardButton(QPlatformDialogHelper::Open); + if (!acceptButton) { + qmlWarning(this).nospace() << "Can't set accept label to " << label + << "; failed to find Open button in DialogButtonBox of " << this; + return; + } + + acceptButton->setText(!label.isEmpty() + ? label : QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Open)); +} + +void QQuickFileDialogImpl::setRejectLabel(const QString &label) +{ + Q_D(QQuickFileDialogImpl); + d->rejectLabel = label; + QQuickFileDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + auto rejectButton = attached->buttonBox()->standardButton(QPlatformDialogHelper::Cancel); + if (!rejectButton) { + qmlWarning(this).nospace() << "Can't set reject label to " << label + << "; failed to find Open button in DialogButtonBox of " << this; + return; + } + + rejectButton->setText(!label.isEmpty() + ? label : QQuickDialogButtonBoxPrivate::buttonText(QPlatformDialogHelper::Cancel)); +} + +void QQuickFileDialogImpl::selectNameFilter(const QString &filter) +{ + qCDebug(lcNameFilters) << "selectNameFilter called with" << filter; + Q_D(QQuickFileDialogImpl); + d->selectedNameFilter->update(filter); + emit filterSelected(filter); +} + +void QQuickFileDialogImpl::componentComplete() +{ + Q_D(QQuickFileDialogImpl); + QQuickDialog::componentComplete(); + + // Find the right-most button and set its key navigation so that + // tab moves focus to the breadcrumb bar's up button. I tried + // doing this via KeyNavigation on the DialogButtonBox in QML, + // but it didn't work (probably because it's not the right item). + QQuickFileDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + const int buttonCount = attached->buttonBox()->count(); + if (buttonCount == 0) + return; + + QQuickAbstractButton *rightMostButton = qobject_cast<QQuickAbstractButton *>( + attached->buttonBox()->itemAt(buttonCount - 1)); + if (!rightMostButton) { + qmlWarning(this) << "Can't find right-most button in DialogButtonBox"; + return; + } + + auto keyNavigationAttached = QQuickKeyNavigationAttached::qmlAttachedProperties(rightMostButton); + if (!keyNavigationAttached) { + qmlWarning(this) << "Can't create attached KeyNavigation object on" << QDebug::toString(rightMostButton); + return; + } + + keyNavigationAttached->setTab(attached->breadcrumbBar()->upButton()); +} + +void QQuickFileDialogImpl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + Q_D(QQuickFileDialogImpl); + QQuickDialog::itemChange(change, data); + + if (change != QQuickItem::ItemVisibleHasChanged || !isComponentComplete() || !data.boolValue) + return; + + QQuickFileDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->fileDialogListView()->forceActiveFocus(); + d->updateEnabled(); +} + +QQuickFileDialogImplAttached *QQuickFileDialogImplPrivate::attachedOrWarn() +{ + Q_Q(QQuickFileDialogImpl); + QQuickFileDialogImplAttached *attached = static_cast<QQuickFileDialogImplAttached*>( + qmlAttachedPropertiesObject<QQuickFileDialogImpl>(q)); + if (!attached) + qmlWarning(q) << "Expected FileDialogImpl attached object to be present on" << this; + return attached; +} + +void QQuickFileDialogImplAttachedPrivate::nameFiltersComboBoxItemActivated(int index) +{ + qCDebug(lcAttachedNameFilters) << "nameFiltersComboBoxItemActivated called with" << index; + auto fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(parent); + if (!fileDialogImpl) + return; + + fileDialogImpl->selectNameFilter(nameFiltersComboBox->textAt(index)); +} + +void QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged() +{ + auto fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(parent); + if (!fileDialogImpl) + return; + + auto fileDialogDelegate = qobject_cast<QQuickFileDialogDelegate*>(fileDialogListView->currentItem()); + if (!fileDialogDelegate) + return; + + fileDialogImpl->setCurrentFile(fileDialogDelegate->file()); +} + +QQuickFileDialogImplAttached::QQuickFileDialogImplAttached(QObject *parent) + : QObject(*(new QQuickFileDialogImplAttachedPrivate), parent) +{ + if (!qobject_cast<QQuickFileDialogImpl*>(parent)) { + qmlWarning(this) << "FileDialogImpl attached properties should only be " + << "accessed through the root FileDialogImpl instance"; + } +} + +QQuickDialogButtonBox *QQuickFileDialogImplAttached::buttonBox() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->buttonBox; +} + +void QQuickFileDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox) +{ + Q_D(QQuickFileDialogImplAttached); + if (buttonBox == d->buttonBox) + return; + + if (d->buttonBox) { + QQuickFileDialogImpl *fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(parent()); + if (fileDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fileDialogImpl); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::accepted, + dialogPrivate, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::rejected, + dialogPrivate, &QQuickDialogPrivate::handleReject); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::clicked, + dialogPrivate, &QQuickDialogPrivate::handleClick); + } + } + + d->buttonBox = buttonBox; + + if (buttonBox) { + QQuickFileDialogImpl *fileDialogImpl = qobject_cast<QQuickFileDialogImpl*>(parent()); + if (fileDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fileDialogImpl); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::accepted, + dialogPrivate, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::rejected, + dialogPrivate, &QQuickDialogPrivate::handleReject); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::clicked, + dialogPrivate, &QQuickDialogPrivate::handleClick); + } + } + + emit buttonBoxChanged(); +} + +QQuickComboBox *QQuickFileDialogImplAttached::nameFiltersComboBox() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->nameFiltersComboBox; +} + +void QQuickFileDialogImplAttached::setNameFiltersComboBox(QQuickComboBox *nameFiltersComboBox) +{ + Q_D(QQuickFileDialogImplAttached); + if (nameFiltersComboBox == d->nameFiltersComboBox) + return; + + d->nameFiltersComboBox = nameFiltersComboBox; + + QObjectPrivate::connect(d->nameFiltersComboBox, &QQuickComboBox::activated, + d, &QQuickFileDialogImplAttachedPrivate::nameFiltersComboBoxItemActivated); + + emit nameFiltersComboBoxChanged(); +} + +QString QQuickFileDialogImplAttached::selectedNameFilter() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->nameFiltersComboBox ? d->nameFiltersComboBox->currentText() : QString(); +} + +void QQuickFileDialogImplAttached::selectNameFilter(const QString &filter) +{ + Q_D(QQuickFileDialogImplAttached); + qCDebug(lcAttachedNameFilters) << "selectNameFilter called with" << filter; + if (!d->nameFiltersComboBox) + return; + + const int indexInComboBox = d->nameFiltersComboBox->find(filter); + if (indexInComboBox == -1) + return; + + qCDebug(lcAttachedNameFilters) << "setting ComboBox's currentIndex to" << indexInComboBox; + d->nameFiltersComboBox->setCurrentIndex(indexInComboBox); +} + +QQuickListView *QQuickFileDialogImplAttached::fileDialogListView() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->fileDialogListView; +} + +void QQuickFileDialogImplAttached::setFileDialogListView(QQuickListView *fileDialogListView) +{ + Q_D(QQuickFileDialogImplAttached); + if (fileDialogListView == d->fileDialogListView) + return; + + d->fileDialogListView = fileDialogListView; + + QObjectPrivate::connect(d->fileDialogListView, &QQuickListView::currentIndexChanged, + d, &QQuickFileDialogImplAttachedPrivate::fileDialogListViewCurrentIndexChanged); + + emit fileDialogListViewChanged(); +} + +QQuickFolderBreadcrumbBar *QQuickFileDialogImplAttached::breadcrumbBar() const +{ + Q_D(const QQuickFileDialogImplAttached); + return d->breadcrumbBar; +} + +void QQuickFileDialogImplAttached::setBreadcrumbBar(QQuickFolderBreadcrumbBar *breadcrumbBar) +{ + Q_D(QQuickFileDialogImplAttached); + if (breadcrumbBar == d->breadcrumbBar) + return; + + d->breadcrumbBar = breadcrumbBar; + emit breadcrumbBarChanged(); +} + +QT_END_NAMESPACE + +#include "moc_qquickfiledialogimpl_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h new file mode 100644 index 0000000000..23f8cf14a4 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p.h @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFILEDIALOGIMPL_P_H +#define QQUICKFILEDIALOGIMPL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickComboBox; +class QQuickDialogButtonBox; + +class QQuickFileDialogImplAttached; +class QQuickFileDialogImplAttachedPrivate; +class QQuickFileDialogImplPrivate; +class QQuickFileNameFilter; +class QQuickFolderBreadcrumbBar; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogImpl : public QQuickDialog +{ + Q_OBJECT + Q_PROPERTY(QUrl currentFolder READ currentFolder WRITE setCurrentFolder NOTIFY currentFolderChanged FINAL) + Q_PROPERTY(QUrl selectedFile READ selectedFile WRITE setSelectedFile NOTIFY selectedFileChanged FINAL) + Q_PROPERTY(QUrl currentFile READ currentFile WRITE setCurrentFile NOTIFY currentFileChanged FINAL) + Q_PROPERTY(QStringList nameFilters READ nameFilters NOTIFY nameFiltersChanged FINAL) + Q_PROPERTY(QQuickFileNameFilter *selectedNameFilter READ selectedNameFilter CONSTANT) + QML_NAMED_ELEMENT(FileDialogImpl) + QML_ATTACHED(QQuickFileDialogImplAttached) + QML_ADDED_IN_VERSION(6, 2) + Q_MOC_INCLUDE(<QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h>) + Q_MOC_INCLUDE(<QtQuickDialogs2QuickImpl/private/qquickfolderbreadcrumbbar_p.h>) + +public: + explicit QQuickFileDialogImpl(QObject *parent = nullptr); + + static QQuickFileDialogImplAttached *qmlAttachedProperties(QObject *object); + + QUrl currentFolder() const; + void setCurrentFolder(const QUrl ¤tFolder); + + QUrl selectedFile() const; + void setSelectedFile(const QUrl &file); + + QUrl currentFile() const; + void setCurrentFile(const QUrl ¤tFile); + + QSharedPointer<QFileDialogOptions> options() const; + void setOptions(const QSharedPointer<QFileDialogOptions> &options); + + QStringList nameFilters() const; + void resetNameFilters(); + + QQuickFileNameFilter *selectedNameFilter() const; + + void setAcceptLabel(const QString &label); + void setRejectLabel(const QString &label); + +public Q_SLOTS: + void selectNameFilter(const QString &filter); + +Q_SIGNALS: + void currentFolderChanged(const QUrl &folderUrl); + void selectedFileChanged(); + void currentFileChanged(const QUrl ¤tFileUrl); + void nameFiltersChanged(); + void fileSelected(const QUrl &fileUrl); + void filterSelected(const QString &filter); + +private: + void componentComplete() override; + void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) override; + + Q_DISABLE_COPY(QQuickFileDialogImpl) + Q_DECLARE_PRIVATE(QQuickFileDialogImpl) +}; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFileDialogImplAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickDialogButtonBox *buttonBox READ buttonBox WRITE setButtonBox NOTIFY buttonBoxChanged FINAL) + Q_PROPERTY(QQuickComboBox *nameFiltersComboBox READ nameFiltersComboBox WRITE setNameFiltersComboBox NOTIFY nameFiltersComboBoxChanged) + Q_PROPERTY(QQuickListView *fileDialogListView READ fileDialogListView WRITE setFileDialogListView NOTIFY fileDialogListViewChanged) + Q_PROPERTY(QQuickFolderBreadcrumbBar *breadcrumbBar READ breadcrumbBar WRITE setBreadcrumbBar NOTIFY breadcrumbBarChanged) + Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickdialogbuttonbox_p.h>) + Q_MOC_INCLUDE(<QtQuickTemplates2/private/qquickcombobox_p.h>) + +public: + explicit QQuickFileDialogImplAttached(QObject *parent = nullptr); + + QQuickDialogButtonBox *buttonBox() const; + void setButtonBox(QQuickDialogButtonBox *buttonBox); + + QQuickComboBox *nameFiltersComboBox() const; + void setNameFiltersComboBox(QQuickComboBox *nameFiltersComboBox); + + QString selectedNameFilter() const; + void selectNameFilter(const QString &filter); + + QQuickListView *fileDialogListView() const; + void setFileDialogListView(QQuickListView *fileDialogListView); + + QQuickFolderBreadcrumbBar *breadcrumbBar() const; + void setBreadcrumbBar(QQuickFolderBreadcrumbBar *breadcrumbBar); + +Q_SIGNALS: + void buttonBoxChanged(); + void nameFiltersComboBoxChanged(); + void fileDialogListViewChanged(); + void breadcrumbBarChanged(); + +private: + Q_DISABLE_COPY(QQuickFileDialogImplAttached) + Q_DECLARE_PRIVATE(QQuickFileDialogImplAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFileDialogImpl) + +#endif // QQUICKFILEDIALOGIMPL_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h new file mode 100644 index 0000000000..1831a7dc58 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfiledialogimpl_p_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFILEDIALOG_P_P_H +#define QQUICKFILEDIALOG_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileNameFilter; + +class QQuickFileDialogImplPrivate : public QQuickDialogPrivate +{ + Q_DECLARE_PUBLIC(QQuickFileDialogImpl) + +public: + QQuickFileDialogImplPrivate(); + + static QQuickFileDialogImplPrivate *get(QQuickFileDialogImpl *dialog) + { + return dialog->d_func(); + } + + QQuickFileDialogImplAttached *attachedOrWarn(); + + void setNameFilters(const QStringList &filters); + + void updateEnabled(); + void updateCurrentFile(const QString &oldFolderPath); + + void handleAccept() override; + void handleClick(QQuickAbstractButton *button) override; + + QSharedPointer<QFileDialogOptions> options; + QUrl currentFolder; + QUrl selectedFile; + QUrl currentFile; + QStringList nameFilters; + mutable QQuickFileNameFilter *selectedNameFilter = nullptr; + QString acceptLabel; + QString rejectLabel; +}; + +class QQuickFileDialogImplAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickFileDialogImplAttached) + + void nameFiltersComboBoxItemActivated(int index); + void fileDialogListViewCurrentIndexChanged(); + +public: + QPointer<QQuickDialogButtonBox> buttonBox; + QPointer<QQuickComboBox> nameFiltersComboBox; + QPointer<QQuickListView> fileDialogListView; + QPointer<QQuickFolderBreadcrumbBar> breadcrumbBar; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFILEDIALOG_P_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp new file mode 100644 index 0000000000..a474282538 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar.cpp @@ -0,0 +1,794 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfolderbreadcrumbbar_p.h" +#include "qquickfolderbreadcrumbbar_p_p.h" + +#include <QtCore/qdir.h> +#include <QtCore/qloggingcategory.h> +#if QT_CONFIG(shortcut) +#include <QtGui/private/qshortcutmap_p.h> +#endif +#include <QtGui/private/qguiapplication_p.h> +#include <QtQml/QQmlFile> +#include <QtQuick/private/qquicktextinput_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickpopupitem_p_p.h> +#include <QtQuickTemplates2/private/qquickshortcutcontext_p_p.h> + +#include "qquickfiledialogimpl_p.h" +#include "qquickfiledialogimpl_p_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcFolderBreadcrumbBar, "qt.quick.dialogs.folderbreadcrumbbar") +Q_LOGGING_CATEGORY(lcContentSize, "qt.quick.dialogs.folderbreadcrumbbar.contentsize") +Q_LOGGING_CATEGORY(lcDelegates, "qt.quick.dialogs.folderbreadcrumbbar.delegates") +Q_LOGGING_CATEGORY(lcShortcuts, "qt.quick.dialogs.folderbreadcrumbbar.shortcuts") +Q_LOGGING_CATEGORY(lcTextInput, "qt.quick.dialogs.folderbreadcrumbbar.textinput") +Q_LOGGING_CATEGORY(lcCurrentItem, "qt.quick.dialogs.folderbreadcrumbbar.currentitem") + +QQuickItem *QQuickFolderBreadcrumbBarPrivate::createDelegateItem(QQmlComponent *component, const QVariantMap &initialProperties) +{ + Q_Q(QQuickFolderBreadcrumbBar); + // If we don't use the correct context, it won't be possible to refer to + // the control's id from within the delegates. + QQmlContext *creationContext = component->creationContext(); + // The component might not have been created in QML, in which case + // the creation context will be null and we have to create it ourselves. + if (!creationContext) + creationContext = qmlContext(q); + QQmlContext *context = new QQmlContext(creationContext, q); + context->setContextObject(q); + QQuickItem *item = qobject_cast<QQuickItem*>(component->createWithInitialProperties(initialProperties, context)); + if (item) + QQml_setParent_noEvent(item, q); + qCDebug(lcDelegates) << "- created delegate item" << item << "with initialProperties" << initialProperties; + return item; +} + +QString QQuickFolderBreadcrumbBarPrivate::folderBaseName(const QString &folderPath) +{ + if (folderPath == QLatin1String("/")) { + // Unix root. + return folderPath; + } else if (folderPath.endsWith(QLatin1String(":/"))) { + // Windows drive. + return folderPath.mid(0, folderPath.size() - 1); + } + const QString baseName = folderPath.mid(folderPath.lastIndexOf(QLatin1Char('/')) + 1); + return baseName; +} + +/*! + \internal + + Returns \c { "/foo", "/foo/bar", "/foo/bar/baz" } if \a folder is \c "/foo/bar/baz". +*/ +QStringList QQuickFolderBreadcrumbBarPrivate::crumbPathsForFolder(const QUrl &folder) +{ + const QString folderPath = QDir::fromNativeSeparators(QQmlFile::urlToLocalFileOrQrc(folder)); + QDir dir(folderPath); + // In order to collect the paths for each breadcrumb, we need to work backwards, so we prepend. + QStringList paths; + do { + paths.prepend(dir.absolutePath()); + } while (dir.cdUp()); + return paths; +} + +void QQuickFolderBreadcrumbBarPrivate::repopulate() +{ + Q_Q(QQuickFolderBreadcrumbBar); + qCDebug(lcDelegates) << "attemping to repopulate breadcrumb bar using folder..."; + + if (repopulating) + return; + + if (!buttonDelegate || !separatorDelegate || !q->contentItem()) { + qCWarning(lcDelegates) << "Both delegates and contentItem must be set before repopulating"; + return; + } + + QBoolBlocker repopulateGuard(repopulating); + + auto failureCleanup = [=](){ + folderPaths.clear(); + while (q->count() > 0) + q->removeItem(q->itemAt(0)); + }; + + qCDebug(lcDelegates) << "- getting paths for directory" << fileDialog->currentFolder(); + folderPaths = crumbPathsForFolder(fileDialog->currentFolder()); + + while (q->count() > 0) + q->removeItem(q->itemAt(0)); + + for (int i = 0; i < folderPaths.size(); ++i) { + const QString &folderPath = folderPaths.at(i); + + QVariantMap initialProperties = { + { QStringLiteral("index"), QVariant::fromValue(i) }, + { QStringLiteral("folderName"), QVariant::fromValue(folderBaseName(folderPath)) } + }; + QQuickItem *buttonItem = createDelegateItem(buttonDelegate, initialProperties); + if (!buttonItem) { + qCWarning(lcDelegates) << "Failed creating breadcrumb buttonDelegate item:\n" << buttonDelegate->errorString(); + failureCleanup(); + break; + } + if (QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(buttonItem)) { + QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, + this, &QQuickFolderBreadcrumbBarPrivate::crumbClicked); + } + insertItem(q->count(), buttonItem); + + // Don't add a separator for the last button. + if (i < folderPaths.size() - 1) { + initialProperties = {}; + QQuickItem *separatorItem = createDelegateItem(separatorDelegate, initialProperties); + if (!separatorItem) { + qCWarning(lcDelegates) << "Failed creating breadcrumb separatorDelegate item:\n" << buttonDelegate->errorString(); + failureCleanup(); + break; + } + insertItem(q->count(), separatorItem); + } + } + + const int finalCount = q->count(); + // We would do - 2, since separators are included in the count, + // but as we don't add a separator for the last button, we only need to subtract 1. + const int newCurrentIndex = finalCount > 2 ? finalCount - 1 : -1; + qCDebug(lcDelegates) << "- setting currentIndex to" << newCurrentIndex; + q->setCurrentIndex(newCurrentIndex); + + updateImplicitContentSize(); + + qCDebug(lcDelegates) << "... bar now contains" << q->count() + << "buttons and separators in total, for the following paths:" << folderPaths; +} + +void QQuickFolderBreadcrumbBarPrivate::crumbClicked() +{ + Q_Q(QQuickFolderBreadcrumbBar); + qCDebug(lcCurrentItem) << "updateCurrentIndex called by sender" << q->sender(); + QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender()); + if (button) { + const int buttonIndex = contentModel->indexOf(button, nullptr); + q->setCurrentIndex(buttonIndex); + const QUrl folderUrl = QUrl::fromLocalFile(folderPaths.at(buttonIndex / 2)); + // TODO: don't repopulate the whole model when clicking on crumbs + qCDebug(lcCurrentItem) << "setting file dialog's folder to" << folderUrl; + fileDialog->setCurrentFolder(folderUrl); + } +} + +void QQuickFolderBreadcrumbBarPrivate::folderChanged() +{ + if (componentComplete) + repopulate(); +} + +static inline QString upButtonName() +{ + return QStringLiteral("upButton"); +} + +void QQuickFolderBreadcrumbBarPrivate::cancelUpButton() +{ + Q_Q(QQuickFolderBreadcrumbBar); + quickCancelDeferred(q, upButtonName()); +} + +void QQuickFolderBreadcrumbBarPrivate::executeUpButton(bool complete) +{ + Q_Q(QQuickFolderBreadcrumbBar); + if (upButton.wasExecuted()) + return; + + if (!upButton || complete) + quickBeginDeferred(q, upButtonName(), upButton); + if (complete) + quickCompleteDeferred(q, upButtonName(), upButton); +} + +void QQuickFolderBreadcrumbBarPrivate::goUp() +{ + QDir dir(QQmlFile::urlToLocalFileOrQrc(fileDialog->currentFolder())); + dir.cdUp(); + fileDialog->setCurrentFolder(QUrl::fromLocalFile(dir.absolutePath())); +} + +static inline QString textFieldName() +{ + return QStringLiteral("textField"); +} + +void QQuickFolderBreadcrumbBarPrivate::cancelTextField() +{ + Q_Q(QQuickFolderBreadcrumbBar); + quickCancelDeferred(q, textFieldName()); +} + +void QQuickFolderBreadcrumbBarPrivate::executeTextField(bool complete) +{ + Q_Q(QQuickFolderBreadcrumbBar); + if (textField.wasExecuted()) + return; + + if (!textField || complete) + quickBeginDeferred(q, textFieldName(), textField); + if (complete) + quickCompleteDeferred(q, textFieldName(), textField); +} + +void QQuickFolderBreadcrumbBarPrivate::toggleTextFieldVisibility() +{ + textField->setText(QQmlFile::urlToLocalFileOrQrc(fileDialog->currentFolder())); + + qCDebug(lcTextInput).nospace() << "text field visibility was " << textField->isVisible() + << "; setting it to " << !textField->isVisible(); + textField->setVisible(!textField->isVisible()); + + if (textField->isVisible()) { + // The text field is now visible, so give it focus, + // select the text, and let it handle escape/back. + textField->forceActiveFocus(Qt::ShortcutFocusReason); + textField->selectAll(); + } + + // We connect to the TextField's visibleChanged signal, so textFieldVisibleChanged() + // will get called automatically and we don't need to call it here. + + contentItem->setVisible(!textField->isVisible()); + + // When the TextField is visible, certain items in the dialog need to be disabled. + auto fileDialogPrivate = QQuickFileDialogImplPrivate::get(fileDialog); + fileDialogPrivate->updateEnabled(); +} + +void QQuickFolderBreadcrumbBarPrivate::textFieldAccepted() +{ + const QUrl fileUrl = QUrl::fromLocalFile(textField->text()); + const bool mustExist = fileDialog->options()->acceptMode() != QFileDialogOptions::AcceptSave; + const bool enteredPathIsValidUrl = fileUrl.isValid(); + bool enteredPathExists = false; + bool enteredPathIsDir = false; + if (enteredPathIsValidUrl) { + const QFileInfo fileInfo(textField->text()); + enteredPathExists = fileInfo.exists(); + if (enteredPathExists) + enteredPathIsDir = fileInfo.isDir(); + } + + qCDebug(lcTextInput).nospace() << "text field accepted -" + << " text=" << textField->text() + << " fileUrl=" << fileUrl + << " mustExist=" << mustExist + << " enteredPathIsValidUrl=" << enteredPathIsValidUrl + << " enteredPathExists=" << enteredPathExists + << " enteredPathIsDir=" << enteredPathIsDir; + + if (enteredPathIsDir && (enteredPathExists || !mustExist)) { + qCDebug(lcTextInput) << "path entered is a folder; setting folder"; + fileDialog->setCurrentFolder(fileUrl); + } else if (!enteredPathIsDir && (enteredPathExists || !mustExist)) { + qCDebug(lcTextInput) << "path entered is a file; setting file and calling accept()"; + // It's important that we set the currentFile here, as that's what + // QQuickPlatformFileDialog::selectedFiles() needs to return, and + // QQuickFileDialog::accept() sets its file property based on + // selectedFiles(). + fileDialog->setCurrentFile(fileUrl); + fileDialog->setSelectedFile(fileUrl); + fileDialog->accept(); + } else { + qCDebug(lcTextInput) << "path entered is not valid; not setting file/folder"; + } + + // If the enter key was pressed and the dialog closed, the text input will lose + // active focus, and textFieldActiveFocusChanged() will toggle its visibility. + // We should only toggle visibility if the dialog is actually closed, otherwise + // we'll end up toggling twice, and the text input will be visible the next time + // the dialog is opened. + if (fileDialog->isVisible()) + toggleTextFieldVisibility(); +} + +void QQuickFolderBreadcrumbBarPrivate::textFieldVisibleChanged() +{ + qCDebug(lcShortcuts) << "text field was either hidden or shown"; + + if (textField && textField->isVisible()) + handleTextFieldShown(); + else + handleTextFieldHidden(); +} + +void QQuickFolderBreadcrumbBarPrivate::textFieldActiveFocusChanged() +{ + qCDebug(lcTextInput) << "text field activeFocus changed to" << textField->hasActiveFocus(); + + // When the text field loses focus, it should be hidden. + if (!textField->hasActiveFocus() && textField->isVisible()) + toggleTextFieldVisibility(); +} + +/* + When the text field is visible: + + - Ctrl+L should do nothing (matches e.g. Ubuntu and Windows) + - Escape/back should hide it +*/ +void QQuickFolderBreadcrumbBarPrivate::handleTextFieldShown() +{ +#if QT_CONFIG(shortcut) + Q_Q(QQuickFolderBreadcrumbBar); + if (editPathToggleShortcutId == 0) + return; + + QGuiApplicationPrivate *appPrivate = QGuiApplicationPrivate::instance(); + qCDebug(lcShortcuts) << "text field was shown; grabbing/ungrabbing relevant shortcuts..."; + + // Disable the back/escape shortcuts for QQuickPopup so that the TextField can get them. + auto popupItem = qobject_cast<QQuickPopupItem*>(fileDialog->popupItem()); + popupItem->ungrabShortcut(); + + appPrivate->shortcutMap.removeShortcut(editPathToggleShortcutId, q); + editPathToggleShortcutId = 0; + + editPathBackShortcutId = appPrivate->shortcutMap.addShortcut( + q, Qt::Key_Back, Qt::WindowShortcut, QQuickShortcutContext::matcher); + editPathEscapeShortcutId = appPrivate->shortcutMap.addShortcut( + q, Qt::Key_Escape, Qt::WindowShortcut, QQuickShortcutContext::matcher); + + qCDebug(lcShortcuts).nospace() << "... shortcut IDs:" + << " editPathToggleShortcutId=" << editPathToggleShortcutId + << " editPathBackShortcutId=" << editPathBackShortcutId + << " editPathEscapeShortcutId=" << editPathEscapeShortcutId; +#endif +} + +/* + When the text field is not visible: + + - Ctrl+L should make it visible + - Escape/back should close the dialog +*/ +void QQuickFolderBreadcrumbBarPrivate::handleTextFieldHidden() +{ +#if QT_CONFIG(shortcut) + Q_Q(QQuickFolderBreadcrumbBar); + + QGuiApplicationPrivate *appPrivate = QGuiApplicationPrivate::instance(); + qCDebug(lcShortcuts) << "text field was hidden; grabbing/ungrabbing relevant shortcuts..."; + + if (editPathToggleShortcutId == 0) { + editPathToggleShortcutId = appPrivate->shortcutMap.addShortcut( + q, Qt::CTRL | Qt::Key_L, Qt::WindowShortcut, QQuickShortcutContext::matcher); + } + + // When the bar is first completed, this function is called, since the text field starts off hidden. + // If removeShortcut is called with a zero id, all shortcuts for the given object will be removed, + // and we don't want that. + if (editPathBackShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathBackShortcutId, q); + editPathBackShortcutId = 0; + } + if (editPathEscapeShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathEscapeShortcutId, q); + editPathEscapeShortcutId = 0; + } + + // Re-enable the back/escape shortcuts for QQuickPopup now that TextField no longer needs them. + auto popupItem = qobject_cast<QQuickPopupItem*>(fileDialog->popupItem()); + if (popupItem) + popupItem->grabShortcut(); + + qCDebug(lcShortcuts).nospace() << "... shortcut IDs: " + << " editPathToggleShortcutId=" << editPathToggleShortcutId + << " editPathBackShortcutId=" << editPathBackShortcutId + << " editPathEscapeShortcutId=" << editPathEscapeShortcutId; +#endif +} + +void QQuickFolderBreadcrumbBarPrivate::ungrabEditPathShortcuts() +{ +#if QT_CONFIG(shortcut) + Q_Q(QQuickFolderBreadcrumbBar); + QGuiApplicationPrivate *appPrivate = QGuiApplicationPrivate::instance(); + qCDebug(lcShortcuts) << "ungrabbing all edit path shortcuts"; + + if (editPathToggleShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathToggleShortcutId, q); + editPathToggleShortcutId = 0; + } + if (editPathBackShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathBackShortcutId, q); + editPathBackShortcutId = 0; + } + if (editPathEscapeShortcutId != 0) { + appPrivate->shortcutMap.removeShortcut(editPathEscapeShortcutId, q); + editPathEscapeShortcutId = 0; + } +#endif +} + +qreal QQuickFolderBreadcrumbBarPrivate::getContentWidth() const +{ + Q_Q(const QQuickFolderBreadcrumbBar); + const int count = contentModel->count(); + qreal totalWidth = qMax(0, count - 1) * spacing; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) { + QQuickItemPrivate *p = QQuickItemPrivate::get(item); + if (!p->widthValid()) + totalWidth += item->implicitWidth(); + else + totalWidth += item->width(); + } + } + qCDebug(lcContentSize) << "content width:" << totalWidth; + return totalWidth; +} + +qreal QQuickFolderBreadcrumbBarPrivate::getContentHeight() const +{ + Q_Q(const QQuickFolderBreadcrumbBar); + const int count = contentModel->count(); + qreal maxHeight = 0; + for (int i = 0; i < count; ++i) { + QQuickItem *item = q->itemAt(i); + if (item) + maxHeight = qMax(maxHeight, item->implicitHeight()); + } + qCDebug(lcContentSize) << "content height:" << maxHeight; + return maxHeight; +} + +void QQuickFolderBreadcrumbBarPrivate::resizeContent() +{ + Q_Q(QQuickFolderBreadcrumbBar); + if (contentItem) { + const int upButtonSpace = q->upButton() ? q->upButton()->width() + upButtonSpacing : 0; + contentItem->setPosition(QPointF(q->leftPadding() + upButtonSpace, q->topPadding())); + contentItem->setSize(QSizeF(q->availableWidth() - upButtonSpace, q->availableHeight())); + + if (textField) { + textField->setPosition(contentItem->position()); + textField->setSize(contentItem->size()); + } + } +} + +void QQuickFolderBreadcrumbBarPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) +{ + QQuickContainerPrivate::itemGeometryChanged(item, change, diff); + if (change.sizeChange()) + updateImplicitContentSize(); +} + +void QQuickFolderBreadcrumbBarPrivate::itemImplicitWidthChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitWidthChanged(item); + if (item != contentItem) + updateImplicitContentWidth(); +} + +void QQuickFolderBreadcrumbBarPrivate::itemImplicitHeightChanged(QQuickItem *item) +{ + QQuickContainerPrivate::itemImplicitHeightChanged(item); + if (item != contentItem) + updateImplicitContentHeight(); +} + +/*! + \internal + + Private class for breadcrumb navigation of a directory. + + Given a FileDialog, FolderBreadCrumbbar creates breadcrumb buttons and + separators from the specified delegate components. +*/ + +QQuickFolderBreadcrumbBar::QQuickFolderBreadcrumbBar(QQuickItem *parent) + : QQuickContainer(*(new QQuickFolderBreadcrumbBarPrivate), parent) +{ + Q_D(QQuickFolderBreadcrumbBar); + d->changeTypes |= QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; +} + +QQuickFileDialogImpl *QQuickFolderBreadcrumbBar::fileDialog() const +{ + Q_D(const QQuickFolderBreadcrumbBar); + return d->fileDialog; +} + +void QQuickFolderBreadcrumbBar::setFileDialog(QQuickFileDialogImpl *fileDialog) +{ + Q_D(QQuickFolderBreadcrumbBar); + if (fileDialog == d->fileDialog) + return; + + if (d->fileDialog) + QObjectPrivate::disconnect(d->fileDialog, &QQuickFileDialogImpl::currentFolderChanged, + d, &QQuickFolderBreadcrumbBarPrivate::folderChanged); + + d->fileDialog = fileDialog; + + if (d->fileDialog) + QObjectPrivate::connect(d->fileDialog, &QQuickFileDialogImpl::currentFolderChanged, + d, &QQuickFolderBreadcrumbBarPrivate::folderChanged); + + emit fileDialogChanged(); +} + +QQmlComponent *QQuickFolderBreadcrumbBar::buttonDelegate() +{ + Q_D(QQuickFolderBreadcrumbBar); + return d->buttonDelegate; +} + +void QQuickFolderBreadcrumbBar::setButtonDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickFolderBreadcrumbBar); + qCDebug(lcFolderBreadcrumbBar) << "setButtonDelegate called with" << delegate; + if (d->componentComplete) { + // Simplify the code by disallowing this. + qCWarning(lcFolderBreadcrumbBar) << "BreadcrumbBar does not support setting delegates after component completion"; + return; + } + + if (delegate == d->buttonDelegate) + return; + + d->buttonDelegate = delegate; + emit buttonDelegateChanged(); +} + +QQmlComponent *QQuickFolderBreadcrumbBar::separatorDelegate() +{ + Q_D(QQuickFolderBreadcrumbBar); + return d->separatorDelegate; +} + +void QQuickFolderBreadcrumbBar::setSeparatorDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickFolderBreadcrumbBar); + qCDebug(lcFolderBreadcrumbBar) << "setSeparatorDelegate called with" << delegate; + if (d->componentComplete) { + qCWarning(lcFolderBreadcrumbBar) << "BreadcrumbBar does not support setting delegates after component completion"; + return; + } + + if (delegate == d->separatorDelegate) + return; + + d->separatorDelegate = delegate; + emit separatorDelegateChanged(); +} + +QQuickAbstractButton *QQuickFolderBreadcrumbBar::upButton() +{ + Q_D(QQuickFolderBreadcrumbBar); + if (!d->upButton) + d->executeUpButton(); + return d->upButton; +} + +void QQuickFolderBreadcrumbBar::setUpButton(QQuickAbstractButton *upButton) +{ + Q_D(QQuickFolderBreadcrumbBar); + if (upButton == d->upButton) + return; + + if (!d->upButton.isExecuting()) + d->cancelUpButton(); + + if (d->upButton) { + QObjectPrivate::disconnect(d->upButton.data(), &QQuickAbstractButton::clicked, + d, &QQuickFolderBreadcrumbBarPrivate::goUp); + } + + QQuickControlPrivate::hideOldItem(d->upButton); + d->upButton = upButton; + if (d->upButton) { + if (!d->upButton->parentItem()) + d->upButton->setParentItem(this); + + QObjectPrivate::connect(d->upButton.data(), &QQuickAbstractButton::clicked, + d, &QQuickFolderBreadcrumbBarPrivate::goUp); + } + if (!d->upButton.isExecuting()) + emit upButtonChanged(); +} + +int QQuickFolderBreadcrumbBar::upButtonSpacing() const +{ + Q_D(const QQuickFolderBreadcrumbBar); + return d->upButtonSpacing; +} + +void QQuickFolderBreadcrumbBar::setUpButtonSpacing(int upButtonSpacing) +{ + Q_D(QQuickFolderBreadcrumbBar); + if (upButtonSpacing == d->upButtonSpacing) + return; + + d->upButtonSpacing = upButtonSpacing; + emit upButtonSpacingChanged(); +} + +QQuickTextField *QQuickFolderBreadcrumbBar::textField() +{ + Q_D(QQuickFolderBreadcrumbBar); + return d->textField; +} + +void QQuickFolderBreadcrumbBar::setTextField(QQuickTextField *textField) +{ + Q_D(QQuickFolderBreadcrumbBar); + if (textField == d->textField) + return; + + if (!d->textField.isExecuting()) + d->cancelUpButton(); + + if (d->textField) + d->handleTextFieldHidden(); + + if (d->textField) { + QObjectPrivate::disconnect(d->textField.data(), &QQuickTextInput::visibleChanged, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldVisibleChanged); + QObjectPrivate::disconnect(d->textField.data(), &QQuickTextInput::activeFocusChanged, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldActiveFocusChanged); + QObjectPrivate::disconnect(d->textField.data(), &QQuickTextInput::accepted, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldAccepted); + } + + QQuickControlPrivate::hideOldItem(d->textField); + d->textField = textField; + if (d->textField) { + if (!d->textField->parentItem()) + d->textField->setParentItem(this); + + d->textField->setVisible(false); + + QObjectPrivate::connect(d->textField.data(), &QQuickTextInput::visibleChanged, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldVisibleChanged); + QObjectPrivate::connect(d->textField.data(), &QQuickTextInput::activeFocusChanged, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldActiveFocusChanged); + QObjectPrivate::connect(d->textField.data(), &QQuickTextInput::accepted, + d, &QQuickFolderBreadcrumbBarPrivate::textFieldAccepted); + } + if (!d->textField.isExecuting()) + emit textFieldChanged(); +} + +bool QQuickFolderBreadcrumbBar::event(QEvent *event) +{ +#if QT_CONFIG(shortcut) + Q_D(QQuickFolderBreadcrumbBar); + if (event->type() == QEvent::Shortcut) { + QShortcutEvent *shortcutEvent = static_cast<QShortcutEvent *>(event); + if (shortcutEvent->shortcutId() == d->editPathToggleShortcutId + || shortcutEvent->shortcutId() == d->editPathBackShortcutId + || shortcutEvent->shortcutId() == d->editPathEscapeShortcutId) { + d->toggleTextFieldVisibility(); + return true; + } else if (shortcutEvent->shortcutId() == d->goUpShortcutId) { + d->goUp(); + } + } +#endif + return QQuickItem::event(event); +} + +void QQuickFolderBreadcrumbBar::componentComplete() +{ + Q_D(QQuickFolderBreadcrumbBar); + qCDebug(lcFolderBreadcrumbBar) << "componentComplete"; + QQuickContainer::componentComplete(); + d->repopulate(); + + if (d->textField) { + // Force it to be updated as setTextField() is too early to do it. + d->textFieldVisibleChanged(); + } +} + +void QQuickFolderBreadcrumbBar::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data) +{ + Q_D(QQuickFolderBreadcrumbBar); + QQuickContainer::itemChange(change, data); + + if (change == QQuickItem::ItemVisibleHasChanged && isComponentComplete()) { + if (data.boolValue && d->fileDialog->isVisible()) { + // It's visible. + d->handleTextFieldHidden(); + + d->goUpShortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut( + this, QKeySequence(Qt::ALT | Qt::Key_Up), Qt::WindowShortcut, QQuickShortcutContext::matcher); + } else { + // It's hidden. + // Hide the text field so that when the dialog gets opened again, it's not still visible. + if (d->textField) + d->textField->setVisible(false); + + // Make the ListView visible again. + if (d->contentItem) + d->contentItem->setVisible(true); + + // We also need to ungrab all shortcuts when we're not visible. + d->ungrabEditPathShortcuts(); + + if (d->goUpShortcutId != 0) { + QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(d->goUpShortcutId, this); + d->goUpShortcutId = 0; + } + } + } +} + +bool QQuickFolderBreadcrumbBar::isContent(QQuickItem *item) const +{ + if (!qmlContext(item)) + return false; + + if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) + return false; + + return true; +} + +QFont QQuickFolderBreadcrumbBar::defaultFont() const +{ + // TODO + return QQuickTheme::font(QQuickTheme::TabBar); +} + +#if QT_CONFIG(accessibility) +QAccessible::Role QQuickFolderBreadcrumbBar::accessibleRole() const +{ + // TODO + return QAccessible::PageTabList; +} +#endif + +QT_END_NAMESPACE + +#include "moc_qquickfolderbreadcrumbbar_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p.h new file mode 100644 index 0000000000..5e14f5b04f --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFOLDERBREADCRUMBBAR_P_H +#define QQUICKFOLDERBREADCRUMBBAR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqmlcomponent.h> +#include <QtQuickTemplates2/private/qquickcontainer_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFolderBreadcrumbBarPrivate; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFolderBreadcrumbBar : public QQuickContainer +{ + Q_OBJECT + Q_PROPERTY(QQuickFileDialogImpl *fileDialog READ fileDialog WRITE setFileDialog NOTIFY fileDialogChanged) + Q_PROPERTY(QQmlComponent *buttonDelegate READ buttonDelegate WRITE setButtonDelegate NOTIFY buttonDelegateChanged) + Q_PROPERTY(QQmlComponent *separatorDelegate READ separatorDelegate WRITE setSeparatorDelegate NOTIFY separatorDelegateChanged) + Q_PROPERTY(QQuickAbstractButton *upButton READ upButton WRITE setUpButton NOTIFY upButtonChanged) + Q_PROPERTY(QQuickTextField *textField READ textField WRITE setTextField NOTIFY textFieldChanged) + Q_PROPERTY(int upButtonSpacing READ upButtonSpacing WRITE setUpButtonSpacing NOTIFY upButtonSpacingChanged) + QML_NAMED_ELEMENT(FolderBreadcrumbBar) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFolderBreadcrumbBar(QQuickItem *parent = nullptr); + + QQuickFileDialogImpl *fileDialog() const; + void setFileDialog(QQuickFileDialogImpl *fileDialog); + + QQmlComponent *buttonDelegate(); + void setButtonDelegate(QQmlComponent *delegate); + + QQmlComponent *separatorDelegate(); + void setSeparatorDelegate(QQmlComponent *delegate); + + QQuickAbstractButton *upButton(); + void setUpButton(QQuickAbstractButton *upButton); + + int upButtonSpacing() const; + void setUpButtonSpacing(int upButtonSpacing); + + QQuickTextField *textField(); + void setTextField(QQuickTextField *textField); + +Q_SIGNALS: + void fileDialogChanged(); + void buttonDelegateChanged(); + void separatorDelegateChanged(); + void upButtonChanged(); + void upButtonSpacingChanged(); + void textFieldChanged(); + +protected: + bool event(QEvent *event) override; + + void componentComplete() override; + + void itemChange(ItemChange change, const ItemChangeData &data) override; + + bool isContent(QQuickItem *item) const override; + + QFont defaultFont() const override; + +#if QT_CONFIG(accessibility) + QAccessible::Role accessibleRole() const override; +#endif + +private: + Q_DISABLE_COPY(QQuickFolderBreadcrumbBar) + Q_DECLARE_PRIVATE(QQuickFolderBreadcrumbBar) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFolderBreadcrumbBar) + +#endif // QQUICKFOLDERBREADCRUMBBAR_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p_p.h new file mode 100644 index 0000000000..4616b6a9c5 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfolderbreadcrumbbar_p_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFOLDERBREADCRUMBBAR_P_P_H +#define QQUICKFOLDERBREADCRUMBBAR_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcontainer_p_p.h> +#include <QtQuickTemplates2/private/qquickdeferredexecute_p_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickAbstractButton; +class QQuickTextField; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFolderBreadcrumbBarPrivate : public QQuickContainerPrivate +{ + Q_DECLARE_PUBLIC(QQuickFolderBreadcrumbBar) + +public: + QQuickItem *createDelegateItem(QQmlComponent *component, const QVariantMap &initialProperties); + static QString folderBaseName(const QString &folderPath); + static QStringList crumbPathsForFolder(const QUrl &folder); + void repopulate(); + void crumbClicked(); + void folderChanged(); + + void cancelUpButton(); + void executeUpButton(bool complete = false); + void goUp(); + + void cancelTextField(); + void executeTextField(bool complete = false); + void toggleTextFieldVisibility(); + void textFieldAccepted(); + + void textFieldVisibleChanged(); + void textFieldActiveFocusChanged(); + void handleTextFieldShown(); + void handleTextFieldHidden(); + void ungrabEditPathShortcuts(); + + qreal getContentWidth() const override; + qreal getContentHeight() const override; + void resizeContent() override; + + void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override; + void itemImplicitWidthChanged(QQuickItem *item) override; + void itemImplicitHeightChanged(QQuickItem *item) override; + +private: + QQuickFileDialogImpl *fileDialog = nullptr; + QList<QString> folderPaths; + QQmlComponent *buttonDelegate = nullptr; + QQmlComponent *separatorDelegate = nullptr; + QQuickDeferredPointer<QQuickAbstractButton> upButton; + QQuickDeferredPointer<QQuickTextField> textField; + int editPathToggleShortcutId = 0; + int editPathBackShortcutId = 0; + int editPathEscapeShortcutId = 0; + int goUpShortcutId = 0; + int upButtonSpacing = 0; + bool repopulating = false; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFOLDERBREADCRUMBBAR_P_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp new file mode 100644 index 0000000000..ba0b69ef26 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp @@ -0,0 +1,865 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfontdialogimpl_p.h" +#include "qquickfontdialogimpl_p_p.h" + +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h> +#include <private/qfontdatabase_p.h> + +#include <QRegularExpression> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcAttachedProperty, "qt.quick.dialogs.quickfontdialogimpl.attachedOrWarn") + +QQuickFontDialogImplPrivate::QQuickFontDialogImplPrivate() +{ +} + +QQuickFontDialogImplAttached *QQuickFontDialogImplPrivate::attachedOrWarn() +{ + Q_Q(QQuickFontDialogImpl); + QQuickFontDialogImplAttached *attached = static_cast<QQuickFontDialogImplAttached *>( + qmlAttachedPropertiesObject<QQuickFontDialogImpl>(q)); + if (!attached) { + qCWarning(lcAttachedProperty) + << "Expected FontDialogImpl attached object to be present on" << this; + } + return attached; +} + +void QQuickFontDialogImplPrivate::handleAccept() { } + +void QQuickFontDialogImplPrivate::handleClick(QQuickAbstractButton *button) +{ + Q_Q(QQuickFontDialogImpl); + if (buttonRole(button) == QPlatformDialogHelper::AcceptRole) { + q->accept(); + QQuickDialogPrivate::handleClick(button); + } +} + +QQuickFontDialogImpl::QQuickFontDialogImpl(QObject *parent) + : QQuickDialog(*(new QQuickFontDialogImplPrivate), parent) +{ +} + +QQuickFontDialogImplAttached *QQuickFontDialogImpl::qmlAttachedProperties(QObject *object) +{ + return new QQuickFontDialogImplAttached(object); +} + +QSharedPointer<QFontDialogOptions> QQuickFontDialogImpl::options() const +{ + Q_D(const QQuickFontDialogImpl); + + return d->options; +} + +void QQuickFontDialogImpl::setOptions(const QSharedPointer<QFontDialogOptions> &options) +{ + Q_D(QQuickFontDialogImpl); + + if (options == d->options) + return; + + d->options = options; + + emit optionsChanged(); +} + +QFont QQuickFontDialogImpl::currentFont() const +{ + Q_D(const QQuickFontDialogImpl); + return d->currentFont; +} + +void QQuickFontDialogImpl::setCurrentFont(const QFont &font, bool selectInListViews) +{ + Q_D(QQuickFontDialogImpl); + + if (font == d->currentFont) + return; + + d->currentFont = font; + + emit currentFontChanged(font); + + if (!selectInListViews) + return; + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->selectFontInListViews(font); +} + +void QQuickFontDialogImpl::init() +{ + Q_D(QQuickFontDialogImpl); + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + if (!attached->familyListView()->model().isValid()) + attached->updateFamilies(); + + attached->buttonBox()->setVisible(!(options()->options() & QFontDialogOptions::NoButtons)); +} + +void QQuickFontDialogImpl::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickFontDialogImpl); + + QQuickDialog::keyReleaseEvent(event); + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + // The family and style text edits are read-only so that they + // can show the current selection but also allow key input to "search". + // This is why we handle just the release event, and don't accept it. + if (window()->activeFocusItem() == attached->familyEdit()) + attached->searchFamily(event->text()); + else if (window()->activeFocusItem() == attached->styleEdit()) + attached->searchStyle(event->text()); +} + +void QQuickFontDialogImpl::focusOutEvent(QFocusEvent *event) +{ + Q_D(QQuickFontDialogImpl); + + QQuickDialog::focusOutEvent(event); + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->clearSearch(); +} + +QQuickFontDialogImplAttached::QQuickFontDialogImplAttached(QObject *parent) + : QObject(*(new QQuickFontDialogImplAttachedPrivate), parent), + m_writingSystem(QFontDatabase::Any), + m_selectedSize(-1), + m_smoothlyScalable(false), + m_ignoreFamilyUpdate(false), + m_ignoreStyleUpdate(false) +{ + if (!qobject_cast<QQuickFontDialogImpl *>(parent)) { + qmlWarning(this) << "FontDialogImpl attached properties should only be " + << "accessed through the root FileDialogImpl instance"; + } +} + +QQuickListView *QQuickFontDialogImplAttached::familyListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->familyListView; +} + +void QQuickFontDialogImplAttached::setFamilyListView(QQuickListView *familyListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->familyListView == familyListView) + return; + + if (d->familyListView) { + disconnect(d->familyListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_familyChanged); + } + + d->familyListView = familyListView; + + if (familyListView) { + connect(d->familyListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_familyChanged); + } + + emit familyListViewChanged(); +} + +QQuickListView *QQuickFontDialogImplAttached::styleListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->styleListView; +} + +void QQuickFontDialogImplAttached::setStyleListView(QQuickListView *styleListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->styleListView == styleListView) + return; + + if (d->styleListView) { + disconnect(d->styleListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_styleChanged); + } + + d->styleListView = styleListView; + + if (styleListView) { + connect(d->styleListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_styleChanged); + } + + emit styleListViewChanged(); +} + +QQuickListView *QQuickFontDialogImplAttached::sizeListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sizeListView; +} + +void QQuickFontDialogImplAttached::setSizeListView(QQuickListView *sizeListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->sizeListView == sizeListView) + return; + + if (d->sizeListView) { + disconnect(d->sizeListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_sizeChanged); + } + + d->sizeListView = sizeListView; + + if (d->sizeListView) { + connect(d->sizeListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_sizeChanged); + } + + emit sizeListViewChanged(); +} + +QQuickTextEdit *QQuickFontDialogImplAttached::sampleEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sampleEdit; +} + +void QQuickFontDialogImplAttached::setSampleEdit(QQuickTextEdit *sampleEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->sampleEdit == sampleEdit) + return; + + if (d->sampleEdit) { + QObjectPrivate::disconnect(d->sampleEdit, &QQuickTextEdit::fontChanged, + d, &QQuickFontDialogImplAttachedPrivate::currentFontChanged); + } + + d->sampleEdit = sampleEdit; + + if (d->sampleEdit) { + QObjectPrivate::connect(d->sampleEdit, &QQuickTextEdit::fontChanged, + d, &QQuickFontDialogImplAttachedPrivate::currentFontChanged); + + d->sampleEdit->setText(QFontDatabase::writingSystemSample(m_writingSystem)); + } + + emit sampleEditChanged(); +} + +QQuickDialogButtonBox *QQuickFontDialogImplAttached::buttonBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->buttonBox; +} + +void QQuickFontDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox) +{ + Q_D(QQuickFontDialogImplAttached); + if (buttonBox == d->buttonBox) + return; + + if (d->buttonBox) { + QQuickFontDialogImpl *fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent()); + if (fontDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fontDialogImpl); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::accepted, + dialogPrivate, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::rejected, + dialogPrivate, &QQuickDialogPrivate::handleReject); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::clicked, dialogPrivate, + &QQuickDialogPrivate::handleClick); + } + } + + d->buttonBox = buttonBox; + + if (buttonBox) { + QQuickFontDialogImpl *fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent()); + if (fontDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fontDialogImpl); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::accepted, dialogPrivate, + &QQuickDialogPrivate::handleAccept); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::rejected, dialogPrivate, + &QQuickDialogPrivate::handleReject); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::clicked, dialogPrivate, + &QQuickDialogPrivate::handleClick); + } + } + + emit buttonBoxChanged(); +} + +QQuickComboBox *QQuickFontDialogImplAttached::writingSystemComboBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->writingSystemComboBox; +} + +void QQuickFontDialogImplAttached::setWritingSystemComboBox(QQuickComboBox *writingSystemComboBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->writingSystemComboBox == writingSystemComboBox) + return; + + if (d->writingSystemComboBox) { + disconnect(d->writingSystemComboBox, &QQuickComboBox::activated, + this, &QQuickFontDialogImplAttached::_q_writingSystemChanged); + } + + d->writingSystemComboBox = writingSystemComboBox; + + if (d->writingSystemComboBox) { + QStringList writingSystemModel; + for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { + QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i); + QString wsName = QFontDatabase::writingSystemName(ws); + if (wsName.isEmpty()) + break; + writingSystemModel.append(wsName); + } + + d->writingSystemComboBox->setModel(writingSystemModel); + + connect(d->writingSystemComboBox, &QQuickComboBox::activated, + this, &QQuickFontDialogImplAttached::_q_writingSystemChanged); + } + + emit writingSystemComboBoxChanged(); +} + +QQuickCheckBox *QQuickFontDialogImplAttached::underlineCheckBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->underlineCheckBox; +} + +void QQuickFontDialogImplAttached::setUnderlineCheckBox(QQuickCheckBox *underlineCheckBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->underlineCheckBox == underlineCheckBox) + return; + + if (d->underlineCheckBox) { + disconnect(d->underlineCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + d->underlineCheckBox = underlineCheckBox; + + if (d->underlineCheckBox) { + connect(d->underlineCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + emit underlineCheckBoxChanged(); +} + +QQuickCheckBox *QQuickFontDialogImplAttached::strikeoutCheckBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->strikeoutCheckBox; +} + +void QQuickFontDialogImplAttached::setStrikeoutCheckBox(QQuickCheckBox *strikeoutCheckBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->strikeoutCheckBox == strikeoutCheckBox) + return; + + if (d->strikeoutCheckBox) { + disconnect(d->strikeoutCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + d->strikeoutCheckBox = strikeoutCheckBox; + + if (d->strikeoutCheckBox) { + connect(d->strikeoutCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + emit strikeoutCheckBoxChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::familyEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->familyEdit; +} + +void QQuickFontDialogImplAttached::setFamilyEdit(QQuickTextField *familyEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->familyEdit == familyEdit) + return; + + d->familyEdit = familyEdit; + + emit familyEditChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::styleEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->styleEdit; +} + +void QQuickFontDialogImplAttached::setStyleEdit(QQuickTextField *styleEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->styleEdit == styleEdit) + return; + + d->styleEdit = styleEdit; + + emit styleEditChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::sizeEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sizeEdit; +} + +void QQuickFontDialogImplAttached::setSizeEdit(QQuickTextField *sizeEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->sizeEdit == sizeEdit) + return; + + if (d->sizeEdit) { + disconnect(d->sizeEdit, &QQuickTextField::textChanged, + this, &QQuickFontDialogImplAttached::_q_sizeEdited); + } + + d->sizeEdit = sizeEdit; + + if (d->sizeEdit) { + connect(d->sizeEdit, &QQuickTextField::textChanged, + this, &QQuickFontDialogImplAttached::_q_sizeEdited); + } + + emit sizeEditChanged(); +} + +static int findFamilyInModel(const QString &selectedFamily, const QStringList &model) +{ + enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 }; + QString foundryName1, familyName1, foundryName2, familyName2; + int bestFamilyMatch = -1; + match_t bestFamilyType = MATCH_NONE; + const QFont f; + + QFontDatabasePrivate::parseFontName(selectedFamily, foundryName1, familyName1); + + int i = 0; + for (auto it = model.constBegin(); it != model.constEnd(); ++it, ++i) { + QFontDatabasePrivate::parseFontName(*it, foundryName2, familyName2); + + if (familyName1 == familyName2) { + bestFamilyType = MATCH_FAMILY; + if (foundryName1 == foundryName2) + return i; + else + bestFamilyMatch = i; + } + + // fallbacks + match_t type = MATCH_NONE; + if (bestFamilyType <= MATCH_NONE && familyName2 == QStringLiteral("helvetica")) + type = MATCH_LAST_RESORT; + if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.families().constFirst()) + type = MATCH_APP; + if (type != MATCH_NONE) { + bestFamilyType = type; + bestFamilyMatch = i; + } + } + + return bestFamilyMatch; +} + +static int findStyleInModel(const QString &selectedStyle, const QStringList &model) +{ + if (model.isEmpty()) + return -1; + + if (!selectedStyle.isEmpty()) { + const int idx = model.indexOf(QRegularExpression(QRegularExpression::escape(selectedStyle), QRegularExpression::CaseInsensitiveOption)); + if (idx >= 0) + return idx; + + enum class StyleClass {Unknown, Normal, Italic}; + auto classifyStyleFallback = [](const QString & style) { + if (style.toLower() == QLatin1String("italic") || style.toLower() == QLatin1String("oblique")) + return StyleClass::Italic; + if (style.toLower() == QLatin1String("normal") || style.toLower() == QLatin1String("regular")) + return StyleClass::Normal; + return StyleClass::Unknown; + }; + + auto styleClass = classifyStyleFallback(selectedStyle); + + if (styleClass != StyleClass::Unknown) + for (int i = 0; i < model.count(); ++i) + if (classifyStyleFallback(model.at(i)) == styleClass) + return i; + } + return 0; +} + +/*! + \internal + + Updates the model for the family list view, and attempt + to reselect the previously selected font family. + */ +void QQuickFontDialogImplAttached::updateFamilies() +{ + const QFontDialogOptions::FontDialogOptions scalableMask( + QFontDialogOptions::ScalableFonts | QFontDialogOptions::NonScalableFonts); + + const QFontDialogOptions::FontDialogOptions spacingMask(QFontDialogOptions::ProportionalFonts + | QFontDialogOptions::MonospacedFonts); + + const auto p = qobject_cast<QQuickFontDialogImpl *>(parent()); + + const auto options = p->options()->options(); + + QStringList familyNames; + const auto families = QFontDatabase::families(m_writingSystem); + for (const auto &family : families) { + if (QFontDatabase::isPrivateFamily(family)) + continue; + + if ((options & scalableMask) && (options & scalableMask) != scalableMask) { + if (bool(options & QFontDialogOptions::ScalableFonts) + != QFontDatabase::isSmoothlyScalable(family)) + continue; + } + + if ((options & spacingMask) && (options & scalableMask) != spacingMask) { + if (bool(options & QFontDialogOptions::MonospacedFonts) + != QFontDatabase::isFixedPitch(family)) + continue; + } + + familyNames << family; + } + + auto listView = familyListView(); + + // Index will be set to -1 on empty model, and 0 for non empty models. + m_ignoreFamilyUpdate = !m_selectedFamily.isEmpty(); + listView->setModel(familyNames); + m_ignoreFamilyUpdate = false; + + // Will overwrite selectedFamily and selectedStyle + listView->setCurrentIndex(findFamilyInModel(m_selectedFamily, familyNames)); + + if (familyNames.isEmpty()) + _q_familyChanged(); +} + +/*! + \internal + + Updates the model for the style list view, and + attempt to reselect the style that was previously selected. + + Calls updateSizes() + */ +void QQuickFontDialogImplAttached::updateStyles() +{ + const QString family = familyListView()->currentIndex() >= 0 ? m_selectedFamily : QString(); + const QStringList styles = QFontDatabase::styles(family); + + auto listView = styleListView(); + + m_ignoreStyleUpdate = !m_selectedStyle.isEmpty(); + listView->setModel(styles); + + if (styles.isEmpty()) { + styleEdit()->clear(); + m_smoothlyScalable = false; + } else { + int newIndex = findStyleInModel(m_selectedStyle, styles); + + listView->setCurrentIndex(newIndex); + + m_selectedStyle = styles.at(newIndex); + styleEdit()->setText(m_selectedStyle); + + m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle); + } + + m_ignoreStyleUpdate = false; + + updateSizes(); +} + +/*! + \internal + + Updates the model for the size list view, + and attempts to reselect the size that was previously selected + */ +void QQuickFontDialogImplAttached::updateSizes() +{ + if (!m_selectedFamily.isEmpty()) { + const QList<int> sizes = QFontDatabase::pointSizes(m_selectedFamily, m_selectedStyle); + + QStringList str_sizes; + + str_sizes.reserve(sizes.size()); + + int idx = 0, current = -1; + for (QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); it++) { + str_sizes.append(QString::number(*it)); + if (current == -1 && m_selectedSize == *it) { + current = idx; + } + ++idx; + } + + auto listView = sizeListView(); + + // only select the first element in the model when this function is first called and the new model isn't empty + listView->setModel(str_sizes); + + if (current != -1) + listView->setCurrentIndex(current); + + sizeEdit()->setText(!m_smoothlyScalable && listView->currentIndex() > 0 + ? str_sizes.at(listView->currentIndex()) + : QString::number(m_selectedSize)); + } else { + qCWarning(lcAttachedProperty) << "Warning! selectedFamily is empty"; + sizeEdit()->clear(); + } + + _q_updateSample(); +} + +void QQuickFontDialogImplAttached::_q_updateSample() +{ + if (m_selectedFamily.isEmpty()) + return; + + const int pSize = sizeEdit()->text().toInt(); + + QFont newFont = QFontDatabase::font(m_selectedFamily, m_selectedStyle, pSize); + + newFont.setUnderline(underlineCheckBox()->isChecked()); + newFont.setStrikeOut(strikeoutCheckBox()->isChecked()); + + sampleEdit()->setFont(newFont); +} + +void QQuickFontDialogImplAttached::_q_writingSystemChanged(int index) +{ + m_writingSystem = QFontDatabase::WritingSystem(index); + sampleEdit()->setText(QFontDatabase::writingSystemSample(m_writingSystem)); + + updateFamilies(); +} + +void QQuickFontDialogImplAttached::searchListView(const QString &s, QQuickListView *listView) +{ + const QStringList model = listView->model().toStringList(); + + bool redo = false; + + do { + m_search.append(s); + + for (int i = 0; i < model.count(); ++i) { + if (model.at(i).startsWith(m_search, Qt::CaseInsensitive)) { + listView->setCurrentIndex(i); + return; + } + } + + clearSearch(); + + redo = !redo; + } while (redo); +} + +void QQuickFontDialogImplAttached::clearSearch() +{ + m_search.clear(); +} + +void QQuickFontDialogImplAttached::_q_familyChanged() +{ + if (m_ignoreFamilyUpdate) + return; + + const int index = familyListView()->currentIndex(); + + if (index < 0) { + familyEdit()->clear(); + } else { + m_selectedFamily = familyListView()->model().toStringList().at(index); + familyEdit()->setText(m_selectedFamily); + } + + updateStyles(); +} + +void QQuickFontDialogImplAttached::_q_styleChanged() +{ + if (m_ignoreStyleUpdate) + return; + + const int index = styleListView()->currentIndex(); + + if (index < 0) { + qCWarning(lcAttachedProperty) << "currentIndex changed to -1"; + return; + } + + m_selectedStyle = styleListView()->model().toStringList().at(index); + styleEdit()->setText(m_selectedStyle); + m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle); + + updateSizes(); +} + +void QQuickFontDialogImplAttached::_q_sizeEdited() +{ + const int size = qAbs(sizeEdit()->text().toInt()); + + if (size == m_selectedSize) + return; + + m_selectedSize = size; + + if (sizeListView()->count()) { + auto model = sizeListView()->model().toStringList(); + + int i; + for (i = 0; i < model.count() - 1; ++i) { + if (model.at(i).toInt() >= size) + break; + } + + QSignalBlocker blocker(sizeListView()); + if (model.at(i).toInt() == size) + sizeListView()->setCurrentIndex(i); + else + sizeListView()->setCurrentIndex(-1); + } + + _q_updateSample(); +} + +void QQuickFontDialogImplAttached::_q_sizeChanged() +{ + const int index = sizeListView()->currentIndex(); + + if (index < 0) { + qCWarning(lcAttachedProperty) << "currentIndex changed to -1"; + return; + } + + const QString s = sizeListView()->model().toStringList().at(index); + m_selectedSize = s.toInt(); + + sizeEdit()->setText(s); + + _q_updateSample(); +} + +void QQuickFontDialogImplAttachedPrivate::currentFontChanged(const QFont &font) +{ + auto fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent); + + if (!fontDialogImpl) { + return; + } + + fontDialogImpl->setCurrentFont(font); + + if (fontDialogImpl->options()->testOption(QFontDialogOptions::NoButtons)) + emit fontDialogImpl->fontSelected(font); +} + +void QQuickFontDialogImplAttached::selectFontInListViews(const QFont &font) +{ + { + QSignalBlocker blocker(sampleEdit()); + familyListView()->setCurrentIndex(findFamilyInModel(font.families().constFirst(), familyListView()->model().toStringList())); + styleListView()->setCurrentIndex(findStyleInModel(QFontDatabase::styleString(font), styleListView()->model().toStringList())); + sizeEdit()->setText(QString::number(font.pointSize())); + + underlineCheckBox()->setChecked(font.underline()); + strikeoutCheckBox()->setChecked(font.strikeOut()); + } + + _q_updateSample(); +} + +QT_END_NAMESPACE + +#include "moc_qquickfontdialogimpl_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h new file mode 100644 index 0000000000..899f1d4b04 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h @@ -0,0 +1,217 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOGIMPL_P_H +#define QQUICKFONTDIALOGIMPL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qfontdatabase.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuick/private/qquicktextedit_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickcheckbox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickDialogButtonBox; + +class QQuickFontDialogImplAttached; +class QQuickFontDialogImplAttachedPrivate; +class QQuickFontDialogImplPrivate; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFontDialogImpl : public QQuickDialog +{ + Q_OBJECT + Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged FINAL) + QML_NAMED_ELEMENT(FontDialogImpl) + QML_ATTACHED(QQuickFontDialogImplAttached) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFontDialogImpl(QObject *parent = nullptr); + + static QQuickFontDialogImplAttached *qmlAttachedProperties(QObject *object); + + QSharedPointer<QFontDialogOptions> options() const; + void setOptions(const QSharedPointer<QFontDialogOptions> &options); + + QFont currentFont() const; + void setCurrentFont(const QFont &font, bool selectInListViews = false); + + void init(); + +Q_SIGNALS: + void optionsChanged(); + void currentFontChanged(const QFont &font); + void fontSelected(const QFont &font); + +private: + void keyReleaseEvent(QKeyEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + + Q_DISABLE_COPY(QQuickFontDialogImpl) + Q_DECLARE_PRIVATE(QQuickFontDialogImpl) +}; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFontDialogImplAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickListView *familyListView READ familyListView WRITE setFamilyListView + NOTIFY familyListViewChanged) + Q_PROPERTY(QQuickListView *styleListView READ styleListView WRITE setStyleListView + NOTIFY styleListViewChanged) + Q_PROPERTY(QQuickListView *sizeListView READ sizeListView WRITE setSizeListView + NOTIFY sizeListViewChanged) + Q_PROPERTY(QQuickTextEdit *sampleEdit READ sampleEdit WRITE setSampleEdit + NOTIFY sampleEditChanged) + Q_PROPERTY(QQuickDialogButtonBox *buttonBox READ buttonBox WRITE setButtonBox + NOTIFY buttonBoxChanged) + Q_PROPERTY(QQuickComboBox *writingSystemComboBox READ writingSystemComboBox + WRITE setWritingSystemComboBox NOTIFY writingSystemComboBoxChanged) + Q_PROPERTY(QQuickCheckBox *underlineCheckBox READ underlineCheckBox WRITE setUnderlineCheckBox + NOTIFY underlineCheckBoxChanged) + Q_PROPERTY(QQuickCheckBox *strikeoutCheckBox READ strikeoutCheckBox WRITE setStrikeoutCheckBox + NOTIFY strikeoutCheckBoxChanged) + + Q_PROPERTY(QQuickTextField *familyEdit READ familyEdit WRITE setFamilyEdit + NOTIFY familyEditChanged) + Q_PROPERTY(QQuickTextField *styleEdit READ styleEdit WRITE setStyleEdit NOTIFY styleEditChanged) + Q_PROPERTY(QQuickTextField *sizeEdit READ sizeEdit WRITE setSizeEdit NOTIFY sizeEditChanged) + + Q_MOC_INCLUDE(<QtQuickTemplates2 / private / qquickdialogbuttonbox_p.h>) + +public: + explicit QQuickFontDialogImplAttached(QObject *parent = nullptr); + + QQuickListView *familyListView() const; + void setFamilyListView(QQuickListView *familyListView); + + QQuickListView *styleListView() const; + void setStyleListView(QQuickListView *styleListView); + + QQuickListView *sizeListView() const; + void setSizeListView(QQuickListView *sizeListView); + + QQuickTextEdit *sampleEdit() const; + void setSampleEdit(QQuickTextEdit *sampleEdit); + + QQuickDialogButtonBox *buttonBox() const; + void setButtonBox(QQuickDialogButtonBox *buttonBox); + + QQuickComboBox *writingSystemComboBox() const; + void setWritingSystemComboBox(QQuickComboBox *writingSystemComboBox); + + QQuickCheckBox *underlineCheckBox() const; + void setUnderlineCheckBox(QQuickCheckBox *underlineCheckBox); + + QQuickCheckBox *strikeoutCheckBox() const; + void setStrikeoutCheckBox(QQuickCheckBox *strikethroughCheckBox); + + QQuickTextField *familyEdit() const; + void setFamilyEdit(QQuickTextField *familyEdit); + + QQuickTextField *styleEdit() const; + void setStyleEdit(QQuickTextField *styleEdit); + + QQuickTextField *sizeEdit() const; + void setSizeEdit(QQuickTextField *sizeEdit); + +Q_SIGNALS: + void buttonBoxChanged(); + void familyListViewChanged(); + void styleListViewChanged(); + void sizeListViewChanged(); + void sampleEditChanged(); + void writingSystemComboBoxChanged(); + void underlineCheckBoxChanged(); + void strikeoutCheckBoxChanged(); + void familyEditChanged(); + void styleEditChanged(); + void sizeEditChanged(); + +public: + void searchFamily(const QString &s) { searchListView(s, familyListView()); } + void searchStyle(const QString &s) { searchListView(s, styleListView()); } + void clearSearch(); + + void updateFamilies(); + void selectFontInListViews(const QFont &font); + +private: + void updateStyles(); + void updateSizes(); + + void _q_familyChanged(); + void _q_styleChanged(); + void _q_sizeEdited(); + void _q_sizeChanged(); + void _q_updateSample(); + + void _q_writingSystemChanged(int index); + + void searchListView(const QString &s, QQuickListView *listView); + + QFontDatabase::WritingSystem m_writingSystem; + QString m_selectedFamily; + QString m_selectedStyle; + QString m_search; + int m_selectedSize; + bool m_smoothlyScalable; + bool m_ignoreFamilyUpdate; + bool m_ignoreStyleUpdate; + + Q_DISABLE_COPY(QQuickFontDialogImplAttached) + Q_DECLARE_PRIVATE(QQuickFontDialogImplAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFontDialogImpl) + +#endif // QQUICKFONTDIALOGIMPL_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h new file mode 100644 index 0000000000..8de3480dd9 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOGIMPL_P_P_H +#define QQUICKFONTDIALOGIMPL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> + +#include "qquickfontdialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFontDialogImplPrivate : public QQuickDialogPrivate +{ + Q_DECLARE_PUBLIC(QQuickFontDialogImpl) +public: + QQuickFontDialogImplPrivate(); + + static QQuickFontDialogImplPrivate *get(QQuickFontDialogImpl *dialog) + { + return dialog->d_func(); + } + + QQuickFontDialogImplAttached *attachedOrWarn(); + + void updateEnabled(); + + void handleAccept() override; + void handleClick(QQuickAbstractButton *button) override; + + QSharedPointer<QFontDialogOptions> options; + + QFont currentFont; +}; + +class QQuickFontDialogImplAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickFontDialogImplAttached) + + void currentFontChanged(const QFont &font); + +public: + QPointer<QQuickDialogButtonBox> buttonBox; + QPointer<QQuickListView> familyListView; + QPointer<QQuickListView> styleListView; + QPointer<QQuickListView> sizeListView; + QPointer<QQuickTextEdit> sampleEdit; + QPointer<QQuickComboBox> writingSystemComboBox; + QPointer<QQuickCheckBox> underlineCheckBox; + QPointer<QQuickCheckBox> strikeoutCheckBox; + QPointer<QQuickTextField> familyEdit; + QPointer<QQuickTextField> styleEdit; + QPointer<QQuickTextField> sizeEdit; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFONTDIALOGIMPL_P_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog.cpp new file mode 100644 index 0000000000..a2d0f8f41c --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog.cpp @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickplatformfiledialog_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtGui/qwindow.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquickpopupanchors_p.h> + +#include "qquickfiledialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQuickPlatformFileDialog, "qt.quick.dialogs.quickplatformfiledialog") + +/*! + \class QQuickPlatformFileDialog + \internal + + An interface that QQuickFileDialog can use to access the non-native Qt Quick FileDialog. + + Both this and the native implementations are created in QQuickAbstractDialog::create(). +*/ +QQuickPlatformFileDialog::QQuickPlatformFileDialog(QObject *parent) +{ + qCDebug(lcQuickPlatformFileDialog) << "creating non-native Qt Quick FileDialog with parent" << parent; + + // Set a parent so that we get deleted if we can't be shown for whatever reason. + // Our eventual parent should be the window, though. + setParent(parent); + + auto qmlContext = ::qmlContext(parent); + if (!qmlContext) { + qmlWarning(parent) << "No QQmlContext for QQuickPlatformFileDialog; can't create non-native FileDialog implementation"; + return; + } + + const auto dialogQmlUrl = QUrl(QStringLiteral("qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/qml/FileDialog.qml")); + QQmlComponent fileDialogComponent(qmlContext->engine(), dialogQmlUrl, parent); + if (!fileDialogComponent.isReady()) { + qmlWarning(parent) << "Failed to load non-native FileDialog implementation:\n" << fileDialogComponent.errorString(); + return; + } + m_dialog = qobject_cast<QQuickFileDialogImpl*>(fileDialogComponent.create()); + if (!m_dialog) { + qmlWarning(parent) << "Failed to create an instance of the non-native FileDialog:\n" << fileDialogComponent.errorString(); + return; + } + // Give it a parent until it's parented to the window in show(). + m_dialog->setParent(this); + + connect(m_dialog, &QQuickDialog::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog, &QQuickDialog::rejected, this, &QPlatformDialogHelper::reject); + + connect(m_dialog, &QQuickFileDialogImpl::fileSelected, this, &QQuickPlatformFileDialog::fileSelected); + // TODO: add support for multiple file selection (QTBUG-92585) +// connect(m_dialog, &QQuickFileDialogImpl::filesSelected, [this](const QList<QString> &files) { +// QList<QUrl> urls; +// urls.reserve(files.count()); +// for (const QString &file : files) +// urls += QUrl::fromLocalFile(file); +// emit filesSelected(urls); +// }); + connect(m_dialog, &QQuickFileDialogImpl::currentFileChanged, this, &QQuickPlatformFileDialog::currentChanged); + connect(m_dialog, &QQuickFileDialogImpl::currentFolderChanged, this, &QQuickPlatformFileDialog::directoryEntered); + connect(m_dialog, &QQuickFileDialogImpl::filterSelected, this, &QQuickPlatformFileDialog::filterSelected); + + // We would do this in QQuickFileDialogImpl, but we need to ensure that folderChanged() + // is connected to directoryEntered() before setting it to ensure that the QQuickFileDialog is notified. + if (m_dialog->currentFolder().isEmpty()) + m_dialog->setCurrentFolder(QUrl::fromLocalFile(QDir().absolutePath())); +} + +bool QQuickPlatformFileDialog::isValid() const +{ + return m_dialog; +} + +bool QQuickPlatformFileDialog::defaultNameFilterDisables() const +{ + return false; +} + +void QQuickPlatformFileDialog::setDirectory(const QUrl &directory) +{ + if (!m_dialog) + return; + + m_dialog->setCurrentFolder(directory); +} + +QUrl QQuickPlatformFileDialog::directory() const +{ + if (!m_dialog) + return {}; + + return m_dialog->currentFolder(); +} + +void QQuickPlatformFileDialog::selectFile(const QUrl &file) +{ + if (!m_dialog) + return; + + m_dialog->setSelectedFile(file); +} + +QList<QUrl> QQuickPlatformFileDialog::selectedFiles() const +{ + // TODO: support for multiple selected files + return { m_dialog->currentFile() }; +} + +void QQuickPlatformFileDialog::setFilter() +{ +} + +void QQuickPlatformFileDialog::selectNameFilter(const QString &filter) +{ + // There is a bit of a problem with order here - QQuickFileDialog::onShow() + // is called before our show(), but it needs to set the selected filter + // (which we can't do in our show() because we don't know about QQuickFileDialog). + // So, delay setting the filter until we're shown. This shouldn't be an issue + // in practice, since it doesn't make sense for the filter to programmatically + // change while the dialog is visible. + m_pendingNameFilter = filter; +} + +QString QQuickPlatformFileDialog::selectedNameFilter() const +{ + return m_dialog->selectedNameFilter()->name(); +} + +void QQuickPlatformFileDialog::exec() +{ + qCWarning(lcQuickPlatformFileDialog) << "exec() is not supported for the Qt Quick FileDialog fallback"; +} + +bool QQuickPlatformFileDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) +{ + qCDebug(lcQuickPlatformFileDialog) << "show called with flags" << flags << + "modality" << modality << "parent" << parent; + if (!m_dialog) + return false; + + if (!parent) + return false; + + auto quickWindow = qobject_cast<QQuickWindow*>(parent); + if (!quickWindow) { + qmlInfo(this->parent()) << "Parent window (" << parent << ") of non-native dialog is not a QQuickWindow"; + return false; + } + m_dialog->setParent(parent); + m_dialog->resetParentItem(); + + auto popupPrivate = QQuickPopupPrivate::get(m_dialog); + popupPrivate->getAnchors()->setCenterIn(m_dialog->parentItem()); + + QSharedPointer<QFileDialogOptions> options = QPlatformFileDialogHelper::options(); + m_dialog->setTitle(options->windowTitle()); + m_dialog->setOptions(options); + m_dialog->selectNameFilter(m_pendingNameFilter); + m_pendingNameFilter.clear(); + m_dialog->setAcceptLabel(options->isLabelExplicitlySet(QFileDialogOptions::Accept) + ? options->labelText(QFileDialogOptions::Accept) : QString()); + m_dialog->setRejectLabel(options->isLabelExplicitlySet(QFileDialogOptions::Reject) + ? options->labelText(QFileDialogOptions::Reject) : QString()); + + m_dialog->open(); + return true; +} + +void QQuickPlatformFileDialog::hide() +{ + if (!m_dialog) + return; + + m_dialog->close(); +} + +QQuickFileDialogImpl *QQuickPlatformFileDialog::dialog() const +{ + return m_dialog; +} + +QT_END_NAMESPACE + +#include "moc_qquickplatformfiledialog_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog_p.h new file mode 100644 index 0000000000..883b7ed9b7 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfiledialog_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPLATFORMFILEDIALOG_P_H +#define QQUICKPLATFORMFILEDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpa/qplatformdialoghelper.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFileDialogImpl; +class QWindow; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickPlatformFileDialog : public QPlatformFileDialogHelper +{ + Q_OBJECT + +public: + explicit QQuickPlatformFileDialog(QObject *parent); + ~QQuickPlatformFileDialog() = default; + + bool isValid() const; + bool defaultNameFilterDisables() const override; + void setDirectory(const QUrl &directory) override; + QUrl directory() const override; + void selectFile(const QUrl &file) override; + QList<QUrl> selectedFiles() const override; + void setFilter() override; + void selectNameFilter(const QString &filter) override; + QString selectedNameFilter() const override; + + void exec() override; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void hide() override; + + QQuickFileDialogImpl *dialog() const; + +private: + QQuickFileDialogImpl *m_dialog = nullptr; + QString m_pendingNameFilter; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPLATFORMFILEDIALOG_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp new file mode 100644 index 0000000000..0512ac1581 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickplatformfontdialog_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtGui/qwindow.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquickpopupanchors_p.h> + +#include "qquickfontdialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQuickPlatformFontDialog, "qt.quick.dialogs.quickplatformfontdialog") + +/*! + \class QQuickPlatformFontDialog + \internal + + An interface that QQuickFontDialog can use to access the non-native Qt Quick FontDialog. + + Both this and the native implementations are created in QQuickAbstractDialog::create(). + +*/ +QQuickPlatformFontDialog::QQuickPlatformFontDialog(QObject *parent) +{ + qCDebug(lcQuickPlatformFontDialog) + << "creating non-native Qt Quick FontDialog with parent" << parent; + + // Set a parent so that we get deleted if we can't be shown for whatever reason. + // Our eventual parent should be the window, though. + setParent(parent); + + auto qmlContext = ::qmlContext(parent); + if (!qmlContext) { + qmlWarning(parent) << "No QQmlContext for QQuickPlatformFontDialog; can't create " + "non-native FontDialog implementation"; + return; + } + + const auto dialogQmlUrl = QUrl(QStringLiteral( + "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/qml/FontDialog.qml")); + + QQmlComponent fontDialogComponent(qmlContext->engine(), dialogQmlUrl, parent); + if (!fontDialogComponent.isReady()) { + qmlWarning(parent) << "Failed to load non-native FontDialog implementation:\n" + << fontDialogComponent.errorString(); + return; + } + + m_dialog = qobject_cast<QQuickFontDialogImpl *>(fontDialogComponent.create()); + + if (!m_dialog) { + qmlWarning(parent) << "Failed to create an instance of the non-native FontDialog:\n" + << fontDialogComponent.errorString(); + return; + } + + m_dialog->setParent(this); + + connect(m_dialog, &QQuickDialog::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog, &QQuickDialog::rejected, this, &QPlatformDialogHelper::reject); + + connect(m_dialog, &QQuickFontDialogImpl::currentFontChanged, + this, &QQuickPlatformFontDialog::currentFontChanged); + connect(m_dialog, &QQuickFontDialogImpl::fontSelected, this, &QQuickPlatformFontDialog::fontSelected); +} + +bool QQuickPlatformFontDialog::isValid() const +{ + return m_dialog; +} + +void QQuickPlatformFontDialog::setCurrentFont(const QFont &font) +{ + if (m_dialog) + m_dialog->setCurrentFont(font, true); +} + +QFont QQuickPlatformFontDialog::currentFont() const +{ + return m_dialog ? m_dialog->currentFont() : QFont(); +} + +void QQuickPlatformFontDialog::exec() +{ + qCWarning(lcQuickPlatformFontDialog) + << "exec() is not supported for the Qt Quick FontDialog fallback"; +} + +bool QQuickPlatformFontDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, + QWindow *parent) +{ + qCDebug(lcQuickPlatformFontDialog) + << "show called with flags" << flags << "modality" << modality << "parent" << parent; + + if (!isValid()) + return false; + + if (!parent) + return false; + + auto quickWindow = qobject_cast<QQuickWindow *>(parent); + if (!quickWindow) { + qmlInfo(this->parent()) << "Parent window (" << parent + << ") of non-native dialog is not a QQuickWindow"; + return false; + } + m_dialog->setParent(parent); + m_dialog->resetParentItem(); + + auto popupPrivate = QQuickPopupPrivate::get(m_dialog); + popupPrivate->getAnchors()->setCenterIn(m_dialog->parentItem()); + + QSharedPointer<QFontDialogOptions> options = QPlatformFontDialogHelper::options(); + m_dialog->setTitle(options->windowTitle()); + m_dialog->setOptions(options); + + m_dialog->init(); + + m_dialog->open(); + return true; +} + +void QQuickPlatformFontDialog::hide() +{ + if (isValid()) + m_dialog->close(); +} + +QQuickFontDialogImpl *QQuickPlatformFontDialog::dialog() const +{ + return m_dialog; +} + +QT_END_NAMESPACE + +#include "moc_qquickplatformfontdialog_p.cpp" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h new file mode 100644 index 0000000000..a5009facab --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPLATFORMFONTDIALOG_P_H +#define QQUICKPLATFORMFONTDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpa/qplatformdialoghelper.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFontDialogImpl; +class QWindow; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickPlatformFontDialog + : public QPlatformFontDialogHelper +{ + Q_OBJECT + +public: + explicit QQuickPlatformFontDialog(QObject *parent); + ~QQuickPlatformFontDialog() = default; + + bool isValid() const; + + virtual void setCurrentFont(const QFont &font) override; + virtual QFont currentFont() const override; + + void exec() override; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void hide() override; + + QQuickFontDialogImpl *dialog() const; + +private: + QQuickFontDialogImpl *m_dialog = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPLATFORMFONTDIALOG_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplforeign_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplforeign_p.h new file mode 100644 index 0000000000..b1740606e3 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplforeign_p.h @@ -0,0 +1,115 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKDIALOGS2QUICKIMPLFOREIGN_P_H +#define QTQUICKDIALOGS2QUICKIMPLFOREIGN_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQml/qqml.h> +#include <QtQuickDialogs2Utils/private/qquickfilenamefilter_p.h> +#include <QtQuickTemplates2/private/qquickabstractbutton_p.h> +#include <QtQuickTemplates2/private/qquickcontrol_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickicon_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p.h> + +QT_BEGIN_NAMESPACE + +struct QQuickFileNameFilterQuickDialogs2QuickImplForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickFileNameFilter) + QML_ADDED_IN_VERSION(6, 2) +}; + +// TODO: remove these ones when not needed (QTBUG-88179) + +// verticalPadding, etc. +struct QQuickControlForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickControl) + QML_ADDED_IN_VERSION(2, 0) +}; + +struct QQuickAbstractButtonForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickAbstractButton) + QML_ADDED_IN_VERSION(2, 0) +}; + +struct QQuickIconForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickIcon) + QML_ADDED_IN_VERSION(6, 2) +}; + +// For leftInset, etc. +struct QQuickPopupForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickPopup) + QML_ADDED_IN_VERSION(2, 0) +}; + +struct QQuickDialogForeign +{ + Q_GADGET + QML_ANONYMOUS + QML_FOREIGN(QQuickDialog) + QML_ADDED_IN_VERSION(2, 1) +}; + +QT_END_NAMESPACE + +#endif // QTQUICKDIALOGS2QUICKIMPLFOREIGN_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplglobal_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplglobal_p.h new file mode 100644 index 0000000000..38b5a01bea --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qtquickdialogs2quickimplglobal_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the 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. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTQUICKDIALOGS2QUICKIMPLGLOBAL_P_H +#define QTQUICKDIALOGS2QUICKIMPLGLOBAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtQml/private/qqmlglobal_p.h> + +QT_BEGIN_NAMESPACE + +#ifndef QT_STATIC +# if defined(QT_BUILD_QUICKDIALOGS2QUICKIMPL_LIB) +# define Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT Q_DECL_EXPORT +# else +# define Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT +#endif + +QT_END_NAMESPACE + +#endif // QTQUICKDIALOGS2QUICKIMPLGLOBAL_P_H |