static gboolean _lib_filmstrip_size_handle_motion_notify_callback(GtkWidget *w, GdkEventButton *e, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_filmstrip_t *d = (dt_lib_filmstrip_t *)self->data; if (d->size_handle_is_dragging) { gint x,y,sx,sy; gdk_window_get_pointer (gtk_widget_get_window(dt_ui_main_window(darktable.gui->ui)), &x, &y, NULL); gtk_widget_get_size_request (d->filmstrip,&sx,&sy); sy = CLAMP(d->size_handle_height+(d->size_handle_y - y), 64,400); dt_conf_set_int("plugins/lighttable/filmstrip/height", sy); gtk_widget_set_size_request(d->filmstrip,-1,sy); return TRUE; } return FALSE; }
static void _preset_popup_posistion(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data) { gint w; gint ww; GtkRequisition requisition = { 0 }; w = gdk_window_get_width(gtk_widget_get_window(GTK_WIDGET(data))); ww = gdk_window_get_width(gtk_widget_get_window(dt_ui_main_window(darktable.gui->ui))); gdk_window_get_origin(gtk_widget_get_window(GTK_WIDGET(data)), x, y); gtk_widget_get_preferred_size(GTK_WIDGET(menu), &requisition, NULL); /* align left panel popupmenu to right edge */ if(*x < ww / 2) (*x) += w - requisition.width; GtkAllocation allocation_data; gtk_widget_get_allocation(GTK_WIDGET(data), &allocation_data); (*y) += allocation_data.height; }
static gboolean facebook_get_user_auth_token_from_server(dt_storage_facebook_gui_data_t *ui) { // create a dialog telling the user to login in the browser GtkWidget *win = dt_ui_main_window(darktable.gui->ui); GtkWidget *dialog = gtk_message_dialog_new( GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, _("a new window or tab of your browser should have been " "loaded. you have to login into your facebook account there " "and authorize darktable to upload photos before continuing.")); gtk_window_set_title(GTK_WINDOW(dialog), _("facebook authentication")); ui->auth_dialog = GTK_MESSAGE_DIALOG(dialog); // create an http server dt_http_server_t *server = dt_http_server_create(port_pool, n_ports, "facebook", _server_callback, ui); if(!server) { gtk_widget_destroy(dialog); return FALSE; } // open the browser if(!_open_browser(server->url)) { gtk_widget_destroy(dialog); dt_http_server_kill(server); return FALSE; } // show the window if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_CANCEL) { // if cancel button is clicked -> kill the server dt_http_server_kill(server); gtk_widget_destroy(dialog); } return TRUE; }
static int32_t dt_film_import1_run(dt_job_t *job) { dt_film_import1_t *params = dt_control_job_get_params(job); dt_film_import1(job, params->film); dt_pthread_mutex_lock(¶ms->film->images_mutex); params->film->ref--; dt_pthread_mutex_unlock(¶ms->film->images_mutex); if(params->film->ref <= 0) { if(dt_film_is_empty(params->film->id)) { dt_film_remove(params->film->id); } } // notify the user via the window manager if(darktable.gui) gtk_window_set_urgency_hint(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), TRUE); return 0; }
static void frame_colorpick_callback (GtkDarktableButton *button, dt_iop_module_t *self) { if(self->dt->gui->reset) return; dt_iop_borders_gui_data_t *g = (dt_iop_borders_gui_data_t *)self->gui_data; dt_iop_borders_params_t *p = (dt_iop_borders_params_t *)self->params; // turn off the other color picker so that this tool actually works ... gtk_toggle_button_set_active(g->frame_picker, FALSE); gtk_toggle_button_set_active(g->border_picker, FALSE); GtkColorSelectionDialog *csd = GTK_COLOR_SELECTION_DIALOG(gtk_color_selection_dialog_new(_("select frame line color"))); gtk_window_set_transient_for(GTK_WINDOW(csd), GTK_WINDOW(dt_ui_main_window(darktable.gui->ui))); GtkWidget *okButton, *cancelButton = 0; g_object_get(G_OBJECT(csd), "ok-button", &okButton, NULL); g_object_get(G_OBJECT(csd), "cancel-button", &cancelButton, NULL); g_signal_connect (G_OBJECT (okButton), "clicked", G_CALLBACK (colorpick_button_callback), csd); g_signal_connect (G_OBJECT (cancelButton), "clicked", G_CALLBACK (colorpick_button_callback), csd); GtkColorSelection *cs = GTK_COLOR_SELECTION(gtk_color_selection_dialog_get_color_selection(csd)); GdkColor c; c.red = 65535 * p->frame_color[0]; c.green = 65535 * p->frame_color[1]; c.blue = 65535 * p->frame_color[2]; gtk_color_selection_set_current_color(cs, &c); if(gtk_dialog_run(GTK_DIALOG(csd)) == GTK_RESPONSE_ACCEPT) { gtk_color_selection_get_current_color(cs, &c); p->frame_color[0] = c.red /65535.0; p->frame_color[1] = c.green/65535.0; p->frame_color[2] = c.blue /65535.0; gtk_widget_modify_fg(GTK_WIDGET(g->frame_colorpick), GTK_STATE_NORMAL, &c); } gtk_widget_destroy(GTK_WIDGET(csd)); dt_dev_add_history_item(darktable.develop, self, TRUE); }
static void export_button_clicked(GtkButton *button, gpointer user_data) { GDateTime *now = g_date_time_new_now_local(); char *export_filename = g_date_time_format(now, "darktable_tags_%F_%R.txt"); char *last_dirname = dt_conf_get_string("plugins/lighttable/tagging/last_import_export_location"); if(!last_dirname || !*last_dirname) { g_free(last_dirname); last_dirname = g_strdup(g_get_home_dir()); } GtkWidget *win = dt_ui_main_window(darktable.gui->ui); GtkWidget *filechooser = gtk_file_chooser_dialog_new(_("Select file to export to"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SAVE, _("_cancel"), GTK_RESPONSE_CANCEL, _("_export"), GTK_RESPONSE_ACCEPT, (char *)NULL); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(filechooser), TRUE); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), last_dirname); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(filechooser), export_filename); if(gtk_dialog_run(GTK_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT) { char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser)); char *dirname = g_path_get_dirname(filename); dt_conf_set_string("plugins/lighttable/tagging/last_import_export_location", dirname); ssize_t count = dt_tag_export(filename); if(count < 0) dt_control_log(_("error exporting tags")); else dt_control_log(_("%zd tags exported"), count); g_free(filename); g_free(dirname); } g_date_time_unref(now); g_free(last_dirname); g_free(export_filename); gtk_widget_destroy(filechooser); }
static void import_clicked (GtkWidget *w,gpointer user_data) { GtkWidget *win = dt_ui_main_window(darktable.gui->ui); GtkWidget *filechooser = gtk_file_chooser_dialog_new (_("select style"), GTK_WINDOW (win), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, (char *)NULL); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(filechooser), FALSE); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(filechooser),g_get_home_dir()); GtkFileFilter *filter; filter = GTK_FILE_FILTER(gtk_file_filter_new()); gtk_file_filter_add_pattern(filter, "*.dtstyle"); gtk_file_filter_set_name(filter, _("darktable style files")); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filechooser), filter); filter = GTK_FILE_FILTER(gtk_file_filter_new()); gtk_file_filter_add_pattern(filter, "*"); gtk_file_filter_set_name(filter, _("all files")); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filechooser), filter); if (gtk_dialog_run (GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT ) { char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser)); dt_styles_import_from_file(filename); // dt_lib_styles_t *d = (dt_lib_styles_t *)user_data; _gui_styles_update_view(d); // g_free (filename); } gtk_widget_destroy (filechooser); }
int dt_control_load_config(dt_control_t *c) { GtkWidget *widget = dt_ui_main_window(darktable.gui->ui); dt_conf_set_int("ui_last/view", DT_MODE_NONE); int width = dt_conf_get_int("ui_last/window_w"); int height = dt_conf_get_int("ui_last/window_h"); #ifndef __WIN32__ gint x = dt_conf_get_int("ui_last/window_x"); gint y = dt_conf_get_int("ui_last/window_y"); gtk_window_move(GTK_WINDOW(widget),x,y); #endif gtk_window_resize(GTK_WINDOW(widget), width, height); int fullscreen = dt_conf_get_bool("ui_last/fullscreen"); if(fullscreen) gtk_window_fullscreen (GTK_WINDOW(widget)); else { gtk_window_unfullscreen(GTK_WINDOW(widget)); int maximized = dt_conf_get_bool("ui_last/maximized"); if(maximized) gtk_window_maximize(GTK_WINDOW(widget)); else gtk_window_unmaximize(GTK_WINDOW(widget)); } return 0; }
static void export_clicked(GtkWidget *w, gpointer user_data) { dt_lib_styles_t *d = (dt_lib_styles_t *)user_data; char *name = get_style_name(d); if(name) { 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, _("_Save"), GTK_RESPONSE_ACCEPT, (char *)NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), g_get_home_dir()); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(filechooser), FALSE); if(gtk_dialog_run(GTK_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT) { char *filedir = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser)); dt_styles_save_to_file(name, filedir, FALSE); dt_control_log(_("style %s was successfully saved"), name); g_free(filedir); } g_free(name); gtk_widget_destroy(filechooser); } }
static void _lib_geotagging_show_offset_window(GtkWidget *widget, dt_lib_module_t *self) { dt_lib_geotagging_t *d = self->data; gint x, y; gint px, py, center_w, center_h, window_w, window_h; GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkWidget *center = dt_ui_center(darktable.gui->ui); gdk_window_get_origin(gtk_widget_get_window(center), &px, &py); center_w = gdk_window_get_width(gtk_widget_get_window(center)); center_h = gdk_window_get_height(gtk_widget_get_window(center)); d->floating_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_can_focus(d->floating_window, TRUE); gtk_window_set_decorated(GTK_WINDOW(d->floating_window), FALSE); gtk_window_set_type_hint(GTK_WINDOW(d->floating_window), GDK_WINDOW_TYPE_HINT_POPUP_MENU); gtk_window_set_transient_for(GTK_WINDOW(d->floating_window), GTK_WINDOW(window)); gtk_widget_set_opacity(d->floating_window, 0.8); gtk_window_set_modal(GTK_WINDOW(d->floating_window), TRUE); GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); gtk_widget_set_margin_top(vbox, DT_PIXEL_APPLY_DPI(2)); gtk_widget_set_margin_bottom(vbox, DT_PIXEL_APPLY_DPI(5)); gtk_widget_set_margin_start(vbox, DT_PIXEL_APPLY_DPI(5)); gtk_widget_set_margin_end(vbox, DT_PIXEL_APPLY_DPI(5)); gtk_container_add(GTK_CONTAINER(d->floating_window), vbox); d->floating_window_entry = gtk_entry_new(); gtk_widget_add_events(d->floating_window_entry, GDK_FOCUS_CHANGE_MASK); g_signal_connect_swapped(d->floating_window, "focus-out-event", G_CALLBACK(gtk_widget_destroy), d->floating_window); gtk_widget_set_tooltip_text(d->floating_window_entry, _("enter the time shown on the selected picture\nformat: hh:mm:ss")); gtk_editable_select_region(GTK_EDITABLE(d->floating_window_entry), 0, -1); gtk_box_pack_start(GTK_BOX(vbox), d->floating_window_entry, TRUE, TRUE, 0); g_signal_connect(d->floating_window_entry, "key-press-event", G_CALLBACK(_lib_geotagging_floating_key_press), self); GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); GtkWidget *cancel_button = gtk_button_new_with_label(_("cancel")); GtkWidget *ok_button = gtk_button_new_with_label(_("ok")); gtk_box_pack_start(GTK_BOX(hbox), cancel_button, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox), ok_button, TRUE, TRUE, 0); g_signal_connect_swapped(G_OBJECT(cancel_button), "clicked", G_CALLBACK(gtk_widget_destroy), d->floating_window); g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(_lib_geotagging_calculate_offset_callback), self); gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); gtk_widget_show_all(d->floating_window); gtk_widget_grab_focus(d->floating_window_entry); window_w = gdk_window_get_width(gtk_widget_get_window(d->floating_window)); window_h = gdk_window_get_height(gtk_widget_get_window(d->floating_window)); x = px + 0.5 * (center_w - window_w); y = py + center_h - 20 - window_h; gtk_window_move(GTK_WINDOW(d->floating_window), x, y); gtk_window_present(GTK_WINDOW(d->floating_window)); }
static gboolean _lib_geotagging_offset_key_press(GtkWidget *entry, GdkEventKey *event, dt_lib_module_t *self) { dt_lib_geotagging_t *d = (dt_lib_geotagging_t *)self->data; switch(event->keyval) { case GDK_KEY_Escape: case GDK_KEY_Tab: { // reset gchar *str = dt_conf_get_string("plugins/lighttable/geotagging/offset"); if(_lib_geotagging_parse_offset(str, NULL)) { gtk_entry_set_text(GTK_ENTRY(d->offset_entry), str); } else { gtk_entry_set_text(GTK_ENTRY(d->offset_entry), "+00:00:00"); dt_conf_set_string("plugins/lighttable/geotagging/offset", "+00:00:00"); } g_free(str); gtk_window_set_focus(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), NULL); return FALSE; } case GDK_KEY_Return: case GDK_KEY_KP_Enter: { const gchar *value = gtk_entry_get_text(GTK_ENTRY(d->offset_entry)); if(_lib_geotagging_parse_offset(value, NULL)) { dt_conf_set_string("plugins/lighttable/geotagging/offset", value); } else { gtk_entry_set_text(GTK_ENTRY(d->offset_entry), "+00:00:00"); dt_conf_set_string("plugins/lighttable/geotagging/offset", "+00:00:00"); } gtk_window_set_focus(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), NULL); return FALSE; } // allow +, -, :, 0 .. 9, left/right/home/end movement using arrow keys and del/backspace case GDK_KEY_plus: case GDK_KEY_KP_Add: case GDK_KEY_minus: case GDK_KEY_KP_Subtract: case GDK_KEY_colon: case GDK_KEY_0: case GDK_KEY_KP_0: case GDK_KEY_1: case GDK_KEY_KP_1: case GDK_KEY_2: case GDK_KEY_KP_2: case GDK_KEY_3: case GDK_KEY_KP_3: case GDK_KEY_4: case GDK_KEY_KP_4: case GDK_KEY_5: case GDK_KEY_KP_5: case GDK_KEY_6: case GDK_KEY_KP_6: case GDK_KEY_7: case GDK_KEY_KP_7: case GDK_KEY_8: case GDK_KEY_KP_8: case GDK_KEY_9: case GDK_KEY_KP_9: case GDK_KEY_Left: case GDK_KEY_Right: case GDK_KEY_Home: case GDK_KEY_KP_Home: case GDK_KEY_End: case GDK_KEY_KP_End: case GDK_KEY_Delete: case GDK_KEY_KP_Delete: case GDK_KEY_BackSpace: return FALSE; default: // block everything else return TRUE; } }
void init_widgets() { GtkWidget* container; GtkWidget* widget; // Creating the main window widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); darktable.gui->ui->main_window = widget; gtk_window_set_default_size(GTK_WINDOW(widget), 900, 500); gtk_window_set_icon_name(GTK_WINDOW(widget), "darktable"); gtk_window_set_title(GTK_WINDOW(widget), "Darktable"); g_signal_connect (G_OBJECT (widget), "delete_event", G_CALLBACK (dt_control_quit), NULL); g_signal_connect (G_OBJECT (widget), "key-press-event", G_CALLBACK (key_pressed_override), NULL); g_signal_connect (G_OBJECT (widget), "key-release-event", G_CALLBACK (key_released), NULL); container = widget; // Adding the outermost vbox widget = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(container), widget); gtk_widget_show(widget); /* connect to signal redraw all */ dt_control_signal_connect(darktable.signals, DT_SIGNAL_CONTROL_REDRAW_ALL, G_CALLBACK(_ui_widget_redraw_callback), darktable.gui->ui->main_window); container = widget; // Initializing the top border widget = gtk_drawing_area_new(); darktable.gui->widgets.top_border = widget; gtk_box_pack_start(GTK_BOX(container), widget, FALSE, TRUE, 0); gtk_widget_set_size_request(widget, -1, 10); gtk_widget_set_app_paintable(widget, TRUE); gtk_widget_set_events(widget, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK | GDK_SCROLL_MASK); gtk_widget_show(widget); // Initializing the main table init_main_table(container); // Initializing the bottom border widget = gtk_drawing_area_new(); darktable.gui->widgets.bottom_border = widget; gtk_box_pack_start(GTK_BOX(container), widget, FALSE, TRUE, 0); gtk_widget_set_size_request(widget, -1, 10); gtk_widget_set_app_paintable(widget, TRUE); gtk_widget_set_events(widget, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK | GDK_SCROLL_MASK); gtk_widget_show(widget); // Showing everything gtk_widget_show_all(dt_ui_main_window(darktable.gui->ui)); /* hide panels depending on last ui state */ for(int k=0;k<DT_UI_PANEL_SIZE;k++) { /* prevent show all */ gtk_widget_set_no_show_all(GTK_WIDGET(darktable.gui->ui->containers[k]), TRUE); /* check last visible state of panel */ char key[512]; g_snprintf(key, 512, "ui_last/%s/visible", _ui_panel_config_names[k]); /* if no key, lets default to TRUE*/ if(!dt_conf_key_exists(key)) dt_conf_set_bool(key,TRUE); if (!dt_conf_get_bool(key)) gtk_widget_set_visible(darktable.gui->ui->panels[k],FALSE); } }
void dt_control_key_accelerators_off(struct dt_control_t *s) { gtk_window_remove_accel_group(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), darktable.control->accelerators); s->key_accelerators_on = 0; }
static gboolean _lib_tagging_tag_show(GtkAccelGroup *accel_group, GObject *acceleratable, guint keyval, GdkModifierType modifier, dt_lib_module_t* self) { int mouse_over_id = -1; int zoom = dt_conf_get_int("plugins/lighttable/images_in_row"); // the order is: // if(zoom == 1) => currently shown image // else if(selection not empty) => selected images // else if(cursor over image) => hovered image // else => return if(zoom == 1 || dt_collection_get_selected_count(darktable.collection) == 0) { DT_CTL_GET_GLOBAL(mouse_over_id, lib_image_mouse_over_id); if(mouse_over_id < 0) return TRUE; } dt_lib_tagging_t *d = (dt_lib_tagging_t*)self->data; d->floating_tag_imgid = mouse_over_id; gint x, y; gint px, py, w, h; GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkWidget *center = dt_ui_center(darktable.gui->ui); gdk_window_get_origin(gtk_widget_get_window(center), &px, &py); w = gdk_window_get_width(gtk_widget_get_window(center)); h = gdk_window_get_height(gtk_widget_get_window(center)); x = px + 0.5*(w-FLOATING_ENTRY_WIDTH); y = py + h - 50; /* put the floating box at the mouse pointer */ // gint pointerx, pointery; // gtk_widget_get_pointer(center, &pointerx, &pointery); // x = px + pointerx + 1; // y = py + pointery + 1; d->floating_tag_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); /* stackoverflow.com/questions/1925568/how-to-give-keyboard-focus-to-a-pop-up-gtk-window */ gtk_widget_set_can_focus(d->floating_tag_window, TRUE); gtk_window_set_decorated(GTK_WINDOW(d->floating_tag_window), FALSE); gtk_window_set_type_hint(GTK_WINDOW(d->floating_tag_window), GDK_WINDOW_TYPE_HINT_POPUP_MENU); gtk_window_set_transient_for(GTK_WINDOW(d->floating_tag_window), GTK_WINDOW(window)); gtk_window_set_opacity(GTK_WINDOW(d->floating_tag_window), 0.8); gtk_window_move(GTK_WINDOW(d->floating_tag_window), x, y); GtkWidget *entry = gtk_entry_new(); gtk_widget_set_size_request(entry, FLOATING_ENTRY_WIDTH, -1); gtk_widget_add_events(entry, GDK_FOCUS_CHANGE_MASK); GtkEntryCompletion *completion = gtk_entry_completion_new(); gtk_entry_completion_set_model(completion, gtk_tree_view_get_model(GTK_TREE_VIEW(d->related))); gtk_entry_completion_set_text_column(completion, 0); gtk_entry_completion_set_inline_completion(completion, TRUE); gtk_entry_completion_set_popup_set_width(completion, FALSE); gtk_entry_set_completion(GTK_ENTRY(entry), completion); gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1); gtk_container_add(GTK_CONTAINER(d->floating_tag_window), entry); g_signal_connect_swapped(entry, "focus-out-event", G_CALLBACK(gtk_widget_destroy), d->floating_tag_window); g_signal_connect(entry, "key-press-event", G_CALLBACK(_lib_tagging_tag_key_press), self); gtk_widget_show_all(d->floating_tag_window); gtk_widget_grab_focus(entry); gtk_window_present(GTK_WINDOW(d->floating_tag_window)); return TRUE; }
static void _camera_import_dialog_new(_camera_import_dialog_t *data) { data->dialog = gtk_dialog_new_with_buttons(_("import images from camera"), NULL, GTK_DIALOG_MODAL, _("cancel"), GTK_RESPONSE_NONE, C_("camera import", "import"), GTK_RESPONSE_ACCEPT, NULL); gtk_window_set_default_size(GTK_WINDOW(data->dialog), 100, 600); gtk_window_set_transient_for(GTK_WINDOW(data->dialog), GTK_WINDOW(dt_ui_main_window(darktable.gui->ui))); GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(data->dialog)); // List - setup store data->store = gtk_list_store_new(2, GDK_TYPE_PIXBUF, G_TYPE_STRING); // IMPORT PAGE data->import.page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); gtk_container_set_border_width(GTK_CONTAINER(data->import.page), 5); // Top info data->import.info = gtk_label_new(_("please wait while prefetching thumbnails of images from camera...")); gtk_label_set_single_line_mode(GTK_LABEL(data->import.info), FALSE); gtk_widget_set_halign(data->import.info, GTK_ALIGN_START); gtk_box_pack_start(GTK_BOX(data->import.page), data->import.info, FALSE, FALSE, 0); // jobcode data->import.jobname = _camera_import_gconf_widget(data, _("jobcode"), "plugins/capture/camera/import/jobcode"); gtk_box_pack_start(GTK_BOX(data->import.page), GTK_WIDGET(data->import.jobname->widget), FALSE, FALSE, 0); // Create the treview with list model data store data->import.treeview = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(data->import.treeview), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_container_add(GTK_CONTAINER(data->import.treeview), gtk_tree_view_new()); GtkTreeView *treeview = GTK_TREE_VIEW(gtk_bin_get_child(GTK_BIN(data->import.treeview))); GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new(); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(_("thumbnail"), renderer, "pixbuf", 0, (char *)NULL); gtk_tree_view_append_column(treeview, column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("storage file"), renderer, "text", 1, (char *)NULL); gtk_tree_view_append_column(treeview, column); gtk_tree_view_column_set_expand(column, TRUE); GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); gtk_tree_view_set_model(treeview, GTK_TREE_MODEL(data->store)); gtk_tree_view_set_headers_visible(treeview, FALSE); gtk_box_pack_start(GTK_BOX(data->import.page), data->import.treeview, TRUE, TRUE, 0); // SETTINGS PAGE data->settings.page = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); gtk_container_set_border_width(GTK_CONTAINER(data->settings.page), 5); // general settings gtk_box_pack_start(GTK_BOX(data->settings.page), gtk_label_new(_("general")), FALSE, FALSE, 0); // ignoring of jpegs. hack while we don't handle raw+jpeg in the same directories. data->settings.general.ignore_jpeg = gtk_check_button_new_with_label(_("ignore JPEG files")); gtk_widget_set_tooltip_text(data->settings.general.ignore_jpeg, _("do not load files with an extension of .jpg or .jpeg. this can be useful when there are " "raw+JPEG in a directory.")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->settings.general.ignore_jpeg), dt_conf_get_bool("ui_last/import_ignore_jpegs")); gtk_box_pack_start(GTK_BOX(data->settings.page), data->settings.general.ignore_jpeg, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(data->settings.general.ignore_jpeg), "clicked", G_CALLBACK(_check_button_callback), data); GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); data->settings.general.date_override = gtk_check_button_new_with_label(_("override today's date")); gtk_box_pack_start(GTK_BOX(hbox), data->settings.general.date_override, FALSE, FALSE, 0); gtk_widget_set_tooltip_text(data->settings.general.date_override, _("check this, if you want to override the timestamp used when expanding variables:\n$(YEAR), " "$(MONTH), $(DAY),\n$(HOUR), $(MINUTE), $(SECONDS)")); data->settings.general.date_entry = gtk_entry_new(); gtk_widget_set_sensitive(data->settings.general.date_entry, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( data->settings.general.date_override))); gtk_box_pack_start(GTK_BOX(hbox), data->settings.general.date_entry, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(data->settings.general.date_override), "clicked", G_CALLBACK(_check_button_callback), data); gtk_box_pack_start(GTK_BOX(data->settings.page), hbox, FALSE, FALSE, 0); // THE NOTEBOOK data->notebook = gtk_notebook_new(); gtk_notebook_append_page(GTK_NOTEBOOK(data->notebook), data->import.page, gtk_label_new(_("images"))); gtk_notebook_append_page(GTK_NOTEBOOK(data->notebook), data->settings.page, gtk_label_new(_("settings"))); // end gtk_box_pack_start(GTK_BOX(content), data->notebook, TRUE, TRUE, 0); // gtk_widget_set_size_request(content, DT_PIXEL_APPLY_DPI(400), DT_PIXEL_APPLY_DPI(400)); }
static void edit_preset (const char *name_in, dt_lib_module_info_t *minfo) { gchar *name = NULL; if(name_in == NULL) { name = get_active_preset_name(minfo); if(name == NULL) return; } else name = g_strdup(name_in); GtkWidget *dialog; /* Create the widgets */ char title[1024]; GtkWidget *window = dt_ui_main_window(darktable.gui->ui); snprintf(title, 1024, _("edit `%s'"), name); dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); GtkContainer *content_area = GTK_CONTAINER(gtk_dialog_get_content_area (GTK_DIALOG (dialog))); GtkWidget *alignment = gtk_alignment_new(0.5, 0.5, 1.0, 1.0); gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 5, 5, 5, 5); gtk_container_add (content_area, alignment); GtkBox *box = GTK_BOX(gtk_vbox_new(FALSE, 5)); gtk_container_add (GTK_CONTAINER(alignment), GTK_WIDGET(box)); dt_lib_presets_edit_dialog_t *g = (dt_lib_presets_edit_dialog_t *)g_malloc0(sizeof(dt_lib_presets_edit_dialog_t)); g->old_id = -1; g_strlcpy(g->plugin_name, minfo->plugin_name, 128); g->version = minfo->version; g->params_size = minfo->params_size; g->params = minfo->params; g->name = GTK_ENTRY(gtk_entry_new()); g->module = minfo->module; g->original_name = name; gtk_entry_set_text(g->name, name); gtk_box_pack_start(box, GTK_WIDGET(g->name), FALSE, FALSE, 0); g_object_set(G_OBJECT(g->name), "tooltip-text", _("name of the preset"), (char *)NULL); g->description = GTK_ENTRY(gtk_entry_new()); gtk_box_pack_start(box, GTK_WIDGET(g->description), FALSE, FALSE, 0); g_object_set(G_OBJECT(g->description), "tooltip-text", _("description or further information"), (char *)NULL); sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select rowid, description from presets where name = ?1 and operation = ?2 and op_version = ?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, name, strlen(name), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, minfo->plugin_name, strlen(minfo->plugin_name), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, minfo->version); if(sqlite3_step(stmt) == SQLITE_ROW) { g->old_id = sqlite3_column_int(stmt, 0); gtk_entry_set_text(g->description, (const char *)sqlite3_column_text(stmt, 1)); } sqlite3_finalize(stmt); g_signal_connect (dialog, "response", G_CALLBACK (edit_preset_response), g); gtk_widget_show_all (dialog); }
static void edit_preset_response(GtkDialog *dialog, gint response_id, dt_lib_presets_edit_dialog_t *g) { gint dlg_ret; gint is_new = 0; if(response_id == GTK_RESPONSE_ACCEPT) { sqlite3_stmt *stmt; // now delete preset, so we can re-insert the new values: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "delete from presets where name=?1 and operation=?2 and op_version=?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, g->original_name, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, g->plugin_name, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, g->version); sqlite3_step(stmt); sqlite3_finalize(stmt); if ( ((g->old_id >= 0) && (strcmp(g->original_name, gtk_entry_get_text(g->name)) != 0)) || (g->old_id < 0) ) { // editing existing preset with different name or store new preset -> check for a preset with the same name: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select name from presets where name = ?1 and operation=?2 and op_version=?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, gtk_entry_get_text(g->name), strlen(gtk_entry_get_text(g->name)), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, g->plugin_name, strlen(g->plugin_name), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, g->version); if(sqlite3_step(stmt) == SQLITE_ROW) { sqlite3_finalize(stmt); GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkWidget *dlg_overwrite = gtk_message_dialog_new (GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("preset `%s' already exists.\ndo you want to overwrite?"), gtk_entry_get_text(g->name) ); gtk_window_set_title(GTK_WINDOW (dlg_overwrite), _("overwrite preset?")); dlg_ret = gtk_dialog_run (GTK_DIALOG (dlg_overwrite)); gtk_widget_destroy (dlg_overwrite); // if result is BUTTON_NO exit without destroy dialog, to permit other name if (dlg_ret == GTK_RESPONSE_NO) return; } else { is_new = 1; sqlite3_finalize(stmt); } } if (is_new == 0) { // delete preset, so we can re-insert the new values: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "delete from presets where name=?1 and operation=?2 and op_version=?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, gtk_entry_get_text(g->name), strlen(gtk_entry_get_text(g->name)), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, g->plugin_name, strlen(g->plugin_name), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, g->version); sqlite3_step(stmt); sqlite3_finalize(stmt); } // commit all the user input fields char path[1024]; snprintf(path,1024,"preset/%s",g->original_name); dt_accel_rename_preset_lib(g->module,path,gtk_entry_get_text(g->name)); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "insert into presets (name, description, operation, op_version, op_params, blendop_params, blendop_version, enabled, model, maker, lens, " "iso_min, iso_max, exposure_min, exposure_max, aperture_min, aperture_max, focal_length_min, focal_length_max, writeprotect, " "autoapply, filter, def, isldr) values (?1, ?2, ?3, ?4, ?5, null, 0, 1, '%', '%', '%', 0, 51200, 0, 100000000, 0, 100000000, 0, 1000, 0, 0, 0, 0, 0)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, gtk_entry_get_text(g->name), strlen(gtk_entry_get_text(g->name)), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, gtk_entry_get_text(g->description), strlen(gtk_entry_get_text(g->description)), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 3, g->plugin_name, strlen(g->plugin_name), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 4, g->version); DT_DEBUG_SQLITE3_BIND_BLOB(stmt, 5, g->params, g->params_size, SQLITE_TRANSIENT); sqlite3_step(stmt); sqlite3_finalize(stmt); dt_gui_store_last_preset (gtk_entry_get_text(g->name)); } gtk_widget_destroy(GTK_WIDGET(dialog)); g_free(g->original_name); free(g); }
static void edit_preset(const char *name_in, dt_iop_module_t *module) { gchar *name = NULL; if(name_in == NULL) { name = get_active_preset_name(module); if(name == NULL) return; } else name = g_strdup(name_in); GtkWidget *dialog; /* Create the widgets */ char title[1024]; GtkWidget *window = dt_ui_main_window(darktable.gui->ui); snprintf(title, sizeof(title), _("edit `%s' for module `%s'"), name, module->name()); dialog = gtk_dialog_new_with_buttons(title, GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, _("_ok"), GTK_RESPONSE_ACCEPT, _("_cancel"), GTK_RESPONSE_REJECT, NULL); GtkContainer *content_area = GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))); GtkBox *box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 5)); gtk_widget_set_margin_start(GTK_WIDGET(box), DT_PIXEL_APPLY_DPI(10)); gtk_widget_set_margin_end(GTK_WIDGET(box), DT_PIXEL_APPLY_DPI(10)); gtk_widget_set_margin_top(GTK_WIDGET(box), DT_PIXEL_APPLY_DPI(10)); gtk_widget_set_margin_bottom(GTK_WIDGET(box), DT_PIXEL_APPLY_DPI(10)); gtk_container_add(content_area, GTK_WIDGET(box)); GtkWidget *label; dt_gui_presets_edit_dialog_t *g = (dt_gui_presets_edit_dialog_t *)malloc(sizeof(dt_gui_presets_edit_dialog_t)); g->old_id = -1; g->original_name = name; g->module = module; g->name = GTK_ENTRY(gtk_entry_new()); gtk_entry_set_text(g->name, name); gtk_box_pack_start(box, GTK_WIDGET(g->name), FALSE, FALSE, 0); gtk_widget_set_tooltip_text(GTK_WIDGET(g->name), _("name of the preset")); g->description = GTK_ENTRY(gtk_entry_new()); gtk_box_pack_start(box, GTK_WIDGET(g->description), FALSE, FALSE, 0); gtk_widget_set_tooltip_text(GTK_WIDGET(g->description), _("description or further information")); g->autoapply = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(_("auto apply this preset to matching images"))); gtk_box_pack_start(box, GTK_WIDGET(g->autoapply), FALSE, FALSE, 0); g->filter = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(_("only show this preset for matching images"))); gtk_widget_set_tooltip_text(GTK_WIDGET(g->filter), _("be very careful with this option. " "this might be the last time you see your preset.")); gtk_box_pack_start(box, GTK_WIDGET(g->filter), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(g->autoapply), "toggled", G_CALLBACK(check_buttons_activated), g); g_signal_connect(G_OBJECT(g->filter), "toggled", G_CALLBACK(check_buttons_activated), g); int line = 0; g->details = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(g->details), DT_PIXEL_APPLY_DPI(5)); gtk_grid_set_column_spacing(GTK_GRID(g->details), DT_PIXEL_APPLY_DPI(10)); gtk_box_pack_start(box, GTK_WIDGET(g->details), TRUE, TRUE, 0); // model, maker, lens g->model = gtk_entry_new(); gtk_widget_set_hexpand(GTK_WIDGET(g->model), TRUE); gtk_widget_set_tooltip_text(g->model, _("string to match model (use % as wildcard)")); label = gtk_label_new(_("model")); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(g->details), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->model, label, GTK_POS_RIGHT, 2, 1); g->maker = gtk_entry_new(); gtk_widget_set_tooltip_text(g->maker, _("string to match maker (use % as wildcard)")); label = gtk_label_new(_("maker")); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(g->details), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->maker, label, GTK_POS_RIGHT, 2, 1); g->lens = gtk_entry_new(); gtk_widget_set_tooltip_text(g->lens, _("string to match lens (use % as wildcard)")); label = gtk_label_new(_("lens")); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(g->details), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->lens, label, GTK_POS_RIGHT, 2, 1); // iso label = gtk_label_new(_("ISO")); gtk_widget_set_halign(label, GTK_ALIGN_START); g->iso_min = gtk_spin_button_new_with_range(0, 51200, 100); gtk_widget_set_tooltip_text(g->iso_min, _("minimum ISO value")); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(g->iso_min), 0); g->iso_max = gtk_spin_button_new_with_range(0, 51200, 100); gtk_widget_set_tooltip_text(g->iso_max, _("maximum ISO value")); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(g->iso_max), 0); gtk_grid_attach(GTK_GRID(g->details), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->iso_min, label, GTK_POS_RIGHT, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->iso_max, g->iso_min, GTK_POS_RIGHT, 1, 1); // exposure label = gtk_label_new(_("exposure")); gtk_widget_set_halign(label, GTK_ALIGN_START); g->exposure_min = dt_bauhaus_combobox_new(NULL); g->exposure_max = dt_bauhaus_combobox_new(NULL); gtk_widget_set_tooltip_text(g->exposure_min, _("minimum exposure time")); gtk_widget_set_tooltip_text(g->exposure_max, _("maximum exposure time")); for(int k = 0; k < dt_gui_presets_exposure_value_cnt; k++) dt_bauhaus_combobox_add(g->exposure_min, dt_gui_presets_exposure_value_str[k]); for(int k = 0; k < dt_gui_presets_exposure_value_cnt; k++) dt_bauhaus_combobox_add(g->exposure_max, dt_gui_presets_exposure_value_str[k]); gtk_grid_attach(GTK_GRID(g->details), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->exposure_min, label, GTK_POS_RIGHT, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->exposure_max, g->exposure_min, GTK_POS_RIGHT, 1, 1); // aperture label = gtk_label_new(_("aperture")); gtk_widget_set_halign(label, GTK_ALIGN_START); g->aperture_min = dt_bauhaus_combobox_new(NULL); g->aperture_max = dt_bauhaus_combobox_new(NULL); gtk_widget_set_tooltip_text(g->aperture_min, _("minimum aperture value")); gtk_widget_set_tooltip_text(g->aperture_max, _("maximum aperture value")); for(int k = 0; k < dt_gui_presets_aperture_value_cnt; k++) dt_bauhaus_combobox_add(g->aperture_min, dt_gui_presets_aperture_value_str[k]); for(int k = 0; k < dt_gui_presets_aperture_value_cnt; k++) dt_bauhaus_combobox_add(g->aperture_max, dt_gui_presets_aperture_value_str[k]); gtk_grid_attach(GTK_GRID(g->details), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->aperture_min, label, GTK_POS_RIGHT, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->aperture_max, g->aperture_min, GTK_POS_RIGHT, 1, 1); // focal length label = gtk_label_new(_("focal length")); gtk_widget_set_halign(label, GTK_ALIGN_START); g->focal_length_min = gtk_spin_button_new_with_range(0, 1000, 10); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(g->focal_length_min), 0); g->focal_length_max = gtk_spin_button_new_with_range(0, 1000, 10); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(g->focal_length_max), 0); gtk_widget_set_tooltip_text(g->focal_length_min, _("minimum focal length")); gtk_widget_set_tooltip_text(g->focal_length_max, _("maximum focal length")); gtk_grid_attach(GTK_GRID(g->details), label, 0, line++, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->focal_length_min, label, GTK_POS_RIGHT, 1, 1); gtk_grid_attach_next_to(GTK_GRID(g->details), g->focal_length_max, g->focal_length_min, GTK_POS_RIGHT, 1, 1); // raw/hdr/ldr label = gtk_label_new(_("format")); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(g->details), label, 0, line, 1, 1); for(int i = 0; i < 3; i++) { g->format_btn[i] = gtk_check_button_new_with_label(_(dt_gui_presets_format_value_str[i])); gtk_grid_attach(GTK_GRID(g->details), g->format_btn[i], 1, line + i, 2, 1); } gtk_widget_set_no_show_all(GTK_WIDGET(g->details), TRUE); sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "SELECT rowid, description, model, maker, lens, iso_min, iso_max, " "exposure_min, exposure_max, aperture_min, aperture_max, focal_length_min, " "focal_length_max, autoapply, filter, format FROM presets WHERE name = ?1 AND " "operation = ?2 AND op_version = ?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, name, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, module->op, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, module->version()); if(sqlite3_step(stmt) == SQLITE_ROW) { g->old_id = sqlite3_column_int(stmt, 0); gtk_entry_set_text(GTK_ENTRY(g->description), (const char *)sqlite3_column_text(stmt, 1)); gtk_entry_set_text(GTK_ENTRY(g->model), (const char *)sqlite3_column_text(stmt, 2)); gtk_entry_set_text(GTK_ENTRY(g->maker), (const char *)sqlite3_column_text(stmt, 3)); gtk_entry_set_text(GTK_ENTRY(g->lens), (const char *)sqlite3_column_text(stmt, 4)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(g->iso_min), sqlite3_column_double(stmt, 5)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(g->iso_max), sqlite3_column_double(stmt, 6)); float val = sqlite3_column_double(stmt, 7); int k = 0; for(; k < dt_gui_presets_exposure_value_cnt && val > dt_gui_presets_exposure_value[k]; k++) ; dt_bauhaus_combobox_set(g->exposure_min, k); val = sqlite3_column_double(stmt, 8); for(k = 0; k < dt_gui_presets_exposure_value_cnt && val > dt_gui_presets_exposure_value[k]; k++) ; dt_bauhaus_combobox_set(g->exposure_max, k); val = sqlite3_column_double(stmt, 9); for(k = 0; k < dt_gui_presets_aperture_value_cnt && val > dt_gui_presets_aperture_value[k]; k++) ; dt_bauhaus_combobox_set(g->aperture_min, k); val = sqlite3_column_double(stmt, 10); for(k = 0; k < dt_gui_presets_aperture_value_cnt && val > dt_gui_presets_aperture_value[k]; k++) ; dt_bauhaus_combobox_set(g->aperture_max, k); gtk_spin_button_set_value(GTK_SPIN_BUTTON(g->focal_length_min), sqlite3_column_double(stmt, 11)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(g->focal_length_max), sqlite3_column_double(stmt, 12)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->autoapply), sqlite3_column_int(stmt, 13)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->filter), sqlite3_column_int(stmt, 14)); const int format = sqlite3_column_int(stmt, 15); for(k = 0; k < 3; k++) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->format_btn[k]), format & (dt_gui_presets_format_flag[k])); } else { gtk_entry_set_text(GTK_ENTRY(g->description), ""); gtk_entry_set_text(GTK_ENTRY(g->model), "%"); gtk_entry_set_text(GTK_ENTRY(g->maker), "%"); gtk_entry_set_text(GTK_ENTRY(g->lens), "%"); gtk_spin_button_set_value(GTK_SPIN_BUTTON(g->iso_min), 0); gtk_spin_button_set_value(GTK_SPIN_BUTTON(g->iso_max), 51200); float val = 0; int k = 0; for(; k < dt_gui_presets_exposure_value_cnt && val > dt_gui_presets_exposure_value[k]; k++) ; dt_bauhaus_combobox_set(g->exposure_min, k); val = 100000000; for(k = 0; k < dt_gui_presets_exposure_value_cnt && val > dt_gui_presets_exposure_value[k]; k++) ; dt_bauhaus_combobox_set(g->exposure_max, k); val = 0; for(k = 0; k < dt_gui_presets_aperture_value_cnt && val > dt_gui_presets_aperture_value[k]; k++) ; dt_bauhaus_combobox_set(g->aperture_min, k); val = 100000000; for(k = 0; k < dt_gui_presets_aperture_value_cnt && val > dt_gui_presets_aperture_value[k]; k++) ; dt_bauhaus_combobox_set(g->aperture_max, k); gtk_spin_button_set_value(GTK_SPIN_BUTTON(g->focal_length_min), 0); gtk_spin_button_set_value(GTK_SPIN_BUTTON(g->focal_length_max), 1000); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->autoapply), 0); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->filter), 0); for(k = 0; k < 3; k++) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->format_btn[k]), TRUE); } sqlite3_finalize(stmt); g_signal_connect(dialog, "response", G_CALLBACK(edit_preset_response), g); gtk_widget_show_all(dialog); }
static void edit_preset_response(GtkDialog *dialog, gint response_id, dt_gui_presets_edit_dialog_t *g) { gint is_new = 0; if(response_id == GTK_RESPONSE_ACCEPT) { sqlite3_stmt *stmt; const gchar *name = gtk_entry_get_text(g->name); if(((g->old_id >= 0) && (strcmp(g->original_name, name) != 0)) || (g->old_id < 0)) { if(strcmp(_("new preset"), name) == 0 || !(name && *name)) { // show error dialog GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkWidget *dlg_changename = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("please give preset a name")); gtk_window_set_title(GTK_WINDOW(dlg_changename), _("unnamed preset")); gtk_dialog_run(GTK_DIALOG(dlg_changename)); gtk_widget_destroy(dlg_changename); return; } // editing existing preset with different name or store new preset -> check for a preset with the same // name: DT_DEBUG_SQLITE3_PREPARE_V2( dt_database_get(darktable.db), "select name from presets where name = ?1 and operation=?2 and op_version=?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, name, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, g->module->op, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, g->module->version()); if(sqlite3_step(stmt) == SQLITE_ROW) { sqlite3_finalize(stmt); // show overwrite question dialog GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkWidget *dlg_overwrite = gtk_message_dialog_new( GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("preset `%s' already exists.\ndo you want to overwrite?"), name); gtk_window_set_title(GTK_WINDOW(dlg_overwrite), _("overwrite preset?")); gint dlg_ret = gtk_dialog_run(GTK_DIALOG(dlg_overwrite)); gtk_widget_destroy(dlg_overwrite); // if result is BUTTON_NO exit without destroy dialog, to permit other name if(dlg_ret == GTK_RESPONSE_NO) return; } else { is_new = 1; sqlite3_finalize(stmt); } } if(g->old_id >= 0) { // now delete old preset: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "delete from presets where name=?1 and operation=?2 and op_version=?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, g->original_name, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, g->module->op, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, g->module->version()); sqlite3_step(stmt); sqlite3_finalize(stmt); } if(is_new == 0) { // delete preset, so we can re-insert the new values: DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "delete from presets where name=?1 and operation=?2 and op_version=?3", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, name, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, g->module->op, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 3, g->module->version()); sqlite3_step(stmt); sqlite3_finalize(stmt); } // rename accelerators char path[1024]; snprintf(path, sizeof(path), "%s/%s", _("preset"), g->original_name); dt_accel_rename_preset_iop(g->module, path, name); // commit all the user input fields DT_DEBUG_SQLITE3_PREPARE_V2( dt_database_get(darktable.db), "INSERT INTO presets (name, description, operation, op_version, op_params, enabled, " "blendop_params, blendop_version, multi_priority, multi_name, " "model, maker, lens, iso_min, iso_max, exposure_min, exposure_max, aperture_min, aperture_max, " "focal_length_min, focal_length_max, writeprotect, autoapply, filter, def, format) " "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, 0, '', ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, " "?19, 0, ?20, ?21, 0, ?22)", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, name, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 2, gtk_entry_get_text(g->description), -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 3, g->module->op, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 4, g->module->version()); DT_DEBUG_SQLITE3_BIND_BLOB(stmt, 5, g->module->params, g->module->params_size, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 6, g->module->enabled); DT_DEBUG_SQLITE3_BIND_BLOB(stmt, 7, g->module->blend_params, sizeof(dt_develop_blend_params_t), SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 8, dt_develop_blend_version()); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 9, gtk_entry_get_text(GTK_ENTRY(g->model)), -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 10, gtk_entry_get_text(GTK_ENTRY(g->maker)), -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 11, gtk_entry_get_text(GTK_ENTRY(g->lens)), -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 12, gtk_spin_button_get_value(GTK_SPIN_BUTTON(g->iso_min))); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 13, gtk_spin_button_get_value(GTK_SPIN_BUTTON(g->iso_max))); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 14, dt_gui_presets_exposure_value[dt_bauhaus_combobox_get(g->exposure_min)]); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 15, dt_gui_presets_exposure_value[dt_bauhaus_combobox_get(g->exposure_max)]); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 16, dt_gui_presets_aperture_value[dt_bauhaus_combobox_get(g->aperture_min)]); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 17, dt_gui_presets_aperture_value[dt_bauhaus_combobox_get(g->aperture_max)]); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 18, gtk_spin_button_get_value(GTK_SPIN_BUTTON(g->focal_length_min))); DT_DEBUG_SQLITE3_BIND_DOUBLE(stmt, 19, gtk_spin_button_get_value(GTK_SPIN_BUTTON(g->focal_length_max))); DT_DEBUG_SQLITE3_BIND_INT(stmt, 20, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g->autoapply))); DT_DEBUG_SQLITE3_BIND_INT(stmt, 21, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g->filter))); int format = 0; for(int k = 0; k < 3; k++) format += gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g->format_btn[k])) * dt_gui_presets_format_flag[k]; DT_DEBUG_SQLITE3_BIND_INT(stmt, 22, format); sqlite3_step(stmt); sqlite3_finalize(stmt); dt_gui_store_last_preset(name); } gtk_widget_destroy(GTK_WIDGET(dialog)); g_free(g->original_name); free(g); }
static void _lib_geotagging_gpx_callback(GtkWidget *widget, dt_lib_module_t *self) { dt_lib_geotagging_t *d = (dt_lib_geotagging_t *)self->data; /* bring a filechooser to select the gpx file to apply to selection */ GtkWidget *win = dt_ui_main_window(darktable.gui->ui); GtkWidget *filechooser = gtk_file_chooser_dialog_new( _("open GPX file"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_OPEN, _("_cancel"), GTK_RESPONSE_CANCEL, _("_open"), GTK_RESPONSE_ACCEPT, (char *)NULL); char *last_directory = dt_conf_get_string("ui_last/gpx_last_directory"); if(last_directory != NULL) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), last_directory); g_free(last_directory); } GtkFileFilter *filter; filter = GTK_FILE_FILTER(gtk_file_filter_new()); gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME | GTK_FILE_FILTER_MIME_TYPE, _lib_geotagging_filter_gpx, NULL, NULL); gtk_file_filter_set_name(filter, _("GPS data exchange format")); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filechooser), filter); filter = GTK_FILE_FILTER(gtk_file_filter_new()); gtk_file_filter_add_pattern(filter, "*"); gtk_file_filter_set_name(filter, _("all files")); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filechooser), filter); // add time zone selection GtkWidget *extra_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); GtkWidget *label = gtk_label_new(_("camera time zone")); gtk_widget_set_tooltip_text(label, _("most cameras don't store the time zone in EXIF. " "give the correct time zone so the GPX data can be correctly matched")); GtkWidget *tz_selection = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(tz_selection), "UTC"); gtk_combo_box_set_active(GTK_COMBO_BOX(tz_selection), 0); GList *iter = d->timezones; int i = 0; gchar *old_tz = dt_conf_get_string("plugins/lighttable/geotagging/tz"); if(iter) { do { i++; gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(tz_selection), (gchar *)iter->data); if(!strcmp((gchar *)iter->data, old_tz)) gtk_combo_box_set_active(GTK_COMBO_BOX(tz_selection), i); } while((iter = g_list_next(iter)) != NULL); } g_free(old_tz); gtk_box_pack_start(GTK_BOX(extra_box), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(extra_box), tz_selection, FALSE, FALSE, 0); gtk_widget_show_all(extra_box); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(filechooser), extra_box); if(gtk_dialog_run(GTK_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT) { gchar *folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(filechooser)); dt_conf_set_string("ui_last/gpx_last_directory", folder); g_free(folder); gchar *tz = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(tz_selection)); dt_conf_set_string("plugins/lighttable/geotagging/tz", tz); gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser)); dt_control_gpx_apply(filename, -1, tz); g_free(filename); g_free(tz); } gtk_widget_destroy(extra_box); gtk_widget_destroy(filechooser); // dt_control_queue_redraw_center(); }
static void delete_button_clicked (GtkButton *button, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_tagging_t *d = (dt_lib_tagging_t *)self->data; int res = GTK_RESPONSE_YES; guint tagid; GtkTreeIter iter; GtkTreeModel *model = NULL; GtkTreeView *view = d->related; GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); if(!gtk_tree_selection_get_selected(selection, &model, &iter)) return; gtk_tree_model_get (model, &iter, DT_LIB_TAGGING_COL_ID, &tagid, -1); // First check how many images are affected by the remove int count = dt_tag_remove(tagid,FALSE); if( count > 0 && dt_conf_get_bool("plugins/lighttable/tagging/ask_before_delete_tag") ) { GtkWidget *dialog; GtkWidget *win = dt_ui_main_window(darktable.gui->ui); gchar *tagname=dt_tag_get_name(tagid); dialog = gtk_message_dialog_new(GTK_WINDOW(win), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, ngettext("do you really want to delete the tag `%s'?\n%d image is assigned this tag!", "do you really want to delete the tag `%s'?\n%d images are assigned this tag!", count), tagname,count); gtk_window_set_title(GTK_WINDOW(dialog), _("delete tag?")); res = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); free(tagname); } if(res != GTK_RESPONSE_YES) return; GList *tagged_images = NULL; sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from tagged_images where tagid=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, tagid); while(sqlite3_step(stmt) == SQLITE_ROW) { tagged_images = g_list_append(tagged_images, GINT_TO_POINTER(sqlite3_column_int(stmt, 0))); } sqlite3_finalize(stmt); dt_tag_remove(tagid,TRUE); GList *list_iter; if((list_iter = g_list_first(tagged_images)) != NULL) { do { dt_image_synch_xmp(GPOINTER_TO_INT(list_iter->data)); } while((list_iter=g_list_next(list_iter)) != NULL); } g_list_free(g_list_first(tagged_images)); update(self, 0); update(self, 1); dt_control_signal_raise(darktable.signals, DT_SIGNAL_TAG_CHANGED); }
static void _lib_import_single_image_callback(GtkWidget *widget, gpointer user_data) { GtkWidget *win = dt_ui_main_window(darktable.gui->ui); GtkWidget *filechooser = gtk_file_chooser_dialog_new( _("import image"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_OPEN, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Open"), GTK_RESPONSE_ACCEPT, (char *)NULL); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(filechooser), TRUE); char *last_directory = dt_conf_get_string("ui_last/import_last_directory"); if(last_directory != NULL) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), last_directory); g_free(last_directory); } char *cp, **extensions, ext[1024]; GtkFileFilter *filter; filter = GTK_FILE_FILTER(gtk_file_filter_new()); extensions = g_strsplit(dt_supported_extensions, ",", 100); for(char **i = extensions; *i != NULL; i++) { snprintf(ext, sizeof(ext), "*.%s", *i); gtk_file_filter_add_pattern(filter, ext); gtk_file_filter_add_pattern(filter, cp = g_ascii_strup(ext, -1)); g_free(cp); } g_strfreev(extensions); gtk_file_filter_set_name(filter, _("supported images")); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filechooser), filter); filter = GTK_FILE_FILTER(gtk_file_filter_new()); gtk_file_filter_add_pattern(filter, "*"); gtk_file_filter_set_name(filter, _("all files")); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filechooser), filter); GtkWidget *preview = gtk_image_new(); gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(filechooser), preview); g_signal_connect(filechooser, "update-preview", G_CALLBACK(_lib_import_update_preview), preview); dt_lib_import_metadata_t metadata; gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(filechooser), _lib_import_get_extra_widget(&metadata, FALSE)); if(gtk_dialog_run(GTK_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT) { dt_conf_set_string("ui_last/import_last_directory", gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(filechooser))); _lib_import_evaluate_extra_widget(&metadata, FALSE); char *filename = NULL; dt_film_t film; GSList *list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(filechooser)); GSList *it = list; int id = 0; int filmid = 0; /* reset filter so that view isn't empty */ dt_view_filter_reset(darktable.view_manager, TRUE); while(it) { filename = (char *)it->data; gchar *directory = g_path_get_dirname((const gchar *)filename); filmid = dt_film_new(&film, directory); id = dt_image_import(filmid, filename, TRUE); if(!id) dt_control_log(_("error loading file `%s'"), filename); g_free(filename); g_free(directory); it = g_slist_next(it); } if(id) { dt_film_open(filmid); // make sure buffers are loaded (load full for testing) dt_mipmap_buffer_t buf; dt_mipmap_cache_get(darktable.mipmap_cache, &buf, id, DT_MIPMAP_FULL, DT_MIPMAP_BLOCKING, 'r'); gboolean loaded = (buf.buf != NULL); dt_mipmap_cache_release(darktable.mipmap_cache, &buf); if(!loaded) { dt_control_log(_("file has unknown format!")); } else { dt_control_set_mouse_over_id(id); dt_ctl_switch_mode_to(DT_DEVELOP); } } } gtk_widget_destroy(metadata.frame); gtk_widget_destroy(filechooser); gtk_widget_queue_draw(dt_ui_center(darktable.gui->ui)); }
_flickr_api_context_t static *_flickr_api_authenticate(dt_storage_flickr_gui_data_t *ui) { char *perms = NULL, *frob; gchar *token; char *flickr_user_token = NULL; gint result; _flickr_api_context_t *ctx = (_flickr_api_context_t *)g_malloc(sizeof(_flickr_api_context_t)); memset(ctx,0,sizeof(_flickr_api_context_t)); flickcurl_init (); ctx->fc = flickcurl_new (); flickcurl_set_api_key (ctx->fc, API_KEY); flickcurl_set_shared_secret (ctx->fc, SHARED_SECRET); flickcurl_set_error_handler(ctx->fc, _flickr_api_error_handler, ctx); if (!ui->user_token) { // Retrieve stored auth_key // TODO: We should be able to store token for different users GHashTable* table = dt_pwstorage_get("flickr"); gchar * _username = g_strdup( g_hash_table_lookup(table, "username")); gchar *_user_token = g_strdup( g_hash_table_lookup(table, "token")); g_hash_table_destroy(table); if (_username) { if (!strcmp(_username,gtk_entry_get_text(ui->entry1))) { flickr_user_token = g_strdup(_user_token); perms = flickcurl_auth_checkToken(ctx->fc, flickr_user_token); } g_free (_username); } if (_user_token) g_free (_user_token); } else { flickr_user_token = ui->user_token; perms = flickcurl_auth_checkToken(ctx->fc, ui->user_token); } if (perms) { ui->user_token = flickr_user_token; flickcurl_set_auth_token(ctx->fc, flickr_user_token); return ctx; } else if (!ctx->error_occured) { frob = flickcurl_auth_getFrob(ctx->fc); GError *error = NULL; char *sign = g_strdup_printf ("%sapi_key%sfrob%spermswrite", SHARED_SECRET, API_KEY, frob); char *sign_md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, sign, strlen (sign)); gchar auth_url[250]; sprintf(auth_url,"http://flickr.com/services/auth/?api_key=%s&perms=write&frob=%s&api_sig=%s", API_KEY, frob, sign_md5); gtk_show_uri (gdk_screen_get_default(), auth_url, gtk_get_current_event_time (), &error); g_free(sign); g_free(sign_md5); // Hold here to let the user interact // Show a dialog. gchar *text1, *text2; text1 = g_strdup(_("step 1: a new window or tab of your browser should have been loaded. you have to login into your flickr account there and authorize darktable to upload photos before continuing.")); text2 = g_strdup(_("step 2: click the OK button once you are done.")); GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkWidget *flickr_auth_dialog = gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK_CANCEL, _("flickr authentication")); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (flickr_auth_dialog), "%s\n\n%s", text1, text2); result = gtk_dialog_run (GTK_DIALOG (flickr_auth_dialog)); gtk_widget_destroy(flickr_auth_dialog); g_free (text1); g_free (text2); switch (result) { case GTK_RESPONSE_OK: token = flickcurl_auth_getToken(ctx->fc, frob); g_free(frob); // TODO: Handle timeouts errors if (token) { flickr_user_token = g_strdup (token); } else { g_free(token); _flickr_api_free(ctx); return NULL; } ui->user_token = g_strdup(flickr_user_token); flickcurl_set_auth_token(ctx->fc, flickr_user_token); /* Add creds to pwstorage */ GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal); gchar* username = g_strdup(gtk_entry_get_text(ui->entry1)); g_hash_table_insert(table, "username", username); g_hash_table_insert(table, "token", flickr_user_token); if( !dt_pwstorage_set("flickr", table) ) { dt_print(DT_DEBUG_PWSTORAGE,"[flickr] cannot store username/token\n"); } g_free(flickr_user_token); g_hash_table_destroy(table); return ctx; break; default: dt_print(DT_DEBUG_PWSTORAGE,"[flickr] user cancelled the login process\n"); return NULL; } } if (perms) free(perms); return NULL; }
int dt_gui_gtk_init(dt_gui_gtk_t *gui, int argc, char *argv[]) { // unset gtk rc from kde: char gtkrc[PATH_MAX], path[PATH_MAX], datadir[PATH_MAX], configdir[PATH_MAX]; dt_loc_get_datadir(datadir, PATH_MAX); dt_loc_get_user_config_dir(configdir, PATH_MAX); g_snprintf(gtkrc, PATH_MAX, "%s/darktable.gtkrc", configdir); if (!g_file_test(gtkrc, G_FILE_TEST_EXISTS)) g_snprintf(gtkrc, PATH_MAX, "%s/darktable.gtkrc", datadir); if (g_file_test(gtkrc, G_FILE_TEST_EXISTS)) (void)setenv("GTK2_RC_FILES", gtkrc, 1); else fprintf(stderr, "[gtk_init] could not found darktable.gtkrc"); /* lets zero mem */ memset(gui,0,sizeof(dt_gui_gtk_t)); #if GLIB_MAJOR_VERSION <= 2 #if GLIB_MINOR_VERSION < 31 if (!g_thread_supported ()) g_thread_init(NULL); #endif #endif gdk_threads_init(); gdk_threads_enter(); gtk_init (&argc, &argv); GtkWidget *widget; gui->ui = dt_ui_initialize(argc,argv); gui->pixmap = NULL; gui->center_tooltip = 0; gui->presets_popup_menu = NULL; if(g_file_test(gtkrc, G_FILE_TEST_EXISTS)) gtk_rc_parse (gtkrc); // Initializing the shortcut groups darktable.control->accelerators = gtk_accel_group_new(); darktable.control->accelerator_list = NULL; // Connecting the callback to update keyboard accels for key_pressed g_signal_connect(G_OBJECT(gtk_accel_map_get()), "changed", G_CALLBACK(key_accel_changed), NULL); // Initializing widgets init_widgets(); // Adding the global shortcut group to the main window gtk_window_add_accel_group(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), darktable.control->accelerators); // get the screen resolution gui->dpi = gdk_screen_get_resolution(gtk_widget_get_screen(GTK_WIDGET(dt_ui_main_window(darktable.gui->ui)))); // set constant width from conf key int panel_width = dt_conf_get_int("panel_width"); if(panel_width < 20 || panel_width > 500) { // fix for unset/insane values. panel_width = 300; dt_conf_set_int("panel_width", panel_width); } // dt_gui_background_jobs_init(); /* Have the delete event (window close) end the program */ dt_loc_get_datadir(datadir, PATH_MAX); snprintf(path, PATH_MAX, "%s/icons", datadir); gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), path); widget = dt_ui_center(darktable.gui->ui); g_signal_connect (G_OBJECT (widget), "key-press-event", G_CALLBACK (key_pressed), NULL); g_signal_connect (G_OBJECT (widget), "configure-event", G_CALLBACK (configure), NULL); g_signal_connect (G_OBJECT (widget), "expose-event", G_CALLBACK (expose), NULL); g_signal_connect (G_OBJECT (widget), "motion-notify-event", G_CALLBACK (mouse_moved), NULL); g_signal_connect (G_OBJECT (widget), "leave-notify-event", G_CALLBACK (center_leave), NULL); g_signal_connect (G_OBJECT (widget), "enter-notify-event", G_CALLBACK (center_enter), NULL); g_signal_connect (G_OBJECT (widget), "button-press-event", G_CALLBACK (button_pressed), NULL); g_signal_connect (G_OBJECT (widget), "button-release-event", G_CALLBACK (button_released), NULL); g_signal_connect (G_OBJECT (widget), "scroll-event", G_CALLBACK (scrolled), NULL); // TODO: left, right, top, bottom: //leave-notify-event widget = darktable.gui->widgets.left_border; g_signal_connect (G_OBJECT (widget), "expose-event", G_CALLBACK (expose_borders), (gpointer)0); g_signal_connect (G_OBJECT (widget), "button-press-event", G_CALLBACK (borders_button_pressed), darktable.gui->ui); g_signal_connect (G_OBJECT (widget), "scroll-event", G_CALLBACK (borders_scrolled), (gpointer)0); g_object_set_data(G_OBJECT (widget), "border", (gpointer)0); widget = darktable.gui->widgets.right_border; g_signal_connect (G_OBJECT (widget), "expose-event", G_CALLBACK (expose_borders), (gpointer)1); g_signal_connect (G_OBJECT (widget), "button-press-event", G_CALLBACK (borders_button_pressed), darktable.gui->ui); g_signal_connect (G_OBJECT (widget), "scroll-event", G_CALLBACK (borders_scrolled), (gpointer)1); g_object_set_data(G_OBJECT (widget), "border", (gpointer)1); widget = darktable.gui->widgets.top_border; g_signal_connect (G_OBJECT (widget), "expose-event", G_CALLBACK (expose_borders), (gpointer)2); g_signal_connect (G_OBJECT (widget), "button-press-event", G_CALLBACK (borders_button_pressed), darktable.gui->ui); g_signal_connect (G_OBJECT (widget), "scroll-event", G_CALLBACK (borders_scrolled), (gpointer)2); g_object_set_data(G_OBJECT (widget), "border", (gpointer)2); widget = darktable.gui->widgets.bottom_border; g_signal_connect (G_OBJECT (widget), "expose-event", G_CALLBACK (expose_borders), (gpointer)3); g_signal_connect (G_OBJECT (widget), "button-press-event", G_CALLBACK (borders_button_pressed), darktable.gui->ui); g_signal_connect (G_OBJECT (widget), "scroll-event", G_CALLBACK (borders_scrolled), (gpointer)3); g_object_set_data(G_OBJECT (widget), "border", (gpointer)3); dt_gui_presets_init(); widget = dt_ui_center(darktable.gui->ui); GTK_WIDGET_UNSET_FLAGS (widget, GTK_DOUBLE_BUFFERED); // GTK_WIDGET_SET_FLAGS (widget, GTK_DOUBLE_BUFFERED); GTK_WIDGET_SET_FLAGS (widget, GTK_APP_PAINTABLE); // TODO: make this work as: libgnomeui testgnome.c /* GtkContainer *box = GTK_CONTAINER(darktable.gui->widgets.plugins_vbox); GtkScrolledWindow *swin = GTK_SCROLLED_WINDOW(darktable.gui-> widgets.right_scrolled_window); gtk_container_set_focus_vadjustment (box, gtk_scrolled_window_get_vadjustment (swin)); */ dt_ctl_get_display_profile(widget, &darktable.control->xprofile_data, &darktable.control->xprofile_size); // register keys for view switching dt_accel_register_global(NC_("accel", "capture view"), GDK_t, 0); dt_accel_register_global(NC_("accel", "lighttable view"), GDK_l, 0); dt_accel_register_global(NC_("accel", "darkroom view"), GDK_d, 0); dt_accel_connect_global( "capture view", g_cclosure_new(G_CALLBACK(_gui_switch_view_key_accel_callback), (gpointer)DT_GUI_VIEW_SWITCH_TO_TETHERING, NULL)); dt_accel_connect_global( "lighttable view", g_cclosure_new(G_CALLBACK(_gui_switch_view_key_accel_callback), (gpointer)DT_GUI_VIEW_SWITCH_TO_LIBRARY, NULL)); dt_accel_connect_global( "darkroom view", g_cclosure_new(G_CALLBACK(_gui_switch_view_key_accel_callback), (gpointer)DT_GUI_VIEW_SWITCH_TO_DARKROOM, NULL)); // register_keys for applying styles init_styles_key_accels(); connect_styles_key_accels(); // register ctrl-q to quit: dt_accel_register_global(NC_("accel", "quit"), GDK_q, GDK_CONTROL_MASK); dt_accel_connect_global( "quit", g_cclosure_new(G_CALLBACK(quit_callback), NULL, NULL)); // Contrast and brightness accelerators dt_accel_register_global(NC_("accel", "increase brightness"), GDK_F10, 0); dt_accel_register_global(NC_("accel", "decrease brightness"), GDK_F9, 0); dt_accel_register_global(NC_("accel", "increase contrast"), GDK_F8, 0); dt_accel_register_global(NC_("accel", "decrease contrast"), GDK_F7, 0); dt_accel_connect_global( "increase brightness", g_cclosure_new(G_CALLBACK(brightness_key_accel_callback), (gpointer)1, NULL)); dt_accel_connect_global( "decrease brightness", g_cclosure_new(G_CALLBACK(brightness_key_accel_callback), (gpointer)0, NULL)); dt_accel_connect_global( "increase contrast", g_cclosure_new(G_CALLBACK(contrast_key_accel_callback), (gpointer)1, NULL)); dt_accel_connect_global( "decrease contrast", g_cclosure_new(G_CALLBACK(contrast_key_accel_callback), (gpointer)0, NULL)); // Full-screen accelerators dt_accel_register_global(NC_("accel", "toggle fullscreen"), GDK_F11, 0); dt_accel_register_global(NC_("accel", "leave fullscreen"), GDK_Escape, 0); dt_accel_connect_global( "toggle fullscreen", g_cclosure_new(G_CALLBACK(fullscreen_key_accel_callback), (gpointer)1, NULL)); dt_accel_connect_global( "leave fullscreen", g_cclosure_new(G_CALLBACK(fullscreen_key_accel_callback), (gpointer)0, NULL)); // Side-border hide/show dt_accel_register_global(NC_("accel", "toggle side borders"), GDK_Tab, 0); // toggle view of header dt_accel_register_global(NC_("accel", "toggle header"), GDK_h, GDK_CONTROL_MASK); // View-switch dt_accel_register_global(NC_("accel", "switch view"), GDK_period, 0); dt_accel_connect_global( "switch view", g_cclosure_new(G_CALLBACK(view_switch_key_accel_callback), NULL, NULL)); darktable.gui->reset = 0; for(int i=0; i<3; i++) darktable.gui->bgcolor[i] = 0.1333; /* apply contrast to theme */ dt_gui_contrast_init (); return 0; }
static void _gui_styles_dialog_run (gboolean edit,const char *name,int imgid) { char title[512]; /* check if style exists */ if (name && (dt_styles_exists (name))==0) return; /* initialize the dialog */ dt_gui_styles_dialog_t *sd=(dt_gui_styles_dialog_t *)g_malloc (sizeof (dt_gui_styles_dialog_t)); sd->nameorig = g_strdup(name); if (edit) { sprintf (title,_("edit style")); g_strlcat (title, " \"", 512); g_strlcat(title, name, 512); g_strlcat(title, "\"", 512); sd->duplicate = gtk_check_button_new_with_label(_("duplicate style")); g_object_set (sd->duplicate, "tooltip-text", _("creates a duplicate of the style before applying changes"), (char *)NULL); } else { sd->imgid = imgid; sprintf (title,"%s",_("create new style")); sd->duplicate = NULL; } GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkDialog *dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (title, GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL)); GtkContainer *content_area = GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))); GtkWidget *alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0); gtk_alignment_set_padding (GTK_ALIGNMENT(alignment), 5, 5, 5, 5); gtk_container_add (content_area, alignment); GtkBox *box = GTK_BOX (gtk_vbox_new(FALSE, 5)); gtk_container_add (GTK_CONTAINER (alignment), GTK_WIDGET (box)); sd->name = gtk_entry_new(); g_object_set (sd->name, "tooltip-text", _("enter a name for the new style"), (char *)NULL); sd->description = gtk_entry_new(); g_object_set (sd->description, "tooltip-text", _("enter a description for the new style, this description is searchable"), (char *)NULL); /*set values*/ if (edit) { /* name */ gtk_entry_set_text(GTK_ENTRY(sd->name), name); /* description */ gchar *desc = dt_styles_get_description (name); if (desc) { gtk_entry_set_text (GTK_ENTRY (sd->description),desc); g_free (desc); } } gtk_box_pack_start (box,sd->name,FALSE,FALSE,0); gtk_box_pack_start (box,sd->description,FALSE,FALSE,0); /* create the list of items */ sd->items = GTK_TREE_VIEW (gtk_tree_view_new ()); GtkListStore *liststore = gtk_list_store_new (DT_STYLE_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_STYLE_ITEMS_COL_ENABLED); g_signal_connect (renderer, "toggled", G_CALLBACK (_gui_styles_item_toggled), sd); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (sd->items), -1, _("include"), renderer, "active", DT_STYLE_ITEMS_COL_ENABLED, NULL); /* name */ renderer = gtk_cell_renderer_text_new (); g_object_set_data (G_OBJECT (renderer), "column", (gint *)DT_STYLE_ITEMS_COL_NAME); g_object_set (renderer, "xalign", 0.0, NULL); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (sd->items), -1, _("item"), renderer, "text", DT_STYLE_ITEMS_COL_NAME, NULL); gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(sd->items)), GTK_SELECTION_SINGLE); gtk_tree_view_set_model (GTK_TREE_VIEW(sd->items), GTK_TREE_MODEL(liststore)); gtk_box_pack_start (box,GTK_WIDGET (sd->items),TRUE,TRUE,0); if (edit) gtk_box_pack_start (box,GTK_WIDGET (sd->duplicate),FALSE,FALSE,0); /* fill list with history items */ GtkTreeIter iter; if (edit) { /* get history items for named style and populate the items list */ GList *items = dt_styles_get_item_list (name, FALSE); if (items) { do { dt_style_item_t *item=(dt_style_item_t *)items->data; gtk_list_store_append (GTK_LIST_STORE(liststore), &iter); gtk_list_store_set (GTK_LIST_STORE(liststore), &iter, DT_STYLE_ITEMS_COL_ENABLED, TRUE, DT_STYLE_ITEMS_COL_NAME, item->name, DT_STYLE_ITEMS_COL_NUM, (guint)item->num, -1); g_free(item->name); g_free(item); } while ((items=g_list_next(items))); } } else { GList *items = dt_history_get_items (imgid,FALSE); if (items) { do { dt_history_item_t *item = (dt_history_item_t *)items->data; /* lookup history item module */ gboolean enabled = TRUE; dt_iop_module_t *module=NULL; GList *modules = g_list_first(darktable.develop->iop); if (modules) { GList *result = g_list_find_custom (modules, item->op, _g_list_find_module_by_name); // (dt_iop_module_t *)(modules->data); if( result ) { module = (dt_iop_module_t *)(result->data); enabled = (module->flags() & IOP_FLAGS_INCLUDE_IN_STYLES)?TRUE:FALSE; } } gchar name[256]= {0}; g_snprintf(name,256,"%s",item->name); gtk_list_store_append (GTK_LIST_STORE(liststore), &iter); gtk_list_store_set (GTK_LIST_STORE(liststore), &iter, DT_STYLE_ITEMS_COL_ENABLED, enabled, DT_STYLE_ITEMS_COL_NAME, name, DT_STYLE_ITEMS_COL_NUM, (guint)item->num, -1); g_free(item->op); g_free(item->name); g_free(item); } while ((items=g_list_next(items))); } else { dt_control_log(_("can't create style out of unaltered image")); return; } } g_object_unref (liststore); /* run dialog */ if (edit) g_signal_connect (dialog, "response", G_CALLBACK (_gui_styles_edit_style_response), sd); else g_signal_connect (dialog, "response", G_CALLBACK (_gui_styles_new_style_response), sd); gtk_widget_show_all (GTK_WIDGET (dialog)); gtk_dialog_run(GTK_DIALOG(dialog)); }
/** * @see https://developers.facebook.com/docs/authentication/ * @returs NULL if the user cancel the operation or a valid token */ static gchar *facebook_get_user_auth_token(dt_storage_facebook_gui_data_t *ui) { ///////////// open the authentication url in a browser GError *error = NULL; gtk_show_uri(gdk_screen_get_default(), FB_WS_BASE_URL"dialog/oauth?" "client_id=" FB_API_KEY "&redirect_uri="FB_WS_BASE_URL"connect/login_success.html" "&scope=user_photos,publish_stream" "&response_type=token", gtk_get_current_event_time(), &error); ////////////// build & show the validation dialog gchar *text1 = _("step 1: a new window or tab of your browser should have been " "loaded. you have to login into your facebook account there " "and authorize darktable to upload photos before continuing."); gchar *text2 = _("step 2: paste your browser URL and click the OK button once " "you are done."); GtkWidget *window = dt_ui_main_window(darktable.gui->ui); GtkDialog *fb_auth_dialog = GTK_DIALOG(gtk_message_dialog_new (GTK_WINDOW (window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, _("facebook authentication"))); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (fb_auth_dialog), "%s\n\n%s", text1, text2); GtkWidget *entry = gtk_entry_new(); GtkWidget *hbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(gtk_label_new(_("URL:"))), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry), TRUE, TRUE, 0); GtkWidget *fbauthdialog_vbox = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(fb_auth_dialog)); gtk_box_pack_end(GTK_BOX(fbauthdialog_vbox), hbox, TRUE, TRUE, 0); gtk_widget_show_all(GTK_WIDGET(fb_auth_dialog)); ////////////// wait for the user to enter the validation URL gint result; gchar *token = NULL; const char *replyurl; while (TRUE) { result = gtk_dialog_run (GTK_DIALOG (fb_auth_dialog)); if (result == GTK_RESPONSE_CANCEL) break; replyurl = gtk_entry_get_text(GTK_ENTRY(entry)); if (replyurl == NULL || g_strcmp0(replyurl, "") == 0) { gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(fb_auth_dialog), "%s\n\n%s\n\n<span foreground=\"" MSGCOLOR_RED "\" ><small>%s</small></span>", text1, text2, _("please enter the validation URL")); continue; } token = fb_extract_token_from_url(replyurl); if (token != NULL)//we have a valid token break; else gtk_message_dialog_format_secondary_markup( GTK_MESSAGE_DIALOG(fb_auth_dialog), "%s\n\n%s%s\n\n<span foreground=\"" MSGCOLOR_RED "\"><small>%s</small></span>", text1, text2, _("the given URL is not valid, it should look like: "), FB_WS_BASE_URL"connect/login_success.html?..."); } gtk_widget_destroy(GTK_WIDGET(fb_auth_dialog)); return token; }
void dt_control_key_accelerators_on(struct dt_control_t *s) { gtk_window_add_accel_group(GTK_WINDOW(dt_ui_main_window(darktable.gui->ui)), darktable.control->accelerators); if(!s->key_accelerators_on) s->key_accelerators_on = 1; }
static void _lib_geolocation_gpx_callback(GtkWidget *widget, dt_lib_module_t *self) { dt_lib_geolocation_t *d = (dt_lib_geolocation_t*)self->data; /* bring a filechooser to select the gpx file to apply to selection */ GtkWidget *win = dt_ui_main_window(darktable.gui->ui); GtkWidget *filechooser = gtk_file_chooser_dialog_new(_("open gpx file"), GTK_WINDOW (win), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, (char *)NULL); GtkFileFilter *filter; filter = GTK_FILE_FILTER(gtk_file_filter_new()); gtk_file_filter_add_pattern(filter, "*.gpx"); gtk_file_filter_set_name(filter, _("GPS Data Exchange Format")); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filechooser), filter); filter = GTK_FILE_FILTER(gtk_file_filter_new()); gtk_file_filter_add_pattern(filter, "*"); gtk_file_filter_set_name(filter, _("all files")); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(filechooser), filter); // add time zone selection GtkWidget *extra_box = gtk_hbox_new(FALSE, 5); GtkWidget *label = gtk_label_new("camera time zone"); g_object_set(G_OBJECT(label), "tooltip-text", _("most cameras don't store the time zone in exif. give the correct time zone so the gpx data can be correctly matched"), (char *)NULL); GtkWidget *tz_selection = gtk_combo_box_text_new(); gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(tz_selection), "UTC"); gtk_combo_box_set_active(GTK_COMBO_BOX(tz_selection), 0); GList *iter = d->timezones; int i = 0; gchar *old_tz= dt_conf_get_string("plugins/lighttable/geolocation/tz"); if(iter) { do { i++; gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(tz_selection), (gchar*)iter->data); if(!strcmp((gchar*)iter->data, old_tz)) gtk_combo_box_set_active(GTK_COMBO_BOX(tz_selection), i); } while( (iter = g_list_next(iter)) != NULL); } gtk_box_pack_start(GTK_BOX(extra_box), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(extra_box), tz_selection, FALSE, FALSE, 0); gtk_widget_show_all(extra_box); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(filechooser), extra_box); if(gtk_dialog_run(GTK_DIALOG (filechooser)) == GTK_RESPONSE_ACCEPT) { gchar *tz = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(tz_selection)); dt_conf_set_string("plugins/lighttable/geolocation/tz", tz); gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (filechooser)); dt_control_gpx_apply(filename, -1, tz); g_free(filename); g_free(tz); } gtk_widget_destroy(extra_box); gtk_widget_destroy(filechooser); // dt_control_queue_redraw_center(); }
static void _lib_import_folder_callback(GtkWidget *widget, gpointer user_data) { GtkWidget *win = dt_ui_main_window(darktable.gui->ui); GtkWidget *filechooser = gtk_file_chooser_dialog_new( _("import film"), GTK_WINDOW(win), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Open"), GTK_RESPONSE_ACCEPT, (char *)NULL); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(filechooser), TRUE); char *last_directory = dt_conf_get_string("ui_last/import_last_directory"); if(last_directory != NULL) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(filechooser), last_directory); g_free(last_directory); } dt_lib_import_metadata_t metadata; gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(filechooser), _lib_import_get_extra_widget(&metadata, TRUE)); // run the dialog if(gtk_dialog_run(GTK_DIALOG(filechooser)) == GTK_RESPONSE_ACCEPT) { dt_conf_set_string("ui_last/import_last_directory", gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(filechooser))); _lib_import_evaluate_extra_widget(&metadata, TRUE); char *filename = NULL, *first_filename = NULL; GSList *list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(filechooser)); GSList *it = list; /* reset filter so that view isn't empty */ dt_view_filter_reset(darktable.view_manager, TRUE); /* for each selected folder add import job */ while(it) { filename = (char *)it->data; dt_film_import(filename); if(!first_filename) { first_filename = g_strdup(filename); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(metadata.recursive))) first_filename = dt_util_dstrcat(first_filename, "%%"); } g_free(filename); it = g_slist_next(it); } /* update collection to view import */ if(first_filename) { dt_conf_set_int("plugins/lighttable/collect/num_rules", 1); dt_conf_set_int("plugins/lighttable/collect/item0", 0); dt_conf_set_string("plugins/lighttable/collect/string0", first_filename); dt_collection_update_query(darktable.collection); g_free(first_filename); } g_slist_free(list); } gtk_widget_destroy(metadata.frame); gtk_widget_destroy(filechooser); gtk_widget_queue_draw(dt_ui_center(darktable.gui->ui)); }
/** * @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 }