1 /* This file is part of Cinaest.
3 * Copyright (C) 2009 Philipp Zabel
5 * Cinaest is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * Cinaest is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
22 class CatalogPlugin : Plugin {
23 List<CatalogSource> sources;
24 private CatalogSqlite sqlite;
25 private Gtk.Dialog dialog;
27 public override void hello (Gtk.Window window, Osso.Context context) {
28 string data_dir = Path.build_filename (Environment.get_user_data_dir(), "cinaest");
29 string filename = Path.build_filename (data_dir, "catalog.db");
31 // Make sure the data directory is available
32 DirUtils.create_with_parents (data_dir, 0770);
34 string hidden_sources = null;
36 var config_file = Path.build_filename (Environment.get_user_config_dir (), "cinaest", "cinaest.cfg");
37 var keyfile = new KeyFile ();
38 if (keyfile.load_from_file (config_file, KeyFileFlags.NONE)
39 && keyfile.has_group ("CatalogPlugin")) {
40 if (keyfile.has_key ("CatalogPlugin", "HiddenSources")) {
41 hidden_sources = keyfile.get_string ("CatalogPlugin", "HiddenSources");
45 if (!(e is KeyFileError.NOT_FOUND))
46 stdout.printf ("Error loading configuration: %s\n", e.message);
49 sqlite = new CatalogSqlite (filename);
50 sources = new List<CatalogSource> ();
52 var source = new CatalogSource ("Collection", _("Collection"), _("Personal movie list"), sqlite, !("Collection" in hidden_sources));
53 sources.append (source);
55 source = new CatalogSource ("Loaned", _("Loaned movies"), _("Movies loaned to friends"), sqlite, !("Loaned" in hidden_sources));
56 sources.append (source);
58 source = new CatalogSource ("Watched", _("Watched movies"), _("Watched / rated movies"), sqlite, !("Watched" in hidden_sources));
59 sources.append (source);
61 source = new CatalogSource ("Watchlist", _("Watchlist"), _("Movies of interest"), sqlite, !("Watchlist" in hidden_sources));
62 sources.append (source);
64 stdout.printf ("Catalog Plugin Loaded.\n");
67 public override unowned List<MovieSource> get_sources () {
68 return (List<MovieSource>) sources;
71 public override List<MovieAction> get_actions (Movie movie, Gtk.Window window) {
72 var list = new List<MovieAction> ();
74 list.append (new MovieAction (_("Add to catalog"), on_add_to_catalog, movie, window));
79 private void on_add_to_catalog (Movie movie, Gtk.Window window) {
80 dialog = new Gtk.Dialog ();
81 dialog.set_transient_for (window);
82 dialog.set_title (_("Add movie to catalog - Select list"));
85 var available_sources = new List<MovieSource> ();
86 foreach (CatalogSource s in sources) {
87 if (!s.contains (movie) && s.table != "Watched") {
88 available_sources.append ((MovieSource) s);
93 var source_list = new SourceListView (available_sources, true, window);
95 var content = (VBox) dialog.get_content_area ();
96 content.pack_start (source_list, true, true, 0);
99 content.set_size_request (-1, i*70);
102 source_list.source_activated.connect (on_source_activated);
105 int res = dialog.run ();
107 var source = sources.nth_data (res);
109 if (source.table == "Loaned") {
110 var dialog = new Gtk.Dialog ();
111 dialog.set_title (_("Add to loaned movies"));
113 var contact = new Hildon.Entry (SizeType.FINGER_HEIGHT);
114 contact.set_placeholder ("Contact");
115 var date = new Hildon.DateButton (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL);
116 date.set_title (_("Loaned on"));
117 date.set_alignment (0.0f, 0.5f, 1.0f, 1.0f);
119 content = (Gtk.VBox) dialog.get_content_area ();
120 content.pack_start (contact, true, false, 0);
121 content.pack_start (date, true, false, 0);
123 dialog.add_button (_("Done"), Gtk.ResponseType.OK);
127 if (res == Gtk.ResponseType.OK) {
128 source.add_movie (movie);
130 var banner = (Banner) Banner.show_information_with_markup (window, null, _("'%s' added to list of loaned movies").printf (movie.title, source.get_name ()));
131 banner.set_timeout (1500);
134 source.add_movie (movie);
136 var banner = (Banner) Banner.show_information_with_markup (window, null, _("'%s' added to list '%s'").printf (movie.title, source.get_name ()));
137 banner.set_timeout (1500);
144 private void on_source_activated (MovieSource source) {
145 int n = sources.index ((CatalogSource) source);
150 public override void settings_dialog (Gtk.Window window) {
151 var dialog = new Gtk.Dialog ();
152 dialog.set_transient_for (window);
153 dialog.set_title (_("Catalog plugin settings"));
155 var button = new Hildon.Button (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL);
156 button.set_title (_("Select active movie lists"));
157 button.set_value (active_sources_text ());
158 button.set_style (ButtonStyle.PICKER);
160 var content = (VBox) dialog.get_content_area ();
161 content.pack_start (button, true, true, 0);
163 dialog.add_button (_("Done"), ResponseType.ACCEPT);
166 button.clicked.connect (() => { on_select_active_lists (button, window); });
169 int res = dialog.run ();
170 if (res == ResponseType.ACCEPT) {
175 private void on_select_active_lists (Hildon.Button button, Gtk.Window window) {
176 dialog = new Gtk.Dialog ();
177 dialog.set_transient_for (window);
178 dialog.set_title (_("Select active movie lists"));
180 var source_list = new SourceListView (sources, false, window);
181 source_list.set_hildon_ui_mode (UIMode.EDIT);
183 var selection = source_list.get_selection ();
184 foreach (CatalogSource s in sources) {
185 var iter = TreeIter ();
187 if (s.active && source_list.get_iter (s, out iter)) {
188 selection.select_iter (iter);
192 var content = (VBox) dialog.get_content_area ();
193 content.pack_start (source_list, true, true, 0);
194 var i = sources.length ();
197 content.set_size_request (-1, (int) i*70);
199 dialog.add_button (_("Done"), ResponseType.ACCEPT);
202 int res = dialog.run ();
203 if (res == ResponseType.ACCEPT) {
204 foreach (CatalogSource s in sources) {
207 if (source_list.get_iter (s, out iter)) {
208 s.active = selection.iter_is_selected (iter);
212 var config_file = Path.build_filename (Environment.get_user_config_dir (), "cinaest", "cinaest.cfg");
213 var keyfile = new KeyFile ();
215 keyfile.load_from_file (config_file, KeyFileFlags.NONE);
217 if (!(e is KeyFileError.NOT_FOUND))
218 stdout.printf ("Error loading configuration: %s\n", e.message);
220 keyfile.set_string ("CatalogPlugin", "HiddenSources", hidden_sources_list ());
223 var file = File.new_for_path (config_file + ".part");
224 var stream = file.create (FileCreateFlags.REPLACE_DESTINATION, null);
225 var data = keyfile.to_data ();
227 stream.write (data, data.length, null);
228 FileUtils.rename (config_file + ".part", config_file);
230 stdout.printf ("Failed to store configuration: %s\n", e.message);
233 button.set_value (active_sources_text ());
239 private string active_sources_text () {
242 foreach (CatalogSource s in sources) {
245 text = s.get_name ();
247 text += ", " + s.get_name ();
254 private string hidden_sources_list () {
257 foreach (CatalogSource s in sources) {
262 list += ", " + s.table;
269 public override unowned string get_name () {
274 class CatalogSource : MovieSource {
275 internal string table;
277 private string description;
278 private CatalogSqlite sqlite;
280 public CatalogSource (string _table, string _name, string _description, CatalogSqlite _sqlite, bool _active) {
281 GLib.Object (active: _active);
284 description = _description;
288 public override bool active { get; set construct; }
290 public override async int get_movies (MovieFilter filter, MovieSource.ReceiveMovieFunction callback, int limit, Cancellable? cancellable) {
291 int n = yield sqlite.query (table, filter, callback, limit, cancellable);
295 public override void add_movie (Movie movie) {
296 sqlite.add_movie (table, movie);
299 public override void delete_movie (Movie movie) {
300 sqlite.delete_movie (table, movie);
303 internal bool contains (Movie movie) {
304 return sqlite.contains (table, movie);
307 public override unowned string get_name () {
311 public override unowned string get_description () {
315 public override SourceFlags get_flags () {
316 return SourceFlags.EDITABLE;
321 public Type register_plugin (TypeModule module) {
322 // types are registered automatically
323 return typeof (CatalogPlugin);