OSX file dialog extensions (#2592)
Re-introduce OpenSavePanelDelegate for filtering when wildcard is provided (Spotlight search field was not working correctly, if extension was not known) (and on macOS 10.11 allow programmatically showing the extra panel) see http://www.github.com/wxWidgets/wxWidgets/pull/2592 and https://trac.wxwidgets.org/ticket/19324 co-authered-by: Jeff Young <jeff at rokeby dot ie>
This commit is contained in:
parent
c5f023a829
commit
e765756555
@ -95,6 +95,7 @@ protected:
|
|||||||
bool m_useFileTypeFilter;
|
bool m_useFileTypeFilter;
|
||||||
int m_firstFileTypeFilter;
|
int m_firstFileTypeFilter;
|
||||||
wxArrayString m_currentExtensions;
|
wxArrayString m_currentExtensions;
|
||||||
|
WX_NSObject m_delegate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -41,6 +41,63 @@
|
|||||||
|
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// delegate for filtering by wildcard
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
@interface wxOpenSavePanelDelegate : NSObject<NSOpenSavePanelDelegate>
|
||||||
|
|
||||||
|
- (void)setAllowedExtensions:(const wxArrayString &)extensions;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation wxOpenSavePanelDelegate
|
||||||
|
{
|
||||||
|
wxArrayString m_extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url
|
||||||
|
{
|
||||||
|
if ( [url isFileURL] )
|
||||||
|
{
|
||||||
|
NSString* filename = [url path];
|
||||||
|
NSString* resolvedLink = [[NSFileManager defaultManager] destinationOfSymbolicLinkAtPath:filename error:nil];
|
||||||
|
|
||||||
|
if ( resolvedLink != nil )
|
||||||
|
filename = resolvedLink;
|
||||||
|
|
||||||
|
BOOL isDir = NO;
|
||||||
|
if( [[NSFileManager defaultManager]
|
||||||
|
fileExistsAtPath:filename isDirectory:&isDir] && isDir )
|
||||||
|
{
|
||||||
|
// allow ordinary folders to be enabled, but for packages apply our extensions check
|
||||||
|
|
||||||
|
if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO)
|
||||||
|
return YES; // it's a folder, OK to show
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_extensions.GetCount() == 0 )
|
||||||
|
return YES;
|
||||||
|
|
||||||
|
NSString *ext = [filename pathExtension];
|
||||||
|
wxString wxext = wxCFStringRef([ext retain]).AsString().Lower();
|
||||||
|
|
||||||
|
for( const wxString& extension : m_extensions )
|
||||||
|
{
|
||||||
|
if( wxext == extension )
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAllowedExtensions:(const wxArrayString &)extensions
|
||||||
|
{
|
||||||
|
m_extensions = extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -50,6 +107,7 @@ wxIMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase);
|
|||||||
void wxFileDialog::Init()
|
void wxFileDialog::Init()
|
||||||
{
|
{
|
||||||
m_filterIndex = -1;
|
m_filterIndex = -1;
|
||||||
|
m_delegate = nil;
|
||||||
m_filterPanel = NULL;
|
m_filterPanel = NULL;
|
||||||
m_filterChoice = NULL;
|
m_filterChoice = NULL;
|
||||||
m_useFileTypeFilter = false;
|
m_useFileTypeFilter = false;
|
||||||
@ -114,13 +172,14 @@ NSArray* GetTypesFromExtension( const wxString extensiongroup, wxArrayString& ex
|
|||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSArray* GetTypesFromFilter( const wxString& filter, wxArrayString& names, wxArrayString& extensiongroups )
|
NSArray* GetTypesFromFilter( const wxString& filter, wxArrayString& names, wxArrayString& extensiongroups, wxArrayString& allextensions )
|
||||||
{
|
{
|
||||||
NSMutableArray* types = nil;
|
NSMutableArray* types = nil;
|
||||||
bool allowAll = false;
|
bool allowAll = false;
|
||||||
|
|
||||||
names.Clear();
|
names.Clear();
|
||||||
extensiongroups.Clear();
|
extensiongroups.Clear();
|
||||||
|
allextensions.Clear();
|
||||||
|
|
||||||
if ( !filter.empty() )
|
if ( !filter.empty() )
|
||||||
{
|
{
|
||||||
@ -159,6 +218,8 @@ NSArray* GetTypesFromFilter( const wxString& filter, wxArrayString& names, wxArr
|
|||||||
types = [[NSMutableArray alloc] init];
|
types = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
[types addObjectsFromArray:exttypes];
|
[types addObjectsFromArray:exttypes];
|
||||||
|
for( auto const& s : extensions )
|
||||||
|
allextensions.Add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -168,6 +229,8 @@ NSArray* GetTypesFromFilter( const wxString& filter, wxArrayString& names, wxArr
|
|||||||
types = nil;
|
types = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( allowAll )
|
||||||
|
allextensions.Clear();
|
||||||
}
|
}
|
||||||
[types autorelease];
|
[types autorelease];
|
||||||
return types;
|
return types;
|
||||||
@ -188,7 +251,7 @@ void wxFileDialog::ShowWindowModal()
|
|||||||
|
|
||||||
wxCHECK_RET(parentWindow, "Window modal display requires parent.");
|
wxCHECK_RET(parentWindow, "Window modal display requires parent.");
|
||||||
|
|
||||||
NSArray* types = GetTypesFromFilter( m_wildCard, m_filterNames, m_filterExtensions ) ;
|
NSArray* types = GetTypesFromFilter( m_wildCard, m_filterNames, m_filterExtensions, m_currentExtensions ) ;
|
||||||
if ( HasFlag(wxFD_SAVE) )
|
if ( HasFlag(wxFD_SAVE) )
|
||||||
{
|
{
|
||||||
NSSavePanel* sPanel = [NSSavePanel savePanel];
|
NSSavePanel* sPanel = [NSSavePanel savePanel];
|
||||||
@ -319,6 +382,12 @@ void wxFileDialog::DoOnFilterSelected(int index)
|
|||||||
{
|
{
|
||||||
NSArray* types = GetTypesFromExtension(m_filterExtensions[index],m_currentExtensions);
|
NSArray* types = GetTypesFromExtension(m_filterExtensions[index],m_currentExtensions);
|
||||||
NSSavePanel* panel = (NSSavePanel*) GetWXWindow();
|
NSSavePanel* panel = (NSSavePanel*) GetWXWindow();
|
||||||
|
if ( m_delegate )
|
||||||
|
{
|
||||||
|
[(wxOpenSavePanelDelegate*)m_delegate setAllowedExtensions:m_currentExtensions];
|
||||||
|
[panel validateVisibleColumns];
|
||||||
|
}
|
||||||
|
else
|
||||||
[panel setAllowedFileTypes:types];
|
[panel setAllowedFileTypes:types];
|
||||||
|
|
||||||
m_currentlySelectedFilterIndex = index;
|
m_currentlySelectedFilterIndex = index;
|
||||||
@ -368,6 +437,10 @@ void wxFileDialog::SetupExtraControls(WXWindow nativeWindow)
|
|||||||
{
|
{
|
||||||
[accView removeFromSuperview];
|
[accView removeFromSuperview];
|
||||||
[panel setAccessoryView:accView];
|
[panel setAccessoryView:accView];
|
||||||
|
if ([panel respondsToSelector:@selector(setAccessoryViewDisclosed)])
|
||||||
|
{
|
||||||
|
[panel setAccessoryViewDisclosed:YES];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -431,7 +504,7 @@ int wxFileDialog::ShowModal()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NSArray* types = GetTypesFromFilter( m_wildCard, m_filterNames, m_filterExtensions ) ;
|
NSArray* types = GetTypesFromFilter( m_wildCard, m_filterNames, m_filterExtensions, m_currentExtensions ) ;
|
||||||
|
|
||||||
m_useFileTypeFilter = m_filterExtensions.GetCount() > 1;
|
m_useFileTypeFilter = m_filterExtensions.GetCount() > 1;
|
||||||
|
|
||||||
@ -512,6 +585,10 @@ int wxFileDialog::ShowModal()
|
|||||||
|
|
||||||
SetupExtraControls(oPanel);
|
SetupExtraControls(oPanel);
|
||||||
|
|
||||||
|
wxOpenSavePanelDelegate* del = [[wxOpenSavePanelDelegate alloc]init];
|
||||||
|
[oPanel setDelegate:del];
|
||||||
|
m_delegate = del;
|
||||||
|
|
||||||
[oPanel setTreatsFilePackagesAsDirectories:NO];
|
[oPanel setTreatsFilePackagesAsDirectories:NO];
|
||||||
[oPanel setCanChooseDirectories:NO];
|
[oPanel setCanChooseDirectories:NO];
|
||||||
[oPanel setResolvesAliases:HasFlag(wxFD_NO_FOLLOW) ? NO : YES];
|
[oPanel setResolvesAliases:HasFlag(wxFD_NO_FOLLOW) ? NO : YES];
|
||||||
@ -530,6 +607,9 @@ int wxFileDialog::ShowModal()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if ( m_delegate )
|
||||||
|
[(wxOpenSavePanelDelegate*) m_delegate setAllowedExtensions: m_currentExtensions];
|
||||||
|
else
|
||||||
[oPanel setAllowedFileTypes: types];
|
[oPanel setAllowedFileTypes: types];
|
||||||
}
|
}
|
||||||
if ( !m_dir.IsEmpty() )
|
if ( !m_dir.IsEmpty() )
|
||||||
@ -595,6 +675,12 @@ void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode)
|
|||||||
else
|
else
|
||||||
m_filterIndex = GetMatchingFilterExtension(m_fileName);
|
m_filterIndex = GetMatchingFilterExtension(m_fileName);
|
||||||
}
|
}
|
||||||
|
if ( m_delegate )
|
||||||
|
{
|
||||||
|
[oPanel setDelegate:nil];
|
||||||
|
[m_delegate release];
|
||||||
|
m_delegate = nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SetReturnCode(result);
|
SetReturnCode(result);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user