Пример #1
0
static void
gtk_file_chooser_native_get_property (GObject    *object,
                                      guint       prop_id,
                                      GValue     *value,
                                      GParamSpec *pspec)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (object);

  switch (prop_id)
    {
    case PROP_ACCEPT_LABEL:
      g_value_set_string (value, self->accept_label);
      break;

    case PROP_CANCEL_LABEL:
      g_value_set_string (value, self->cancel_label);
      break;

    case GTK_FILE_CHOOSER_PROP_FILTER:
      g_value_set_object (value, self->current_filter);
      break;

    default:
      g_object_get_property (G_OBJECT (self->dialog), pspec->name, value);
      break;
    }
}
Пример #2
0
static void
gtk_file_chooser_native_hide (GtkNativeDialog *native)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (native);

  switch (self->mode)
    {
    case MODE_FALLBACK:
      hide_dialog (self);
      break;
    case MODE_WIN32:
#ifdef GDK_WINDOWING_WIN32
      gtk_file_chooser_native_win32_hide (self);
#endif
      break;
    case MODE_QUARTZ:
#ifdef GDK_WINDOWING_QUARTZ
      gtk_file_chooser_native_quartz_hide (self);
#endif
      break;
    case MODE_PORTAL:
      gtk_file_chooser_native_portal_hide (self);
      break;
    default:
      break;
    }
}
Пример #3
0
static void
gtk_file_chooser_native_set_choice (GtkFileChooser *chooser,
                                    const char     *id,
                                    const char     *selected)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
  GtkFileChooserNativeChoice *choice = find_choice (self, id);

  if (choice == NULL)
    {
      g_warning ("No choice with id %s found in %s %p", id, G_OBJECT_TYPE_NAME (self), self);
      return;
    }

  if ((choice->options && !g_strv_contains ((const char *const*)choice->options, selected)) ||
      (!choice->options && !g_str_equal (selected, "true") && !g_str_equal (selected, "false")))
    {
      g_warning ("Not a valid option for %s: %s", id, selected);
      return;
    }

  g_free (choice->selected);
  choice->selected = g_strdup (selected);

  gtk_file_chooser_set_choice (GTK_FILE_CHOOSER (self->dialog), id, selected);
}
Пример #4
0
static void
gtk_file_chooser_native_add_choice (GtkFileChooser  *chooser,
                                    const char      *id,
                                    const char      *label,
                                    const char     **options,
                                    const char     **option_labels)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
  GtkFileChooserNativeChoice *choice = find_choice (self, id);

  if (choice != NULL)
    {
      g_warning ("Choice with id %s already added to %s %p", id, G_OBJECT_TYPE_NAME (self), self);
      return;
    }

  g_assert ((options == NULL && option_labels == NULL) ||
            g_strv_length ((char **)options) == g_strv_length ((char **)option_labels));

  choice = g_new0 (GtkFileChooserNativeChoice, 1);
  choice->id = g_strdup (id);
  choice->label = g_strdup (label);
  choice->options = g_strdupv ((char **)options);
  choice->option_labels = g_strdupv ((char **)option_labels);

  self->choices = g_slist_prepend (self->choices, choice);

  gtk_file_chooser_add_choice (GTK_FILE_CHOOSER (self->dialog),
                               id, label, options, option_labels);
}
Пример #5
0
static void
gtk_file_chooser_native_set_current_name (GtkFileChooser    *chooser,
                                          const gchar       *name)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);

  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (self->dialog), name);

  g_clear_pointer (&self->current_name, g_free);
  self->current_name = g_strdup (name);

  g_clear_object (&self->current_file);
}
Пример #6
0
static void
gtk_file_chooser_native_show (GtkNativeDialog *native)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (native);

  self->mode = MODE_FALLBACK;

#ifdef GDK_WINDOWING_WIN32
  if (gtk_file_chooser_native_win32_show (self))
    self->mode = MODE_WIN32;
#endif

  if (self->mode == MODE_FALLBACK)
    show_dialog (self);
}
Пример #7
0
static GSList *
gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);

  switch (self->mode)
    {
    case MODE_WIN32:
      return g_slist_copy_deep (self->custom_files, (GCopyFunc)g_object_ref, NULL);

    case MODE_FALLBACK:
    default:
      return gtk_file_chooser_get_files (GTK_FILE_CHOOSER (self->dialog));
    }
}
Пример #8
0
static void
gtk_file_chooser_native_finalize (GObject *object)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (object);

  g_clear_pointer (&self->current_name, g_free);
  g_clear_object (&self->current_file);
  g_clear_object (&self->current_folder);

  g_clear_pointer (&self->accept_label, g_free);
  g_clear_pointer (&self->cancel_label, g_free);
  gtk_widget_destroy (self->dialog);

  g_slist_free_full (self->custom_files, g_object_unref);

  G_OBJECT_CLASS (gtk_file_chooser_native_parent_class)->finalize (object);
}
Пример #9
0
static const char *
gtk_file_chooser_native_get_choice (GtkFileChooser *chooser,
                                    const char     *id)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
  GtkFileChooserNativeChoice *choice = find_choice (self, id);

  if (choice == NULL)
    {
      g_warning ("No choice with id %s found in %s %p", id, G_OBJECT_TYPE_NAME (self), self);
      return NULL;
    }

  if (self->mode == MODE_FALLBACK)
    return gtk_file_chooser_get_choice (GTK_FILE_CHOOSER (self->dialog), id);

  return choice->selected;
}
Пример #10
0
static void
gtk_file_chooser_native_remove_choice (GtkFileChooser *chooser,
                                       const char     *id)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
  GtkFileChooserNativeChoice *choice = find_choice (self, id);

  if (choice == NULL)
    {
      g_warning ("No choice with id %s found in %s %p", id, G_OBJECT_TYPE_NAME (self), self);
      return;
    }

  self->choices = g_slist_remove (self->choices, choice);

  gtk_file_chooser_native_choice_free (choice);

  gtk_file_chooser_remove_choice (GTK_FILE_CHOOSER (self->dialog), id);
}
Пример #11
0
static gboolean
gtk_file_chooser_native_select_file (GtkFileChooser    *chooser,
                                     GFile             *file,
                                     GError           **error)
{
  GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
  gboolean res;

  res = gtk_file_chooser_select_file (GTK_FILE_CHOOSER (self->dialog),
                                      file, error);

  if (res)
    {
      g_set_object (&self->current_file, file);

      g_clear_object (&self->current_folder);
      g_clear_pointer (&self->current_name, g_free);
    }

  return res;
}
Пример #12
0
gboolean
gtk_file_chooser_native_portal_show (GtkFileChooserNative *self)
{
  FilechooserPortalData *data;
  GtkWindow *transient_for;
  GDBusConnection *connection;
  char *parent_window_str;
  GDBusMessage *message;
  GVariantBuilder opt_builder;
  GtkFileChooserAction action;
  gboolean multiple;
  const char *method_name;

  if (!gtk_should_use_portal ())
    return FALSE;

  connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
  if (connection == NULL)
    return FALSE;

  action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (self));
  multiple = gtk_file_chooser_get_select_multiple (GTK_FILE_CHOOSER (self));

  if (action == GTK_FILE_CHOOSER_ACTION_OPEN)
    method_name = "OpenFile";
  else if (action == GTK_FILE_CHOOSER_ACTION_SAVE)
    method_name = "SaveFile";
  else
    {
      g_warning ("GTK_FILE_CHOOSER_ACTION_%s is not supported by GtkFileChooserNativePortal", action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ? "SELECT_FOLDER" : "CREATE_FOLDER");
      return FALSE;
    }

  data = g_new0 (FilechooserPortalData, 1);
  data->self = g_object_ref (self);
  data->connection = connection;

  message = g_dbus_message_new_method_call ("org.freedesktop.portal.Desktop",
                                            "/org/freedesktop/portal/desktop",
                                            "org.freedesktop.portal.FileChooser",
                                            method_name);

  parent_window_str = NULL;
  transient_for = gtk_native_dialog_get_transient_for (GTK_NATIVE_DIALOG (self));
  if (transient_for != NULL && gtk_widget_is_visible (GTK_WIDGET (transient_for)))
    {
      GdkWindow *window = gtk_widget_get_window (GTK_WIDGET (transient_for));
#ifdef GDK_WINDOWING_X11
      if (GDK_IS_X11_WINDOW(window))
        parent_window_str = g_strdup_printf ("x11:%x", (guint32)gdk_x11_window_get_xid (window));
#endif
    }

  if (gtk_native_dialog_get_modal (GTK_NATIVE_DIALOG (self)))
    data->modal = TRUE;

  if (data->modal && transient_for != NULL)
    {
      data->grab_widget = gtk_invisible_new_for_screen (gtk_widget_get_screen (GTK_WIDGET (transient_for)));
      gtk_grab_add (GTK_WIDGET (data->grab_widget));
    }

  g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT);
  g_variant_builder_add (&opt_builder, "{sv}", "multiple",
                         g_variant_new_boolean (multiple));
  if (self->accept_label)
    g_variant_builder_add (&opt_builder, "{sv}", "accept_label",
                           g_variant_new_string (self->accept_label));
  if (self->cancel_label)
    g_variant_builder_add (&opt_builder, "{sv}", "cancel_label",
                           g_variant_new_string (self->cancel_label));
  g_variant_builder_add (&opt_builder, "{sv}", "modal",
                         g_variant_new_boolean (data->modal));
  g_variant_builder_add (&opt_builder, "{sv}", "filters", get_filters (GTK_FILE_CHOOSER (self)));
  if (GTK_FILE_CHOOSER_NATIVE (self)->current_name)
    g_variant_builder_add (&opt_builder, "{sv}", "current_name",
                           g_variant_new_string (GTK_FILE_CHOOSER_NATIVE (self)->current_name));
  if (GTK_FILE_CHOOSER_NATIVE (self)->current_folder)
    {
      gchar *path;

      path = g_file_get_path (GTK_FILE_CHOOSER_NATIVE (self)->current_folder);
      g_variant_builder_add (&opt_builder, "{sv}", "current_folder",
                             g_variant_new_bytestring (path));
      g_free (path);
    }
  if (GTK_FILE_CHOOSER_NATIVE (self)->current_file)
    {
      gchar *path;

      path = g_file_get_path (GTK_FILE_CHOOSER_NATIVE (self)->current_file);
      g_variant_builder_add (&opt_builder, "{sv}", "current_file",
                             g_variant_new_bytestring (path));
      g_free (path);
    }

  if (GTK_FILE_CHOOSER_NATIVE (self)->choices)
    g_variant_builder_add (&opt_builder, "{sv}", "choices",
                           serialize_choices (GTK_FILE_CHOOSER_NATIVE (self)));

  g_dbus_message_set_body (message,
                           g_variant_new ("(ss@a{sv})",
                                          parent_window_str ? parent_window_str : "",
                                          gtk_native_dialog_get_title (GTK_NATIVE_DIALOG (self)),
                                          g_variant_builder_end (&opt_builder)));
  g_free (parent_window_str);

  g_dbus_connection_send_message_with_reply (data->connection,
                                             message,
                                             G_DBUS_SEND_MESSAGE_FLAGS_NONE,
                                             G_MAXINT,
                                             NULL,
                                             NULL,
                                             open_file_msg_cb,
                                             data);

  g_object_unref (message);

  self->mode_data = data;
  return TRUE;
}
Пример #13
0
GtkFileChooser *
ephy_create_file_chooser (const char           *title,
                          GtkWidget            *parent,
                          GtkFileChooserAction  action,
                          EphyFileFilterDefault default_filter)
{
  GtkFileChooser *dialog;
  GtkFileFilter *filter[EPHY_FILE_FILTER_LAST];
  g_autofree char *downloads_dir = NULL;
  GtkWidget *preview = gtk_image_new ();

  g_assert (GTK_IS_WINDOW (parent));
  g_assert (default_filter >= 0 && default_filter <= EPHY_FILE_FILTER_LAST);

  dialog = GTK_FILE_CHOOSER (gtk_file_chooser_native_new (title,
                                                          GTK_WINDOW (parent),
                                                          action,
                                                          NULL,
                                                          _("_Cancel")));
  gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);

  downloads_dir = ephy_file_get_downloads_dir ();
  gtk_file_chooser_add_shortcut_folder (dialog, downloads_dir, NULL);

  if (action == GTK_FILE_CHOOSER_ACTION_OPEN ||
      action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
      action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER) {
    gtk_file_chooser_native_set_accept_label (GTK_FILE_CHOOSER_NATIVE (dialog), _("_Open"));
  } else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
    gtk_file_chooser_native_set_accept_label (GTK_FILE_CHOOSER_NATIVE (dialog), _("_Save"));
  }

  gtk_file_chooser_set_preview_widget (dialog, preview);
  gtk_file_chooser_set_use_preview_label (dialog, FALSE);
  g_signal_connect (dialog, "update-preview",
                    G_CALLBACK (update_preview_cb),
                    preview);

  if (default_filter != EPHY_FILE_FILTER_NONE) {
    filter[EPHY_FILE_FILTER_ALL_SUPPORTED] =
      ephy_file_chooser_add_mime_filter
        (dialog,
        _("All supported types"),
        "text/html",
        "application/xhtml+xml",
        "text/xml",
        "message/rfc822",                                     /* MHTML */
        "multipart/related",                                  /* MHTML */
        "application/x-mimearchive",                          /* MHTML */
        "image/png",
        "image/jpeg",
        "image/gif",
        "image/webp",
        NULL);

    filter[EPHY_FILE_FILTER_WEBPAGES] =
      ephy_file_chooser_add_mime_filter
        (dialog, _("Web pages"),
        "text/html",
        "application/xhtml+xml",
        "text/xml",
        "message/rfc822",                                     /* MHTML */
        "multipart/related",                                  /* MHTML */
        "application/x-mimearchive",                          /* MHTML */
        NULL);

    filter[EPHY_FILE_FILTER_IMAGES] =
      ephy_file_chooser_add_mime_filter
        (dialog, _("Images"),
        "image/png",
        "image/jpeg",
        "image/gif",
        "image/webp",
        NULL);

    filter[EPHY_FILE_FILTER_ALL] =
      ephy_file_chooser_add_pattern_filter
        (dialog, _("All files"), "*", NULL);

    gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog),
                                 filter[default_filter]);
  }

  return dialog;
}