GtkFileChooserNativeWin32: add support for get_filter and set_filter
authorTom Schoonjans <Tom.Schoonjans@diamond.ac.uk>
Thu, 13 Jul 2017 19:07:22 +0000 (20:07 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 18 Jul 2017 17:48:13 +0000 (13:48 -0400)
https://bugzilla.gnome.org/show_bug.cgi?id=784723

gtk/gtkfilechoosernativewin32.c

index 9a1a3a2c13d4581c35e29d9c0f91f14c7f406bf7..cb9c42ef4d0d9559a497714806b2555629e84eb2 100644 (file)
@@ -103,6 +103,7 @@ typedef struct {
   gboolean got_hwnd;
   HWND dialog_hwnd;
   gboolean do_close; /* Set if hide was called before dialog_hwnd was set */
+  FilechooserWin32ThreadData *data;
 } FileDialogEvents;
 
 
@@ -235,6 +236,19 @@ static HRESULT STDMETHODCALLTYPE
 ifiledialogevents_OnTypeChange (IFileDialogEvents * self,
                                 IFileDialog *pfd)
 {
+  FileDialogEvents *events = (FileDialogEvents *) self;
+  UINT fileType;
+  HRESULT hr = IFileDialog_GetFileTypeIndex (pfd, &fileType);
+  if (FAILED (hr))
+    {
+      g_warning_hr ("Can't get current file type", hr);
+      return S_OK;
+    }
+  fileType--; // fileTypeIndex starts at 1 
+  GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (events->data->self));
+  events->data->self->current_filter = g_slist_nth_data (filters, fileType);
+  g_slist_free (filters);
+  g_object_notify (G_OBJECT (events->data->self), "filter");
   return S_OK;
 }
 
@@ -276,7 +290,7 @@ file_dialog_events_send_close (IFileDialogEvents *self)
 }
 
 static IFileDialogEvents *
-file_dialog_events_new (gboolean enable_owner)
+file_dialog_events_new (gboolean enable_owner, FilechooserWin32ThreadData *data)
 {
   FileDialogEvents *events;
 
@@ -284,6 +298,7 @@ file_dialog_events_new (gboolean enable_owner)
   events->iFileDialogEvents.lpVtbl = &ifde_vtbl;
   events->ref_count = 1;
   events->enable_owner = enable_owner;
+  events->data = data;
 
   return &events->iFileDialogEvents;
 }
@@ -553,6 +568,24 @@ filechooser_win32_thread (gpointer _data)
       hr = IFileDialog_SetFileTypes (pfd, n, data->filters);
       if (FAILED (hr))
         g_warning_hr ("Can't set file types", hr);
+
+      if (data->self->current_filter)
+        {
+          GSList *filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (data->self));
+         gint current_filter_index = g_slist_index (filters, data->self->current_filter);
+         g_slist_free (filters);
+
+         if (current_filter_index >= 0)
+           hr = IFileDialog_SetFileTypeIndex (pfd, current_filter_index + 1);
+         else
+           hr = IFileDialog_SetFileTypeIndex (pfd, 1);
+        }
+      else
+        {
+         hr = IFileDialog_SetFileTypeIndex (pfd, 1);
+        }
+      if (FAILED (hr))
+        g_warning_hr ("Can't set current file type", hr);
     }
 
   data->response = GTK_RESPONSE_CANCEL;
@@ -716,6 +749,11 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
               return FALSE;
             }
         }
+      self->current_filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
+    }
+  else
+    {
+      self->current_filter = NULL;
     }
 
   self->mode_data = data;
@@ -772,7 +810,7 @@ gtk_file_chooser_native_win32_show (GtkFileChooserNative *self)
         data->current_name = g_strdup (self->current_name);
     }
 
-  data->events = file_dialog_events_new (!data->modal);
+  data->events = file_dialog_events_new (!data->modal, data);
 
   thread = g_thread_new ("win32 filechooser", filechooser_win32_thread, data);
   if (thread == NULL)