1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
|
/* Copyright 2016 Software Freedom Conservancy Inc.
* Copyright 2017 Jens Georg <mail@jensge.org>
*
* This software is licensed under the GNU LGPL (version 2.1 or later).
* See the COPYING file in this distribution.
*/
public interface WelcomeServiceEntry : GLib.Object {
public abstract string get_service_name();
public abstract void execute();
}
public class WelcomeDialog : Gtk.Dialog {
Gtk.CheckButton hide_button;
Gtk.CheckButton? system_pictures_import_check = null;
Gtk.CheckButton[] external_import_checks = new Gtk.CheckButton[0];
WelcomeServiceEntry[] external_import_entries = new WelcomeServiceEntry[0];
Gtk.Label secondary_text;
Gtk.Label instruction_header;
Gtk.Box import_content;
Gtk.Box import_action_checkbox_packer;
Gtk.Box external_import_action_checkbox_packer;
Spit.DataImports.WelcomeImportMetaHost import_meta_host;
bool import_content_already_installed = false;
bool ok_clicked = false;
public WelcomeDialog(Gtk.Window owner) {
Object(use_header_bar : Resources.use_header_bar());
import_meta_host = new Spit.DataImports.WelcomeImportMetaHost(this);
bool show_system_pictures_import = is_system_pictures_import_possible();
Gtk.Widget ok_button = add_button(Resources.OK_LABEL, Gtk.ResponseType.CLOSE);
set_default_response(Gtk.ResponseType.CLOSE);
set_title(_("Welcome!"));
set_resizable(false);
set_type_hint(Gdk.WindowTypeHint.DIALOG);
set_transient_for(owner);
Gtk.Label primary_text = new Gtk.Label("");
primary_text.set_markup(
"<span size=\"large\" weight=\"bold\">%s</span>".printf(_("Welcome to Shotwell!")));
primary_text.xalign = 0.0f;
primary_text.yalign = 0.5f;
secondary_text = new Gtk.Label("");
secondary_text.set_markup("<span weight=\"normal\">%s</span>".printf(
_("To get started, import photos in any of these ways:")));
secondary_text.xalign = 0.0f;
secondary_text.yalign = 0.5f;
var image = new Gtk.Image.from_icon_name ("shotwell", Gtk.IconSize.DIALOG);
Gtk.Box header_text = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
header_text.pack_start(primary_text, false, false, 5);
header_text.pack_start(secondary_text, false, false, 0);
Gtk.Box header_content = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 12);
header_content.pack_start(image, false, false, 0);
header_content.pack_start(header_text, false, false, 0);
Gtk.Label instructions = new Gtk.Label("");
string indent_prefix = " "; // we can't tell what the indent prefix is going to be so assume we need one
instructions.set_markup(((indent_prefix + "• %s\n") + (indent_prefix + "• %s\n")
+ (indent_prefix + "• %s")).printf(
_("Choose “Import From Folder” from the File menu"),
_("Drag and drop photos onto the Shotwell window"),
_("Connect a camera to your computer and import")));
instructions.xalign = 0.0f;
instructions.yalign = 0.5f;
import_action_checkbox_packer = new Gtk.Box(Gtk.Orientation.VERTICAL, 2);
external_import_action_checkbox_packer = new Gtk.Box(Gtk.Orientation.VERTICAL, 2);
import_action_checkbox_packer.add(external_import_action_checkbox_packer);
if (show_system_pictures_import) {
system_pictures_import_check = new Gtk.CheckButton.with_mnemonic(
_("_Import photos from your %s folder").printf(
get_display_pathname(AppDirs.get_import_dir())));
import_action_checkbox_packer.add(system_pictures_import_check);
system_pictures_import_check.set_active(true);
}
instruction_header = new Gtk.Label(
_("You can also import photos in any of these ways:"));
instruction_header.xalign = 0.0f;
instruction_header.yalign = 0.5f;
instruction_header.set_margin_top(20);
Gtk.Box content = new Gtk.Box(Gtk.Orientation.VERTICAL, 16);
content.pack_start(header_content, true, true, 0);
import_content = new Gtk.Box(Gtk.Orientation.VERTICAL, 2);
content.add(import_content);
content.pack_start(instructions, false, false, 0);
hide_button = new Gtk.CheckButton.with_mnemonic(_("_Don’t show this message again"));
hide_button.set_active(true);
content.pack_start(hide_button, false, false, 6);
content.halign = Gtk.Align.FILL;
content.valign = Gtk.Align.FILL;
content.hexpand = false;
content.vexpand = false;
content.margin_top = 12;
content.margin_bottom = 0;
content.margin_start = 12;
content.margin_end = 12;
((Gtk.Box) get_content_area()).pack_start(content, false, false, 0);
ok_button.grab_focus();
install_import_content();
import_meta_host.start();
}
private void install_import_content() {
if (
(external_import_checks.length > 0 || system_pictures_import_check != null) &&
(import_content_already_installed == false)
) {
secondary_text.set_markup("");
import_content.add(import_action_checkbox_packer);
import_content.add(instruction_header);
import_content_already_installed = true;
}
}
public void install_service_entry(WelcomeServiceEntry entry) {
debug("WelcomeDialog: Installing service entry for %s".printf(entry.get_service_name()));
external_import_entries += entry;
Gtk.CheckButton entry_check = new Gtk.CheckButton.with_label(
_("Import photos from your %s library").printf(entry.get_service_name()));
external_import_checks += entry_check;
entry_check.set_active(true);
external_import_action_checkbox_packer.add(entry_check);
install_import_content();
}
/**
* Connected to the 'response' signal. This is part of a workaround
* for the fact that run()-ning this dialog can interfere with displaying
* images from a camera; please see #4997 for details.
*/
private void on_dismiss(int resp) {
if (resp == Gtk.ResponseType.CLOSE) {
ok_clicked = true;
}
hide();
Gtk.main_quit();
}
public bool execute(out WelcomeServiceEntry[] selected_import_entries, out bool do_system_pictures_import) {
// it's unsafe to call run() here - it interferes with displaying
// images from a camera - so we process the dialog ourselves.
response.connect(on_dismiss);
show_all();
show();
// this will block the thread we're in until a matching call
// to main_quit() is encountered; this happens when either the window
// is closed or OK is clicked.
Gtk.main();
// at this point, the inner main loop will have been exited.
// we've got the response, so we don't need this signal anymore.
response.disconnect(on_dismiss);
bool ok = ok_clicked;
bool show_dialog = true;
if (ok)
show_dialog = !hide_button.get_active();
// Use a temporary variable as += cannot be used on parameters
WelcomeServiceEntry[] result = new WelcomeServiceEntry[0];
for (int i = 0; i < external_import_entries.length; i++) {
if (external_import_checks[i].get_active() == true)
result += external_import_entries[i];
}
selected_import_entries = result;
do_system_pictures_import =
(system_pictures_import_check != null) ? system_pictures_import_check.get_active() : false;
destroy();
return show_dialog;
}
private static bool is_system_pictures_import_possible() {
File system_pictures = AppDirs.get_import_dir();
if (!system_pictures.query_exists(null))
return false;
if (!(system_pictures.query_file_type(FileQueryInfoFlags.NONE, null) == FileType.DIRECTORY))
return false;
try {
FileEnumerator syspics_child_enum = system_pictures.enumerate_children("standard::*",
FileQueryInfoFlags.NONE, null);
return (syspics_child_enum.next_file(null) != null);
} catch (Error e) {
return false;
}
}
}
|