mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-16 15:14:17 +00:00
GtkFileChooserNativeQuartz: add support for filters
Includes: * Simple glob patterns (*.ext, *.*,...) * MIME types * pixbuf formats https://bugzilla.gnome.org/show_bug.cgi?id=784723
This commit is contained in:
parent
55d139bc46
commit
a4775f8e92
@ -63,18 +63,46 @@ typedef struct {
|
||||
char *title;
|
||||
char *message;
|
||||
|
||||
GSList *shortcut_uris;
|
||||
|
||||
GFile *current_folder;
|
||||
GFile *current_file;
|
||||
char *current_name;
|
||||
|
||||
NSArray<NSString *> *filters;
|
||||
NSMutableArray<NSArray<NSString *> *> *filters;
|
||||
NSMutableArray<NSString *> *filter_names;
|
||||
NSComboBox *filter_combo_box;
|
||||
|
||||
GSList *files;
|
||||
int response;
|
||||
} FileChooserQuartzData;
|
||||
|
||||
@interface FilterComboBox : NSObject<NSComboBoxDelegate>
|
||||
{
|
||||
FileChooserQuartzData *data;
|
||||
}
|
||||
- (id) initWithData:(FileChooserQuartzData *) quartz_data;
|
||||
- (void)comboBoxSelectionDidChange:(NSNotification *)notification;
|
||||
@end
|
||||
|
||||
@implementation FilterComboBox
|
||||
|
||||
- (id) initWithData:(FileChooserQuartzData *) quartz_data
|
||||
{
|
||||
[super init];
|
||||
data = quartz_data;
|
||||
return self;
|
||||
}
|
||||
- (void)comboBoxSelectionDidChange:(NSNotification *)notification
|
||||
{
|
||||
NSInteger selected_index = [data->filter_combo_box indexOfSelectedItem];
|
||||
NSArray<NSString *> *filter = [data->filters objectAtIndex:selected_index];
|
||||
// check for empty strings in filter -> indicates all filetypes should be allowed!
|
||||
if ([filter containsObject:@""])
|
||||
[data->panel setAllowedFileTypes:nil];
|
||||
else
|
||||
[data->panel setAllowedFileTypes:filter];
|
||||
}
|
||||
@end
|
||||
|
||||
static GFile *
|
||||
ns_url_to_g_file (NSURL *url)
|
||||
{
|
||||
@ -150,16 +178,21 @@ chooser_set_current_name (FileChooserQuartzData *data,
|
||||
static void
|
||||
filechooser_quartz_data_free (FileChooserQuartzData *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (data->filters)
|
||||
{
|
||||
[data->filters release];
|
||||
}
|
||||
|
||||
if (data->filter_names)
|
||||
{
|
||||
[data->filter_names release];
|
||||
}
|
||||
|
||||
g_clear_object (&data->current_folder);
|
||||
g_clear_object (&data->current_file);
|
||||
g_free (data->current_name);
|
||||
|
||||
g_slist_free_full (data->shortcut_uris, g_free);
|
||||
g_slist_free_full (data->files, g_object_unref);
|
||||
if (data->self)
|
||||
g_object_unref (data->self);
|
||||
@ -174,17 +207,9 @@ static gboolean
|
||||
filechooser_quartz_launch (FileChooserQuartzData *data)
|
||||
{
|
||||
|
||||
// GTK_FILE_CHOOSER_ACTION_SAVE and GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
|
||||
if (data->save)
|
||||
{
|
||||
|
||||
/*if ([panel respondsToSelector:@selector(setShowsTagField:)])
|
||||
{
|
||||
[(id<CanSetShowsTagField>)panel setShowsTagField:NO];
|
||||
}
|
||||
*/
|
||||
|
||||
// GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
|
||||
if (data->folder)
|
||||
{
|
||||
NSOpenPanel *panel = [[NSOpenPanel openPanel] retain];
|
||||
@ -193,7 +218,6 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
|
||||
[panel setCanCreateDirectories:YES];
|
||||
data->panel = panel;
|
||||
}
|
||||
// GTK_FILE_CHOOSER_ACTION_SAVE
|
||||
else
|
||||
{
|
||||
NSSavePanel *panel = [[NSSavePanel savePanel] retain];
|
||||
@ -208,7 +232,6 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
|
||||
data->panel = panel;
|
||||
}
|
||||
}
|
||||
// GTK_FILE_CHOOSER_ACTION_OPEN and GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER
|
||||
else
|
||||
{
|
||||
NSOpenPanel *panel = [[NSOpenPanel openPanel] retain];
|
||||
@ -274,7 +297,20 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
|
||||
|
||||
if (data->filters)
|
||||
{
|
||||
// TODO
|
||||
// when filters have been provided, a combobox needs to be added
|
||||
data->filter_combo_box = [[NSComboBox alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 20)];
|
||||
[data->filter_combo_box addItemsWithObjectValues:data->filter_names];
|
||||
[data->filter_combo_box setEditable:NO];
|
||||
[data->filter_combo_box setDelegate:[[FilterComboBox alloc] initWithData:data]];
|
||||
[data->filter_combo_box selectItemAtIndex:0];
|
||||
[data->filter_combo_box setToolTip:[NSString stringWithUTF8String:_("Select which types of files are shown")]];
|
||||
[data->panel setAccessoryView:data->filter_combo_box];
|
||||
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_11_AND_LATER
|
||||
if (!data->save)
|
||||
{
|
||||
[(NSOpenPanel *) data->panel setAccessoryViewDisclosed:YES];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
data->response = GTK_RESPONSE_CANCEL;
|
||||
@ -342,6 +378,36 @@ strip_mnemonic (const gchar *s)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_filter_to_quartz (GtkFileFilter *file_filter,
|
||||
NSMutableArray<NSArray<NSString *> *> *filters,
|
||||
NSMutableArray<NSString *> *filter_names)
|
||||
{
|
||||
const char *name;
|
||||
NSArray<NSString *> *pattern_nsstrings;
|
||||
|
||||
pattern_nsstrings = _gtk_file_filter_get_as_pattern_nsstrings (file_filter);
|
||||
if (pattern_nsstrings == NULL)
|
||||
return FALSE;
|
||||
|
||||
name = gtk_file_filter_get_name (file_filter);
|
||||
NSString *name_nsstring;
|
||||
if (name == NULL)
|
||||
{
|
||||
name_nsstring = [pattern_nsstrings componentsJoinedByString:@","];;
|
||||
}
|
||||
else
|
||||
{
|
||||
name_nsstring = [NSString stringWithUTF8String:name];
|
||||
[name_nsstring retain];
|
||||
}
|
||||
|
||||
[filter_names addObject:name_nsstring];
|
||||
[filters addObject:pattern_nsstrings];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
|
||||
{
|
||||
@ -371,12 +437,30 @@ gtk_file_chooser_native_quartz_show (GtkFileChooserNative *self)
|
||||
|
||||
data = g_new0 (FileChooserQuartzData, 1);
|
||||
|
||||
// examine filters! TODO
|
||||
// examine filters!
|
||||
filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (self));
|
||||
n_filters = g_slist_length (filters);
|
||||
if (n_filters > 0)
|
||||
{
|
||||
data->filters = [NSMutableArray<NSArray<NSString *> *> arrayWithCapacity:n_filters];
|
||||
[data->filters retain];
|
||||
data->filter_names = [NSMutableArray<NSString *> arrayWithCapacity:n_filters];
|
||||
[data->filter_names retain];
|
||||
|
||||
for (l = filters, i = 0; l != NULL; l = l->next, i++)
|
||||
{
|
||||
if (!file_filter_to_quartz (l->data, data->filters, data->filter_names))
|
||||
{
|
||||
filechooser_quartz_data_free (data);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self->mode_data = data;
|
||||
data->self = g_object_ref (self);
|
||||
|
||||
data->create_folders = gtk_file_chooser_get_create_folders( GTK_FILE_CHOOSER (self));
|
||||
data->create_folders = gtk_file_chooser_get_create_folders (GTK_FILE_CHOOSER (self));
|
||||
|
||||
// shortcut_folder_uris support seems difficult if not impossible
|
||||
|
||||
|
@ -592,6 +592,84 @@ gtk_file_filter_get_needed (GtkFileFilter *filter)
|
||||
return filter->needed;
|
||||
}
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NSArray<NSString *> * _gtk_file_filter_get_as_pattern_nsstrings (GtkFileFilter *filter)
|
||||
{
|
||||
NSMutableArray<NSString *> *array = [[NSMutableArray alloc] init];
|
||||
GSList *tmp_list;
|
||||
|
||||
for (tmp_list = filter->rules; tmp_list; tmp_list = tmp_list->next)
|
||||
{
|
||||
FilterRule *rule = tmp_list->data;
|
||||
|
||||
switch (rule->type)
|
||||
{
|
||||
case FILTER_RULE_CUSTOM:
|
||||
[array release];
|
||||
return NULL;
|
||||
break;
|
||||
case FILTER_RULE_MIME_TYPE:
|
||||
{
|
||||
// convert mime-types to UTI
|
||||
NSString *mime_type_nsstring = [NSString stringWithUTF8String: rule->u.mime_type];
|
||||
NSString *uti_nsstring = (NSString *) UTTypeCreatePreferredIdentifierForTag (kUTTagClassMIMEType, (CFStringRef) mime_type_nsstring, NULL);
|
||||
if (uti_nsstring == NULL)
|
||||
{
|
||||
[array release];
|
||||
return NULL;
|
||||
}
|
||||
[array addObject:uti_nsstring];
|
||||
}
|
||||
break;
|
||||
case FILTER_RULE_PATTERN:
|
||||
{
|
||||
// patterns will need to be stripped of their leading *.
|
||||
GString *pattern = g_string_new (rule->u.pattern);
|
||||
if (strncmp (pattern->str, "*.", 2) == 0)
|
||||
{
|
||||
pattern = g_string_erase (pattern, 0, 2);
|
||||
}
|
||||
else if (strncmp (pattern->str, "*", 1) == 0)
|
||||
{
|
||||
pattern = g_string_erase (pattern, 0, 1);
|
||||
}
|
||||
gchar *pattern_c = g_string_free (pattern, FALSE);
|
||||
NSString *pattern_nsstring = [NSString stringWithUTF8String:pattern_c];
|
||||
g_free (pattern_c);
|
||||
[pattern_nsstring retain];
|
||||
[array addObject:pattern_nsstring];
|
||||
}
|
||||
break;
|
||||
case FILTER_RULE_PIXBUF_FORMATS:
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
for (list = rule->u.pixbuf_formats; list; list = list->next)
|
||||
{
|
||||
int i;
|
||||
gchar **extensions;
|
||||
|
||||
extensions = gdk_pixbuf_format_get_extensions (list->data);
|
||||
|
||||
for (i = 0; extensions[i] != NULL; i++)
|
||||
{
|
||||
NSString *extension = [NSString stringWithUTF8String: extensions[i]];
|
||||
[extension retain];
|
||||
[array addObject:extension];
|
||||
}
|
||||
g_strfreev (extensions);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
#endif
|
||||
|
||||
char **
|
||||
_gtk_file_filter_get_as_patterns (GtkFileFilter *filter)
|
||||
{
|
||||
|
@ -20,11 +20,21 @@
|
||||
#define __GTK_FILE_FILTER_PRIVATE_H__
|
||||
|
||||
#include <gtk/gtkfilefilter.h>
|
||||
#include <gdk/gdkconfig.h>
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
#import <Foundation/Foundation.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
char ** _gtk_file_filter_get_as_patterns (GtkFileFilter *filter);
|
||||
|
||||
#ifdef GDK_WINDOWING_QUARTZ
|
||||
NSArray<NSString *> * _gtk_file_filter_get_as_pattern_nsstrings (GtkFileFilter *filter);
|
||||
#endif
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FILE_FILTER_PRIVATE_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user