diff options
Diffstat (limited to 'lib/gcstar/GCBorrowings.pm')
| -rw-r--r-- | lib/gcstar/GCBorrowings.pm | 662 | 
1 files changed, 662 insertions, 0 deletions
diff --git a/lib/gcstar/GCBorrowings.pm b/lib/gcstar/GCBorrowings.pm new file mode 100644 index 0000000..d93c444 --- /dev/null +++ b/lib/gcstar/GCBorrowings.pm @@ -0,0 +1,662 @@ +package GCBorrowings; + +################################################### +# +#  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 GCDialogs; +use GCUtils; + +{ +    package GCImportBorrowersDialog; +    use base 'GCModalDialog'; + +    use XML::Simple; + +    sub importClaws +    { +        my ($self, $file) = @_; +        my @result; +        open XML, $file; +        my $xmlString = do {local $/; <XML>}; +        close XML; +        my $xs = XML::Simple->new; +        my $addressBook = $xs->XMLin($xmlString, +                                     ForceArray => ['address', 'person'] +                                    ); +        foreach (@{$addressBook->{person}}) +        { +            push @result, [$_->{cn}, $_->{'address-list'}->{address}->[0]->{email}]; +        } +        return \@result; +    } + +    sub importLdif +    { +        my ($self, $file) = @_; +        my @result; +        open DATA, $file; +        my %current; +        while (<DATA>) +        { +            if (/^dn/) +            { +                push @result, [$current{name}, $current{email}] if %current; +                %current = {}; +            } +            $current{name} = $1 if (/^cn:\s*(.*)$/); +            $current{email} = $1 if (/^mail:\s*(.*)$/); +        } +        close DATA; +        push @result, [$current{name}, $current{email}] if %current; +        return \@result; +    } + +    sub importVcard +    { +        my ($self, $file) = @_; +        my @result; +        open DATA, $file; +        my %current; +        while (<DATA>) +        { +            push @result, [$current{name}, $current{email}] if /^END:VCARD/i; +            $current{name} = $1 if (/^FN:(.*)$/i); +            $current{email} = $1 if (/^EMAIL;INTERNET:(.*)$/); +        } +        close DATA; +        return \@result; +    } + +    sub show +    { +        my $self = shift; +        $self->SUPER::show(); +        $self->show_all; +        $self->set_position('center'); +        my $done = 0; +        my $code; +        while (!$done) +        { +            $code = $self->run; +            if ($code ne 'ok') +            { +                $done = 1; +            } +            else +            { +                my $type = $self->{type}->getValue; +                my $file = $self->{file}->getValue; +                if (!$file) +                { +                    my $dialog = Gtk2::MessageDialog->new($self, +                                                          [qw/modal destroy-with-parent/], +                                                          'error', +                                                          'ok', +                                                          $self->{parent}->{lang}->{ImportExportFileEmpty}); + +                    $dialog->set_position('center-on-parent'); +                    $dialog->run(); +                    $dialog->destroy; +                    next; +                } +                if ($type eq 'claws') +                { +                    $self->{borrowers} = $self->importClaws($file); +                } +                elsif ($type eq 'ldif') +                { +                    $self->{borrowers} = $self->importLdif($file); +                } +                elsif ($type eq 'vcard') +                { +                    $self->{borrowers} = $self->importVcard($file); +                } +                $done = 1; +            } +        } +        $self->hide; +        return ($code eq 'ok'); +    } + +    sub getBorrowers +    { +        my $self = shift; +        return $self->{borrowers}; +    } + +    sub new +    { +        my ($proto, $parent) = @_; +        my $class = ref($proto) || $proto; +        my $self  = $class->SUPER::new($parent, +                                       $parent->{lang}->{BorrowersImportTitle}, +                                       'gtk-convert' +                                      ); +        bless ($self, $class); +        $self->{parent} = $parent; +        $self->{lang} = $parent->{lang}; + +        my $table = new Gtk2::Table(2,2,0); +        $table->set_row_spacings($GCUtils::halfMargin); +        $table->set_col_spacings($GCUtils::halfMargin); +        $table->set_border_width($GCUtils::margin); + +        my $typeLabel = new GCLabel($parent->{lang}->{BorrowersImportType}); +        $self->{type} = new GCMenuList; +        $self->{type}->setValues([ +            {value => 'ldif', displayed => 'LDIF'}, +            {value => 'claws', displayed => 'Claws Mail'}, +            {value => 'vcard', displayed => 'VCARD'}, +        ]); +        my $fileLabel = new GCLabel($parent->{lang}->{BorrowersImportFile}); +        $self->{file} = new GCFile($self); + +        $table->attach($typeLabel, 0, 1, 0, 1, 'fill', 'fill', 0, 0); +        $table->attach($self->{type}, 1, 2, 0, 1, ['expand', 'fill'], 'fill', 0, 0); +        $table->attach($fileLabel, 0, 1, 1, 2, 'fill', 'fill', 0, 0); +        $table->attach($self->{file}, 1, 2, 1, 2, ['expand', 'fill'], 'fill', 0, 0); + +        $self->vbox->pack_start($table, 1, 1, 0); + +        return $self; +    } +} + +{ +    package GCBorrowersDialog; +    use base 'GCModalDialog'; + +    sub initValues +    { +        use locale; +         +        my $self = shift; +        my $keepPrevious = shift; + +        my @borrowers; +        my @emails; + +        if ($keepPrevious) +        { +            foreach my $line(@{$self->{people}->{data}}) +            { +                push @borrowers, $line->[0]; +                push @emails, $line->[1]; +            } +        } +        else +        { +            @borrowers = split m/\|/, $self->{options}->borrowers; +            @emails = split m/\|/, $self->{options}->emails; +        } +         +        @{$self->{people}->{data}} = (); +        my %directory; +         +        for (my $i = 0; $i < scalar(@borrowers); $i++) +        { +            $directory{$borrowers[$i]} = $emails[$i]; +        } +         +        my @keys = sort keys %directory; +        @keys = reverse @keys if $self->{reverse}; +        foreach (@keys) +        { +            my @infos = [$_, $directory{$_}]; +            push @{$self->{people}->{data}}, @infos; +        } +        $self->{people}->select(0); +         +        (my $template = $self->{options}->template) =~ s|<br/>|\n|g; +        $self->{mailTemplate}->setValue($template); +         +        $self->{subject}->set_text($self->{options}->subject); +   } +     +   sub saveValues +   { +        my $self = shift; +        +        my $borrowers = ''; +        my $emails = ''; +        foreach (@{$self->{people}->{data}}) +        { +            $borrowers .= $_->[0].'|'; +            $emails .= $_->[1].'|'; +        } +        $borrowers =~ s/.$//; +        $emails =~ s/.$//; +        $self->{options}->borrowers($borrowers); +        $self->{options}->emails($emails); +         +        (my $template = $self->{mailTemplate}->getValue) =~ s/\n/<br\/>/g; +        $self->{options}->template($template); +  +        $self->{options}->subject($self->{subject}->get_text); +         +        $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 importBorrowers +    { +        my $self = shift; +         +        $self->{importDialog} = new GCImportBorrowersDialog($self) +            if ! $self->{importDialog}; +             +        if ($self->{importDialog}->show) +        { +            unshift @{$self->{people}->{data}}, @{$self->{importDialog}->getBorrowers}; +        } +    } + +    sub removeCurrent +    { +        my $self = shift; +        my @idx = $self->{people}->get_selected_indices; +                 +        if ($^O =~ /win32/i) +        { +            my @newData; +            my $i = 0; +            foreach (@{$self->{people}->{data}}) +            { +                push @newData, [$_->[0], $_->[1]] if $i != $idx[0]; +                $i++; +            } +            @{$self->{people}->{data}} = @newData; +        } +        else +        { +            splice @{$self->{people}->{data}}, $idx[0], 1; +        } +    } +     +    sub add +    { +        my $self = shift; +         +        my $dialog = new Gtk2::Dialog($self->{parent}->{lang}->{BorrowersAdd}, +                                                        $self, +                                                        [qw/modal destroy-with-parent/], +                                                        @GCDialogs::okCancelButtons +                                                    ); +         +        my $table = new Gtk2::Table(2,2,0); +                                                     +        my $labelName = new Gtk2::Label($self->{parent}->{lang}->{BorrowersName}); +        $table->attach($labelName, 0, 1, 0, 1, 'expand', 'fill', 5, 5); +        my $name = new Gtk2::Entry; +        $name->signal_connect('activate' => sub {$dialog->response('ok')}); +        $table->attach($name, 1, 2, 0, 1, 'expand', 'fill', 5, 5); +  +        my $labelEmail = new Gtk2::Label($self->{parent}->{lang}->{BorrowersEmail}); +        $table->attach($labelEmail, 0, 1, 1, 2, 'expand', 'fill', 5, 5); +        my $email = new Gtk2::Entry; +        $email->signal_connect('activate' => sub {$dialog->response('ok')}); +        $table->attach($email, 1, 2, 1, 2, 'expand', 'fill', 5, 5); +        +        $dialog->vbox->pack_start($table,1,1,0); +        $dialog->vbox->show_all; +                                                     +        if ($dialog->run eq 'ok') +        { +            unshift @{$self->{people}->{data}}, [$name->get_text, $email->get_text]; +        } +         +        $dialog->destroy; +    } +     +    sub new +    { +        my ($proto, $parent) = @_; +        my $class = ref($proto) || $proto; +        my $self  = $class->SUPER::new($parent, +                                       $parent->{lang}->{BorrowersTitle}, +                                      ); + +        bless ($self, $class); +  +        #$self->set_modal(1); +		$self->set_position('center'); +        $self->set_default_size(400,400); + +        $self->{reverse} = 0; + +        $self->{parent} = $parent; +        $self->{lang} = $parent->{lang}; +        $self->{options} = $parent->{options}; + +        my $borrowersFrame = new GCGroup($self->{parent}->{lang}->{BorrowersList}); +        my $hbox = new Gtk2::HBox(0,0); +         +        $self->{people} = new Gtk2::SimpleList($parent->{lang}->{BorrowersName} => "text", +                                                $parent->{lang}->{BorrowersEmail} => "text"); +        $self->{people}->set_column_editable(1, 1); +        $self->{people}->set_rules_hint(1); + +        $self->{people}->get_column(0)->set_sort_column_id(0); +        $self->{people}->get_model->set_sort_column_id(0, 'ascending'); + +        for my $i (0..1) +        { +            $self->{people}->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->set_border_width(0); +        $scrollPanelList->add($self->{people}); +         +        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 $importButton = Gtk2::Button->new_from_stock('gtk-convert'); +        $importButton->signal_connect('clicked' => sub { +                $self->importBorrowers; +            }); +             +        #my $editButton = new Gtk2::Button($parent->{lang}->{BorrowersEdit}); +        $vboxButtons->pack_start($addButton,0,0,$GCUtils::halfMargin); +        $vboxButtons->pack_start($removeButton,0,0,$GCUtils::halfMargin); +        $vboxButtons->pack_start($importButton,0,0,$GCUtils::halfMargin); +        #$vboxButtons->pack_start($editButton,0,0,0); +        +        $hbox->pack_start($scrollPanelList,1,1,0); +        $hbox->pack_start($vboxButtons,0,0,$GCUtils::margin); +        $hbox->set_border_width(0); +        $borrowersFrame->addWidget($hbox); +        $self->vbox->pack_start($borrowersFrame,1,1,0); + +        my $templateFrame = new GCGroup($self->{parent}->{lang}->{BorrowersTemplate}); +        my $templateBox = new Gtk2::VBox(0,0); +        $templateFrame->addWidget($templateBox); + +        $self->{mailTemplate} = new GCLongText; +        $self->{mailTemplate}->set_size_request(-1,80); + +        my $hboxSubject = new Gtk2::HBox(0,0); +        my $labelSubject = new Gtk2::Label($self->{parent}->{lang}->{BorrowersSubject}); +        $self->{subject} = new Gtk2::Entry; +        $hboxSubject->pack_start($labelSubject,0,0,0); +        $hboxSubject->pack_start($self->{subject},0,0,$GCUtils::halfMargin); +         + +#        $templateBox->pack_start($labelTemplate,0,0,$GCUtils::halfMargin); +        $templateBox->pack_start($hboxSubject,0,0,0); +        $templateBox->pack_start($self->{mailTemplate},1,1,$GCUtils::halfMargin); +         +        my $label1 = new Gtk2::Label($self->{parent}->{lang}->{BorrowersNotice1}); +        $label1->set_alignment(0,0); +        my $label2 = new Gtk2::Label($self->{parent}->{lang}->{BorrowersNotice2}); +        $label2->set_alignment(0,0); +        my $label3 = new Gtk2::Label($self->{parent}->{lang}->{BorrowersNotice3}); +        $label3->set_alignment(0,0); +        $templateBox->pack_start($label1,0,0,0); +        $templateBox->pack_start($label2,0,0,0); +        $templateBox->pack_start($label3,0,0,0); +         +        $self->vbox->pack_start($templateFrame, 1, 1, 0); +         +        return $self; +    } +     +} + +{ +    package GCBorrowedDialog; +    use base "Gtk2::Dialog"; + +    sub setList +    { +        my ($self, $data, $model) = @_; + +        $self->setModel($model); +        my $items = $data->getItemsListFiltered; +        $self->{data} = $data; +  +        $self->{itemsList} = []; +        $self->{listModel}->clear; +        my ($listId, $dataId) = (-1, -1); +        foreach (@{$items}) +        { +            $dataId++; +            next if (!$_->{$self->{borrowerField}}) || ($_->{$self->{borrowerField}} eq 'none'); +            $listId++; +            my $borrower = $_->{$self->{borrowerField}}; +            $borrower = $self->{parent}->{model}->getDisplayedText('PanelUnknown') +                if $borrower eq 'unknown'; +            my $lendDate = GCUtils::timeToStr($_->{$self->{lendDateField}}, +                                              $self->{parent}->{options}->dateFormat); +            push @{$self->{itemsList}}, { +                $self->{titleField} => $_->{$self->{titleField}}, +                $self->{borrowerField} => $borrower, +                $self->{lendDateField} => $_->{$self->{lendDateField}} +            }; +            $self->{listModel}->set($self->{listModel}->append, +                                    0 => $_->{$self->{titleField}}, +                                    1 => $borrower, +                                    2 => $lendDate, +                                    3 => $listId, +                                    4 => $dataId); +        } +         +        $self->{listView}->columns_autosize; +        return if $listId == -1; +        $self->{listView}->get_selection->select_iter($self->{listModel}->get_iter_first); +    } +     +    sub show +    { +        my $self = shift; + +        $self->SUPER::show(); +        $self->show_all; +        $self->run; +        $self->hide; +    } + +    sub setModel +    { +        my ($self, $model) = @_; +        $self->{titleField} = $model->{commonFields}->{title}; +        $self->{borrowerField} = $model->{commonFields}->{borrower}->{name}; +        $self->{lendDateField} = $model->{commonFields}->{borrower}->{date}; +        $self->{historyField} = $model->{commonFields}->{borrower}->{history}; +  +        $self->{titleColumn}->set_title($model->getDisplayedItems); +    } + +    sub displayItem +    { +        my ($self, $idx) = @_; +        $self->{data}->display($idx); +        $self->{data}->select($idx); +    } + +    sub returnItem +    { +        my $self = shift; +        my $current = $self->{data}->getCurrent; +        my $iter = $self->{listView}->get_selection->get_selected; +        my $idx = $self->{listModel}->get($iter, 4); +        $self->displayItem($idx); +        if ($self->{data}->{panel}->itemBack) +        { +            $self->{listModel}->remove($iter); +        } +        $self->displayItem($current); +        return; +    } + +    sub showHistory +    { +        my $self = shift; +        my $iter = $self->{listView}->get_selection->get_selected; +        return if !$iter; +        my $idx = $self->{listModel}->get($iter, 4); +        $self->{history}->setValue( +            $self->{data}->getValue($idx, $self->{historyField}) +        ); +    } + +    sub new +    { +        my ($proto, $parent) = @_; +        my $class = ref($proto) || $proto; +        my $self  = $class->SUPER::new($parent->{lang}->{BorrowedTitle}, +                              $parent, +                              [qw/modal destroy-with-parent/], +                              'gtk-ok' => 'ok' +                            ); + +        bless ($self, $class); +         +        $self->{parent} = $parent; + +        $self->set_modal(1); +        $self->set_position('center'); +        $self->set_default_size(400,400); + +        $self->{parent} = $parent; +        $self->{options} = $parent->{options}; + +        my $hbox = new Gtk2::HBox(0,0); +         +        $self->{listModel} = new Gtk2::ListStore('Glib::String', 'Glib::String', 'Glib::String', +                                                 'Glib::Int', 'Glib::Int'); +        $self->{listView} = Gtk2::TreeView->new_with_model($self->{listModel}); +        $self->{listView}->set_rules_hint(1); +        $self->{listView}->set_headers_clickable(1); + +        my @columns; +        push @columns, Gtk2::TreeViewColumn->new_with_attributes('', +                                                                 Gtk2::CellRendererText->new,  +                                                                 'text' => 0); +        push @columns, Gtk2::TreeViewColumn->new_with_attributes($parent->{lang}->{PanelBorrower}, +                                                                 Gtk2::CellRendererText->new,  +                                                                 'text' => 1); +        push @columns, Gtk2::TreeViewColumn->new_with_attributes($parent->{lang}->{BorrowedDate}, +                                                                 Gtk2::CellRendererText->new,  +                                                                 'text' => 2); +        $self->{titleColumn} = $columns[0]; +        for my $i (0..2) +        { +            $columns[$i]->set_resizable(1); +            $columns[$i]->set_sort_column_id($i); +            $columns[$i]->set_reorderable(1); +            $self->{listView}->append_column($columns[$i]); +        } +        $self->{listModel}->set_sort_func(2, sub { +            my ($model, $a, $b) = @_; +            my ($day, $month, $year) = split m/\//,  +                $self->{itemsList}->[$model->get($a, 3)]->{$self->{lendDateField}}; +            my $dateA = join "_", $year, $month, $day; +            ($day, $month, $year) = split m/\//,  +                $self->{itemsList}->[$model->get($b, 3)]->{$self->{lendDateField}}; +            my $dateB = join "_", $year, $month, $day; +            return $dateA cmp $dateB; +             +        }); + +        $self->{listView}->get_selection->signal_connect ('changed' => sub { +            $self->showHistory; +        }); + +        my $scrollPanelList = new Gtk2::ScrolledWindow; +        $scrollPanelList->set_policy ('never', 'automatic'); +        $scrollPanelList->set_shadow_type('etched-in'); +        $scrollPanelList->set_border_width($GCUtils::margin); +        $scrollPanelList->add($self->{listView}); + +        $self->{context} = new Gtk2::Menu; +        $self->{returned} = Gtk2::MenuItem->new($parent->{lang}->{PanelReturned}); +        $self->{returned}->signal_connect('activate', sub { +            $self->returnItem; +        }); +        $self->{context}->append($self->{returned}); +        $self->{display} = Gtk2::MenuItem->new($parent->{lang}->{BorrowedDisplayInPanel}); +        $self->{display}->signal_connect('activate', sub { +            my $iter = $self->{listView}->get_selection->get_selected; +            my $idx = $self->{listModel}->get($iter, 4); +            $self->displayItem($idx); +        }); +        $self->{context}->append($self->{display}); +        $self->{context}->show_all; + +        $self->{listView}->signal_connect('button_press_event' => sub { +            my ($widget, $event) = @_; +            return 0 if $event->button ne 3; +            $self->{context}->popup(undef, undef, undef, undef, $event->button, $event->time); +            return 0; +        }); + +        my $historyExpander = new GCExpander($parent->{lang}->{PanelHistory}); +        $historyExpander->setValue($parent->{lang}->{PanelHistory}); + +        my @labels = ($parent->{lang}->{PanelBorrower}, +                      $parent->{lang}->{PanelLendDate}, +                      $parent->{lang}->{PanelReturnDate}); +        $self->{history} = new GCMultipleList($self, 3, \@labels, 0, 2); + +        my $historyBox = new Gtk2::VBox(0,0); +        $historyBox->set_border_width($GCUtils::margin); +        $historyBox->pack_start($self->{history}, 1, 1, 0); + +        $historyExpander->add($historyBox); +        $historyExpander->show_all; + +        $self->vbox->pack_start($scrollPanelList,1,1,0); +        $self->vbox->pack_start($historyExpander,0,0, $GCUtils::halfMargin); +  +        return $self; +    } +} + +1;  | 
