Use NSSavePanel.allowedContentTypes instead of allowedFileTypes

The latter has been deprecated as of macOS 12.

Change-Id: I5282ce7a42922e91813c21ebe163dde44a40c6a6
Reviewed-by: Doris Verria <doris.verria@qt.io>
This commit is contained in:
Tor Arne Vestbø 2025-04-09 12:32:07 +02:00
parent 3224b2fb14
commit 006329964d

View File

@ -275,10 +275,10 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
{ {
Q_ASSERT(sender == m_panel); Q_ASSERT(sender == m_panel);
if (!m_panel.allowedFileTypes && !m_selectedNameFilter.isEmpty()) { if (![m_panel.allowedContentTypes count] && !m_selectedNameFilter.isEmpty()) {
// The save panel hasn't done filtering on our behalf, // The save panel hasn't done filtering on our behalf,
// either because we couldn't represent the filter via // either because we couldn't represent the filter via
// allowedFileTypes, or we opted out due to a multi part // allowedContentTypes, or we opted out due to a multi part
// extension, so do the filtering/validation ourselves. // extension, so do the filtering/validation ourselves.
QFileInfo fileInfo(QString::fromNSString(url.path).normalized(QString::NormalizationForm_C)); QFileInfo fileInfo(QString::fromNSString(url.path).normalized(QString::NormalizationForm_C));
@ -447,9 +447,9 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
m_popupButton.hidden = chooseDirsOnly; // TODO hide the whole sunken pane instead? m_popupButton.hidden = chooseDirsOnly; // TODO hide the whole sunken pane instead?
m_panel.allowedFileTypes = [self computeAllowedFileTypes]; m_panel.allowedContentTypes = [self computeAllowedContentTypes];
// Setting allowedFileTypes to nil is not enough to reset any // Setting allowedContentTypes to @[] is not enough to reset any
// automatically added extension based on a previous filter. // automatically added extension based on a previous filter.
// This is problematic because extensions can in some cases // This is problematic because extensions can in some cases
// be hidden from the user, resulting in confusion when the // be hidden from the user, resulting in confusion when the
@ -458,10 +458,10 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
// content type to one without an extension, which forces // content type to one without an extension, which forces
// the save panel to update and remove the extension. // the save panel to update and remove the extension.
const bool nameFieldHasExtension = m_panel.nameFieldStringValue.pathExtension.length > 0; const bool nameFieldHasExtension = m_panel.nameFieldStringValue.pathExtension.length > 0;
if (!m_panel.allowedFileTypes && !nameFieldHasExtension && !openpanel_cast(m_panel)) { if (![m_panel.allowedContentTypes count] && !nameFieldHasExtension && !openpanel_cast(m_panel)) {
if (!UTTypeDirectory.preferredFilenameExtension) { if (!UTTypeDirectory.preferredFilenameExtension) {
m_panel.allowedContentTypes = @[ UTTypeDirectory ]; m_panel.allowedContentTypes = @[ UTTypeDirectory ];
m_panel.allowedFileTypes = nil; m_panel.allowedContentTypes = @[];
} else { } else {
qWarning() << "UTTypeDirectory unexpectedly reported an extension"; qWarning() << "UTTypeDirectory unexpectedly reported an extension";
} }
@ -508,20 +508,20 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
} }
/* /*
Computes a list of extensions (e.g. "png", "jpg", "gif") Computes a list of UTTypes ("public.plain-text" e.g.)
for the current name filter, and updates the save panel. for the current name filter.
If a filter do not conform to the format *.xyz or * or *.*, If a filter do not conform to the format *.xyz or * or *.*,
or contains an extensions with more than one part (e.g. "tar.gz") or contains an extensions with more than one part (e.g. "tar.gz")
we treat that as allowing all file types, and do our own we treat that as allowing all file types, and do our own
validation in panel:validateURL:error. validation in panel:validateURL:error.
*/ */
- (NSArray<NSString*>*)computeAllowedFileTypes - (NSArray<UTType*>*)computeAllowedContentTypes
{ {
if (m_options->acceptMode() != QFileDialogOptions::AcceptSave) if (m_options->acceptMode() != QFileDialogOptions::AcceptSave)
return nil; // panel:shouldEnableURL: does the file filtering for NSOpenPanel return @[]; // panel:shouldEnableURL: does the file filtering for NSOpenPanel
QStringList fileTypes; auto *types = [[NSMutableArray<UTType*> new] autorelease];
for (const QString &filter : std::as_const(m_selectedNameFilter)) { for (const QString &filter : std::as_const(m_selectedNameFilter)) {
if (!filter.startsWith("*."_L1)) if (!filter.startsWith("*."_L1))
continue; continue;
@ -534,12 +534,13 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
auto extensions = filter.split('.', Qt::SkipEmptyParts); auto extensions = filter.split('.', Qt::SkipEmptyParts);
if (extensions.count() > 2) if (extensions.count() > 2)
return nil; return @[];
fileTypes += extensions.last(); auto *utType = [UTType typeWithFilenameExtension:extensions.last().toNSString()];
[types addObject:utType];
} }
return fileTypes.isEmpty() ? nil : qt_mac_QStringListToNSMutableArray(fileTypes); return types;
} }
- (QString)removeExtensions:(const QString &)filter - (QString)removeExtensions:(const QString &)filter