summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2023-06-14 20:36:37 +0200
committerJörg Frings-Fürst <debian@jff.email>2023-06-14 20:36:37 +0200
commitbb80d3feebdc9acc52e3f4ad24084d8425f043a2 (patch)
tree2084a84c39f159c6aea254775dc0880d52579d45 /src/plugins
parentb26ff0798252a1a8072dd2c7a67f6205de9fde11 (diff)
parent31804433d72460cbe0a39f9f8ea5e76058d84cda (diff)
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/DataImportsInterfaces.vala4
-rw-r--r--src/plugins/ManifestWidget.vala412
-rw-r--r--src/plugins/Plugins.vala45
-rw-r--r--src/plugins/PublishingInterfaces.vala44
-rw-r--r--src/plugins/SpitInterfaces.vala33
-rw-r--r--src/plugins/StandardHostInterface.vala9
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: