diff options
Diffstat (limited to 'src/publishing')
| -rw-r--r-- | src/publishing/APIGlue.vala | 6 | ||||
| -rw-r--r-- | src/publishing/LoginWelcomePaneWidget.vala | 45 | ||||
| -rw-r--r-- | src/publishing/ProgressPaneWidget.vala | 44 | ||||
| -rw-r--r-- | src/publishing/Publishing.vala | 7 | ||||
| -rw-r--r-- | src/publishing/PublishingPluginHost.vala | 8 | ||||
| -rw-r--r-- | src/publishing/PublishingUI.vala | 202 | ||||
| -rw-r--r-- | src/publishing/StaticMessagePaneWidget.vala | 62 | ||||
| -rw-r--r-- | src/publishing/SuccessPaneWidget.vala | 39 | ||||
| -rw-r--r-- | src/publishing/meson.build | 27 | 
9 files changed, 269 insertions, 171 deletions
| diff --git a/src/publishing/APIGlue.vala b/src/publishing/APIGlue.vala index 23c4e8c..56013a2 100644 --- a/src/publishing/APIGlue.vala +++ b/src/publishing/APIGlue.vala @@ -126,7 +126,11 @@ public class MediaSourcePublishableWrapper : Spit.Publishing.Publishable, GLib.O      }      public GLib.DateTime get_exposure_date_time() { -        return new GLib.DateTime.from_unix_local(wrapped.get_exposure_time()); +        return wrapped.get_exposure_time().to_local(); +    } + +    public uint get_rating() { +        return wrapped.get_rating();      }  } diff --git a/src/publishing/LoginWelcomePaneWidget.vala b/src/publishing/LoginWelcomePaneWidget.vala new file mode 100644 index 0000000..3e9847b --- /dev/null +++ b/src/publishing/LoginWelcomePaneWidget.vala @@ -0,0 +1,45 @@ +/* Copyright 2016 Software Freedom Conservancy Inc. + * Copyright 2019 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. + */ + +namespace PublishingUI { + +[GtkTemplate (ui = "/org/gnome/Shotwell/ui/login_welcome_pane_widget.ui")] +public class LoginWelcomePane : Spit.Publishing.DialogPane, Gtk.Box { +    [GtkChild] +    private unowned Gtk.Button login_button; +    [GtkChild] +    private unowned Gtk.Label not_logged_in_label; + +    public Gtk.Widget get_widget() { +        return this; +    } + +    public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() { +        return Spit.Publishing.DialogPane.GeometryOptions.NONE; +    } + +    public void on_pane_installed() { +    } + +    public void on_pane_uninstalled() { +    } + +    public signal void login_requested(); + +    public LoginWelcomePane(string service_welcome_message) { +        Object(); + +        login_button.clicked.connect(on_login_clicked); +        not_logged_in_label.set_use_markup(true); +        not_logged_in_label.set_markup(service_welcome_message); +    } + +    private void on_login_clicked() { +        login_requested(); +    } +} +} // namespace PublishingUI diff --git a/src/publishing/ProgressPaneWidget.vala b/src/publishing/ProgressPaneWidget.vala new file mode 100644 index 0000000..0c89d77 --- /dev/null +++ b/src/publishing/ProgressPaneWidget.vala @@ -0,0 +1,44 @@ +/* Copyright 2016 Software Freedom Conservancy Inc. + * Copyright 2019 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. + */ + +namespace PublishingUI { + +[GtkTemplate (ui = "/org/gnome/Shotwell/ui/progress_pane_widget.ui")] +public class ProgressPane : Spit.Publishing.DialogPane, Gtk.Box { +    [GtkChild] +    private unowned Gtk.ProgressBar progress_bar; + +    public Gtk.Widget get_widget() { +        return this; +    } + +    public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() { +        return Spit.Publishing.DialogPane.GeometryOptions.NONE; +    } + +    public void on_pane_installed() { +    } + +    public void on_pane_uninstalled() { +    } + +    public void set_text(string text) { +        progress_bar.set_text(text); +    } + +    public void set_progress(double progress) { +        progress_bar.set_fraction(progress); +    } + +    public void set_status(string status_text, double progress) { +        if (status_text != progress_bar.get_text()) +            progress_bar.set_text(status_text); + +        set_progress(progress); +    } +} +} // namespace PublishingUI diff --git a/src/publishing/Publishing.vala b/src/publishing/Publishing.vala index 455013c..c41e121 100644 --- a/src/publishing/Publishing.vala +++ b/src/publishing/Publishing.vala @@ -8,10 +8,9 @@ namespace Publishing {  public void init() throws Error {      string[] core_ids = new string[0]; -    core_ids += "org.yorba.shotwell.publishing.facebook"; -    core_ids += "org.yorba.shotwell.publishing.flickr"; -    core_ids += "org.yorba.shotwell.publishing.youtube"; -    core_ids += "org.yorba.shotwell.publishing.gnome-photos"; +    core_ids += "org.gnome.shotwell.publishing.flickr"; +    core_ids += "org.gnome.shotwell.publishing.youtube"; +    core_ids += "org.gnome.shotwell.publishing.gnome-photos";      Plugins.register_extension_point(typeof(Spit.Publishing.Service), _("Publishing"),          Resources.PUBLISH, core_ids); diff --git a/src/publishing/PublishingPluginHost.vala b/src/publishing/PublishingPluginHost.vala index ca935ab..7804924 100644 --- a/src/publishing/PublishingPluginHost.vala +++ b/src/publishing/PublishingPluginHost.vala @@ -22,7 +22,7 @@ public class ConcretePublishingHost : Plugins.StandardHostInterface,          Spit.Publishing.Publisher.MediaType.NONE;      public ConcretePublishingHost(Service service, PublishingUI.PublishingDialog dialog, -        Publishable[] publishables) { +        Publishable[] publishables, Account account) {          base(service, "sharing");          this.dialog = dialog;          this.publishables = publishables; @@ -30,7 +30,11 @@ public class ConcretePublishingHost : Plugins.StandardHostInterface,          foreach (Publishable curr_publishable in publishables)              this.media_type |= curr_publishable.get_media_type(); -        this.active_publisher = service.create_publisher(this); +        this.active_publisher = service.create_publisher_with_account(this, account); +    } + +    public string get_current_profile_id() { +        return Shotwell.ProfileManager.get_instance().id();      }      private void on_login_clicked() { diff --git a/src/publishing/PublishingUI.vala b/src/publishing/PublishingUI.vala index d3d4a69..de642a4 100644 --- a/src/publishing/PublishingUI.vala +++ b/src/publishing/PublishingUI.vala @@ -6,134 +6,6 @@  namespace PublishingUI { -public class ConcreteDialogPane : Spit.Publishing.DialogPane, GLib.Object { -    protected Gtk.Box pane_widget = null; -    protected Gtk.Builder builder = null; - -    public ConcreteDialogPane() { -        builder = AppWindow.create_builder(); -    } - -    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 void on_pane_uninstalled() { -    } -} - -public class StaticMessagePane : ConcreteDialogPane { -    private Gtk.Label msg_label = null; - -    public StaticMessagePane(string message_string, bool enable_markup = false) { -        base(); -        msg_label = builder.get_object("static_msg_label") as Gtk.Label; -        pane_widget = builder.get_object("static_msg_pane_widget") as Gtk.Box; - -        if (enable_markup) { -            msg_label.set_markup(message_string); -            msg_label.set_line_wrap(true); -            msg_label.set_use_markup(true); -        } else { -            msg_label.set_label(message_string); -        } -    } -} - -public class LoginWelcomePane : ConcreteDialogPane { -    private Gtk.Button login_button = null; -    private Gtk.Label not_logged_in_label = null; - -    public signal void login_requested(); - -    public LoginWelcomePane(string service_welcome_message) { -        base(); -        pane_widget = builder.get_object("welcome_pane_widget") as Gtk.Box; -        login_button = builder.get_object("login_button") as Gtk.Button; -        not_logged_in_label = builder.get_object("not_logged_in_label") as Gtk.Label; - -        login_button.clicked.connect(on_login_clicked); -        not_logged_in_label.set_use_markup(true); -        not_logged_in_label.set_markup(service_welcome_message); -    } - -    private void on_login_clicked() { -        login_requested(); -    } -} - -public class ProgressPane : ConcreteDialogPane { -    private Gtk.ProgressBar progress_bar = null; - -    public ProgressPane() { -        base(); -        pane_widget = (Gtk.Box) builder.get_object("progress_pane_widget"); -        progress_bar = (Gtk.ProgressBar) builder.get_object("publishing_progress_bar"); -    } - -    public void set_text(string text) { -        progress_bar.set_text(text); -    } - -    public void set_progress(double progress) { -        progress_bar.set_fraction(progress); -    } - -    public void set_status(string status_text, double progress) { -        if (status_text != progress_bar.get_text()) -            progress_bar.set_text(status_text); - -        set_progress(progress); -    } -} - -public class SuccessPane : StaticMessagePane { -    public SuccessPane(Spit.Publishing.Publisher.MediaType published_media, int num_uploaded = 1) { -        string? message_string = null; - -        // Here, we check whether more than one item is being uploaded, and if so, display -        // an alternate message. -        if (published_media == Spit.Publishing.Publisher.MediaType.VIDEO) { -            message_string = ngettext ("The selected video was successfully published.", -                                       "The selected videos were successfully published.", -                                       num_uploaded); -        } -        else if (published_media == Spit.Publishing.Publisher.MediaType.PHOTO) { -            message_string = ngettext ("The selected photo was successfully published.", -                                       "The selected photos were successfully published.", -                                       num_uploaded); -        } -        else if (published_media == (Spit.Publishing.Publisher.MediaType.PHOTO -                                     | Spit.Publishing.Publisher.MediaType.VIDEO)) { -            message_string = _("The selected photos/videos were successfully published."); -        } -        else { -            assert_not_reached (); -        } - -        base(message_string); -    } -} - -public class AccountFetchWaitPane : StaticMessagePane { -    public AccountFetchWaitPane() { -        base(_("Fetching account information…")); -    } -} - -public class LoginWaitPane : StaticMessagePane { -    public LoginWaitPane() { -        base(_("Logging in…")); -    } -} -  public class PublishingDialog : Gtk.Dialog {      private const int LARGE_WINDOW_WIDTH = 860;      private const int LARGE_WINDOW_HEIGHT = 688; @@ -205,12 +77,13 @@ public class PublishingDialog : Gtk.Dialog {          }          set_title(title); -        service_selector_box_model = new Gtk.ListStore(2, typeof(Gdk.Pixbuf), typeof(string)); +        service_selector_box_model = new Gtk.ListStore(3, typeof(string), typeof(string), +            typeof(Spit.Publishing.Account));          service_selector_box = new Gtk.ComboBox.with_model(service_selector_box_model);          Gtk.CellRendererPixbuf renderer_pix = new Gtk.CellRendererPixbuf();          service_selector_box.pack_start(renderer_pix,true); -        service_selector_box.add_attribute(renderer_pix, "pixbuf", 0); +        service_selector_box.add_attribute(renderer_pix, "icon-name", 0);          Gtk.CellRendererText renderer_text = new Gtk.CellRendererText();          service_selector_box.pack_start(renderer_text,true); @@ -226,30 +99,26 @@ public class PublishingDialog : Gtk.Dialog {          Gtk.TreeIter iter;          foreach (Spit.Publishing.Service service in loaded_services) { -            service_selector_box_model.append(out iter); -              string curr_service_id = service.get_id(); -            service.get_info(ref info); +            info = service.get_info(); -            if (null != info.icons && 0 < info.icons.length) { -                // check if the icons object is set -- if set use that icon -                service_selector_box_model.set(iter, 0, info.icons[0], 1, -                    service.get_pluggable_name()); -                 -                // in case the icons object is not set on the next iteration -                info.icons[0] = Resources.get_icon(Resources.ICON_GENERIC_PLUGIN); -            } else { -                // if icons object is null or zero length use a generic icon -                service_selector_box_model.set(iter, 0, Resources.get_icon( -                    Resources.ICON_GENERIC_PLUGIN), 1, service.get_pluggable_name()); -            } -             -            if (last_used_service == null) { -                service_selector_box.set_active_iter(iter); -                last_used_service = service.get_id(); -            } else if (last_used_service == curr_service_id) { -                service_selector_box.set_active_iter(iter); +            var accounts = service.get_accounts(Shotwell.ProfileManager.get_instance().id()); + +            foreach (var account in accounts) { +                service_selector_box_model.append(out iter); + +                var account_name = account.display_name(); +                var display_name = service.get_pluggable_name() + (account_name == "" ? "" : "/" + account_name); + +                service_selector_box_model.set(iter, 0, info.icon_name, 1, display_name, 2, account); + +                if (last_used_service == null) { +                    service_selector_box.set_active_iter(iter); +                    last_used_service = service.get_id(); +                } else if (last_used_service == curr_service_id) { +                    service_selector_box.set_active_iter(iter); +                }              }          } @@ -373,15 +242,17 @@ public class PublishingDialog : Gtk.Dialog {          return filtered_services;      } -    // Because of this bug: http://trac.yorba.org/ticket/3623, we use some extreme measures. The -    // bug occurs because, in some cases, when publishing is started asynchronous network  -    // transactions are performed. The mechanism inside libsoup that we use to perform asynchronous -    // network transactions isn't based on threads but is instead based on the GLib event loop. So -    // whenever we run a network transaction, the GLib event loop gets spun. One consequence of -    // this is that PublishingDialog.go( ) can be called multiple times. Note that since events -    // are processed sequentially, PublishingDialog.go( ) is never called re-entrantly. It just -    // gets called twice back-to-back in quick succession. So use a timer to do a short circuit -    // return if this call to go( ) follows immediately on the heels of another call to go( ). +    // Because of this bug: https://bugzilla.gnome.org/show_bug.cgi?id=717505, we use some +    // extreme measures. The bug occurs because, in some cases, when publishing is started +    // asynchronous network transactions are performed. The mechanism inside libsoup that we +    // use to perform asynchronous network transactions isn't based on threads but is instead +    // based on the GLib event loop. So whenever we run a network transaction, the GLib event +    // loop gets spun. One consequence of this is that PublishingDialog.go( ) can be called +    // multiple times. Note that since events are processed sequentially, PublishingDialog.go() +    // is never called re-entrantly. It just gets called twice back-to-back in quick +    // succession. So use a timer to do a short circuit return if this call to go( ) follows +    // immediately on the heels of another call to go( ) +    // FIXME: Port publising to async libsoup, then there is no nested main loop anymore.      private static Timer since_last_start = null;      private static bool elapsed_is_valid = false;      public static void go(Gee.Collection<MediaSource> to_publish) { @@ -412,7 +283,7 @@ public class PublishingDialog : Gtk.Dialog {              // There are no enabled publishing services that accept this media type,              // warn the user.              AppWindow.error_message_with_title(_("Unable to publish"), -                _("Shotwell cannot publish the selected items because you do not have a compatible publishing plugin enabled. To correct this, choose <b>Edit %s Preferences</b> and enable one or more of the publishing plugins on the <b>Plugins</b> tab.").printf("▸"), +                _("Shotwell cannot publish the selected items because you do not have a compatible publishing plugin enabled. To correct this, choose Edit %s Preferences and enable one or more of the publishing plugins on the <b>Plugins</b> tab.").printf("▸"),                  null, false);              return; @@ -458,14 +329,17 @@ public class PublishingDialog : Gtk.Dialog {          }          Value service_name_val; +        Value account_val;          service_selector_box_model.get_value(iter, 1, out service_name_val); +        service_selector_box_model.get_value(iter, 2, out account_val);          string service_name = (string) service_name_val; -         +        var service_account = (Spit.Publishing.Account) account_val; +                 Spit.Publishing.Service? selected_service = null;          Spit.Publishing.Service[] services = load_all_services();          foreach (Spit.Publishing.Service service in services) { -            if (service.get_pluggable_name() == service_name) { +             if (service_name.has_prefix(service.get_pluggable_name())) {                  selected_service = service;                  break;              } @@ -474,7 +348,7 @@ public class PublishingDialog : Gtk.Dialog {          Config.Facade.get_instance().set_last_used_service(selected_service.get_id()); -        host = new Spit.Publishing.ConcretePublishingHost(selected_service, this, publishables); +        host = new Spit.Publishing.ConcretePublishingHost(selected_service, this, publishables, service_account);          host.start_publishing();      } diff --git a/src/publishing/StaticMessagePaneWidget.vala b/src/publishing/StaticMessagePaneWidget.vala new file mode 100644 index 0000000..5f8de66 --- /dev/null +++ b/src/publishing/StaticMessagePaneWidget.vala @@ -0,0 +1,62 @@ +/* Copyright 2016 Software Freedom Conservancy Inc. + * Copyright 2019 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. + */ + +namespace PublishingUI { + +[GtkTemplate (ui = "/org/gnome/Shotwell/ui/static_message_pane_widget.ui")] +public class StaticMessagePane : Spit.Publishing.DialogPane, Gtk.Box { +    public bool show_spinner{get; construct; default=false; } + +    [GtkChild] +    private unowned Gtk.Label static_msg_label; + +    [GtkChild] +    private unowned Gtk.Spinner spinner; + +    public Gtk.Widget get_widget() { +        return this; +    } + +    public Spit.Publishing.DialogPane.GeometryOptions get_preferred_geometry() { +        return Spit.Publishing.DialogPane.GeometryOptions.NONE; +    } + +    public void on_pane_installed() { +    } + +    public void on_pane_uninstalled() { +    } + +    public StaticMessagePane(string message_string, bool enable_markup = false, bool show_spinner = false) { +        Object(show_spinner: false); + +        spinner.active = show_spinner; + +        if (enable_markup) { +            static_msg_label.set_markup(message_string); +            static_msg_label.set_line_wrap(true); +            static_msg_label.set_use_markup(true); +        } else { +            static_msg_label.set_label(message_string); +        } +    } +} + +public class AccountFetchWaitPane : StaticMessagePane { +    public AccountFetchWaitPane() { +        base(_("Fetching account information…"), false, true); +    } +} + +public class LoginWaitPane : StaticMessagePane { +    public LoginWaitPane() { +        base(_("Logging in…"), false, true); +    } +} + + +} // namespace PublishingUI diff --git a/src/publishing/SuccessPaneWidget.vala b/src/publishing/SuccessPaneWidget.vala new file mode 100644 index 0000000..05b0c16 --- /dev/null +++ b/src/publishing/SuccessPaneWidget.vala @@ -0,0 +1,39 @@ +/* Copyright 2016 Software Freedom Conservancy Inc. + * Copyright 2019 Jens Georg <mail@jensge.org> + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later).  See the COPYING file in this distribution. + */ + +namespace PublishingUI { + +public class SuccessPane : StaticMessagePane { +    public SuccessPane(Spit.Publishing.Publisher.MediaType published_media, int num_uploaded = 1) { +        string? message_string = null; + +        // Here, we check whether more than one item is being uploaded, and if so, display +        // an alternate message. +        if (published_media == Spit.Publishing.Publisher.MediaType.VIDEO) { +            message_string = ngettext ("The selected video was successfully published.", +                                       "The selected videos were successfully published.", +                                       num_uploaded); +        } +        else if (published_media == Spit.Publishing.Publisher.MediaType.PHOTO) { +            message_string = ngettext ("The selected photo was successfully published.", +                                       "The selected photos were successfully published.", +                                       num_uploaded); +        } +        else if (published_media == (Spit.Publishing.Publisher.MediaType.PHOTO +                                     | Spit.Publishing.Publisher.MediaType.VIDEO)) { +            message_string = _("The selected photos/videos were successfully published."); +        } +        else { +            assert_not_reached (); +        } + +        base(message_string); +    } +} +} + + diff --git a/src/publishing/meson.build b/src/publishing/meson.build new file mode 100644 index 0000000..38178d6 --- /dev/null +++ b/src/publishing/meson.build @@ -0,0 +1,27 @@ +libsw_publishing_gui = static_library( +    'publishing_gui', +    [ +        'StaticMessagePaneWidget.vala', +        'ProgressPaneWidget.vala', +        'SuccessPaneWidget.vala', +        'LoginWelcomePaneWidget.vala', +    ], +    vala_header : 'shotwell-internal-publishing-gui.h', +    vala_vapi : 'shotwell-internal-publishing-gui.vapi', +    include_directories : config_incdir, +    dependencies: [ +        gtk, +        gee, +        sw_plugin +    ], +    vala_args : [ +        '--gresources', +        join_paths(meson.project_source_root(), 'data', +        'org.gnome.Shotwell.gresource.xml') +    ] +) + +sw_publishing_gui = declare_dependency( +    include_directories : include_directories('.'), +    link_with : libsw_publishing_gui +) | 
