diff options
Diffstat (limited to 'plugins/shotwell-publishing/PiwigoPublishing.vala')
-rw-r--r-- | plugins/shotwell-publishing/PiwigoPublishing.vala | 440 |
1 files changed, 202 insertions, 238 deletions
diff --git a/plugins/shotwell-publishing/PiwigoPublishing.vala b/plugins/shotwell-publishing/PiwigoPublishing.vala index 0b98f05..ca07554 100644 --- a/plugins/shotwell-publishing/PiwigoPublishing.vala +++ b/plugins/shotwell-publishing/PiwigoPublishing.vala @@ -85,6 +85,10 @@ internal class Category { public bool is_local() { return this.id == NO_ID; } + + public static bool equal (Category self, Category other) { + return self.id == other.id; + } } internal class PermissionLevel { @@ -613,35 +617,29 @@ public class PiwigoPublisher : Spit.Publishing.Publisher, GLib.Object { string name = ""; string id_string = ""; string uppercats = ""; + var id_map = new Gee.HashMap<string, string> (); + for ( ; category_node_iter != null; category_node_iter = category_node_iter->next) { name_node = doc.get_named_child(category_node_iter, "name"); name = name_node->get_content(); uppercats_node = doc.get_named_child(category_node_iter, "uppercats"); uppercats = (string)uppercats_node->get_content(); id_string = category_node_iter->get_prop("id"); + id_map.set (id_string, name); + if (categories == null) { categories = new Category[0]; } categories += new Category(int.parse(id_string), name, uppercats); } + // compute the display name for the categories - // currently done by an unnecessary triple loop - // one could make a loop that goes over the categories - // and creates a list of back references cat_id -> index - // but since cat_ids are not guaranteed to be continuous - // that needs a perl hash ;-) for(int i = 0; i < categories.length; i++) { string[] upcatids = categories[i].uppercats.split(","); var builder = new StringBuilder(); for (int j=0; j < upcatids.length; j++) { builder.append ("/ "); - // search for the upper category - for (int k=0; k < categories.length; k++) { - if (upcatids[j] == categories[k].id.to_string()) { - builder.append (categories[k].name); - break; - } - } + builder.append (id_map.get (upcatids[j])); builder.append (" "); } categories[i].display_name = builder.str; @@ -1005,158 +1003,148 @@ internal class Uploader : Publishing.RESTSupport.BatchUploader { // UI elements -internal class SSLErrorPane : Spit.Publishing.DialogPane, Object { - private Gtk.Builder builder; - private Gtk.Widget content; +internal class SSLErrorPane : Shotwell.Plugins.Common.BuilderPane { public signal void proceed (); + public string host { owned get; construct; } + public TlsCertificate cert { private get; construct; } + public string error_text { owned get; construct; } public SSLErrorPane (SessionLoginTransaction transaction, string host) { - try { - TlsCertificate cert; - this.builder = new Gtk.Builder (); - this.builder.add_from_resource (Resources.RESOURCE_PATH + - "/piwigo_ssl_failure_pane.ui"); - this.content = this.builder.get_object ("content") as Gtk.Widget; - var label = this.builder.get_object ("main_text") as Gtk.Label; - // %s is the host name that we tried to connect to - label.set_text (_("This does not look like the real <b>%s</b>. Attackers might be trying to steal or alter information going to or from this site (for example, private messages, credit card information, or passwords).").printf (host)); - label.use_markup = true; - - label = this.builder.get_object ("ssl_errors") as Gtk.Label; - var text = transaction.detailed_error_from_tls_flags (out cert); - label.set_text (text); - - var info = this.builder.get_object ("default") as Gtk.Button; - info.clicked.connect (() => { - var simple_cert = new Gcr.SimpleCertificate (cert.certificate.data); - var widget = new Gcr.CertificateWidget (simple_cert); - - var dialog = new Gtk.Dialog (); - dialog.get_content_area ().add (widget); - dialog.add_button ("_OK", Gtk.ResponseType.OK); - dialog.set_default_response (Gtk.ResponseType.OK); - dialog.set_default_size (640, -1); - dialog.show_all (); - dialog.run (); - dialog.destroy (); - }); - - var proceed = this.builder.get_object ("proceed_button") as Gtk.Button; - proceed.clicked.connect (() => { this.proceed (); }); - - if (this.content.parent != null) { - this.content.parent.remove (this.content); + TlsCertificate cert; + var text = transaction.detailed_error_from_tls_flags (out cert); + Object (resource_path : Resources.RESOURCE_PATH + + "/piwigo_ssl_failure_pane.ui", + default_id: "default", + cert : cert, + error_text : text, + host : host); + } + + public override void constructed () { + base.constructed (); + + var label = this.get_builder ().get_object ("main_text") as Gtk.Label; + // %s is the host name that we tried to connect to + label.set_text (_("This does not look like the real <b>%s</b>. Attackers might be trying to steal or alter information going to or from this site (for example, private messages, credit card information, or passwords).").printf (host)); + label.use_markup = true; + + label = this.get_builder ().get_object ("ssl_errors") as Gtk.Label; + label.set_text (error_text); + + var info = this.get_builder ().get_object ("default") as Gtk.Button; + info.clicked.connect (() => { + var simple_cert = new Gcr.SimpleCertificate (cert.certificate.data); + var widget = new Gcr.CertificateWidget (simple_cert); + bool use_header = true; + Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header); + var flags = (Gtk.DialogFlags) 0; + if (use_header) { + flags |= Gtk.DialogFlags.USE_HEADER_BAR; } - } catch (Error error) { - warning ("Failed to create ui file: %s", error.message); - assert_not_reached (); - } - } - public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry () { - return Spit.Publishing.DialogPane.GeometryOptions.NONE; - } - - public Gtk.Widget get_widget () { - return this.content; - } + var dialog = new Gtk.Dialog.with_buttons ( + _("Certificate of %s").printf (host), + null, + flags, + _("_OK"), Gtk.ResponseType.OK); + dialog.get_content_area ().add (widget); + dialog.set_default_response (Gtk.ResponseType.OK); + dialog.set_default_size (640, -1); + dialog.show_all (); + dialog.run (); + dialog.destroy (); + }); - public Gtk.Widget get_default_widget () { - return this.builder.get_object ("default") as Gtk.Widget; + var proceed = this.get_builder ().get_object ("proceed_button") as Gtk.Button; + proceed.clicked.connect (() => { this.proceed (); }); } - - public void on_pane_installed () { } - - public void on_pane_uninstalled () { } } /** * The authentication pane used when asking service URL, user name and password * from the user. */ -internal class AuthenticationPane : Spit.Publishing.DialogPane, Object { +internal class AuthenticationPane : Shotwell.Plugins.Common.BuilderPane { public enum Mode { INTRO, FAILED_RETRY_URL, FAILED_RETRY_USER } + + public Mode mode { get; construct; } + public unowned PiwigoPublisher publisher { get; construct; } + private static string INTRO_MESSAGE = _("Enter the URL of your Piwigo photo library as well as the username and password associated with your Piwigo account for that library."); private static string FAILED_RETRY_URL_MESSAGE = _("Shotwell cannot contact your Piwigo photo library. Please verify the URL you entered"); private static string FAILED_RETRY_USER_MESSAGE = _("Username and/or password invalid. Please try again"); - private Gtk.Box pane_widget = null; - private Gtk.Builder builder; private Gtk.Entry url_entry; private Gtk.Entry username_entry; private Gtk.Entry password_entry; - private Gtk.CheckButton remember_password_checkbutton; + private Gtk.Switch remember_password_checkbutton; private Gtk.Button login_button; public signal void login(string url, string user, string password, bool remember_password); - public AuthenticationPane(PiwigoPublisher publisher, Mode mode = Mode.INTRO) { - this.pane_widget = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); + public AuthenticationPane (PiwigoPublisher publisher, Mode mode = Mode.INTRO) { + Object (resource_path : Resources.RESOURCE_PATH + + "/piwigo_authentication_pane.ui", + connect_signals : true, + default_id : "login_button", + mode : mode, + publisher : publisher); + } - try { - builder = new Gtk.Builder(); - builder.add_from_resource (Resources.RESOURCE_PATH + "/piwigo_authentication_pane.ui"); - builder.connect_signals(null); - Gtk.Alignment align = builder.get_object("alignment") as Gtk.Alignment; - - Gtk.Label message_label = builder.get_object("message_label") as Gtk.Label; - switch (mode) { - case Mode.INTRO: - message_label.set_text(INTRO_MESSAGE); - break; - - case Mode.FAILED_RETRY_URL: - message_label.set_markup("<b>%s</b>\n\n%s".printf(_( - "Invalid URL"), FAILED_RETRY_URL_MESSAGE)); - break; - - case Mode.FAILED_RETRY_USER: - message_label.set_markup("<b>%s</b>\n\n%s".printf(_( - "Invalid User Name or Password"), FAILED_RETRY_USER_MESSAGE)); - break; - } + public override void constructed () { + base.constructed (); - url_entry = builder.get_object ("url_entry") as Gtk.Entry; - string? persistent_url = publisher.get_persistent_url(); - if (persistent_url != null) { - url_entry.set_text(persistent_url); - } - username_entry = builder.get_object ("username_entry") as Gtk.Entry; - string? persistent_username = publisher.get_persistent_username(); - if (persistent_username != null) { - username_entry.set_text(persistent_username); - } - password_entry = builder.get_object ("password_entry") as Gtk.Entry; - string? persistent_password = publisher.get_persistent_password(); - if (persistent_password != null) { - password_entry.set_text(persistent_password); - } - remember_password_checkbutton = - builder.get_object ("remember_password_checkbutton") as Gtk.CheckButton; - remember_password_checkbutton.set_active(publisher.get_remember_password()); + var builder = this.get_builder (); + var message_label = builder.get_object("message_label") as Gtk.Label; + switch (mode) { + case Mode.INTRO: + message_label.set_text(INTRO_MESSAGE); + break; - login_button = builder.get_object("login_button") as Gtk.Button; + case Mode.FAILED_RETRY_URL: + message_label.set_markup("<b>%s</b>\n\n%s".printf(_( + "Invalid URL"), FAILED_RETRY_URL_MESSAGE)); + break; - username_entry.changed.connect(on_user_changed); - url_entry.changed.connect(on_url_changed); - password_entry.changed.connect(on_password_changed); - login_button.clicked.connect(on_login_button_clicked); + case Mode.FAILED_RETRY_USER: + message_label.set_markup("<b>%s</b>\n\n%s".printf(_( + "Invalid User Name or Password"), FAILED_RETRY_USER_MESSAGE)); + break; + } - align.reparent(pane_widget); - publisher.get_host().set_dialog_default_widget(login_button); - } catch (Error e) { - warning("Could not load UI: %s", e.message); + url_entry = builder.get_object ("url_entry") as Gtk.Entry; + string? persistent_url = publisher.get_persistent_url(); + if (persistent_url != null) { + url_entry.set_text(persistent_url); } - } - - public Gtk.Widget get_default_widget() { - return login_button; + username_entry = builder.get_object ("username_entry") as Gtk.Entry; + string? persistent_username = publisher.get_persistent_username(); + if (persistent_username != null) { + username_entry.set_text(persistent_username); + } + password_entry = builder.get_object ("password_entry") as Gtk.Entry; + string? persistent_password = publisher.get_persistent_password(); + if (persistent_password != null) { + password_entry.set_text(persistent_password); + } + remember_password_checkbutton = + builder.get_object ("remember_password_checkbutton") as Gtk.Switch; + remember_password_checkbutton.set_active(publisher.get_remember_password()); + + login_button = builder.get_object("login_button") as Gtk.Button; + + username_entry.changed.connect(on_user_changed); + url_entry.changed.connect(on_url_changed); + password_entry.changed.connect(on_password_changed); + login_button.clicked.connect(on_login_button_clicked); + + publisher.get_host().set_dialog_default_widget(login_button); } private void on_login_button_clicked() { @@ -1182,34 +1170,23 @@ internal class AuthenticationPane : Spit.Publishing.DialogPane, Object { password_entry.text_length != 0); } - public Gtk.Widget get_widget() { - return pane_widget; - } - - public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() { - return Spit.Publishing.DialogPane.GeometryOptions.NONE; - } - - public void on_pane_installed() { + public override void on_pane_installed() { + base.on_pane_installed (); + url_entry.grab_focus(); password_entry.set_activates_default(true); login_button.can_default = true; update_login_button_sensitivity(); } - - public void on_pane_uninstalled() { - } } /** * The publishing options pane. */ -internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object { +internal class PublishingOptionsPane : Shotwell.Plugins.Common.BuilderPane { private static string DEFAULT_CATEGORY_NAME = _("Shotwell Connect"); - private Gtk.Box pane_widget = null; - private Gtk.Builder builder; private Gtk.RadioButton use_existing_radio; private Gtk.RadioButton create_new_radio; private Gtk.ComboBoxText existing_categories_combo; @@ -1225,88 +1202,88 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object { private Gtk.Button publish_button; private Gtk.TextView album_comment; private Gtk.Label album_comment_label; - - private Category[] existing_categories; + private PermissionLevel[] perm_levels; private SizeEntry[] photo_sizes; - - private int last_category; - private int last_permission_level; - private int last_photo_size; - private bool last_title_as_comment; - private bool last_no_upload_tags; + + public int last_category { private get; construct; } + public int last_permission_level { private get; construct; } + public int last_photo_size { private get; construct; } + public bool last_title_as_comment { private get; construct; } + public bool last_no_upload_tags { private get; construct; } + public bool strip_metadata_enabled { private get; construct; } + public Gee.List<Category> existing_categories { private get; construct; } + public string default_comment { private get; construct; } public signal void publish(PublishingParameters parameters, bool strip_metadata); public signal void logout(); - public PublishingOptionsPane( - PiwigoPublisher publisher, Category[] categories, - int last_category, int last_permission_level, int last_photo_size, - bool last_title_as_comment, bool last_no_upload_tags, bool strip_metadata_enabled - ) { - this.pane_widget = new Gtk.Box(Gtk.Orientation.VERTICAL, 0); - this.last_category = last_category; - this.last_permission_level = last_permission_level; - this.last_photo_size = last_photo_size; - this.last_title_as_comment = last_title_as_comment; - this.last_no_upload_tags = last_no_upload_tags; + public PublishingOptionsPane(PiwigoPublisher publisher, + Category[] categories, + int last_category, + int last_permission_level, + int last_photo_size, + bool last_title_as_comment, + bool last_no_upload_tags, + bool strip_metadata_enabled) { + Object (resource_path : Resources.RESOURCE_PATH + + "/piwigo_publishing_options_pane.ui", + connect_signals : true, + default_id : "publish_button", + last_category : last_category, + last_permission_level : last_permission_level, + last_photo_size : last_photo_size, + last_title_as_comment : last_title_as_comment, + last_no_upload_tags : last_no_upload_tags, + strip_metadata_enabled : strip_metadata_enabled, + existing_categories : new Gee.ArrayList<Category>.wrap (categories, + Category.equal), + default_comment : get_common_comment_if_possible (publisher)); + } + + public override void constructed () { + base.constructed (); + var builder = this.get_builder (); + + use_existing_radio = builder.get_object("use_existing_radio") as Gtk.RadioButton; + create_new_radio = builder.get_object("create_new_radio") as Gtk.RadioButton; + existing_categories_combo = builder.get_object("existing_categories_combo") as Gtk.ComboBoxText; + new_category_entry = builder.get_object ("new_category_entry") as Gtk.Entry; + within_existing_label = builder.get_object ("within_existing_label") as Gtk.Label; + within_existing_combo = builder.get_object ("within_existing_combo") as Gtk.ComboBoxText; + + album_comment = builder.get_object ("album_comment") as Gtk.TextView; + album_comment.buffer = new Gtk.TextBuffer(null); + album_comment_label = builder.get_object ("album_comment_label") as Gtk.Label; + + perms_combo = builder.get_object("perms_combo") as Gtk.ComboBoxText; + size_combo = builder.get_object("size_combo") as Gtk.ComboBoxText; + + strip_metadata_check = builder.get_object("strip_metadata_check") as Gtk.CheckButton; + strip_metadata_check.set_active(strip_metadata_enabled); + + title_as_comment_check = builder.get_object("title_as_comment_check") as Gtk.CheckButton; + title_as_comment_check.set_active(last_title_as_comment); + + no_upload_tags_check = builder.get_object("no_upload_tags_check") as Gtk.CheckButton; + no_upload_tags_check.set_active(last_no_upload_tags); + + logout_button = builder.get_object("logout_button") as Gtk.Button; + logout_button.clicked.connect(on_logout_button_clicked); + + publish_button = builder.get_object("publish_button") as Gtk.Button; + publish_button.clicked.connect(on_publish_button_clicked); + + use_existing_radio.clicked.connect(on_use_existing_radio_clicked); + create_new_radio.clicked.connect(on_create_new_radio_clicked); + new_category_entry.changed.connect(on_new_category_entry_changed); + within_existing_combo.changed.connect(on_existing_combo_changed); - try { - builder = new Gtk.Builder(); - builder.add_from_resource (Resources.RESOURCE_PATH + "/piwigo_publishing_options_pane.ui"); - builder.connect_signals(null); - Gtk.Alignment align = builder.get_object("alignment") as Gtk.Alignment; - - use_existing_radio = builder.get_object("use_existing_radio") as Gtk.RadioButton; - create_new_radio = builder.get_object("create_new_radio") as Gtk.RadioButton; - existing_categories_combo = builder.get_object("existing_categories_combo") as Gtk.ComboBoxText; - new_category_entry = builder.get_object ("new_category_entry") as Gtk.Entry; - within_existing_label = builder.get_object ("within_existing_label") as Gtk.Label; - within_existing_combo = builder.get_object ("within_existing_combo") as Gtk.ComboBoxText; - - album_comment = builder.get_object ("album_comment") as Gtk.TextView; - album_comment.buffer = new Gtk.TextBuffer(null); - album_comment_label = builder.get_object ("album_comment_label") as Gtk.Label; - - perms_combo = builder.get_object("perms_combo") as Gtk.ComboBoxText; - size_combo = builder.get_object("size_combo") as Gtk.ComboBoxText; - - strip_metadata_check = builder.get_object("strip_metadata_check") as Gtk.CheckButton; - strip_metadata_check.set_active(strip_metadata_enabled); - - title_as_comment_check = builder.get_object("title_as_comment_check") as Gtk.CheckButton; - title_as_comment_check.set_active(last_title_as_comment); - - no_upload_tags_check = builder.get_object("no_upload_tags_check") as Gtk.CheckButton; - no_upload_tags_check.set_active(last_no_upload_tags); - - logout_button = builder.get_object("logout_button") as Gtk.Button; - logout_button.clicked.connect(on_logout_button_clicked); - - publish_button = builder.get_object("publish_button") as Gtk.Button; - publish_button.clicked.connect(on_publish_button_clicked); - - use_existing_radio.clicked.connect(on_use_existing_radio_clicked); - create_new_radio.clicked.connect(on_create_new_radio_clicked); - new_category_entry.changed.connect(on_new_category_entry_changed); - within_existing_combo.changed.connect(on_existing_combo_changed); - - align.reparent(pane_widget); - pane_widget.set_child_packing(align, true, true, 0, Gtk.PackType.START); - } catch (Error e) { - warning("Could not load UI: %s", e.message); - } - - this.existing_categories = categories; this.perm_levels = create_perm_levels(); this.photo_sizes = create_sizes(); - this.album_comment.buffer.set_text(get_common_comment_if_possible(publisher)); - } - - public Gtk.Widget get_default_widget() { - return publish_button; + this.album_comment.buffer.set_text(this.default_comment); } - + private PermissionLevel[] create_perm_levels() { PermissionLevel[] result = new PermissionLevel[0]; @@ -1410,16 +1387,10 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object { ) ); } - - public Gtk.Widget get_widget() { - return pane_widget; - } - - public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() { - return Spit.Publishing.DialogPane.GeometryOptions.NONE; - } - - public void on_pane_installed() { + + public override void on_pane_installed() { + base.on_pane_installed (); + create_categories_combo(); create_within_categories_combo(); create_permissions_combo(); @@ -1428,8 +1399,8 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object { publish_button.can_default = true; update_publish_button_sensitivity(); } - - private string get_common_comment_if_possible(PiwigoPublisher publisher) { + + private static string get_common_comment_if_possible(PiwigoPublisher publisher) { // we have to determine whether all the publishing items // belong to the same event Spit.Publishing.Publishable[] publishables = publisher.get_host().get_publishables(); @@ -1462,7 +1433,7 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object { foreach (Category cat in existing_categories) { existing_categories_combo.append_text(cat.display_name); } - if (existing_categories.length == 0) { + if (existing_categories.is_empty) { // if no existing categories, disable the option to choose one existing_categories_combo.set_sensitive(false); use_existing_radio.set_sensitive(false); @@ -1472,11 +1443,7 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object { new_category_entry.grab_focus(); } else { int last_category_index = find_category_index(last_category); - if (last_category_index < 0) { - existing_categories_combo.set_active(0); - } else { - existing_categories_combo.set_active(last_category_index); - } + existing_categories_combo.set_active(last_category_index); new_category_entry.set_sensitive(false); album_comment.set_sensitive(false); album_comment_label.set_sensitive(false); @@ -1520,13 +1487,10 @@ internal class PublishingOptionsPane : Spit.Publishing.DialogPane, Object { size_combo.set_active(last_size_index); } } - - public void on_pane_uninstalled() { - } - + private int find_category_index(int category_id) { - int result = -1; - for(int i = 0; i < existing_categories.length; i++) { + int result = 0; + for(int i = 0; i < existing_categories.size; i++) { if (existing_categories[i].id == category_id) { result = i; break; |