From 4075ffa498634c38771290275a3162df2c5c5e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 9 Dec 2023 19:06:01 +0100 Subject: [PATCH] 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.6 6.5 6.2 Change-Id: I379a47053302e73d5e06a2b941f40365c17390d5 Reviewed-by: Volker Hilsheimer (cherry picked from commit a81395f2c604c84cd0e6f18165c766419f26b7ba) Reviewed-by: Qt Cherry-pick Bot --- .../platforms/cocoa/qcocoafiledialoghelper.h | 1 + .../platforms/cocoa/qcocoafiledialoghelper.mm | 44 +++++++++---------- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h index 85e317b8ef8..3ffccb10fd8 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h @@ -38,6 +38,7 @@ public: public: // for QNSOpenSavePanelDelegate void panelClosed(NSInteger result); + void panelDirectoryDidChange(NSString *path); private: void createNSOpenSavePanelDelegate(); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index f2161fd9a7d..6ce2ed2056d 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -55,7 +55,6 @@ typedef QSharedPointer SharedPointerFileDialogOptions; NSPopUpButton *m_popupButton; NSTextField *m_textField; QPointer m_helper; - NSString *m_currentDirectory; SharedPointerFileDialogOptions m_options; QString m_currentSelection; @@ -86,10 +85,10 @@ typedef QSharedPointer 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 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 SharedPointerFileDialogOptions; [m_accessoryView release]; m_panel.delegate = nil; [m_panel release]; - [m_currentDirectory release]; [super dealloc]; } @@ -132,7 +130,6 @@ typedef QSharedPointer 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 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();