diff options
Diffstat (limited to 'src/plugins')
| -rw-r--r-- | src/plugins/DataImportsInterfaces.vala | 4 | ||||
| -rw-r--r-- | src/plugins/ManifestWidget.vala | 412 | ||||
| -rw-r--r-- | src/plugins/Plugins.vala | 45 | ||||
| -rw-r--r-- | src/plugins/PublishingInterfaces.vala | 44 | ||||
| -rw-r--r-- | src/plugins/SpitInterfaces.vala | 33 | ||||
| -rw-r--r-- | src/plugins/StandardHostInterface.vala | 9 | 
6 files changed, 267 insertions, 280 deletions
diff --git a/src/plugins/DataImportsInterfaces.vala b/src/plugins/DataImportsInterfaces.vala index f2c8a53..518f8d0 100644 --- a/src/plugins/DataImportsInterfaces.vala +++ b/src/plugins/DataImportsInterfaces.vala @@ -120,7 +120,7 @@ public interface ImportableMediaItem : GLib.Object {      public abstract string get_filename(); -    public abstract time_t? get_exposure_time(); +    public abstract DateTime? get_exposure_time();  }  /** @@ -416,7 +416,7 @@ public interface PluginHost : GLib.Object, Spit.HostInterface {       * @param host_progress_delta the amount of progress the host should update       * the progress bar during import preparation. Plugins should ensure that       * a proportion of progress for each media item is set aside for the host -     * in oder to ensure a smoother update to the progress bar. +     * in order to ensure a smoother update to the progress bar.       *       * @param progress_message the text to be displayed below the progress bar. If that       * parameter is null, the message will be left unchanged. diff --git a/src/plugins/ManifestWidget.vala b/src/plugins/ManifestWidget.vala index 8fb0ba2..55ccdc3 100644 --- a/src/plugins/ManifestWidget.vala +++ b/src/plugins/ManifestWidget.vala @@ -10,10 +10,7 @@ namespace Plugins {  [GtkTemplate (ui = "/org/gnome/Shotwell/ui/manifest_widget.ui")]  public class ManifestWidgetMediator : Gtk.Box {      [GtkChild] -    private Gtk.Button about_button; -     -    [GtkChild] -    private Gtk.ScrolledWindow list_bin; +    private unowned Gtk.ScrolledWindow list_bin;      private ManifestListView list = new ManifestListView(); @@ -21,247 +18,212 @@ public class ManifestWidgetMediator : Gtk.Box {          Object();          list_bin.add(list); -         -        about_button.clicked.connect(on_about); -        list.get_selection().changed.connect(on_selection_changed); -         -        set_about_button_sensitivity(); +    }     +} + +private class CollectionModel<G> : GLib.ListModel, Object { +    private Gee.Collection<G> target; +    private unowned Gee.List<G>? as_list = null; + +    public CollectionModel(Gee.Collection<G> target) { +        Object(); +        this.target = target.read_only_view; +        if (this.target is Gee.List) { +            this.as_list = (Gee.List<G>)this.target; +        }      } -     -    private void on_about() { -        string[] ids = list.get_selected_ids(); -        if (ids.length == 0) -            return; -         -        string id = ids[0]; -         -        Spit.PluggableInfo info = Spit.PluggableInfo(); -        if (!get_pluggable_info(id, ref info)) { -            warning("Unable to retrieve information for plugin %s", id); -             -            return; + +    GLib.Object? get_item(uint position) { +        if (position >= this.target.size) { +            return null;          } -         -        // prepare authors names (which are comma-delimited by the plugin) for the about box -        // (which wants an array of names) -        string[]? authors = null; -        if (info.authors != null) { -            string[] split = info.authors.split(","); -            for (int ctr = 0; ctr < split.length; ctr++) { -                string stripped = split[ctr].strip(); -                if (!is_string_empty(stripped)) { -                    if (authors == null) -                        authors = new string[0]; -                     -                    authors += stripped; -                } + +        if (this.as_list != null) { +            return (GLib.Object) this.as_list.@get((int) position); +        } + +        var count = 0U; +        foreach (var g in this.target) { +            if (count == position) { +                return (GLib.Object)g;              } +            count++;          } -         -        Gtk.AboutDialog about_dialog = new Gtk.AboutDialog(); -        about_dialog.authors = authors; -        about_dialog.comments = info.brief_description; -        about_dialog.copyright = info.copyright; -        about_dialog.license = info.license; -        about_dialog.wrap_license = info.is_license_wordwrapped; -        about_dialog.logo = (info.icons != null && info.icons.length > 0) ? info.icons[0] : -            Resources.get_icon(Resources.ICON_GENERIC_PLUGIN); -        about_dialog.program_name = get_pluggable_name(id); -        about_dialog.translator_credits = info.translators; -        about_dialog.version = info.version; -        about_dialog.website = info.website_url; -        about_dialog.website_label = info.website_name; -         -        about_dialog.run(); -         -        about_dialog.destroy(); + +        return null;      } -     -    private void on_selection_changed() { -        set_about_button_sensitivity(); + +    GLib.Type get_item_type() { +        return typeof(G);      } -     -    private void set_about_button_sensitivity() { -        // have to get the array and then get its length rather than do so in one call due to a  -        // bug in Vala 0.10: -        //     list.get_selected_ids().length -> uninitialized value -        // this appears to be fixed in Vala 0.11 -        string[] ids = list.get_selected_ids(); -        about_button.sensitive = (ids.length == 1); + +    uint get_n_items() { +        return this.target.size;      } +  } -private class ManifestListView : Gtk.TreeView { -    private const int ICON_SIZE = 24; -    private const int ICON_X_PADDING = 6; -    private const int ICON_Y_PADDING = 2; -     -    private enum Column { -        ENABLED, -        CAN_ENABLE, -        ICON, -        NAME, -        ID, -        N_COLUMNS +private class Selection : Object { +    public signal void changed(); +} + +private class PluggableRow : Gtk.Box { +    public Spit.Pluggable pluggable { get; construct; } +    public bool enabled {get; construct; } + +    public PluggableRow(Spit.Pluggable pluggable_, bool enable_) { +        Object(orientation: Gtk.Orientation.VERTICAL, pluggable: pluggable_, +            enabled: enable_, margin_top: 6, margin_bottom:6, margin_start:6, margin_end:6);      } -     -    private Gtk.TreeStore store = new Gtk.TreeStore(Column.N_COLUMNS, -        typeof(bool),       // ENABLED -        typeof(bool),       // CAN_ENABLE -        typeof(Gdk.Pixbuf), // ICON -        typeof(string),     // NAME -        typeof(string)      // ID -    ); -     -    public ManifestListView() { -        set_model(store); -         -        Gtk.CellRendererToggle checkbox_renderer = new Gtk.CellRendererToggle(); -        checkbox_renderer.radio = false; -        checkbox_renderer.activatable = true; -         -        Gtk.CellRendererPixbuf icon_renderer = new Gtk.CellRendererPixbuf(); -        icon_renderer.stock_size = Gtk.IconSize.MENU; -        icon_renderer.xpad = ICON_X_PADDING; -        icon_renderer.ypad = ICON_Y_PADDING; -         -        Gtk.CellRendererText text_renderer = new Gtk.CellRendererText(); -         -        Gtk.TreeViewColumn column = new Gtk.TreeViewColumn(); -        column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE); -        column.pack_start(checkbox_renderer, false); -        column.pack_start(icon_renderer, false); -        column.pack_end(text_renderer, true); -         -        column.add_attribute(checkbox_renderer, "active", Column.ENABLED); -        column.add_attribute(checkbox_renderer, "visible", Column.CAN_ENABLE); -        column.add_attribute(icon_renderer, "pixbuf", Column.ICON); -        column.add_attribute(text_renderer, "text", Column.NAME); -         -        append_column(column); + +    public override void constructed() { +        base.constructed(); +        var content = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 6); +        pack_start(content, true); + +        var revealer = new Gtk.Revealer(); +        revealer.margin_top = 6; +        pack_end(revealer, true); -        set_headers_visible(false); -        set_enable_search(false); -        set_show_expanders(true); -        set_reorderable(false); -        set_enable_tree_lines(false); -        set_grid_lines(Gtk.TreeViewGridLines.NONE); -        get_selection().set_mode(Gtk.SelectionMode.BROWSE); +        var info = pluggable.get_info(); -        Gtk.IconTheme icon_theme = Resources.get_icon_theme_engine(); +        var image = new Gtk.Image.from_icon_name(info.icon_name, Gtk.IconSize.BUTTON); +        content.pack_start(image, false, false, 6); +        image.hexpand = false; + +        var label = new Gtk.Label(pluggable.get_pluggable_name()); +        label.halign = Gtk.Align.START; +        content.pack_start(label, true, true, 6); + +        var button = new Gtk.ToggleButton(); +        button.get_style_context().add_class("flat"); +        content.pack_end(button, false, false, 6); +        button.bind_property("active", revealer, "reveal-child", BindingFlags.DEFAULT); +        image = new Gtk.Image.from_icon_name("go-down-symbolic", Gtk.IconSize.SMALL_TOOLBAR); +        button.add(image); + +        var plugin_enabled = new Gtk.Switch(); +        plugin_enabled.hexpand = false; +        plugin_enabled.vexpand = false; +        plugin_enabled.valign = Gtk.Align.CENTER; +        plugin_enabled.set_active(enabled); + +        content.pack_end(plugin_enabled, false, false, 6); +        plugin_enabled.notify["active"].connect(() => { +            var id = pluggable.get_id(); +            set_pluggable_enabled(id, plugin_enabled.active); +        }); + +        if (pluggable is Spit.Publishing.Service) { +#if 0 +            var manage = new Gtk.Button.from_icon_name("avatar-default-symbolic", Gtk.IconSize.SMALL_TOOLBAR); +            manage.get_style_context().add_class("flat"); +            // TRANSLATORS: %s is the name of an online service such as YouTube, Mastodon, ... +            manage.set_tooltip_text(_("Manage accounts for %s").printf(pluggable.get_pluggable_name())); +            content.pack_start(manage, false, false, 6); +#endif +        } + +        var grid = new Gtk.Grid(); +        grid.get_style_context().add_class("content"); +        grid.set_row_spacing(12); +        grid.set_column_spacing(6); +        revealer.add(grid); +        label = new Gtk.Label(info.copyright); +        label.hexpand = true; +        label.halign = Gtk.Align.START; +        grid.attach(label, 0, 0, 2, 1); +        label = new Gtk.Label(_("Authors")); +        label.get_style_context().add_class("dim-label"); +        label.halign = Gtk.Align.END; +        label.margin_start = 12; +        grid.attach(label, 0, 1, 1, 1); +        label = new Gtk.Label(info.authors); +        label.halign = Gtk.Align.START; +        label.hexpand = true; +        grid.attach(label, 1, 1, 1, 1); + +        label = new Gtk.Label(_("Version")); +        label.get_style_context().add_class("dim-label"); +        label.halign = Gtk.Align.END; +        label.margin_start = 12; +        grid.attach(label, 0, 2, 1, 1); +        label = new Gtk.Label(info.version); +        label.halign = Gtk.Align.START; +        label.hexpand = true; +        grid.attach(label, 1, 2, 1, 1); + +        label = new Gtk.Label(_("License")); +        label.get_style_context().add_class("dim-label"); +        label.halign = Gtk.Align.END; +        label.margin_start = 12; +        grid.attach(label, 0, 3, 1, 1); +        var link = new Gtk.LinkButton.with_label(info.license_url, info.license_blurp); +        link.halign = Gtk.Align.START; +        // remove the annoying padding around the link +        link.get_style_context().remove_class("text-button"); +        link.get_style_context().add_class("shotwell-plain-link"); +        grid.attach(link, 1, 3, 1, 1); + +        label = new Gtk.Label(_("Website")); +        label.get_style_context().add_class("dim-label"); +        label.halign = Gtk.Align.END; +        label.margin_start = 12; +        grid.attach(label, 0, 4, 1, 1); +        link = new Gtk.LinkButton.with_label(info.website_url, info.website_name); +        link.halign = Gtk.Align.START; +        // remove the annoying padding around the link +        link.get_style_context().remove_class("text-button"); +        link.get_style_context().add_class("shotwell-plain-link"); +        grid.attach(link, 1, 4, 1, 1); -        // create a list of plugins (sorted by name) that are separated by extension points (sorted -        // by name) -        foreach (ExtensionPoint extension_point in get_extension_points(compare_extension_point_names)) { -            Gtk.TreeIter category_iter; -            store.append(out category_iter, null); -             -            Gdk.Pixbuf? icon = null; -            if (extension_point.icon_name != null) { -                Gtk.IconInfo? icon_info = icon_theme.lookup_by_gicon( -                    new ThemedIcon(extension_point.icon_name), ICON_SIZE, 0); -                if (icon_info != null) { -                    try { -                        icon = icon_info.load_icon(); -                    } catch (Error err) { -                        warning("Unable to load icon %s: %s", extension_point.icon_name, err.message); -                    } -                } -            } -             -            store.set(category_iter, Column.NAME, extension_point.name, Column.CAN_ENABLE, false, -                Column.ICON, icon); -             -            Gee.Collection<Spit.Pluggable> pluggables = get_pluggables_for_type( -                extension_point.pluggable_type, compare_pluggable_names, true); -            foreach (Spit.Pluggable pluggable in pluggables) { +    } +} + +private class ManifestListView : Gtk.Box { +    public ManifestListView() { +        Object(orientation: Gtk.Orientation.VERTICAL, spacing: 6); +    } + +    public signal void row_selected(Spit.Pluggable? pluggable); + +    public override void constructed() { +        base.constructed(); + +        foreach (var extension_point in get_extension_points(compare_extension_point_names)) { +            var label = new Gtk.Label(null); +            label.set_markup("<span weight=\"bold\">%s</span>".printf(extension_point.name)); +            label.halign = Gtk.Align.START; +            label.hexpand = true; +            add(label); + +            var pluggables = get_pluggables_for_type(extension_point.pluggable_type, compare_pluggable_names, true); +            var box = new Gtk.ListBox(); +            box.set_selection_mode(Gtk.SelectionMode.NONE); +            box.hexpand = true; +            box.margin_start = 12; +            box.margin_end = 12; + +            var added = 0; +            foreach (var pluggable in pluggables) {                  bool enabled; +                  if (!get_pluggable_enabled(pluggable.get_id(), out enabled))                      continue; -                 -                Spit.PluggableInfo info = Spit.PluggableInfo(); -                pluggable.get_info(ref info); -                 -                icon = (info.icons != null && info.icons.length > 0)  -                    ? info.icons[0] -                    : Resources.get_icon(Resources.ICON_GENERIC_PLUGIN, ICON_SIZE); -                 -                Gtk.TreeIter plugin_iter; -                store.append(out plugin_iter, category_iter); -                 -                store.set(plugin_iter, Column.ENABLED, enabled, Column.NAME, pluggable.get_pluggable_name(), -                    Column.ID, pluggable.get_id(), Column.CAN_ENABLE, true, Column.ICON, icon); + +                var pluggable_row = new PluggableRow(pluggable, enabled); + +                added++; +                box.insert(pluggable_row, -1); +            } +            if (added > 0) { +                add(box);              }          } -         -        expand_all(); -    } -     -    public string[] get_selected_ids() { -        string[] ids = new string[0]; -         -        List<Gtk.TreePath> selected = get_selection().get_selected_rows(null); -        foreach (Gtk.TreePath path in selected) { -            Gtk.TreeIter iter; -            string? id = get_id_at_path(path, out iter); -            if (id != null) -                ids += id; -        } -         -        return ids; -    } -     -    private string? get_id_at_path(Gtk.TreePath path, out Gtk.TreeIter iter) { -        if (!store.get_iter(out iter, path)) -            return null; -         -        unowned string id; -        store.get(iter, Column.ID, out id); -         -        return id; -    } -    // Because we want each row to left-align and not for each column to line up in a grid -    // (otherwise the checkboxes -- hidden or not -- would cause the rest of the row to line up -    // along the icon's left edge), we put all the renderers into a single column.  However, the -    // checkbox renderer then triggers its "toggle" signal any time the row is single-clicked, -    // whether or not the actual checkbox hit-tests. -    // -    // The only way found to work around this is to capture the button-down event and do our own -    // hit-testing. -    public override bool button_press_event(Gdk.EventButton event) { -        Gtk.TreePath path; -        Gtk.TreeViewColumn col; -        int cellx; -        int celly; -        if (!get_path_at_pos((int) event.x, (int) event.y, out path, out col, out cellx, -            out celly)) -            return base.button_press_event(event); -         -        // Perform custom hit testing as described above. The first cell in the column is offset -        // from the left edge by whatever size the group description icon is allocated (including -        // padding). -        if (cellx < (ICON_SIZE + ICON_X_PADDING) || cellx > (2 * (ICON_X_PADDING + ICON_SIZE))) -            return base.button_press_event(event); - -        Gtk.TreeIter iter; -        string? id = get_id_at_path(path, out iter); -        if (id == null) -            return base.button_press_event(event); -         -        bool enabled; -        if (!get_pluggable_enabled(id, out enabled)) -            return base.button_press_event(event); -         -        // toggle and set -        enabled = !enabled; -        set_pluggable_enabled(id, enabled); -         -        store.set(iter, Column.ENABLED, enabled); -         -        return true; +        show_all();      } -} +}   } diff --git a/src/plugins/Plugins.vala b/src/plugins/Plugins.vala index 6aff461..cfab7e8 100644 --- a/src/plugins/Plugins.vala +++ b/src/plugins/Plugins.vala @@ -6,10 +6,6 @@  namespace Plugins { -// GModule doesn't have a truly generic way to determine if a file is a shared library by extension, -// so these are hard-coded -private const string[] SHARED_LIB_EXTS = { "so", "la" }; -  // Although not expecting this system to last very long, these ranges declare what versions of this  // interface are supported by the current implementation.  private const int MIN_SPIT_INTERFACE = 0; @@ -39,8 +35,12 @@ private class ModuleRep {      private ModuleRep(File file) {          this.file = file; -         + +#if VALA_0_46 +        module = Module.open(file.get_path(), ModuleFlags.LAZY); +#else          module = Module.open(file.get_path(), ModuleFlags.BIND_LAZY); +#endif      }      ~ModuleRep() { @@ -221,7 +221,7 @@ public string? get_pluggable_module_id(Spit.Pluggable needle) {      return (module_rep != null) ? module_rep.spit_module.get_id() : null;  } -public Gee.Collection<ExtensionPoint> get_extension_points(owned CompareDataFunc? compare_func = null) { +public Gee.Collection<ExtensionPoint> get_extension_points(owned CompareDataFunc<ExtensionPoint>? compare_func = null) {      Gee.Collection<ExtensionPoint> sorted = new Gee.TreeSet<ExtensionPoint>((owned) compare_func);      sorted.add_all(extension_points.values); @@ -229,7 +229,7 @@ public Gee.Collection<ExtensionPoint> get_extension_points(owned CompareDataFunc  }  public Gee.Collection<Spit.Pluggable> get_pluggables_for_type(Type type, -    owned CompareDataFunc? compare_func = null, bool include_disabled = false) { +    owned CompareDataFunc<Spit.Pluggable>? compare_func = null, bool include_disabled = false) {      // if this triggers it means the extension point didn't register itself at init() time      assert(extension_points.has_key(type)); @@ -252,12 +252,14 @@ public string? get_pluggable_name(string id) {          ? pluggable_rep.pluggable.get_pluggable_name() : null;  } -public bool get_pluggable_info(string id, ref Spit.PluggableInfo info) { +public bool get_pluggable_info(string id, out Spit.PluggableInfo info) {      PluggableRep? pluggable_rep = pluggable_table.get(id); -    if (pluggable_rep == null || !pluggable_rep.activated) +    if (pluggable_rep == null || !pluggable_rep.activated) { +        info = null;          return false; +    } -    pluggable_rep.pluggable.get_info(ref info); +    info = pluggable_rep.pluggable.get_info();      return true;  } @@ -290,30 +292,19 @@ public File get_pluggable_module_file(Spit.Pluggable pluggable) {      return (module_rep != null) ? module_rep.file : null;  } -public int compare_pluggable_names(void *a, void *b) { -    Spit.Pluggable *apluggable = (Spit.Pluggable *) a; -    Spit.Pluggable *bpluggable = (Spit.Pluggable *) b; -     -    return apluggable->get_pluggable_name().collate(bpluggable->get_pluggable_name()); +public int compare_pluggable_names(Spit.Pluggable a, Spit.Pluggable b) { +    return a.get_pluggable_name().collate(b.get_pluggable_name());  } -public int compare_extension_point_names(void *a, void *b) { -    ExtensionPoint *apoint = (ExtensionPoint *) a; -    ExtensionPoint *bpoint = (ExtensionPoint *) b; -     -    return apoint->name.collate(bpoint->name); +public int compare_extension_point_names(ExtensionPoint a, ExtensionPoint b) { +    return a.name.collate(b.name);  }  private bool is_shared_library(File file) {      string name, ext;      disassemble_filename(file.get_basename(), out name, out ext); -     -    foreach (string shared_ext in SHARED_LIB_EXTS) { -        if (ext == shared_ext) -            return true; -    } -     -    return false; + +    return ext == Module.SUFFIX;  }  private void search_for_plugins(File dir) throws Error { diff --git a/src/plugins/PublishingInterfaces.vala b/src/plugins/PublishingInterfaces.vala index 6518142..05b161f 100644 --- a/src/plugins/PublishingInterfaces.vala +++ b/src/plugins/PublishingInterfaces.vala @@ -9,7 +9,7 @@   *   * The Shotwell Pluggable Publishing API allows you to write plugins that upload   * photos and videos to web services. The Shotwell distribution includes publishing - * support for four core services: Facebook, Flickr, Picasa Web Albums, and YouTube. + * support for three core services: Flickr, Google Photos, and YouTube.   * To enable Shotwell to connect to additional services, developers like you write   * publishing plugins, dynamically-loadable shared objects that are linked into the   * Shotwell process at runtime. Publishing plugins are just one of several kinds of @@ -87,7 +87,7 @@ public errordomain PublishingError {      /**       * Indicates that a secure connection to the remote host cannot be       * established. This might have various reasons such as expired -     * certificats, invalid certificates, self-signed certificates... +     * certificates, invalid certificates, self-signed certificates...       */      SSL_FAILED  } @@ -268,6 +268,8 @@ public interface PluginHost : GLib.Object, Spit.HostInterface {          CANCEL = 1      } +    public abstract string get_current_profile_id(); +      /**       * Notifies the user that an unrecoverable publishing error has occurred and halts       * the publishing process. @@ -367,7 +369,7 @@ public interface PluginHost : GLib.Object, Spit.HostInterface {       * The text displayed depends on the type of media the current publishing service       * supports. To provide visual consistency across publishing services and to allow       * Shotwell to handle internationalization, always use this convenience method; don’t -     * contruct and install success panes manually. +     * construct and install success panes manually.       *       * If an error has posted, the {@link PluginHost} will not honor       * this request. @@ -413,7 +415,7 @@ public interface PluginHost : GLib.Object, Spit.HostInterface {       * the callback 'on_login_clicked'. Every Publisher should provide a welcome pane to       * introduce the service and explain service-specific features or restrictions. To provide       * visual consistency across publishing services and to allow Shotwell to handle -     * internationalization, always use this convenience method; don’t contruct and install +     * internationalization, always use this convenience method; don’t construct and install       * welcome panes manually.       *       * If an error has posted, the {@link PluginHost} will not honor this request. @@ -565,6 +567,11 @@ public interface Publishable : GLib.Object {       */      public abstract GLib.DateTime get_exposure_date_time(); +    /** +     * Returns the rating on the file. +     */ +    public abstract uint get_rating(); +      //      // For future expansion.      // @@ -578,6 +585,17 @@ public interface Publishable : GLib.Object {      protected virtual void reserved7() {}  } +public interface Account : Object { +    public abstract string display_name(); +} + +public class DefaultAccount : Spit.Publishing.Account, Object { +    public string display_name() { +        return ""; +    } +} + +  /**   * Describes the features and capabilities of a remote publishing service.   * @@ -590,10 +608,26 @@ public interface Service : Object, Spit.Pluggable {       */      public abstract Spit.Publishing.Publisher create_publisher(Spit.Publishing.PluginHost host); +    public virtual Spit.Publishing.Publisher create_publisher_with_account(Spit.Publishing.PluginHost host, +                                                              Spit.Publishing.Account? account) { +        return this.create_publisher(host); +    } +      /**       * Returns the kinds of media that this service can work with.       */      public abstract Spit.Publishing.Publisher.MediaType get_supported_media(); + +    /** +     * Returns a list of accounts associated with the service +     * Returns: null if there are no accounts, identifier +     */ +    public virtual Gee.List<Account>? get_accounts(string profile_id) { +        var list = new Gee.ArrayList<Account>(); +        list.add(new DefaultAccount()); + +        return list; +    }      //      // For future expansion. @@ -617,6 +651,8 @@ public interface Authenticator : Object {      public abstract void logout();      public abstract void refresh(); +    public abstract void set_accountname(string name); +      public abstract GLib.HashTable<string, Variant> get_authentication_parameter();  } diff --git a/src/plugins/SpitInterfaces.vala b/src/plugins/SpitInterfaces.vala index 3e2c70e..94e6f95 100644 --- a/src/plugins/SpitInterfaces.vala +++ b/src/plugins/SpitInterfaces.vala @@ -4,6 +4,8 @@   * (version 2.1 or later).  See the COPYING file in this distribution.   */ +private extern const string _VERSION; +  /**   * Shotwell Pluggable Interface Technology (SPIT)   * @@ -156,27 +158,26 @@ public interface Module : Object {      protected virtual void reserved7() {}  } +  /**   * A structure holding an assortment of information about a {@link Pluggable}.   */ -public struct PluggableInfo { -    public string? version; -    public string? brief_description; +public class PluggableInfo : Object { +    public string? version {get; set; default = _VERSION; } +    public string? brief_description {get; set; }      /**       * A comma-delimited list of the authors of this {@link Pluggable}.       */ -    public string? authors; -    public string? copyright; -    public string? license; -    public bool is_license_wordwrapped; -    public string? website_url; -    public string? website_name; -    public string? translators; -    /** -     * An icon representing this plugin at one or more sizes. Shotwell may select an icon  -     * according to the size that closest fits the control its being drawn in. -     */ -    public Gdk.Pixbuf[]? icons; +    public string? authors { get; set; } +    public string? copyright {get; set; } +    public string? license_blurp { get; set; default = _("LGPL v2.1 or later"); } +    public string? license_url { get; set; default = "https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"; } +    public string? website_url {get; set;  default = "https://wiki.gnome.org/Apps/Shotwell";} +    public string? website_name { get; set;  default = _("Visit the Shotwell home page");} +    public string? translators {get; set; default = _("translator-credits"); } + +    // Name of an icon in the theme, to be set in the Pluggable implementation +    public string icon_name {get; set; default = "application-x-addon-symbolic"; }  }  /** @@ -225,7 +226,7 @@ public interface Pluggable : Object {      /**       * Returns extra information about the Pluggable that is used to identify it to the user.       */ -    public abstract void get_info(ref PluggableInfo info); +    public abstract PluggableInfo get_info();      /**       * Called when the Pluggable is enabled (activated) or disabled (deactivated). diff --git a/src/plugins/StandardHostInterface.vala b/src/plugins/StandardHostInterface.vala index d0f3ed4..aa012ef 100644 --- a/src/plugins/StandardHostInterface.vala +++ b/src/plugins/StandardHostInterface.vala @@ -16,20 +16,17 @@ public class StandardHostInterface : Object, Spit.HostInterface {          this.config_domain = config_domain;          config_id = parse_key(pluggable.get_id());          module_file = get_pluggable_module_file(pluggable); -        pluggable.get_info(ref info); +        info = pluggable.get_info();      }      private static string parse_key(string id) {          // special case: legacy plugins (Web publishers moved into SPIT) have special names          // new plugins will use their full ID          switch (id) { -            case "org.yorba.shotwell.publishing.facebook": -                return "facebook"; -             -            case "org.yorba.shotwell.publishing.flickr": +            case "org.gnome.shotwell.publishing.flickr":                  return "flickr"; -            case "org.yorba.shotwell.publishing.youtube": +            case "org.gnome.shotwell.publishing.youtube":                  return "youtube";              default:  | 
