macOS: Reset save dialog extension when resetting file name filter
We map QFileDialog name filters to NSSavePanel.allowedFileTypes, for example turning "Text Files (*.txt)" into allowedFileTypes = @[@"txt"]. In this case, the NSSavePanel will automatically add the extension to the user's file name, if they just type "foo". When a filter allows all files, we reset the allowedFileTypes to nil, but this does not reset the automatically added extension, so if the user switches from one filter (*.txt) to another (*.*), the file name will still have a .txt extension. This is problematic when the save panel's file name field does not show the extension to the user, which can happen automatically if the user types an initial file name without an extension, overriding what we've asked by setting extensionHidden=NO. When that happens, the user is shown "foo", but the actual file name is "foo.txt". To mitigate this confusing situation we do a round-trip via the UTTypeDirectory content type, which is a valid type without any extension. This forces the save panel to remove any extensions added automatically by previous filters. Change-Id: Ia17a8c2734eff656116ef77a9813113a5076e9cc Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> (cherry picked from commit 40506954979fa7cdd34da8251f179557eb9be4f3) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
5dabb905e7
commit
6972b8deea
@ -37,6 +37,7 @@ macro(qt_find_apple_system_frameworks)
|
||||
qt_internal_find_apple_system_framework(FWContacts Contacts)
|
||||
qt_internal_find_apple_system_framework(FWEventKit EventKit)
|
||||
qt_internal_find_apple_system_framework(FWHealthKit HealthKit)
|
||||
qt_internal_find_apple_system_framework(FWUniformTypeIdentifiers UniformTypeIdentifiers)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
@ -56,6 +56,7 @@ qt_internal_add_plugin(QCocoaIntegrationPlugin
|
||||
${FWIOSurface}
|
||||
${FWMetal}
|
||||
${FWQuartzCore}
|
||||
${FWUniformTypeIdentifiers}
|
||||
Qt::Core
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <qpa/qplatformtheme.h>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
#include <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
@ -438,6 +440,24 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
|
||||
|
||||
m_panel.allowedFileTypes = [self computeAllowedFileTypes];
|
||||
|
||||
// Setting allowedFileTypes to nil is not enough to reset any
|
||||
// automatically added extension based on a previous filter.
|
||||
// This is problematic because extensions can in some cases
|
||||
// be hidden from the user, resulting in confusion when the
|
||||
// resulting file name doesn't match the current empty filter.
|
||||
// We work around this by temporarily resetting the allowed
|
||||
// content type to one without an extension, which forces
|
||||
// the save panel to update and remove the extension.
|
||||
const bool nameFieldHasExtension = m_panel.nameFieldStringValue.pathExtension.length > 0;
|
||||
if (!m_panel.allowedFileTypes && !nameFieldHasExtension && !openpanel_cast(m_panel)) {
|
||||
if (!UTTypeDirectory.preferredFilenameExtension) {
|
||||
m_panel.allowedContentTypes = @[ UTTypeDirectory ];
|
||||
m_panel.allowedFileTypes = nil;
|
||||
} else {
|
||||
qWarning() << "UTTypeDirectory unexpectedly reported an extension";
|
||||
}
|
||||
}
|
||||
|
||||
m_panel.showsHiddenFiles = m_options->filter().testFlag(QDir::Hidden);
|
||||
|
||||
if (m_panel.visible)
|
||||
|
Loading…
x
Reference in New Issue
Block a user