291 self->
data = (
void *)
d;
297 GtkWidget *control_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
301 GtkWidget *datetime_label = gtk_label_new(_(
"Project date"));
302 gtk_widget_set_halign(datetime_label, GTK_ALIGN_START);
303 gtk_box_pack_start(GTK_BOX(datetime_box), datetime_label,
FALSE,
FALSE, 0);
305 d->datetime = gtk_entry_new();
307 gtk_entry_set_placeholder_text(GTK_ENTRY(
d->datetime), _(
"Current date at import time"));
308 gtk_widget_set_tooltip_text(
d->datetime,
309 _(
"Format: YYYY-MM-DD, optionally followed by HH:MM:SS.mmm\n"
310 "Partial values are completed with defaults, e.g. \"2026\" becomes "
312 "Leave empty to use the current date at import time."));
316 GtkWidget *calendar = gtk_calendar_new();
317 GDateTime *now = g_date_time_new_now_local();
319 gtk_calendar_select_month(GTK_CALENDAR(calendar), g_date_time_get_month(now) - 1, g_date_time_get_year(now));
320 const guint today = g_date_time_get_day_of_month(now);
321 gtk_calendar_select_day(GTK_CALENDAR(calendar), today);
322 gtk_calendar_mark_day(GTK_CALENDAR(calendar), today);
323 g_date_time_unref(now);
324 GtkBox *box_datetime =
attach_popover(
d->datetime,
"appointment-new-symbolic", calendar);
326 gtk_widget_set_valign(GTK_WIDGET(box_datetime), GTK_ALIGN_START);
328 gtk_box_pack_start(GTK_BOX(datetime_box), GTK_WIDGET(box_datetime),
FALSE,
FALSE, 0);
331 gtk_box_pack_start(GTK_BOX(control_box), datetime_box,
FALSE,
FALSE, 0);
335 GtkWidget *jobcode_label = gtk_label_new(_(
"Jobcode"));
336 gtk_widget_set_halign(jobcode_label, GTK_ALIGN_START);
337 gtk_box_pack_start(GTK_BOX(jobcode_box), jobcode_label,
FALSE,
FALSE, 0);
339 d->jobcode = gtk_entry_new();
342 gtk_box_pack_start(GTK_BOX(jobcode_box),
d->jobcode,
TRUE,
TRUE, 0);
344 gtk_box_pack_start(GTK_BOX(control_box), jobcode_box,
TRUE,
TRUE, 0);
348 GtkWidget *interval_label = gtk_label_new(_(
"Scan frequency (seconds)"));
349 gtk_widget_set_halign(interval_label, GTK_ALIGN_START);
350 gtk_box_pack_start(GTK_BOX(interval_box), interval_label,
FALSE,
FALSE, 0);
352 d->interval = gtk_spin_button_new_with_range(2, 3600, 1);
353 gtk_spin_button_set_value(GTK_SPIN_BUTTON(
d->interval),
355 gtk_widget_set_tooltip_text(
d->interval, _(
"Applied the next time the session is started"));
357 gtk_box_pack_start(GTK_BOX(interval_box),
d->interval,
TRUE,
TRUE, 0);
359 gtk_box_pack_start(GTK_BOX(control_box), interval_box,
TRUE,
TRUE, 0);
361 d->status = gtk_label_new(
"");
362 gtk_widget_set_halign(
d->status, GTK_ALIGN_START);
363 gtk_label_set_line_wrap(GTK_LABEL(
d->status),
TRUE);
364 gtk_label_set_ellipsize(GTK_LABEL(
d->status), PANGO_ELLIPSIZE_MIDDLE);
365 gtk_label_set_lines(GTK_LABEL(
d->status), 2);
366 PangoLayout *status_layout = gtk_widget_create_pango_layout(
d->status,
"Xg\nXg");
367 int status_width, status_height;
368 pango_layout_get_pixel_size(status_layout, &status_width, &status_height);
369 g_object_unref(status_layout);
370 gtk_widget_set_size_request(
d->status, -1, status_height);
372 d->status_icon = gtk_image_new_from_icon_name(
"emblem-ok-symbolic", GTK_ICON_SIZE_BUTTON);
373 gtk_widget_set_valign(
d->status_icon, GTK_ALIGN_CENTER);
374 gtk_widget_set_no_show_all(
d->status_icon,
TRUE);
377 gtk_box_pack_start(GTK_BOX(status_box),
d->status_icon,
FALSE,
FALSE, 0);
378 gtk_box_pack_start(GTK_BOX(status_box),
d->status,
TRUE,
TRUE, 0);
379 gtk_box_pack_start(GTK_BOX(control_box), status_box,
FALSE,
FALSE, 0);
396 d->toggle = gtk_toggle_button_new_with_label(_(
"Start the session"));
397 gtk_widget_set_tooltip_text(
d->toggle,
398 _(
"Monitor the source folder and import new images as they appear.\n"
399 "The first scan records the existing images as a baseline: only images "
400 "arriving afterwards are imported."));
402 gtk_notebook_set_action_widget(
notebook,
d->toggle, GTK_PACK_END);
403 gtk_widget_show(
d->toggle);
409 GtkWidget *source_folder_label = gtk_label_new(_(
"Source"));
410 gtk_widget_set_halign(source_folder_label, GTK_ALIGN_START);
411 gtk_box_pack_start(GTK_BOX(source_folder_box), source_folder_label,
FALSE,
FALSE, 0);
413 d->source_folder = gtk_file_chooser_button_new(_(
"Select a folder to survey"),
414 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
417 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(
d->source_folder), folder);
418 gtk_widget_set_tooltip_text(
d->source_folder, _(
"Folder receiving the captured images to monitor"));
419 g_signal_connect(G_OBJECT(
d->source_folder),
"file-set",
421 gtk_box_pack_start(GTK_BOX(source_folder_box),
d->source_folder,
TRUE,
TRUE, 0);
423 gtk_box_pack_start(GTK_BOX(source_page), source_folder_box,
FALSE,
FALSE, 0);
425 d->delete_source = gtk_check_button_new_with_label(_(
"Delete original file"));
426 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
d->delete_source),
428 gtk_widget_set_tooltip_text(
d->delete_source,
429 _(
"Delete the original image file after verifying the complete copy."));
431 gtk_box_pack_start(GTK_BOX(source_page),
d->delete_source,
FALSE,
FALSE, 0);
436 GINT_TO_POINTER(0), NULL,
TRUE);
438 GINT_TO_POINTER(1), NULL,
TRUE);
441 gtk_box_pack_start(GTK_BOX(destination_page),
d->copy,
FALSE,
FALSE, 0);
445 gtk_widget_set_no_show_all(
d->copy_options,
TRUE);
446 gtk_box_pack_start(GTK_BOX(destination_page),
d->copy_options,
FALSE,
FALSE, 0);
452 GINT_TO_POINTER(0), NULL,
TRUE);
454 GINT_TO_POINTER(1), NULL,
TRUE);
456 GINT_TO_POINTER(2), NULL,
TRUE);
460 gtk_widget_set_tooltip_text(
d->on_conflict, _(
"Expected behaviour when the naming pattern produces a destination file "
461 "that already exists"));
464 gtk_box_pack_start(GTK_BOX(
d->copy_options),
d->on_conflict,
TRUE,
TRUE, 0);
468 GtkWidget *base_folder_label = gtk_label_new(_(
"Base directory"));
469 gtk_widget_set_halign(base_folder_label, GTK_ALIGN_START);
470 gtk_box_pack_start(GTK_BOX(base_folder_box), base_folder_label,
TRUE,
TRUE, 0);
472 d->base_folder = gtk_file_chooser_button_new(_(
"Select a base directory"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
475 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(
d->base_folder), base_folder);
477 gtk_box_pack_end(GTK_BOX(base_folder_box),
d->base_folder,
TRUE,
TRUE, 0);
479 gtk_box_pack_start(GTK_BOX(
d->copy_options), base_folder_box,
TRUE,
TRUE, 0);
481 d->subfolder_pattern = gtk_entry_new();
482 gtk_entry_set_text(GTK_ENTRY(
d->subfolder_pattern),
486 gtk_widget_set_tooltip_text(
d->subfolder_pattern,
487 _(
"Start typing `$(` to see available variables through auto-completion"));
488 g_signal_connect(G_OBJECT(
d->subfolder_pattern),
"changed",
492 d->file_pattern = gtk_entry_new();
495 gtk_widget_set_tooltip_text(
d->file_pattern,
496 _(
"Start typing `$(` to see available variables through auto-completion"));
497 g_signal_connect(G_OBJECT(
d->file_pattern),
"changed",
501 d->preview = gtk_label_new(
"");
502 gtk_widget_set_halign(
d->preview, GTK_ALIGN_START);
503 gtk_label_set_ellipsize(GTK_LABEL(
d->preview), PANGO_ELLIPSIZE_MIDDLE);
504 gtk_label_set_line_wrap(GTK_LABEL(
d->preview),
TRUE);
505 gtk_box_pack_start(GTK_BOX(destination_page),
d->preview,
FALSE,
FALSE, 0);