macOS: Use single truth to track file dialog current directory

Unfortunately we can not rely on the file dialog panel for this,
via the directoryURL property, as that property has not yet been
updated during a panel:directoryDidChange: callback, resulting in
the directory reported to the user being the previous directory.

Since we already have to store the current directory for the case
where we haven't yet created the file dialog panel we re-use this
variable as the single place to store the current directory.

It's not clear whether we still need to normalize the strings
we get from the NSSavePanel, but the code has been left in,
even if the old callback code didn't normalize the path that
we then emitted as directoryEntered().

Fixes: QTBUG-119371
Pick-to: 6.5 6.2
Change-Id: I379a47053302e73d5e06a2b941f40365c17390d5
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit a81395f2c604c84cd0e6f18165c766419f26b7ba)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 4075ffa498634c38771290275a3162df2c5c5e5b)
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Tor Arne Vestbø 2023-12-09 19:06:01 +01:00
parent 14ee331052
commit 9a38001737
2 changed files with 22 additions and 23 deletions

View File

@ -38,6 +38,7 @@ public:
public: // for QNSOpenSavePanelDelegate
void panelClosed(NSInteger result);
void panelDirectoryDidChange(NSString *path);
private:
void createNSOpenSavePanelDelegate();

View File

@ -55,7 +55,6 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
NSPopUpButton *m_popupButton;
NSTextField *m_textField;
QPointer<QCocoaFileDialogHelper> m_helper;
NSString *m_currentDirectory;
SharedPointerFileDialogOptions m_options;
QString m_currentSelection;
@ -86,10 +85,10 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
const QFileInfo sel(selectFile);
if (sel.isDir() && !sel.isBundle()){
m_currentDirectory = [sel.absoluteFilePath().toNSString() retain];
m_panel.directoryURL = [NSURL fileURLWithPath:sel.absoluteFilePath().toNSString()];
m_currentSelection.clear();
} else {
m_currentDirectory = [sel.absolutePath().toNSString() retain];
m_panel.directoryURL = [NSURL fileURLWithPath:sel.absolutePath().toNSString()];
m_currentSelection = sel.absoluteFilePath();
}
@ -99,7 +98,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
m_panel.accessoryView = m_nameFilterDropDownList.size() > 1 ? m_accessoryView : nil;
// -setAccessoryView: can result in -panel:directoryDidChange:
// resetting our m_currentDirectory, set the delegate
// resetting our current directory. Set the delegate
// here to make sure it gets the correct value.
m_panel.delegate = self;
@ -120,7 +119,6 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
[m_accessoryView release];
m_panel.delegate = nil;
[m_panel release];
[m_currentDirectory release];
[super dealloc];
}
@ -132,7 +130,6 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
bool selectable = (m_options->acceptMode() == QFileDialogOptions::AcceptSave)
|| [self panel:m_panel shouldEnableURL:url];
m_panel.directoryURL = [NSURL fileURLWithPath:m_currentDirectory];
m_panel.nameFieldStringValue = selectable ? info.fileName().toNSString() : @"";
[self updateProperties];
@ -379,17 +376,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
if (!m_helper)
return;
if (!path || [path isEqual:NSNull.null] || !path.length)
return;
if ([path isEqualToString:m_currentDirectory])
return;
[m_currentDirectory release];
m_currentDirectory = [path retain];
// ### fixme: priv->setLastVisitedDirectory(newDir);
emit m_helper->directoryEntered(QUrl::fromLocalFile(QString::fromNSString(m_currentDirectory)));
m_helper->panelDirectoryDidChange(path);
}
/*
@ -516,21 +503,32 @@ void QCocoaFileDialogHelper::panelClosed(NSInteger result)
void QCocoaFileDialogHelper::setDirectory(const QUrl &directory)
{
m_directory = directory;
if (m_delegate)
m_delegate->m_panel.directoryURL = [NSURL fileURLWithPath:directory.toLocalFile().toNSString()];
else
m_directory = directory;
}
QUrl QCocoaFileDialogHelper::directory() const
{
if (m_delegate) {
QString path = QString::fromNSString(m_delegate->m_panel.directoryURL.path).normalized(QString::NormalizationForm_C);
return QUrl::fromLocalFile(path);
}
return m_directory;
}
void QCocoaFileDialogHelper::panelDirectoryDidChange(NSString *path)
{
if (!path || [path isEqual:NSNull.null] || !path.length)
return;
const auto oldDirectory = m_directory;
m_directory = QUrl::fromLocalFile(
QString::fromNSString(path).normalized(QString::NormalizationForm_C));
if (m_directory != oldDirectory) {
// FIXME: Plumb old directory back to QFileDialog's lastVisitedDir?
emit directoryEntered(m_directory);
}
}
void QCocoaFileDialogHelper::selectFile(const QUrl &filename)
{
QString filePath = filename.toLocalFile();