34 memset(
out, 0, outsize);
39 char str[400] = { 0 };
42 sscanf(buf,
"%d", &num_rules);
43 while(buf[0] !=
'\0' && buf[0] !=
':') buf++;
44 if(buf[0] ==
':') buf++;
46 for(
int k = 0;
k < num_rules;
k++)
48 const int n = sscanf(buf,
"%d:%d:%399[^$]", &mode, &item, str);
52 if(
k > 0)
switch(mode)
55 c = g_strlcpy(
out, _(
" and "), outsize);
60 c = g_strlcpy(
out, _(
" or "), outsize);
65 c = g_strlcpy(
out, _(
" but not "), outsize);
71 while(str[
i] !=
'\0' && str[
i] !=
'$')
i++;
72 if(str[
i] ==
'$') str[
i] =
'\0';
79 while(buf[0] !=
'$' && buf[0] !=
'\0') buf++;
80 if(buf[0] ==
'$') buf++;
85static gboolean
update_collection_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
88 const int index = GPOINTER_TO_INT(
get_custom_data(GTK_WIDGET(user_data)));
92 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d", index);
95 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/pos%1d", index);
109 GtkWidget *widget = GTK_WIDGET(user_data);
116 snprintf(confname,
sizeof(confname),
"plugins/lighttable/recentcollect/line%1d", index);
122 if(collection && collection[0] !=
'\0')
124 char label[2048] = { 0 };
130 GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget));
131 gchar *escaped = g_markup_escape_text(label, -1);
132 gtk_label_set_markup(GTK_LABEL(child), escaped);
148static gboolean
export_files_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
172#ifdef GDK_WINDOWING_QUARTZ
179 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
181 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
182 gtk_window_set_modal(GTK_WINDOW(dialog),
FALSE);
184 gtk_window_set_title(GTK_WINDOW(dialog), _(
"Ansel - Export images"));
193 GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
194 gtk_box_pack_start(GTK_BOX(content), w,
TRUE,
TRUE, 0);
195 gtk_widget_set_visible(w,
TRUE);
196 gtk_widget_show_all(dialog);
219 GString *str = g_string_new(NULL);
220 for(GList *l = imgids; l; l = g_list_next(l))
222 const int32_t imgid = GPOINTER_TO_INT(l->data);
226 gboolean from_cache =
FALSE;
229 g_string_append(str, path);
232 gchar *quoted = g_shell_quote(path);
233 g_string_append(str, quoted);
238 g_string_append_printf(str,
"%i", imgid);
241 g_string_append_c(str,
'\n');
245 return g_string_free(str,
FALSE);
250 GtkTextBuffer *buffer = GTK_TEXT_BUFFER(user_data);
251 GList *imgids = (GList *)g_object_get_data(G_OBJECT(buffer),
"imgids");
253 gtk_text_buffer_set_text(buffer, text, -1);
259 GList *imgids = (GList *)g_object_get_data(G_OBJECT(buffer),
"imgids");
260 GtkComboBox *combo = GTK_COMBO_BOX(g_object_get_data(G_OBJECT(buffer),
"combo"));
261 const int mode = gtk_combo_box_get_active(combo);
264 GtkFileChooserNative *chooser
265 = gtk_file_chooser_native_new(_(
"Ansel - Save image list"), GTK_WINDOW(dialog),
266 GTK_FILE_CHOOSER_ACTION_SAVE, _(
"_Save"), _(
"_Cancel"));
267 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(chooser),
TRUE);
268 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(chooser),
270 :
"ansel-image-ids.txt");
271 if(gtk_native_dialog_run(GTK_NATIVE_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT)
273 gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
275 GError *
error = NULL;
276 if(!g_file_set_contents(filename, text, -1, &
error))
284 g_object_unref(chooser);
289 if(response_id == GTK_RESPONSE_OK)
291 else if(response_id == GTK_RESPONSE_APPLY)
295 GtkTextBuffer *buffer = GTK_TEXT_BUFFER(user_data);
296 GtkTextIter start, end;
297 gtk_text_buffer_get_bounds(buffer, &start, &end);
298 gchar *text = gtk_text_buffer_get_text(buffer, &start, &end,
FALSE);
299 GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
300 gtk_clipboard_set_text(clipboard, text, -1);
301 gtk_clipboard_store(clipboard);
305 gtk_widget_destroy(dialog);
308static gboolean
export_image_list_callback(GtkAccelGroup *group, GObject *acceleratable, guint keyval, GdkModifierType mods, gpointer user_data)
313 if(dialog) gtk_widget_destroy(dialog);
318 dialog = gtk_dialog_new_with_buttons(_(
"Ansel - Export image list"),
320 GTK_DIALOG_DESTROY_WITH_PARENT,
321 _(
"Copy to clipboard"), GTK_RESPONSE_APPLY,
322 _(
"Save as file..."), GTK_RESPONSE_OK,
323 _(
"Close"), GTK_RESPONSE_CLOSE, NULL);
324#ifdef GDK_WINDOWING_QUARTZ
326 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
328 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
329 gtk_window_set_modal(GTK_WINDOW(dialog),
FALSE);
330 g_signal_connect(G_OBJECT(dialog),
"destroy", G_CALLBACK(gtk_widget_destroyed), &dialog);
332 GtkWidget *combo = gtk_combo_box_text_new();
333 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(
"Image ID"));
334 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(
"Image filename"));
337 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new(_(
"Export:")),
FALSE,
FALSE, 0);
338 gtk_box_pack_start(GTK_BOX(hbox), combo,
TRUE,
TRUE, 0);
341 gtk_text_view_set_editable(GTK_TEXT_VIEW(
view),
FALSE);
342 gtk_text_view_set_monospace(GTK_TEXT_VIEW(
view),
TRUE);
343 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(
view), GTK_WRAP_WORD_CHAR);
344 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(
view));
345 g_object_set_data_full(G_OBJECT(buffer),
"imgids", imgids, (GDestroyNotify)g_list_free);
346 g_object_set_data(G_OBJECT(buffer),
"combo", combo);
348 GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
349 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
350 gtk_scrolled_window_set_min_content_width(GTK_SCROLLED_WINDOW(scroll),
DT_PIXEL_APPLY_DPI(450));
351 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scroll),
DT_PIXEL_APPLY_DPI(300));
352 gtk_container_add(GTK_CONTAINER(scroll),
view);
354 GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
356 gtk_box_pack_start(GTK_BOX(content), scroll,
TRUE,
TRUE, 0);
358 g_signal_connect(G_OBJECT(combo),
"changed", G_CALLBACK(
_export_list_fill), buffer);
364 gtk_widget_show_all(dialog);
382 NULL, GDK_KEY_i, GDK_CONTROL_MASK | GDK_SHIFT_MASK);
385 NULL, GDK_KEY_e, GDK_CONTROL_MASK | GDK_SHIFT_MASK);
398 gchar *item_label = g_strdup_printf(_(
"Most recent collection #%i"),
i);
399 add_sub_sub_menu_entry(menus, parent, lists, item_label, index, GINT_TO_POINTER(
i),
update_collection_callback, NULL, NULL, NULL, 0, 0);
440 add_sub_menu_entry(menus, lists, _(
"Quit"), index, NULL,
GET_ACCEL_WRAPPER(
dt_control_quit), NULL, NULL, NULL, GDK_KEY_q, GDK_CONTROL_MASK);
static void error(char *msg)
@ 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
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
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.
const char * dt_conf_get_string_const(const char *name)
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()
uint32_t view(const dt_view_t *self)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
@ 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_capitalize_label(gchar *text)
void dt_gui_add_help_link(GtkWidget *widget, char *link)
GtkWidget * dt_ui_main_window(dt_ui_t *ui)
get the main window widget
#define DT_PIXEL_APPLY_DPI(value)
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
void dt_osx_disallow_fullscreen(GtkWidget *widget)
GList * dt_selection_get_list(struct dt_selection_t *selection)
@ 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 _GtkWidget GtkWidget
struct dt_gui_gtk_t * gui
struct dt_selection_t * selection
struct dt_control_signal_t * signals
struct dt_gui_gtk_t::@50 export_popup
char * dt_get_help_url(char *name)