Gtk2-Ex-ICal-Recur
view release on metacpan or search on metacpan
lib/Gtk2/Ex/ICal/Recur.pm view on Meta::CPAN
package Gtk2::Ex::ICal::Recur;
our $VERSION = '0.06';
use strict;
use warnings;
use Gtk2 '-init';
use Gtk2::Ex::Simple::Menu;
use Gtk2::Ex::Simple::List;
use Glib qw /TRUE FALSE/;
use Data::Dumper;
use Gtk2::Ex::ICal::Recur::Selection;
use DateTime::Event::ICal;
use Gtk2::Ex::CalendarButton;
###########################################################
# There are four public methods. The rest are all private #
###########################################################
sub new {
my ($class) = @_;
my $self = {};
$self->{freqspinbutton} = Gtk2::SpinButton->new_with_range(1,100,1);
$self->{freqcombobox} = Gtk2::ComboBox->new_text();
$self->{recurrencepatterntable} = Gtk2::Table->new(1,1,FALSE);
$self->{recurbox}->{hbox} = undef;
$self->{recurbox}->{buttons} = undef;
$self->{freqchoices} = [
{ 'label' => 'Year(s)' , 'code' => 'yearly' },
{ 'label' => 'Month(s)', 'code' => 'monthly' },
{ 'label' => 'Week(s)' , 'code' => 'weekly' },
{ 'label' => 'Day(s)' , 'code' => 'daily' },
];
$self->{exceptionslist} = undef;
$self->{icalselection} = Gtk2::Ex::ICal::Recur::Selection->new;
bless ($self, $class);
$self->{widget} = $self->package_all;
return $self;
}
sub update_preview {
my ($self) = @_;
my $temp = [
['Generating Preview'],
['Please wait...'],
];
my $none= [
['No dates matching'],
['your criteria...'],
];
@{$self->{preview}->{slist}->{data}} = @$temp;
$self->{preview}->{slist}->show_all;
$self->{model} = $self->get_model;
my $date_list = $self->generate_date_list($self->{model});
if ($#{@$date_list} >= 0) {
@{$self->{preview}->{slist}->{data}} = @$date_list;
} else {
@{$self->{preview}->{slist}->{data}} = @$none;
}
}
sub set_model {
my ($self, $model) = @_;
$self->{model} = $model;
$self->{recurbox}->{hbox} = undef;
my $temphash = $self->controller(0, 0);
$self->{recurbox}->{hbox}->[0]->[0] = $self->create_box(0,0,$temphash);
$self->packbox();
$self->{freqspinbutton}->set_value($model->{interval});
my $mapped = { 'yearly' => 0, 'monthly' => 1, 'weekly' => 2, 'daily' => 3 };
$self->{freqcombobox}->set_active($mapped->{$model->{freq}});
if ($model->{freq} eq 'yearly') {
if ($model->{bymonth}) {
$self->set_month_of_the_year($model, 0);
if ($model->{bymonthday}) {
$self->set_month_day_by_day($model, 1);
} elsif ($model->{byday}) {
$self->set_month_day_by_week($model, 1);
}
} elsif ($model->{byyearday}) {
$self->set_day_of_the_year($model, 0);
} elsif ($model->{byweekno}) {
$self->set_weeknumber_of_the_year($model, 0);
if ($model->{byday}) {
$self->set_week_day($model, 1);
}
}
} elsif ($model->{freq} eq 'monthly') {
if ($model->{bymonthday}) {
$self->set_month_day_by_day($model, 0);
} elsif ($model->{byday}) {
$self->set_month_day_by_week($model, 0);
}
} elsif ($model->{freq} eq 'weekly') {
if ($model->{byday}) {
$self->set_week_day($model, 0);
}
} elsif ($model->{freq} eq 'daily') {
# Save this for hourly
}
if ($model->{dtstart}) {
$self->{'dtstart'} = $model->{'dtstart'};
$self->{duration}->{dtstart}->set_date(
_transform_date($model->{dtstart})
);
}
if ($model->{dtend}) {
$self->{'dtend'} = $model->{'dtend'};
$self->{duration}->{dtend}->set_date(
_transform_date($model->{dtend})
);
$self->{duration}->{end_on_radio}->set_active(TRUE);
} elsif ($model->{count}) {
$self->{duration}->{count}->set_value($model->{count});
$self->{duration}->{end_after_radio}->set_active(TRUE);
}
}
sub _transform_date {
my ($datehash) = @_;
my $datearray = [
$datehash->{year},
$datehash->{month},
$datehash->{day},
];
return $datearray;
}
sub get_model {
my ($self) = @_;
my $model;
my $freqcombochoice = $self->{freqchoices}->[$self->{freqcombobox}->get_active()]->{'code'};
$model->{freq} = $freqcombochoice;
$model->{interval} = $self->{freqspinbutton}->get_value;
foreach my $level (@{$self->{recurbox}->{buttons}}) {
my $i = 0;
foreach my $count (@$level) {
my $type = $count->{type};
my $code = $count->{code};
$model->{$type}->[$i++] = $code;
}
}
$model->{'dtstart'} = $self->{'dtstart'};
if ($self->{duration}->{end_on_radio}->get_active) {
$model->{'dtend'} = $self->{'dtend'} if $self->{'dtend'};
} else {
$model->{'count'} = $self->{duration}->{'count'}->get_value if $self->{duration}->{'count'};
}
my @temp = @{$self->{exceptionslist}->{data}};
my @exceptions = ();
foreach my $x (@temp) {
my ($mon, $day, $junk, $year) = split /\W/, $x->[0];
my $monthlist = month();
my $i = 0;
my %hash = map {$_ => $i++} @$monthlist;
my $date = { month => $hash{$mon}, day => $day, year => $year};
push @exceptions, $date;
}
$model->{exceptions} = \@exceptions;
$self->{model} = $model;
return $model;
}
##############################################
# All methods below this are private methods #
##############################################
sub generate_date_list {
my ($self, $origmodel) = @_;
my $model;
my @list;
$model->{dtstart} = hash_to_datetime($origmodel->{dtstart}) if ($origmodel->{dtstart});
$model->{dtend} = hash_to_datetime($origmodel->{dtend}) if ($origmodel->{dtend});
$model->{count} = $origmodel->{count} if ($origmodel->{count});
$model->{freq} = $origmodel->{freq} if ($origmodel->{freq});
$model->{interval} = $origmodel->{interval} if ($origmodel->{interval});
$model->{byday} = $origmodel->{byday} if ($origmodel->{byday});
$model->{byyearday} = $origmodel->{byyearday} if ($origmodel->{byyearday});
$model->{bymonthday} = $origmodel->{bymonthday} if ($origmodel->{bymonthday});
$model->{byweekno} = $origmodel->{byweekno} if ($origmodel->{byweekno});
$model->{bymonth} = $origmodel->{bymonth} if ($origmodel->{bymonth});
my $set = DateTime::Event::ICal->recur(%$model);
my $iter = $set->iterator;
my $exceptions = $self->{model}->{exceptions};
my $hash;
foreach my $x (@$exceptions) {
my $year = $x->{year};
my $mon = $x->{month};
my $day= $x->{day};
$hash->{"$year\-$mon\-$day"} = 1;
}
my $i = 0;
lib/Gtk2/Ex/ICal/Recur.pm view on Meta::CPAN
}
);
my $hbox = Gtk2::HBox->new;
$hbox->pack_start($ok, TRUE, TRUE, 0);
$hbox->pack_start($cancel, TRUE, TRUE, 0);
$vbox->pack_start($cal, TRUE, TRUE, 0);
$vbox->pack_start($hbox, TRUE, TRUE, 0);
$calwindow->add($vbox);
$calwindow->set_position('mouse');
$calwindow->show_all;
}
);
$removebutton->signal_connect('button-release-event' =>
sub {
my @sel = $slist->get_selected_indices;
my @temp = @{$slist->{data}};
my @newlist;
my %hash = map { $_ => 1 } @sel;
for (my $i=0; $i<=$#temp; $i++) {
push @newlist, [$temp[$i]->[0]] unless $hash{$i};
}
@{$slist->{data}} = ();
foreach my $x (@newlist) {
push @{$slist->{data}}, $x;
}
}
);
$buttonbox->pack_start($addbutton, TRUE, TRUE, 0);
$buttonbox->pack_start($removebutton, TRUE, TRUE, 0);
my $vbox = Gtk2::VBox->new;
my $scroll = Gtk2::ScrolledWindow->new;
$scroll->set_policy('never','automatic');
$scroll->add($slist);
$self->{exceptionslist} = $slist;
$vbox->pack_start($scroll, TRUE, TRUE, 0);
$vbox->pack_start($buttonbox, FALSE, FALSE, 0);
return $vbox;
}
sub month {
return [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
];
}
sub get_widget {
my ($self) = @_;
foreach my $choice (@{$self->{freqchoices}}) {
$self->{freqcombobox}->append_text($choice->{'label'});
}
my $freqhbox = Gtk2::HBox->new(FALSE);
$freqhbox->pack_start(Gtk2::Label->new('Occurs every'), FALSE, FALSE, 0);
$freqhbox->pack_start($self->{freqspinbutton}, FALSE, FALSE, 0);
$freqhbox->pack_start($self->{freqcombobox}, FALSE, FALSE, 0);
$self->{freqcombobox}->signal_connect('changed' =>
sub {
$self->{recurbox}->{hbox} = undef;
$self->{recurbox}->{buttons} = undef;
my $temphash = $self->controller(0, 0);
$self->{recurbox}->{hbox}->[0]->[0] = $self->create_box(0,0,$temphash);
$self->packbox();
}
);
my $scroll = Gtk2::ScrolledWindow->new;
$scroll->add_with_viewport($self->{recurrencepatterntable});
$scroll->set_policy('never', 'automatic');
$self->{recurrencepatterntable}->set_col_spacings(1);
$self->{recurrencepatterntable}->set_row_spacings(1);
my $vbox = Gtk2::VBox->new(FALSE, 5);
$vbox->pack_start($freqhbox, FALSE, FALSE, 0);
$vbox->pack_start($scroll, TRUE, TRUE, 0);
return $vbox;
}
sub set_month_of_the_year {
my ($self, $model, $level) = @_;
my @months = @{$model->{bymonth}};
my $list = $self->{icalselection}->month_of_the_year();
my $hash;
for (my $i=0; $i<=$#{@$list}; $i+=2) {
my $x = $list->[$i+1]->{callback_data};
$hash->{$x->[2]} = $x->[1];
}
$self->update_ui_from_model(\@months, $hash, '/^/by month of the year/', $level);
}
sub set_day_of_the_year {
my ($self, $model, $level) = @_;
my @yeardays = @{$model->{byyearday}};
my $list = $self->{icalselection}->day_of_the_year();
my $hash;
for (my $i=0; $i<=$#{@$list}; $i+=2) {
my $x = $list->[$i+1]->{children};
for (my $j=0; $j<=$#{@$x}; $j+=2) {
my $y = $x->[$j+1]->{callback_data};
$hash->{$y->[2]} = $list->[$i].'/'.$y->[1];
}
}
$self->update_ui_from_model(\@yeardays, $hash, '/^/by day of the year/', $level);
}
sub set_weeknumber_of_the_year {
my ($self, $model, $level) = @_;
my @weeknums = @{$model->{byweekno}};
my $list = $self->{icalselection}->weeknumber_of_the_year();
my $hash;
for (my $i=0; $i<=$#{@$list}; $i+=2) {
my $x = $list->[$i+1]->{children};
for (my $j=0; $j<=$#{@$x}; $j+=2) {
my $y = $x->[$j+1]->{callback_data};
$hash->{$y->[2]} = $list->[$i].'/'.$y->[1];
}
}
lib/Gtk2/Ex/ICal/Recur.pm view on Meta::CPAN
my @weekdays = @{$model->{byday}};
my $list = $self->{icalselection}->week_day();
my $hash;
for (my $i=0; $i<=$#{@$list}; $i+=2) {
my $x = $list->[$i+1]->{callback_data};
$hash->{$x->[2]} = $x->[1];
}
$self->update_ui_from_model(\@weekdays, $hash, '/^/', $level);
}
sub set_month_day_by_day {
my ($self, $model, $level) = @_;
my @monthdays = @{$model->{bymonthday}};
my $list = $self->{icalselection}->month_day_by_day();
my $hash;
for (my $i=0; $i<=$#{@$list}; $i+=2) {
my $x = $list->[$i+1]->{children};
for (my $j=0; $j<=$#{@$x}; $j+=2) {
my $y = $x->[$j+1]->{callback_data};
$hash->{$y->[2]} = $list->[$i].'/'.$y->[1];
}
}
$self->update_ui_from_model(\@monthdays, $hash, '/^/by day/', $level);
}
sub set_month_day_by_week {
my ($self, $model, $level) = @_;
my @monthdays = @{$model->{byday}};
my $list = $self->{icalselection}->month_day_by_week();
my $hash;
for (my $i=0; $i<=$#{@$list}; $i+=2) {
my $x = $list->[$i+1]->{children};
for (my $j=0; $j<=$#{@$x}; $j+=2) {
my $y = $x->[$j+1]->{callback_data};
$hash->{$y->[2]} = $list->[$i].'/'.$y->[1];
}
}
$self->update_ui_from_model(\@monthdays, $hash, '/^/by week day/', $level);
}
sub update_ui_from_model {
my ($self, $list, $hash, $string, $level) = @_;
for (my $i=0; $i<=$#{@$list}; $i++) {
$self->{recurbox}->{buttons}->[$level]->[$i]->{simplemenu}->get_widget($string.$hash->{$list->[$i]})->activate;
$self->{recurbox}->{buttons}->[$level]->[$i]->{next}->set_sensitive(FALSE);
if ($i<$#{@$list}) {
$self->addbuttonclicked($level, $i);
$self->{recurbox}->{buttons}->[$level]->[$i]->{add}->set_sensitive(FALSE);
$self->{recurbox}->{buttons}->[$level]->[$i]->{remove}->set_sensitive(FALSE);
} else {
$self->nextbuttonclicked($level, $i);
}
}
}
sub controller {
my ($self, $level, $count) = @_;
my $temphash = undef;
if ($level == 0) {
my $freqcombochoice = $self->{freqchoices}->[$self->{freqcombobox}->get_active()]->{'code'};
if ($freqcombochoice eq 'yearly') {
$temphash = $self->month_or_day_of_the_year($level,$count);
} elsif ($freqcombochoice eq 'monthly') {
$temphash = $self->day_of_the_month($level,$count);
} elsif ($freqcombochoice eq 'weekly') {
$temphash = $self->day_of_the_week($level,$count);
} elsif ($freqcombochoice eq 'daily') {
}
} elsif ($level == 1) {
my $parent = $self->{recurbox}->{buttons}->[$level-1]->[0]->{type};
if ($parent eq 'bymonth') {
$temphash = $self->day_of_the_month($level,$count);
} elsif ($parent eq 'byyearday') {
} elsif ($parent eq 'byweekno') {
$temphash = $self->day_of_the_week($level,$count);
}
}
if (!$temphash) {
# print "controller called with $level $count Un-implemented\n";
}
return $temphash;
}
sub packbox {
my ($self) = @_;
my $rows = 0;
foreach my $level (@{$self->{recurbox}->{hbox}}) {
foreach my $count (@$level) {
$rows++ if ($count);
}
}
# First I will clear the contents of the $table
my @children = $self->{recurrencepatterntable}->get_children;
foreach my $child (@children) {
$self->{recurrencepatterntable}->remove($child);
}
# Now I will resize the table
$self->{recurrencepatterntable}->resize($rows,5) if ($rows > 0);
my $row = 0;
foreach my $level (@{$self->{recurbox}->{hbox}}) {
foreach my $count (@$level) {
my $col = 0;
foreach my $widget (@$count) {
if ($widget) {
$self->{recurrencepatterntable}->attach($widget, $col, $col+1, $row, $row+1, 'fill', 'fill', 0, 0) ;
$col++;
}
}
$row++;
}
}
$self->{recurrencepatterntable}->show_all;
}
sub create_box {
my ($self, $level, $count, $temphash) = @_;
return undef unless $temphash;
( run in 0.961 second using v1.01-cache-2.11-cpan-8dfa8b56332 )