294 self->
data = (
void *)
d;
300 GtkWidget *control_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
304 GtkWidget *datetime_label = gtk_label_new(_(
"Project date"));
305 gtk_widget_set_halign(datetime_label, GTK_ALIGN_START);
306 gtk_box_pack_start(GTK_BOX(datetime_box), datetime_label,
FALSE,
FALSE, 0);
308 d->datetime = gtk_entry_new();
310 gtk_entry_set_placeholder_text(GTK_ENTRY(
d->datetime), _(
"Current date at import time"));
311 gtk_widget_set_tooltip_text(
d->datetime,
312 _(
"Format: YYYY-MM-DD, optionally followed by HH:MM:SS.mmm\n"
313 "Partial values are completed with defaults, e.g. \"2026\" becomes "
315 "Leave empty to use the current date at import time."));
319 GtkWidget *calendar = gtk_calendar_new();
320 GDateTime *now = g_date_time_new_now_local();
322 gtk_calendar_select_month(GTK_CALENDAR(calendar), g_date_time_get_month(now) - 1, g_date_time_get_year(now));
323 const guint today = g_date_time_get_day_of_month(now);
324 gtk_calendar_select_day(GTK_CALENDAR(calendar), today);
325 gtk_calendar_mark_day(GTK_CALENDAR(calendar), today);
326 g_date_time_unref(now);
327 GtkBox *box_datetime =
attach_popover(
d->datetime,
"appointment-new-symbolic", calendar);
329 gtk_widget_set_valign(GTK_WIDGET(box_datetime), GTK_ALIGN_START);
331 gtk_box_pack_start(GTK_BOX(datetime_box), GTK_WIDGET(box_datetime),
FALSE,
FALSE, 0);
334 gtk_box_pack_start(GTK_BOX(control_box), datetime_box,
FALSE,
FALSE, 0);
338 GtkWidget *jobcode_label = gtk_label_new(_(
"Jobcode"));
339 gtk_widget_set_halign(jobcode_label, GTK_ALIGN_START);
340 gtk_box_pack_start(GTK_BOX(jobcode_box), jobcode_label,
FALSE,
FALSE, 0);
342 d->jobcode = gtk_entry_new();
345 gtk_box_pack_start(GTK_BOX(jobcode_box),
d->jobcode,
TRUE,
TRUE, 0);
347 gtk_box_pack_start(GTK_BOX(control_box), jobcode_box,
TRUE,
TRUE, 0);
351 GtkWidget *interval_label = gtk_label_new(_(
"Scan frequency (seconds)"));
352 gtk_widget_set_halign(interval_label, GTK_ALIGN_START);
353 gtk_box_pack_start(GTK_BOX(interval_box), interval_label,
FALSE,
FALSE, 0);
355 d->interval = gtk_spin_button_new_with_range(2, 3600, 1);
356 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
d->interval),
358 gtk_widget_set_tooltip_text(
d->interval, _(
"Applied the next time the session is started"));
360 gtk_box_pack_start(GTK_BOX(interval_box),
d->interval,
TRUE,
TRUE, 0);
362 gtk_box_pack_start(GTK_BOX(control_box), interval_box,
TRUE,
TRUE, 0);
364 d->status = gtk_label_new(
"");
365 gtk_widget_set_halign(
d->status, GTK_ALIGN_START);
366 gtk_label_set_line_wrap(GTK_LABEL(
d->status),
TRUE);
367 gtk_label_set_ellipsize(GTK_LABEL(
d->status), PANGO_ELLIPSIZE_MIDDLE);
368 gtk_label_set_lines(GTK_LABEL(
d->status), 2);
369 PangoLayout *status_layout = gtk_widget_create_pango_layout(
d->status,
"Xg\nXg");
370 int status_width, status_height;
371 pango_layout_get_pixel_size(status_layout, &status_width, &status_height);
372 g_object_unref(status_layout);
373 gtk_widget_set_size_request(
d->status, -1, status_height);
375 d->status_icon = gtk_image_new_from_icon_name(
"emblem-ok-symbolic", GTK_ICON_SIZE_BUTTON);
376 gtk_widget_set_valign(
d->status_icon, GTK_ALIGN_CENTER);
377 gtk_widget_set_no_show_all(
d->status_icon,
TRUE);
380 gtk_box_pack_start(GTK_BOX(status_box),
d->status_icon,
FALSE,
FALSE, 0);
381 gtk_box_pack_start(GTK_BOX(status_box),
d->status,
TRUE,
TRUE, 0);
382 gtk_box_pack_start(GTK_BOX(control_box), status_box,
FALSE,
FALSE, 0);
399 d->toggle = gtk_toggle_button_new_with_label(_(
"Start the session"));
400 gtk_widget_set_tooltip_text(
d->toggle,
401 _(
"Monitor the source folder and import new images as they appear.\n"
402 "The first scan records the existing images as a baseline: only images "
403 "arriving afterwards are imported."));
405 gtk_notebook_set_action_widget(
notebook,
d->toggle, GTK_PACK_END);
406 gtk_widget_show(
d->toggle);
412 GtkWidget *source_folder_label = gtk_label_new(_(
"Source"));
413 gtk_widget_set_halign(source_folder_label, GTK_ALIGN_START);
414 gtk_box_pack_start(GTK_BOX(source_folder_box), source_folder_label,
FALSE,
FALSE, 0);
416 d->source_folder = gtk_file_chooser_button_new(_(
"Select a folder to survey"),
417 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
420 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(
d->source_folder),
folder);
421 gtk_widget_set_tooltip_text(
d->source_folder, _(
"Folder receiving the captured images to monitor"));
422 g_signal_connect(G_OBJECT(
d->source_folder),
"file-set",
424 gtk_box_pack_start(GTK_BOX(source_folder_box),
d->source_folder,
TRUE,
TRUE, 0);
426 gtk_box_pack_start(GTK_BOX(source_page), source_folder_box,
FALSE,
FALSE, 0);
428 d->delete_source = gtk_check_button_new_with_label(_(
"Delete original file"));
429 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
d->delete_source),
431 gtk_widget_set_tooltip_text(
d->delete_source,
432 _(
"Delete the original image file after verifying the complete copy."));
434 gtk_box_pack_start(GTK_BOX(source_page),
d->delete_source,
FALSE,
FALSE, 0);
439 GINT_TO_POINTER(0), NULL,
TRUE);
441 GINT_TO_POINTER(1), NULL,
TRUE);
444 gtk_box_pack_start(GTK_BOX(destination_page),
d->copy,
FALSE,
FALSE, 0);
448 gtk_widget_set_no_show_all(
d->copy_options,
TRUE);
449 gtk_box_pack_start(GTK_BOX(destination_page),
d->copy_options,
FALSE,
FALSE, 0);
455 GINT_TO_POINTER(0), NULL,
TRUE);
457 GINT_TO_POINTER(1), NULL,
TRUE);
459 GINT_TO_POINTER(2), NULL,
TRUE);
463 gtk_widget_set_tooltip_text(
d->on_conflict, _(
"Expected behaviour when the naming pattern produces a destination file "
464 "that already exists"));
467 gtk_box_pack_start(GTK_BOX(
d->copy_options),
d->on_conflict,
TRUE,
TRUE, 0);
471 GtkWidget *base_folder_label = gtk_label_new(_(
"Base directory"));
472 gtk_widget_set_halign(base_folder_label, GTK_ALIGN_START);
473 gtk_box_pack_start(GTK_BOX(base_folder_box), base_folder_label,
TRUE,
TRUE, 0);
475 d->base_folder = gtk_file_chooser_button_new(_(
"Select a base directory"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
478 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(
d->base_folder), base_folder);
480 gtk_box_pack_end(GTK_BOX(base_folder_box),
d->base_folder,
TRUE,
TRUE, 0);
482 gtk_box_pack_start(GTK_BOX(
d->copy_options), base_folder_box,
TRUE,
TRUE, 0);
484 d->subfolder_pattern = gtk_entry_new();
485 gtk_entry_set_text(GTK_ENTRY(
d->subfolder_pattern),
489 gtk_widget_set_tooltip_text(
d->subfolder_pattern,
490 _(
"Start typing `$(` to see available variables through auto-completion"));
491 g_signal_connect(G_OBJECT(
d->subfolder_pattern),
"changed",
495 d->file_pattern = gtk_entry_new();
498 gtk_widget_set_tooltip_text(
d->file_pattern,
499 _(
"Start typing `$(` to see available variables through auto-completion"));
500 g_signal_connect(G_OBJECT(
d->file_pattern),
"changed",
504 d->preview = gtk_label_new(
"");
505 gtk_widget_set_halign(
d->preview, GTK_ALIGN_START);
506 gtk_label_set_ellipsize(GTK_LABEL(
d->preview), PANGO_ELLIPSIZE_MIDDLE);
507 gtk_label_set_line_wrap(GTK_LABEL(
d->preview),
TRUE);
508 gtk_box_pack_start(GTK_BOX(destination_page),
d->preview,
FALSE,
FALSE, 0);