/* This file is part of Cinaest.
*
* Copyright (C) 2009 Philipp Zabel
*
* Cinaest is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Cinaest is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cinaest. If not, see .
*/
using Gtk;
using Hildon;
class CatalogPlugin : Plugin {
List sources;
private CatalogSqlite sqlite;
private Gtk.Dialog dialog;
public override void hello (Gtk.Window window, Osso.Context context) {
string data_dir = Path.build_filename (Environment.get_user_data_dir(), "cinaest");
string filename = Path.build_filename (data_dir, "catalog.db");
// Make sure the data directory is available
DirUtils.create_with_parents (data_dir, 0770);
string hidden_sources = null;
try {
var config_file = Path.build_filename (Environment.get_user_config_dir (), "cinaest", "cinaest.cfg");
var keyfile = new KeyFile ();
if (keyfile.load_from_file (config_file, KeyFileFlags.NONE)
&& keyfile.has_group ("CatalogPlugin")) {
if (keyfile.has_key ("CatalogPlugin", "HiddenSources")) {
hidden_sources = keyfile.get_string ("CatalogPlugin", "HiddenSources");
}
}
} catch (Error e) {
if (!(e is KeyFileError.NOT_FOUND))
stdout.printf ("Error loading configuration: %s\n", e.message);
}
sqlite = new CatalogSqlite (filename);
sources = new List ();
var source = new CatalogSource ("Collection", _("Collection"), _("Personal movie list"), sqlite, !("Collection" in hidden_sources));
sources.append (source);
source = new CatalogSource ("Loaned", _("Loaned movies"), _("Movies loaned to friends"), sqlite, !("Loaned" in hidden_sources));
sources.append (source);
source = new CatalogSource ("Watched", _("Watched movies"), _("Watched / rated movies"), sqlite, !("Watched" in hidden_sources));
sources.append (source);
source = new CatalogSource ("Watchlist", _("Watchlist"), _("Movies of interest"), sqlite, !("Watchlist" in hidden_sources));
sources.append (source);
stdout.printf ("Catalog Plugin Loaded.\n");
}
public override unowned List get_sources () {
return (List) sources;
}
public override List get_actions (Movie movie, Gtk.Window window) {
var list = new List ();
list.append (new MovieAction (_("Add to catalog"), on_add_to_catalog, movie, window));
return list;
}
private void on_add_to_catalog (Movie movie, Gtk.Window window) {
dialog = new Gtk.Dialog ();
dialog.set_transient_for (window);
dialog.set_title (_("Add movie to catalog - Select list"));
int i = 0;
var available_sources = new List ();
foreach (CatalogSource s in sources) {
if (!s.contains (movie)) {
available_sources.append ((MovieSource) s);
i++;
}
}
var source_list = new SourceListView (available_sources, true, window);
var content = (VBox) dialog.get_content_area ();
content.pack_start (source_list, true, true, 0);
if (i > 5)
i = 5;
content.set_size_request (-1, i*70);
// Connect signals
source_list.source_activated.connect (on_source_activated);
dialog.show_all ();
int res = dialog.run ();
if (res >= 0) {
var source = sources.nth_data (res);
if (source.table == "Loaned") {
var dialog = new Gtk.Dialog ();
dialog.set_title (_("Add to loaned movies"));
var contact = new Hildon.Entry (SizeType.FINGER_HEIGHT);
contact.set_placeholder ("Contact");
var date = new Hildon.DateButton (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL);
date.set_title (_("Loaned on"));
date.set_alignment (0.0f, 0.5f, 1.0f, 1.0f);
content = (Gtk.VBox) dialog.get_content_area ();
content.pack_start (contact, true, false, 0);
content.pack_start (date, true, false, 0);
dialog.add_button (_("Done"), Gtk.ResponseType.OK);
dialog.show_all ();
res = dialog.run ();
dialog.destroy ();
if (res == Gtk.ResponseType.OK) {
source.add_movie (movie);
var banner = (Banner) Banner.show_information_with_markup (window, null, _("'%s' added to list of loaned movies").printf (movie.title, source.get_name ()));
banner.set_timeout (1500);
}
} else if (source.table == "Watched") {
var dialog = new Gtk.Dialog ();
dialog.set_title (_("Add to watched movies"));
var rating = new RatingWidget ();
var date = new Hildon.DateButton (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL);
date.set_title (_("Watched on"));
date.set_alignment (0.0f, 0.5f, 1.0f, 1.0f);
content = (Gtk.VBox) dialog.get_content_area ();
content.pack_start (rating, true, false, 0);
content.pack_start (date, true, false, 0);
dialog.add_button (_("Done"), Gtk.ResponseType.OK);
dialog.show_all ();
res = dialog.run ();
dialog.destroy ();
if (res == Gtk.ResponseType.OK) {
if (rating.get_rating () > 0)
movie.rating = 10 * rating.get_rating ();
source.add_movie (movie);
var banner = (Banner) Banner.show_information_with_markup (window, null, _("'%s' added to list of watched movies").printf (movie.title, source.get_name ()));
banner.set_timeout (1500);
}
} else {
source.add_movie (movie);
var banner = (Banner) Banner.show_information_with_markup (window, null, _("'%s' added to list '%s'").printf (movie.title, source.get_name ()));
banner.set_timeout (1500);
}
}
dialog.destroy ();
dialog = null;
}
private void on_source_activated (MovieSource source) {
int n = sources.index ((CatalogSource) source);
dialog.response (n);
}
public override void settings_dialog (Gtk.Window window) {
var dialog = new Gtk.Dialog ();
dialog.set_transient_for (window);
dialog.set_title (_("Catalog plugin settings"));
var button = new Hildon.Button (SizeType.FINGER_HEIGHT, ButtonArrangement.VERTICAL);
button.set_title (_("Select active movie lists"));
button.set_value (active_sources_text ());
button.set_style (ButtonStyle.PICKER);
var content = (VBox) dialog.get_content_area ();
content.pack_start (button, true, true, 0);
dialog.add_button (_("Done"), ResponseType.ACCEPT);
// Connect signals
button.clicked.connect (() => { on_select_active_lists (button, window); });
dialog.show_all ();
int res = dialog.run ();
if (res == ResponseType.ACCEPT) {
}
dialog.destroy ();
}
private void on_select_active_lists (Hildon.Button button, Gtk.Window window) {
dialog = new Gtk.Dialog ();
dialog.set_transient_for (window);
dialog.set_title (_("Select active movie lists"));
var source_list = new SourceListView (sources, false, window);
source_list.set_hildon_ui_mode (UIMode.EDIT);
var selection = source_list.get_selection ();
foreach (CatalogSource s in sources) {
var iter = TreeIter ();
if (s.active && source_list.get_iter (s, out iter)) {
selection.select_iter (iter);
}
}
var content = (VBox) dialog.get_content_area ();
content.pack_start (source_list, true, true, 0);
var i = sources.length ();
if (i > 5)
i = 5;
content.set_size_request (-1, (int) i*70);
dialog.add_button (_("Done"), ResponseType.ACCEPT);
dialog.show_all ();
int res = dialog.run ();
if (res == ResponseType.ACCEPT) {
foreach (CatalogSource s in sources) {
TreeIter iter;
if (source_list.get_iter (s, out iter)) {
s.active = selection.iter_is_selected (iter);
}
}
var config_file = Path.build_filename (Environment.get_user_config_dir (), "cinaest", "cinaest.cfg");
var keyfile = new KeyFile ();
try {
keyfile.load_from_file (config_file, KeyFileFlags.NONE);
} catch (Error e) {
if (!(e is KeyFileError.NOT_FOUND))
stdout.printf ("Error loading configuration: %s\n", e.message);
}
keyfile.set_string ("CatalogPlugin", "HiddenSources", hidden_sources_list ());
try {
var file = File.new_for_path (config_file + ".part");
var stream = file.create (FileCreateFlags.REPLACE_DESTINATION, null);
var data = keyfile.to_data ();
stream.write (data, data.length, null);
FileUtils.rename (config_file + ".part", config_file);
} catch (Error e) {
stdout.printf ("Failed to store configuration: %s\n", e.message);
}
button.set_value (active_sources_text ());
}
dialog.destroy ();
dialog = null;
}
private string active_sources_text () {
string text = null;
foreach (CatalogSource s in sources) {
if (s.active) {
if (text == null) {
text = s.get_name ();
} else {
text += ", " + s.get_name ();
}
}
}
return text;
}
private string hidden_sources_list () {
string list = "";
foreach (CatalogSource s in sources) {
if (!s.active) {
if (list == "") {
list = s.table;
} else {
list += ", " + s.table;
}
}
}
return list;
}
public override unowned string get_name () {
return _("Catalog");
}
}
class CatalogSource : MovieSource {
internal string table;
private string name;
private string description;
private CatalogSqlite sqlite;
public CatalogSource (string _table, string _name, string _description, CatalogSqlite _sqlite, bool _active) {
GLib.Object (active: _active);
table = _table;
name = _name;
description = _description;
sqlite = _sqlite;
}
public override bool active { get; set construct; }
public override async int get_movies (MovieFilter filter, MovieSource.ReceiveMovieFunction callback, int limit, Cancellable? cancellable) {
int n = yield sqlite.query (table, filter, callback, limit, cancellable);
return n;
}
public override void add_movie (Movie movie) {
sqlite.add_movie (table, movie);
}
public override void delete_movie (Movie movie) {
sqlite.delete_movie (table, movie);
}
internal bool contains (Movie movie) {
return sqlite.contains (table, movie);
}
public override unowned string get_name () {
return name;
}
public override unowned string get_description () {
return description;
}
public override bool get_editable () {
return true;
}
}
[ModuleInit]
public Type register_plugin (TypeModule module) {
// types are registered automatically
return typeof (CatalogPlugin);
}