Exemple #1
0
static void button_clicked(GtkWidget *widget, dt_imageio_module_storage_t *self)
{
  disk_t *d = (disk_t *)self->gui_data;
  GtkWidget *win = dt_ui_main_window(darktable.gui->ui);
  GtkWidget *filechooser = gtk_file_chooser_dialog_new(
      _("select directory"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, _("_cancel"),
      GTK_RESPONSE_CANCEL, _("_select as output destination"), GTK_RESPONSE_ACCEPT, (char *)NULL);
#ifdef GDK_WINDOWING_QUARTZ
  dt_osx_disallow_fullscreen(filechooser);
#endif

  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(filechooser), FALSE);
  gchar *old = g_strdup(gtk_entry_get_text(d->entry));
  char *c = g_strstr_len(old, -1, "$");
  if(c) *c = '\0';
  gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), old);
  g_free(old);
  if(gtk_dialog_run(GTK_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT)
  {
    gchar *dir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser));
    char *composed = g_build_filename(dir, "$(FILE_NAME)", NULL);

    // composed can now contain '\': on Windows it's the path separator,
    // on other platforms it can be part of a regular folder name.
    // This would later clash with variable substitution, so we have to escape them
    gchar *escaped = dt_util_str_replace(composed, "\\", "\\\\");

    gtk_entry_set_text(GTK_ENTRY(d->entry), escaped); // the signal handler will write this to conf
    g_free(dir);
    g_free(composed);
    g_free(escaped);
  }
  gtk_widget_destroy(filechooser);
}
Exemple #2
0
static gboolean ask_and_delete(gpointer user_data)
{
  GList *empty_dirs = (GList *)user_data;
  const int n_empty_dirs = g_list_length(empty_dirs);

  GtkWidget *dialog;
  GtkWidget *win = dt_ui_main_window(darktable.gui->ui);

  dialog = gtk_message_dialog_new(GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
                                  GTK_BUTTONS_YES_NO,
                                  ngettext("do you want to remove this empty directory?",
                                           "do you want to remove these empty directories?", n_empty_dirs));
#ifdef GDK_WINDOWING_QUARTZ
  dt_osx_disallow_fullscreen(dialog);
#endif

  gtk_window_set_title(GTK_WINDOW(dialog),
                       ngettext("remove empty directory?", "remove empty directories?", n_empty_dirs));

  GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));

  GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
  gtk_widget_set_vexpand(scroll, TRUE);

  GtkListStore *store = gtk_list_store_new(1, G_TYPE_STRING);

  for(GList *list_iter = empty_dirs; list_iter; list_iter = g_list_next(list_iter))
  {
    GtkTreeIter iter;
    gtk_list_store_append(store, &iter);
    gtk_list_store_set(store, &iter, 0, list_iter->data, -1);
  }

  GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree), FALSE);

  GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("name"), gtk_cell_renderer_text_new(),
                                                                       "text", 0, NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);

  gtk_container_add(GTK_CONTAINER(scroll), tree);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

  gtk_container_add(GTK_CONTAINER(content_area), scroll);

  gtk_widget_show_all(dialog); // needed for the content area!

  gint res = gtk_dialog_run(GTK_DIALOG(dialog));
  gtk_widget_destroy(dialog);
  if(res == GTK_RESPONSE_YES)
    for(GList *iter = empty_dirs; iter; iter = g_list_next(iter))
      rmdir((char *)iter->data);

  g_list_free_full(empty_dirs, g_free);
  g_object_unref(store);

  return FALSE;
}
Exemple #3
0
/**
 * @see https://developers.google.com/accounts/docs/OAuth2InstalledApp
 * @returns NULL if the user cancels the operation or a valid token
 */
static int gphoto_get_user_auth_token(dt_storage_gphoto_gui_data_t *ui)
{
  ///////////// open the authentication url in a browser
  GError *error = NULL;
  gchar *params = NULL;
  params = dt_util_dstrcat(params,
                           GOOGLE_WS_BASE_URL
                           "o/oauth2/v2/auth?"
                           "client_id=%s&redirect_uri=urn:ietf:wg:oauth:2.0:oob"
                           "&scope=" GOOGLE_API_BASE_URL "auth/photoslibrary "
                           GOOGLE_API_BASE_URL "auth/userinfo.profile "
                           GOOGLE_API_BASE_URL "auth/userinfo.email"
                           "&response_type=code&access_type=offline",
                           ui->gphoto_api->google_client_id);

  if(!gtk_show_uri(gdk_screen_get_default(), params, gtk_get_current_event_time(), &error))
  {
    fprintf(stderr, "[gphoto] error opening browser: %s\n", error->message);
    g_error_free(error);
  }

  ////////////// build & show the validation dialog
  const gchar *text1 = _("step 1: a new window or tab of your browser should have been "
                         "loaded. you have to login into your google account there "
                         "and authorize darktable to upload photos before continuing.");
  const gchar *text2 = _("step 2: paste the verification code shown to you in the browser "
                         "and click the OK button once you are done.");

  GtkWidget *window = dt_ui_main_window(darktable.gui->ui);
  GtkDialog *gphoto_auth_dialog = GTK_DIALOG(
      gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION,
                             GTK_BUTTONS_OK_CANCEL, _("google authentication")));
#ifdef GDK_WINDOWING_QUARTZ
  dt_osx_disallow_fullscreen(GTK_WIDGET(gphoto_auth_dialog));
#endif
  gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(gphoto_auth_dialog), "%s\n\n%s", text1, text2);

  GtkWidget *entry = gtk_entry_new();
  GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
  gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(gtk_label_new(_("verification code:"))), FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry), TRUE, TRUE, 0);

  GtkWidget *gphotoauthdialog_vbox
      = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(gphoto_auth_dialog));
  gtk_box_pack_end(GTK_BOX(gphotoauthdialog_vbox), hbox, TRUE, TRUE, 0);

  gtk_widget_show_all(GTK_WIDGET(gphoto_auth_dialog));

  ////////////// wait for the user to enter the verification code
  gint result;
  gchar *token = NULL;
  const char *replycode;
  while(TRUE)
  {
    result = gtk_dialog_run(GTK_DIALOG(gphoto_auth_dialog));
    if(result == GTK_RESPONSE_CANCEL) break;
    replycode = gtk_entry_get_text(GTK_ENTRY(entry));
    if(replycode == NULL || g_strcmp0(replycode, "") == 0)
    {
      gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(gphoto_auth_dialog),
                                                 "%s\n\n%s\n\n<span foreground=\"" MSGCOLOR_RED
                                                 "\" ><small>%s</small></span>",
                                                 text1, text2, _("please enter the verification code"));
      continue;
    }
    else
    {
      token = g_strdup(replycode);
      break;
    }
  }
  gtk_widget_destroy(GTK_WIDGET(gphoto_auth_dialog));
  g_free(params);

  if(result == GTK_RESPONSE_CANCEL)
    return 1;

  // Interchange now the authorization_code for an access_token and refresh_token
  JsonObject *reply;

  params = NULL;
  params = dt_util_dstrcat(params, "code=%s&client_id=%s&client_secret=%s"
                           "&redirect_uri=" GOOGLE_URI "&grant_type=authorization_code",
                           token, ui->gphoto_api->google_client_id, ui->gphoto_api->google_client_secret);

  g_free(token);

  reply = gphoto_query_post_auth(ui->gphoto_api, GOOGLE_WS_BASE_URL "o/oauth2/token", params);

  gchar *access_token = g_strdup(json_object_get_string_member(reply, "access_token"));

  gchar *refresh_token = g_strdup(json_object_get_string_member(reply, "refresh_token"));

  ui->gphoto_api->token = access_token;
  ui->gphoto_api->refresh_token = refresh_token;

  g_free(params);

  return 0; // FIXME
}
Exemple #4
0
int dt_gui_hist_dialog_new(dt_gui_hist_dialog_t *d, int imgid, gboolean iscopy)
{
  int res;
  GtkWidget *window = dt_ui_main_window(darktable.gui->ui);

  GtkDialog *dialog = GTK_DIALOG(gtk_dialog_new_with_buttons(
      _("select parts"), GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, _("_cancel"),
      GTK_RESPONSE_CANCEL, _("select _all"), GTK_RESPONSE_YES, _("select _none"), GTK_RESPONSE_NONE, _("_ok"),
      GTK_RESPONSE_OK, NULL));
#ifdef GDK_WINDOWING_QUARTZ
  dt_osx_disallow_fullscreen(GTK_WIDGET(dialog));
#endif

  GtkContainer *content_area = GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
  GtkBox *box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 3));
  gtk_widget_set_margin_start(GTK_WIDGET(box), DT_PIXEL_APPLY_DPI(5));
  gtk_widget_set_margin_end(GTK_WIDGET(box), DT_PIXEL_APPLY_DPI(5));
  gtk_widget_set_margin_top(GTK_WIDGET(box), DT_PIXEL_APPLY_DPI(5));
  gtk_widget_set_margin_bottom(GTK_WIDGET(box), DT_PIXEL_APPLY_DPI(5));
  gtk_container_add(content_area, GTK_WIDGET(box));

  /* create the list of items */
  d->items = GTK_TREE_VIEW(gtk_tree_view_new());
  GtkListStore *liststore
      = gtk_list_store_new(DT_HIST_ITEMS_NUM_COLS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_UINT);

  /* enabled */
  GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
  gtk_cell_renderer_toggle_set_activatable(GTK_CELL_RENDERER_TOGGLE(renderer), TRUE);
  g_object_set_data(G_OBJECT(renderer), "column", (gint *)DT_HIST_ITEMS_COL_ENABLED);
  g_signal_connect(renderer, "toggled", G_CALLBACK(_gui_hist_item_toggled), d);

  gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(d->items), -1, _("include"), renderer, "active",
                                              DT_HIST_ITEMS_COL_ENABLED, NULL);

  /* name */
  renderer = gtk_cell_renderer_text_new();
  g_object_set_data(G_OBJECT(renderer), "column", (gint *)DT_HIST_ITEMS_COL_NAME);
  g_object_set(renderer, "xalign", 0.0, (gchar *)0);
  gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(d->items), -1, _("item"), renderer, "text",
                                              DT_HIST_ITEMS_COL_NAME, NULL);


  gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(d->items)), GTK_SELECTION_SINGLE);
  gtk_tree_view_set_model(GTK_TREE_VIEW(d->items), GTK_TREE_MODEL(liststore));

  gtk_box_pack_start(box, GTK_WIDGET(d->items), TRUE, TRUE, 0);

  /* fill list with history items */
  GtkTreeIter iter;
  GList *items = dt_history_get_items(imgid, FALSE);
  if(items)
  {
    do
    {
      dt_history_item_t *item = (dt_history_item_t *)items->data;

      gtk_list_store_append(GTK_LIST_STORE(liststore), &iter);
      gtk_list_store_set(GTK_LIST_STORE(liststore), &iter, DT_HIST_ITEMS_COL_ENABLED,
                         iscopy ? TRUE : _gui_is_set(d->selops, item->num), DT_HIST_ITEMS_COL_NAME,
                         item->name, DT_HIST_ITEMS_COL_NUM, (guint)item->num, -1);

    } while((items = g_list_next(items)));
    g_list_free_full(items, dt_history_item_free);
  }
  else
  {
    dt_control_log(_("can't copy history out of unaltered image"));
    return GTK_RESPONSE_CANCEL;
  }

  g_object_unref(liststore);

  g_signal_connect(dialog, "response", G_CALLBACK(_gui_hist_copy_response), d);

  gtk_widget_show_all(GTK_WIDGET(dialog));

  while(1)
  {
    res = gtk_dialog_run(GTK_DIALOG(dialog));
    if(res == GTK_RESPONSE_CANCEL || res == GTK_RESPONSE_DELETE_EVENT || res == GTK_RESPONSE_OK) break;
  }

  gtk_widget_destroy(GTK_WIDGET(dialog));
  return res;
}