summaryrefslogtreecommitdiff
path: root/lib/gcstar/GCGenres.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gcstar/GCGenres.pm')
-rw-r--r--lib/gcstar/GCGenres.pm404
1 files changed, 404 insertions, 0 deletions
diff --git a/lib/gcstar/GCGenres.pm b/lib/gcstar/GCGenres.pm
new file mode 100644
index 0000000..8f89e24
--- /dev/null
+++ b/lib/gcstar/GCGenres.pm
@@ -0,0 +1,404 @@
+package GCGenres;
+
+###################################################
+#
+# Copyright 2005-2010 Christian Jodar
+#
+# This file is part of GCstar.
+#
+# GCstar 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 2 of the License, or
+# (at your option) any later version.
+#
+# GCstar 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 GCstar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+#
+###################################################
+
+use strict;
+use Gtk2;
+
+{
+ package GCGenresGroupsDialog;
+ use base "Gtk2::Dialog";
+ use utf8;
+
+ sub initValues
+ {
+ use locale;
+
+ my $self = shift;
+ my $keepPrevious = shift;
+
+ my %directory;
+
+ if ($keepPrevious)
+ {
+ foreach my $line(@{$self->{categories}->{data}})
+ {
+ $directory{$line->[0]} = $line->[1];
+ }
+ }
+ else
+ {
+ foreach (keys %{$self->{convertor}->{groups}})
+ {
+ $directory{$_} = join ',', @{$self->{convertor}->{groups}->{$_}};
+ }
+ }
+
+ @{$self->{categories}->{data}} = ();
+
+ my @keys = sort keys %directory;
+ @keys = reverse @keys if $self->{reverse};
+ foreach (@keys)
+ {
+ my @infos = [$_, $directory{$_}];
+ push @{$self->{categories}->{data}}, @infos;
+ }
+ $self->{categories}->select(0);
+
+ }
+
+ sub generateString
+ {
+ my $self = shift;
+ my $genresString;
+
+ foreach (@{$self->{categories}->{data}})
+ {
+ $genresString .= $_->[0];
+ $genresString .= '|'.$_->[1].';';
+ }
+ $genresString =~ s/.$//;
+ return $genresString;
+ }
+
+ sub saveValues
+ {
+ my $self = shift;
+
+ my $genresString = $self->generateString;
+
+ $self->{options}->genres($genresString);
+ $self->{convertor}->loadValues;
+ $self->{options}->save;
+ }
+
+ sub show
+ {
+ my $self = shift;
+
+ $self->initValues;
+
+ $self->SUPER::show();
+ $self->show_all;
+
+ if ($self->run eq 'ok')
+ {
+ $self->saveValues;
+ }
+ $self->hide;
+ }
+
+ sub removeCurrent
+ {
+ my $self = shift;
+ my @idx = $self->{categories}->get_selected_indices;
+
+ splice @{$self->{categories}->{data}}, $idx[0], 1;
+
+ $self->{categories}->select((($idx[0] - 1) > 0) ? ($idx[0] - 1) : 0);
+ }
+
+ sub add
+ {
+ my $self = shift;
+
+ unshift @{$self->{categories}->{data}}, ['',''];
+ }
+
+ sub editCurrent
+ {
+ my $self = shift;
+
+ my @idxtmp = $self->{categories}->get_selected_indices;
+ my $idx = $idxtmp[0];
+ my $line = $self->{categories}->{data}->[$idx];
+
+ my $dialog = new Gtk2::Dialog($self->{parent}->{lang}->{GenresModify},
+ $self,
+ [qw/modal destroy-with-parent/],
+ @GCDialogs::okCancelButtons
+ );
+
+ my $table = new Gtk2::Table(3,2,0);
+
+ my $labelCategory = new Gtk2::Label($self->{parent}->{lang}->{GenresCategoryName});
+ $table->attach($labelCategory, 0, 1, 0, 1, 'fill', 'fill', 5, 5);
+ my $category = new Gtk2::Entry;
+ $category->set_text($line->[0]);
+ my $hbox1 = new Gtk2::HBox(0,0);
+ $hbox1->pack_start($category,1,1,0);
+ $table->attach($hbox1, 1, 2, 0, 1, 'fill', 'fill', 5, 5);
+
+ my $labelMembers = new Gtk2::Label($self->{parent}->{lang}->{GenresCategoryMembers});
+ $table->attach($labelMembers, 0, 1, 1, 2, 'fill', 'fill', 5, 5);
+ my $members = new Gtk2::Entry;
+ $members->set_text($line->[1]);
+ my $hbox2 = new Gtk2::HBox(0,0);
+ $hbox2->pack_start($members,1,1,0);
+ $table->attach($hbox2, 1, 2, 1, 2, 'fill', 'fill', 5, 5);
+
+ my $labelFoo = new Gtk2::Label('');
+ my $labelBar = new Gtk2::Label('');
+ $table->attach($labelFoo, 0, 1, 2, 3, 'fill', 'fill', 0, 0);
+ $table->attach($labelBar, 1, 2, 2, 3, 'expand', 'expand', 0, 0);
+
+ $dialog->set_default_size(500,1);
+
+ $dialog->vbox->pack_start($table,1,1,0);
+ $dialog->vbox->show_all;
+
+ if ($dialog->run eq 'ok')
+ {
+ splice @{$self->{categories}->{data}}, $idx, 1, [$category->get_text, $members->get_text];
+ }
+
+ $dialog->destroy;
+ }
+
+ sub load
+ {
+ my $self = shift;
+
+ my $response = $self->{loadDialog}->run;
+ if ($response eq 'ok')
+ {
+ my $fileName = $self->{loadDialog}->get_filename;
+ $self->{convertor}->loadValues(undef, $fileName);
+ $self->initValues;
+ }
+ $self->{loadDialog}->hide;
+ }
+
+ sub export
+ {
+ my $self = shift;
+
+ my $response = $self->{exportDialog}->run;
+ if ($response eq 'ok')
+ {
+ my $fileName = $self->{exportDialog}->get_filename;
+ $self->{convertor}->saveValues($self->generateString, $fileName);
+ $self->initValues;
+ }
+ $self->{exportDialog}->hide;
+ }
+
+ sub clear
+ {
+ my $self = shift;
+ @{$self->{categories}->{data}} = ();
+ }
+
+ sub sort
+ {
+ my $self = shift;
+
+ $self->{reverse} = 1 - $self->{reverse};
+
+ $self->{categories}->get_column(0)->set_sort_indicator(1);
+ $self->{categories}->get_column(0)->set_sort_order($self->{reverse} ? 'descending' : 'ascending');
+ $self->initValues(1);
+ }
+
+ sub new
+ {
+ my ($proto, $parent) = @_;
+ my $class = ref($proto) || $proto;
+ my $self = $class->SUPER::new($parent->{lang}->{GenresTitle},
+ $parent,
+ [qw/modal destroy-with-parent/],
+ @GCDialogs::okCancelButtons
+ );
+
+ bless ($self, $class);
+
+ $self->set_modal(1);
+ $self->set_position('center');
+ $self->set_default_size(600,400);
+
+ $self->{reverse} = 0;
+
+ $self->{parent} = $parent;
+ $self->{lang} = $parent->{lang};
+ $self->{options} = $parent->{options};
+
+ my $hbox = new Gtk2::HBox(0,0);
+
+ $self->{categories} = new Gtk2::SimpleList($parent->{lang}->{GenresCategoryName} => "text",
+ $parent->{lang}->{GenresCategoryMembers} => "text");
+ $self->{categories}->set_column_editable(0, 1);
+ $self->{categories}->set_column_editable(1, 1);
+ $self->{categories}->set_rules_hint(1);
+ $self->{categories}->get_column(0)->signal_connect('clicked' => sub {
+ $self->sort;
+ });
+ $self->{categories}->get_column(0)->set_sort_indicator(1);
+ $self->{categories}->get_column(0)->set_clickable(1);
+ for my $i (0..1)
+ {
+ $self->{categories}->get_column($i)->set_resizable(1);
+ }
+ $self->{order} = 1;
+ $self->{sort} = -1;
+
+ my $scrollPanelList = new Gtk2::ScrolledWindow;
+ $scrollPanelList->set_policy ('never', 'automatic');
+ $scrollPanelList->set_shadow_type('etched-in');
+ $scrollPanelList->add($self->{categories});
+
+ my $vboxButtons = new Gtk2::VBox(0,0);
+ my $addButton = Gtk2::Button->new_from_stock('gtk-add');
+ $addButton->signal_connect('clicked' => sub {
+ $self->add;
+ });
+ my $removeButton = Gtk2::Button->new_from_stock('gtk-remove');
+ $removeButton->signal_connect('clicked' => sub {
+ $self->removeCurrent;
+ });
+
+ my $clearButton = Gtk2::Button->new_from_stock('gtk-clear');
+ $clearButton->signal_connect('clicked' => sub {
+ $self->clear;
+ });
+
+ my $editButton = Gtk2::Button->new_from_stock('gtk-properties');
+ $editButton->signal_connect('clicked' => sub {
+ $self->editCurrent;
+ });
+ my $openButton = Gtk2::Button->new_from_stock('gtk-open');
+ $openButton->signal_connect('clicked' => sub {
+ $self->load;
+ });
+ my $exportButton = Gtk2::Button->new_from_stock('gtk-save-as');
+ $exportButton->signal_connect('clicked' => sub {
+ $self->export;
+ });
+
+ $vboxButtons->pack_start($addButton,0,0,5);
+ $vboxButtons->pack_start($removeButton,0,0,5);
+ $vboxButtons->pack_start($clearButton,0,0,5);
+ $vboxButtons->pack_start($editButton,0,0,5);
+ $vboxButtons->pack_start($openButton,0,0,5);
+ $vboxButtons->pack_start($exportButton,0,0,5);
+
+ $hbox->pack_start($scrollPanelList,1,1,10);
+ $hbox->pack_start($vboxButtons,0,0,10);
+
+ $self->vbox->pack_start($hbox,1,1,10);
+
+ $self->{convertor} = new GCGenresConvertor($self->{options});
+
+ $self->{loadDialog} = new GCFileChooserDialog($self->{lang}->{GenresLoad}, $self, 'open', 1);
+ $self->{loadDialog}->set_pattern_filter((['*.genres', '*.genres']));
+ $self->{loadDialog}->set_filename($ENV{GCS_SHARE_DIR}.'/genres/');
+
+ $self->{exportDialog} = new GCFileChooserDialog($self->{lang}->{GenresExport}, $self, 'save');
+
+ return $self;
+ }
+}
+
+{
+ package GCGenresConvertor;
+
+ sub new
+ {
+ my ($proto, $options) = @_;
+ my $class = ref($proto) || $proto;
+ my $self = {};
+ bless ($self, $class);
+
+ $self->{options} = $options;
+ $self->loadValues($options->genres);
+
+ return $self;
+ }
+
+ sub loadValues
+ {
+ my ($self, $values, $file) = @_;
+
+ $self->{groups} = {};
+ $self->{genres} = {};
+
+ my @groups;
+
+ if ($file)
+ {
+ open FG, "< $file" or return -1;
+ binmode( FG, ':utf8' );
+ foreach(<FG>)
+ {
+ chomp;
+ s/(.*?)\W*$/$1/;
+ push (@groups,$_);
+ }
+ close FG;
+ }
+ else
+ {
+ $values = $self->{options}->genres unless $values;
+ @groups = split /;/, $values;
+ }
+
+ foreach my $group(@groups)
+ {
+ my @details = split /\|/, $group;
+ my $groupName = $details[0];
+ my @groupList;
+ foreach my $genre(split /,/,$details[1])
+ {
+ push @groupList, $genre;
+ $self->{genres}->{uc $genre} = $groupName;
+ }
+ $self->{genres}->{uc $groupName} = $groupName;
+ $self->{groups}->{$groupName} = \@groupList;
+ }
+ }
+
+ sub saveValues
+ {
+ my ($self, $value, $file) = @_;
+
+ open FG, "> $file" or return -1;
+ my @values = split /;/, $value;
+
+ foreach (@values)
+ {
+ print FG "$_\n";
+ }
+ close FG;
+ }
+
+ sub convert
+ {
+ my ($self, $genre) = @_;
+
+ my $ucGenre = uc $genre;
+
+ return $genre if ! exists $self->{genres}->{$ucGenre};
+ return $self->{genres}->{$ucGenre};
+ }
+}
+
+1;