47 memset(
out, 0, outsize);
52 char str[400] = { 0 };
55 sscanf(buf,
"%d", &num_rules);
56 while(buf[0] !=
'\0' && buf[0] !=
':') buf++;
57 if(buf[0] ==
':') buf++;
59 for(
int k = 0;
k < num_rules;
k++)
61 const int n = sscanf(buf,
"%d:%d:%399[^$]", &mode, &item, str);
65 if(
k > 0)
switch(mode)
68 c = g_strlcpy(
out, _(
" and "), outsize);
73 c = g_strlcpy(
out, _(
" or "), outsize);
78 c = g_strlcpy(
out, _(
" but not "), outsize);
84 while(str[
i] !=
'\0' && str[
i] !=
'$')
i++;
85 if(str[
i] ==
'$') str[
i] =
'\0';
92 while(buf[0] !=
'$' && buf[0] !=
'\0') buf++;
93 if(buf[0] ==
'$') buf++;
98static gboolean
update_collection_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
101 const int index = GPOINTER_TO_INT(
get_custom_data(GTK_WIDGET(user_data)));
105 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d", index);
108 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/pos%1d", index);
122 GtkWidget *widget = GTK_WIDGET(user_data);
129 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d", index);
135 if(collection && collection[0] !=
'\0')
137 char label[2048] = { 0 };
143 GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget));
144 gchar *escaped = g_markup_escape_text(label, -1);
145 gtk_label_set_markup(GTK_LABEL(child), escaped);
157 gtk_container_remove(GTK_CONTAINER(content),
dt_gui_get_global()->export_popup.module);
161static gboolean
export_files_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
185#ifdef GDK_WINDOWING_QUARTZ
192 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
194 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
195 gtk_window_set_modal(GTK_WINDOW(dialog),
FALSE);
197 gtk_window_set_title(GTK_WINDOW(dialog), _(
"Ansel - Export images"));
206 GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
207 gtk_box_pack_start(GTK_BOX(content), w,
TRUE,
TRUE, 0);
208 gtk_widget_set_visible(w,
TRUE);
209 gtk_widget_show_all(dialog);
232 GString *str = g_string_new(NULL);
233 for(GList *l = imgids; l; l = g_list_next(l))
235 const int32_t imgid = GPOINTER_TO_INT(l->data);
239 gboolean from_cache =
FALSE;
242 g_string_append(str, path);
245 gchar *quoted = g_shell_quote(path);
246 g_string_append(str, quoted);
251 g_string_append_printf(str,
"%i", imgid);
254 g_string_append_c(str,
'\n');
258 return g_string_free(str,
FALSE);
263 GtkTextBuffer *buffer = GTK_TEXT_BUFFER(user_data);
264 GList *imgids = (GList *)g_object_get_data(G_OBJECT(buffer),
"imgids");
266 gtk_text_buffer_set_text(buffer, text, -1);
272 GList *imgids = (GList *)g_object_get_data(G_OBJECT(buffer),
"imgids");
273 GtkComboBox *combo = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(buffer),
"combo"));
274 const int mode = gtk_combo_box_get_active(combo);
277 GtkFileChooserNative *chooser
278 = gtk_file_chooser_native_new(_(
"Ansel - Save image list"), GTK_WINDOW(dialog),
279 GTK_FILE_CHOOSER_ACTION_SAVE, _(
"_Save"), _(
"_Cancel"));
280 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser),
TRUE);
281 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(chooser),
283 :
"ansel-image-ids.txt");
284 if(gtk_native_dialog_run(GTK_NATIVE_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT)
286 gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
288 GError *
error = NULL;
289 if(!g_file_set_contents(filename, text, -1, &
error))
297 g_object_unref(chooser);
302 if(response_id == GTK_RESPONSE_OK)
304 else if(response_id == GTK_RESPONSE_APPLY)
308 GtkTextBuffer *buffer = GTK_TEXT_BUFFER(user_data);
309 GtkTextIter start, end;
310 gtk_text_buffer_get_bounds(buffer, &start, &end);
311 gchar *text = gtk_text_buffer_get_text(buffer, &start, &end,
FALSE);
312 GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
313 gtk_clipboard_set_text(clipboard, text, -1);
314 gtk_clipboard_store(clipboard);
318 gtk_widget_destroy(dialog);
321static gboolean
export_image_list_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
326 if(dialog) gtk_widget_destroy(dialog);
331 dialog = gtk_dialog_new_with_buttons(_(
"Ansel - Export image list"),
333 GTK_DIALOG_DESTROY_WITH_PARENT,
334 _(
"Copy to clipboard"), GTK_RESPONSE_APPLY,
335 _(
"Save as file..."), GTK_RESPONSE_OK,
336 _(
"Close"), GTK_RESPONSE_CLOSE, NULL);
337#ifdef GDK_WINDOWING_QUARTZ
339 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
341 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
342 gtk_window_set_modal(GTK_WINDOW(dialog),
FALSE);
343 g_signal_connect(G_OBJECT(dialog),
"destroy", G_CALLBACK(gtk_widget_destroyed), &dialog);
345 GtkWidget *combo = gtk_combo_box_text_new();
346 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(
"Image ID"));
347 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(
"Image filename"));
350 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_(
"Export:")),
FALSE,
FALSE, 0);
351 gtk_box_pack_start(GTK_BOX(hbox), combo,
TRUE,
TRUE, 0);
354 gtk_text_view_set_editable(GTK_TEXT_VIEW(
view),
FALSE);
355 gtk_text_view_set_monospace(GTK_TEXT_VIEW(
view),
TRUE);
356 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(
view), GTK_WRAP_WORD_CHAR);
357 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(
view));
358 g_object_set_data_full(G_OBJECT(buffer),
"imgids", imgids, (GDestroyNotify)g_list_free);
359 g_object_set_data(G_OBJECT(buffer),
"combo", combo);
361 GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
362 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
363 gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(scroll),
DT_PIXEL_APPLY_DPI(450));
364 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scroll),
DT_PIXEL_APPLY_DPI(300));
365 gtk_container_add(GTK_CONTAINER(scroll),
view);
367 GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
369 gtk_box_pack_start(GTK_BOX(content), scroll,
TRUE,
TRUE, 0);
371 g_signal_connect(G_OBJECT(combo),
"changed", G_CALLBACK(
_export_list_fill), buffer);
377 gtk_widget_show_all(dialog);
411 gchar *item_label = g_strdup_printf(_(
"Most recent collection #%i"),
i);
412 add_sub_sub_menu_entry(menus, parent, lists, item_label, index, GINT_TO_POINTER(
i),
update_collection_callback, NULL, NULL, NULL, 0, 0);
453 add_sub_menu_entry(menus, lists, _(
"Quit"), index, NULL,
GET_ACCEL_WRAPPER(
dt_control_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))
@ 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_log(const char *msg,...)
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)