48 memset(
out, 0, outsize);
53 char str[400] = { 0 };
56 sscanf(buf,
"%d", &num_rules);
57 while(buf[0] !=
'\0' && buf[0] !=
':') buf++;
58 if(buf[0] ==
':') buf++;
60 for(
int k = 0;
k < num_rules;
k++)
62 const int n = sscanf(buf,
"%d:%d:%399[^$]", &mode, &item, str);
66 if(
k > 0)
switch(mode)
69 c = g_strlcpy(
out, _(
" and "), outsize);
74 c = g_strlcpy(
out, _(
" or "), outsize);
79 c = g_strlcpy(
out, _(
" but not "), outsize);
85 while(str[
i] !=
'\0' && str[
i] !=
'$')
i++;
86 if(str[
i] ==
'$') str[
i] =
'\0';
93 while(buf[0] !=
'$' && buf[0] !=
'\0') buf++;
94 if(buf[0] ==
'$') buf++;
99static gboolean
update_collection_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
102 const int index = GPOINTER_TO_INT(
get_custom_data(GTK_WIDGET(user_data)));
106 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d", index);
109 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/pos%1d", index);
123 GtkWidget *widget = GTK_WIDGET(user_data);
130 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d", index);
136 if(collection && collection[0] !=
'\0')
138 char label[2048] = { 0 };
144 GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget));
145 gchar *escaped = g_markup_escape_text(label, -1);
146 gtk_label_set_markup(GTK_LABEL(child), escaped);
158 gtk_container_remove(GTK_CONTAINER(content),
dt_gui_get_global()->export_popup.module);
162static gboolean
export_files_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
186#ifdef GDK_WINDOWING_QUARTZ
193 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
195 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
196 gtk_window_set_modal(GTK_WINDOW(dialog),
FALSE);
198 gtk_window_set_title(GTK_WINDOW(dialog), _(
"Ansel - Export images"));
207 GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
208 gtk_box_pack_start(GTK_BOX(content), w,
TRUE,
TRUE, 0);
209 gtk_widget_set_visible(w,
TRUE);
210 gtk_widget_show_all(dialog);
233 GString *str = g_string_new(NULL);
234 for(GList *l = imgids; l; l = g_list_next(l))
236 const int32_t imgid = GPOINTER_TO_INT(l->data);
240 gboolean from_cache =
FALSE;
243 g_string_append(str, path);
246 gchar *quoted = g_shell_quote(path);
247 g_string_append(str, quoted);
252 g_string_append_printf(str,
"%i", imgid);
255 g_string_append_c(str,
'\n');
259 return g_string_free(str,
FALSE);
264 GtkTextBuffer *buffer = GTK_TEXT_BUFFER(user_data);
265 GList *imgids = (GList *)g_object_get_data(G_OBJECT(buffer),
"imgids");
267 gtk_text_buffer_set_text(buffer, text, -1);
273 GList *imgids = (GList *)g_object_get_data(G_OBJECT(buffer),
"imgids");
274 GtkComboBox *combo = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(buffer),
"combo"));
275 const int mode = gtk_combo_box_get_active(combo);
278 GtkFileChooserNative *chooser
279 = gtk_file_chooser_native_new(_(
"Ansel - Save image list"), GTK_WINDOW(dialog),
280 GTK_FILE_CHOOSER_ACTION_SAVE, _(
"_Save"), _(
"_Cancel"));
281 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser),
TRUE);
282 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(chooser),
284 :
"ansel-image-ids.txt");
285 if(gtk_native_dialog_run(GTK_NATIVE_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT)
287 gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
289 GError *
error = NULL;
290 if(!g_file_set_contents(filename, text, -1, &
error))
292 gchar *item = g_strdup_printf(
"%s: %s", filename,
error->message);
293 dt_control_alert(_(
"Could not save"), _(
"could not save the image list"), item);
300 g_object_unref(chooser);
305 if(response_id == GTK_RESPONSE_OK)
307 else if(response_id == GTK_RESPONSE_APPLY)
311 GtkTextBuffer *buffer = GTK_TEXT_BUFFER(user_data);
312 GtkTextIter start, end;
313 gtk_text_buffer_get_bounds(buffer, &start, &end);
314 gchar *text = gtk_text_buffer_get_text(buffer, &start, &end,
FALSE);
315 GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
316 gtk_clipboard_set_text(clipboard, text, -1);
317 gtk_clipboard_store(clipboard);
321 gtk_widget_destroy(dialog);
324static gboolean
export_image_list_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
329 if(dialog) gtk_widget_destroy(dialog);
334 dialog = gtk_dialog_new_with_buttons(_(
"Ansel - Export image list"),
336 GTK_DIALOG_DESTROY_WITH_PARENT,
337 _(
"Copy to clipboard"), GTK_RESPONSE_APPLY,
338 _(
"Save as file..."), GTK_RESPONSE_OK,
339 _(
"Close"), GTK_RESPONSE_CLOSE, NULL);
340#ifdef GDK_WINDOWING_QUARTZ
342 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
344 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
345 gtk_window_set_modal(GTK_WINDOW(dialog),
FALSE);
346 g_signal_connect(G_OBJECT(dialog),
"destroy", G_CALLBACK(gtk_widget_destroyed), &dialog);
348 GtkWidget *combo = gtk_combo_box_text_new();
349 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(
"Image ID"));
350 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(
"Image filename"));
353 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_(
"Export:")),
FALSE,
FALSE, 0);
354 gtk_box_pack_start(GTK_BOX(hbox), combo,
TRUE,
TRUE, 0);
357 gtk_text_view_set_editable(GTK_TEXT_VIEW(
view),
FALSE);
358 gtk_text_view_set_monospace(GTK_TEXT_VIEW(
view),
TRUE);
359 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(
view), GTK_WRAP_WORD_CHAR);
360 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(
view));
361 g_object_set_data_full(G_OBJECT(buffer),
"imgids", imgids, (GDestroyNotify)g_list_free);
362 g_object_set_data(G_OBJECT(buffer),
"combo", combo);
364 GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
365 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
366 gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(scroll),
DT_PIXEL_APPLY_DPI(450));
367 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scroll),
DT_PIXEL_APPLY_DPI(300));
368 gtk_container_add(GTK_CONTAINER(scroll),
view);
370 GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
372 gtk_box_pack_start(GTK_BOX(content), scroll,
TRUE,
TRUE, 0);
374 g_signal_connect(G_OBJECT(combo),
"changed", G_CALLBACK(
_export_list_fill), buffer);
380 gtk_widget_show_all(dialog);
414 gchar *item_label = g_strdup_printf(_(
"Most recent collection #%i"),
i);
415 add_sub_sub_menu_entry(menus, parent, lists, item_label, index, GINT_TO_POINTER(
i),
update_collection_callback, NULL, NULL, NULL, 0, 0);
456 add_sub_menu_entry(menus, lists, _(
"Quit"), index, NULL,
GET_ACCEL_WRAPPER(
dt_gui_closing_quit), NULL, NULL, NULL, GDK_KEY_q,
DT_PRIMARY_MASK);
Handle default and user-set shortcuts (accelerators)
GtkWidget * dt_gui_main_window(void)
void dt_gui_add_help_link(GtkWidget *widget, char *link)
static void error(char *msg)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_gui_closing_quit(void)
@ DT_LIB_COLLECT_MODE_AND
const char * dt_collection_name(dt_collection_properties_t prop)
void dt_collection_deserialize(const char *buf)
dt_collection_properties_t
@ DT_COLLECTION_PROP_LAST
@ DT_COLLECTION_PROP_UNDEF
@ DT_COLLECTION_CHANGE_NONE
#define NUM_LAST_COLLECTIONS
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
const dt_colormatrix_t dt_aligned_pixel_t out
const char * dt_conf_get_string_const(const char *name)
Borrow the stored string for name without copying it.
const char * dt_image_film_roll_name(const char *path)
void dt_image_full_path(const int32_t imgid, char *pathname, size_t pathname_len, gboolean *from_cache, const char *calling_func)
Get the full path of an image out of the database.
void dt_control_alert(const char *title, const char *message, const char *item)
Tell the user something that must not go unseen: what it says stays true after a toast would have fad...
void dt_control_delete_images()
void dt_control_move_images()
void dt_control_reset_local_copy_images()
void dt_control_set_local_copy_images()
gboolean dt_control_remove_images()
void dt_control_merge_hdr()
void dt_control_copy_images()
struct dt_gui_gtk_t * dt_gui_get_global(void)
GtkWidget * view
the tree view
@ DT_EXPORT_LIST_FILENAMES
void init_collection_line(gpointer instance, dt_collection_change_t query_change, dt_collection_properties_t changed_property, gpointer imgs, int next, gpointer user_data)
static gboolean export_files_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
static gboolean update_collection_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
static gchar * _export_list_build(GList *imgids, const int mode, const gboolean one_per_line)
static gboolean export_image_list_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
static void _export_list_response(GtkWidget *dialog, gint response_id, gpointer user_data)
void _close_export_popup(GtkWidget *dialog, gint response_id, gpointer data)
static void _export_list_save(GtkWidget *dialog, GtkTextBuffer *buffer)
static void pretty_print_collection(const char *buf, char *out, size_t outsize)
static void _export_list_fill(GtkComboBox *combo, gpointer user_data)
void append_file(GtkWidget **menus, GList **lists, const dt_menus_t index)
void dt_lib_gui_set_expanded(dt_lib_module_t *module, gboolean expanded)
GtkWidget * dt_lib_gui_get_expander(dt_lib_module_t *module)
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
void dt_osx_disallow_fullscreen(GtkWidget *widget)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
struct dt_selection_t * dt_selection_get_global(void)
GList * dt_selection_get_list(struct dt_selection_t *selection)
struct dt_control_signal_t * dt_control_signal_get_global(void)
@ DT_SIGNAL_COLLECTION_CHANGED
This signal is raised when collection changed. To avoid leaking the list, dt_collection_t is connecte...
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct dt_gui_gtk_t::@34 export_popup
char * dt_get_help_url(char *name)