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 ("Watchlist", _("Watchlist"), _("Movies of interest"), sqlite, !("Watchlist" in hidden_sources));
59 sources.append (source);
61 stdout.printf ("Catalog Plugin Loaded.\n");
64 public override unowned List<MovieSource> get_sources () {
65 return (List<MovieSource>) sources;
68 public override List<MovieAction> get_actions (Movie movie, Gtk.Window window) {
69 var list = new List<MovieAction> ();
71 list.append (new MovieAction (_("Add to catalog"), on_add_to_catalog, movie, window));
76 private void on_add_to_catalog (Movie movie, Gtk.Window window) {
77 dialog = new Gtk.Dialog ();
78 dialog.set_transient_for (window);
79 dialog.set_title (_("Add movie to catalog - Select list"));
82 var available_sources = new List<MovieSource> ();
83 foreach (CatalogSource s in sources) {
84 if (!s.contains (movie)) {
85 available_sources.append ((MovieSource) s);
90 var source_list = new SourceListView (available_sources, true);
92 var content = (VBox) dialog.get_content_area ();
93 content.pack_start (source_list, true, true, 0);
96 content.set_size_request (-1, i*70);
99 source_list.source_activated.connect (on_source_activated);
102 int res = dialog.run ();
104 var source = sources.nth_data (res);
105 source.add_movie (movie);
107 var banner = (Banner) Banner.show_information_with_markup (window, null, _("'%s' added to list '%s'").printf (movie.title, source.get_name ()));
108 banner.set_timeout (1500);
114 private void on_source_activated (MovieSource source) {
115 int n = sources.index ((CatalogSource) source);
120 public override void settings_dialog (Gtk.Window window) {
121 var dialog = new Gtk.Dialog ();
122 dialog.set_transient_for (window);
123 dialog.set_title (_("Catalog plugin settings"));
125 var button = new Hildon.Button (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL);
126 button.set_title (_("Select active movie lists"));
127 button.set_value (active_sources_text ());
128 button.set_style (ButtonStyle.PICKER);
130 var content = (VBox) dialog.get_content_area ();
131 content.pack_start (button, true, true, 0);
133 dialog.add_button (_("Done"), ResponseType.ACCEPT);
136 button.clicked.connect (() => { on_select_active_lists (button, window); });
139 int res = dialog.run ();
140 if (res == ResponseType.ACCEPT) {
145 private void on_select_active_lists (Hildon.Button button, Gtk.Window window) {
146 dialog = new Gtk.Dialog ();
147 dialog.set_transient_for (window);
148 dialog.set_title (_("Select active movie lists"));
150 var source_list = new SourceListView (sources, false);
151 source_list.set_hildon_ui_mode (UIMode.EDIT);
153 var selection = source_list.get_selection ();
154 foreach (CatalogSource s in sources) {
155 var iter = TreeIter ();
157 if (s.active && source_list.get_iter (s, out iter)) {
158 selection.select_iter (iter);
162 var content = (VBox) dialog.get_content_area ();
163 content.pack_start (source_list, true, true, 0);
164 var i = sources.length ();
167 content.set_size_request (-1, (int) i*70);
169 dialog.add_button (_("Done"), ResponseType.ACCEPT);
172 int res = dialog.run ();
173 if (res == ResponseType.ACCEPT) {
174 foreach (CatalogSource s in sources) {
177 if (source_list.get_iter (s, out iter)) {
178 s.active = selection.iter_is_selected (iter);
182 var config_file = Path.build_filename (Environment.get_user_config_dir (), "cinaest", "cinaest.cfg");
183 var keyfile = new KeyFile ();
185 keyfile.load_from_file (config_file, KeyFileFlags.NONE);
187 if (!(e is KeyFileError.NOT_FOUND))
188 stdout.printf ("Error loading configuration: %s\n", e.message);
190 keyfile.set_string ("CatalogPlugin", "HiddenSources", hidden_sources_list ());
193 var file = File.new_for_path (config_file + ".part");
194 var stream = file.create (FileCreateFlags.REPLACE_DESTINATION, null);
195 var data = keyfile.to_data ();
197 stream.write (data, data.length, null);
198 FileUtils.rename (config_file + ".part", config_file);
200 stdout.printf ("Failed to store configuration: %s\n", e.message);
203 button.set_value (active_sources_text ());
209 private string active_sources_text () {
212 foreach (CatalogSource s in sources) {
215 text = s.get_name ();
217 text += ", " + s.get_name ();
224 private string hidden_sources_list () {
227 foreach (CatalogSource s in sources) {
232 list += ", " + s.table;
239 public override unowned string get_name () {
244 class CatalogSource : MovieSource {
245 internal string table;
247 private string description;
248 private CatalogSqlite sqlite;
250 public CatalogSource (string _table, string _name, string _description, CatalogSqlite _sqlite, bool _active) {
251 GLib.Object (active: _active);
254 description = _description;
258 public override bool active { get; set construct; }
260 public override async void get_movies (MovieFilter filter, MovieSource.ReceiveMovieFunction callback, int limit, Cancellable? cancellable) {
261 yield sqlite.query (table, filter, callback, limit, cancellable);
264 public override void add_movie (Movie movie) {
265 sqlite.add_movie (table, movie);
268 public override void delete_movie (Movie movie) {
269 sqlite.delete_movie (table, movie);
272 internal bool contains (Movie movie) {
273 return sqlite.contains (table, movie);
276 public override unowned string get_name () {
280 public override unowned string get_description () {
284 public override bool get_editable () {
290 public Type register_plugin () {
291 // types are registered automatically
292 return typeof (CatalogPlugin);