source: extensions/pLoader/trunk/src/Uploader/GUI/wxApp.pm @ 4126

Last change on this file since 4126 was 4126, checked in by ronosman, 14 years ago

Feature 1190 : Add Hungarian in language switch.

  • Property svn:eol-style set to LF
File size: 21.1 KB
Line 
1# +-----------------------------------------------------------------------+
2# | pLoader - a Perl photo uploader for Piwigo                            |
3# +-----------------------------------------------------------------------+
4# | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
5# +-----------------------------------------------------------------------+
6# | This program is free software; you can redistribute it and/or modify  |
7# | it under the terms of the GNU General Public License as published by  |
8# | the Free Software Foundation                                          |
9# |                                                                       |
10# | This program is distributed in the hope that it will be useful, but   |
11# | WITHOUT ANY WARRANTY; without even the implied warranty of            |
12# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
13# | General Public License for more details.                              |
14# |                                                                       |
15# | You should have received a copy of the GNU General Public License     |
16# | along with this program; if not, write to the Free Software           |
17# | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
18# | USA.                                                                  |
19# +-----------------------------------------------------------------------+
20package Uploader::GUI::wxApp;
21use strict;
22use base qw/Wx::App Class::Accessor::Fast/;   
23use Wx qw/
24             wxBITMAP_TYPE_GIF
25             wxBITMAP_TYPE_ICO
26             wxBITMAP_TYPE_BMP
27             wxBITMAP_TYPE_PNG
28             wxBITMAP_TYPE_JPEG
29             wxIMAGE_QUALITY_NORMAL
30             wxIMAGE_QUALITY_HIGH
31             wxSPLASH_CENTRE_ON_SCREEN
32             wxSPLASH_TIMEOUT
33             wxDefaultPosition
34             wxDefaultSize
35             wxSIMPLE_BORDER
36             wxFRAME_TOOL_WINDOW
37             wxFRAME_NO_TASKBAR wxSTAY_ON_TOP
38             wxWHITE
39             wxICON_EXCLAMATION
40             wxOK
41             wxLANGUAGE_CHINESE_SIMPLIFIED   
42             wxLANGUAGE_CZECH   
43             wxLANGUAGE_DANISH   
44             wxLANGUAGE_DUTCH   
45             wxLANGUAGE_ENGLISH   
46             wxLANGUAGE_FRENCH   
47             wxLANGUAGE_GERMAN   
48             wxLANGUAGE_HUNGARIAN
49             wxLANGUAGE_ITALIAN   
50             wxLANGUAGE_JAPANESE   
51             wxLANGUAGE_POLISH   
52             wxLANGUAGE_PORTUGUESE   
53             wxLANGUAGE_PORTUGUESE_BRAZILIAN   
54             wxLANGUAGE_RUSSIAN   
55             wxLANGUAGE_SLOVAK   
56             wxLANGUAGE_SPANISH   
57         /;
58use Uploader::GUI::wxFrameAUI;
59use File::Slurp ;
60use Data::Dumper;
61use Storable;
62use File::HomeDir;
63use File::Spec;
64use Uploader::PWG;
65use Uploader::ImageList;
66use Uploader::GUI::wxLoginDlg;
67use Wx::Locale qw/:default/;
68use utf8;
69
70$|=1;
71
72__PACKAGE__->mk_accessors( 
73    qw/
74          pwg
75          site_url
76          site_username
77          site_password
78          http_username
79          http_password
80          rejects
81          imagelist
82          storable_file
83          wx_thumb_dir
84          resized_dir
85          preview_dir
86          userdata_dir
87          resized_dir
88          thumb_dir
89          conf_file
90          layout_file
91          locale
92          current_language
93          languages
94          available_languages
95          version
96          imagelist_version
97          use_offline
98          login_dlg
99          branding
100          frame
101          perspective
102          imageviewerIndex
103          frameLayout
104          chunk_size
105      / 
106);
107
108sub FilterEvent {
109    my( $self, $event ) = @_;
110   
111    Wx::LogMessage "EventType %s", $event->GetEventType();
112   
113    return -1;
114}
115
116
117sub OnInit {
118    my( $self ) = @_;
119   
120    $self->version(
121        '2.0.5b'
122    );
123   
124    # to check if we can use stored cache
125    $self->imagelist_version(
126        '6'
127    );
128
129    $self->languages(
130      [
131             ["中文 (%s)", wxLANGUAGE_CHINESE_SIMPLIFIED, 'Chinese simplified'],   
132             ["Česky (%s)", wxLANGUAGE_CZECH, 'Czech'],   
133             ["Dansk (%s)", wxLANGUAGE_DANISH, 'Danish'],   
134             ["Deutsch (%s)", wxLANGUAGE_GERMAN, 'German'],   
135             ["English (%s)", wxLANGUAGE_ENGLISH, 'English'],   
136             ["Español (%s)", wxLANGUAGE_SPANISH, 'Spanish'],   
137             ["Français (%s)", wxLANGUAGE_FRENCH, 'French'],   
138             ["Italiano (%s)", wxLANGUAGE_ITALIAN, 'Italian'],   
139             ["日本語 (にほんご) (%s)", wxLANGUAGE_JAPANESE, 'Japanese'],   
140             ["Magyar (%s)", wxLANGUAGE_HUNGARIAN, 'Hungarian'],
141             ["Nederlands (%s)", wxLANGUAGE_DUTCH, 'Dutch'],   
142             ["Polski (%s)", wxLANGUAGE_POLISH, 'Polish'],   
143             ["Português Brasileiro (%s)", wxLANGUAGE_PORTUGUESE_BRAZILIAN, 'Portuguese Brazil'],   
144             ["Português Portugal (%s)", wxLANGUAGE_PORTUGUESE, 'Portuguese Portugal'],   
145             ["Русский (%s)", wxLANGUAGE_RUSSIAN, 'Russian'],
146             ["Slovenčina (%s)", wxLANGUAGE_SLOVAK, 'Slovak'],
147      ]
148    );
149    # some languages may be unavailable due to system configuration.
150    $self->_filter_available_languages;
151    Wx::InitAllImageHandlers();
152    my $applicationName = "pLoader" ;
153    $self->SetAppName( $applicationName );
154    $self->SetVendorName( "Piwigo Team" );
155
156    $self->{IMGTYPE} = {
157        'jpg' => wxBITMAP_TYPE_JPEG,
158        'gif' => wxBITMAP_TYPE_GIF,
159        'png' => wxBITMAP_TYPE_PNG,
160    };
161
162    $self->_init_userdir;
163
164
165    my $conf = retrieve $self->conf_file if -e $self->conf_file;       
166    my $layout = retrieve $self->layout_file if -e $self->layout_file; 
167
168    if(defined $conf ){
169        $self->SetKeyValues($conf);
170    }
171    else {
172        $self->_readParams( 'pLoader.ini' ) unless defined $conf ;
173    }
174
175    if(defined $layout ){
176        $self->SetKeyValues($layout);
177    }
178
179
180    $self->site_url(
181        $self->{site_url}
182    );
183   
184
185    $self->site_username(
186        $self->{site_username}
187    );
188    $self->site_password(
189        $self->{site_password}
190    );
191
192    $self->http_username(
193        $self->{http_username}
194    );
195    $self->http_password(
196        $self->{http_password}
197    );
198
199
200    $self->current_language(
201        $self->{current_language}||Wx::Locale::GetSystemLanguage()
202    );
203
204    $self->chunk_size(
205        $self->{chunk_size}||500_000
206    );
207   
208    $self->init_locale;
209
210    my $not_exit = $self->Login();
211    # user pressed OK
212    if($not_exit){
213        $self->StoreConnectionProperties;
214        if( !$self->use_offline ){
215            while( $not_exit and !$self->_is_connected ){
216                $not_exit = $self->Login();
217                last if $self->use_offline;
218            }
219        }
220        $self->_init_imagelist;
221        $self->_init_thumbimagelist;
222        $self->_init_frame;
223    }
224
225    $not_exit;
226}
227
228sub _filter_available_languages {
229    my ( $self ) = @_;
230
231    # check if the locale can be set and the translation catalog available
232    $self->available_languages(
233        [
234            grep {$_} 
235            map{
236                            #  a locale may be unavailable due to system limitations ( ex: chinese, japanese when language pack are not installed )
237                            if(Wx::Locale::IsAvailable($_->[1])){
238                            my $locale = Wx::Locale->new($_->[1]);
239                            $locale->AddCatalogLookupPathPrefix('../locale');
240                            $_ if $locale->AddCatalog('pLoader');
241                                }
242            }
243            @{$self->languages}
244        ]
245    );
246}
247
248sub _is_connected {
249    my ( $self ) = @_;
250
251    my $is_connected;
252
253    if($self->pwg->login_result->{stat} eq 'ok'){
254        $is_connected = 1;
255    }
256    else{
257        Wx::MessageBox( 
258            sprintf(
259                "%s\n\n%s %s %s",
260                $self->pwg->login_result->{message},
261                gettext("Connection to"),
262                $self->site_url,
263                gettext("failed"),
264            ),
265            gettext("Piwigo login error"),
266            wxOK | wxICON_EXCLAMATION, 
267        );
268    }
269   
270    $is_connected;
271}
272
273
274my $locale;
275sub init_locale {
276    my ( $self, $language ) = @_;
277   
278    $self->current_language(
279        $language
280    ) if defined $language;
281
282    undef $locale;
283    $locale = Wx::Locale->new(
284        $self->current_language
285    );
286    $locale->AddCatalogLookupPathPrefix( '../locale');
287    if(!$locale->AddCatalog( 'pLoader.mo' )){
288        Wx::LogMessage gettext("Cannot find translation catalog files for %s. Use default language"), $locale->GetCanonicalName();
289    }
290    $self->locale($locale);     
291}
292
293sub StoreConnectionProperties {
294    my ( $self ) = @_;
295
296    eval {   
297        store( 
298            {
299                map{
300                   $_ => $self->{$_},
301                }
302                qw/
303                    site_url
304                    site_username
305                    site_password
306                    http_username
307                    http_password
308                    current_language
309                    chunk_size
310                /
311            },
312            $self->conf_file
313        );
314    };
315}
316
317sub StoreLayoutProperties {
318    my ( $self ) = @_;
319
320    eval {   
321        store( 
322            {
323                map{
324                   $_ => $self->{$_},
325                }
326                qw/
327                      perspective
328                      imageviewerIndex
329                      frameLayout
330                /
331            },
332            $self->layout_file
333        );
334    };
335}
336
337sub _init_imagelist {
338    my ( $self ) = @_; 
339
340    my $stored_imagelist;
341   
342    my $use_new_imagelist;
343   
344    if( -e $self->storable_file ){
345        eval {
346            $stored_imagelist = retrieve $self->storable_file;
347        };
348        if($@){
349            Wx::LogMessage(
350                gettext("An error has occured. Can not read %s\n%s"),
351                $self->storable_file,
352                $@
353            );
354            $use_new_imagelist = 1 ;
355        }
356        # should have a valid imagelist
357        else{
358            $use_new_imagelist = 1 unless $self->imagelist_version eq $stored_imagelist->{imagelist_version};
359            if($use_new_imagelist){
360                Wx::LogMessage(gettext("pLoader has to reset image cache."));
361            }
362        }
363    }
364    else{
365        $use_new_imagelist = 1 ;
366    }
367
368    if($use_new_imagelist){
369        $stored_imagelist = $self->_default_imagelist_params ;
370    }
371
372
373    $self->imagelist(
374        Uploader::ImageList->new(
375            $stored_imagelist
376        )
377    );
378
379    $self->imagelist->RescaleCallback(
380        sub { $self->RescaleImage(@_) }
381    );
382
383    $self->imagelist->ResizeCallback(
384        sub { $self->ResizeImage(@_) }
385    );
386
387    $self->imagelist->YieldCallback(
388        sub { Wx::Yield }
389    );
390}
391
392
393sub _default_imagelist_params {
394    my ( $self ) = @_ ;
395
396    my $params = {
397        new_files        => [],
398        thumb_size       => 120,
399        site_thumb_dir   => $self->thumb_dir,
400        wx_thumb_size    => 120,
401        wx_thumb_dir     => $self->wx_thumb_dir,
402        preview_ratio    => 25, 
403        preview_dir      => $self->preview_dir,
404        resize_w         => 800,
405        resize_h         => 600,
406        site_resized_dir => $self->resized_dir,
407        type             => 'jpg',
408        filter           => 'Lanczos',
409        blur             => 0.9,
410        quality          => 95,
411        wx_quality       => 80,
412        th_quality       => 90,
413        auto_rotate      => 1,
414        remove_uploaded_from_selection => 1,
415        interlace        => 'Line',
416        create_resized   => 1,
417        use_exif_preview => 1,
418        prefix           => 'TN',
419        count            => 0,
420        storable_file    => $self->storable_file,
421        userdata_dir     => $self->userdata_dir,
422        default_photo_name => gettext('File name'),
423        default_name_prefix => gettext('Photo '),
424        upload_rejects   =>  [],
425        image_sums       => {},
426        sums             => [],
427        version          => $self->version,
428        imagelist_version => $self->imagelist_version,
429        RescaleCallback  => sub { $self->RescaleImage(@_) },
430        ResizeCallback   => sub { $self->ResizeImage(@_) },
431        watermark_text => gettext("my watermark"),
432        watermark_text_size => 12,
433        watermark_position => gettext("Center"),
434        watermark_y => 10,
435        watermark_x => 10,
436        watermark_color => gettext("White"),
437    };
438
439    return $params;
440}
441
442sub Login {
443    my ( $self ) = @_; 
444
445    $self->login_dlg( 
446        Uploader::GUI::wxLoginDlg->new(
447            {
448                title         => gettext("Piwigo login"),
449                site_url      => sub { $self->site_url(@_) },
450                site_username => sub { $self->site_username(@_) },     
451                site_password => sub { $self->site_password(@_) },
452                use_offline   => sub { $self->use_offline(@_) },       
453            }
454        )
455    ) unless $self->login_dlg;
456
457    my $icon = Wx::Icon->new();
458    $icon->LoadFile('../res/favicon.ico', wxBITMAP_TYPE_ICO);
459    $self->login_dlg->SetIcon($icon);   
460
461   
462    my $rval = $self->login_dlg->ShowModal();
463    $self->login_dlg->Show(0);
464
465    $self->_init_branding;
466   
467    if ($self->site_url !~ /^http:/){
468        $self->site_url(
469            sprintf(
470                "http://%s",
471                $self->site_url
472            )
473        );     
474    }
475
476    $self->pwg(
477        # get these parameters from dialog or from file
478        Uploader::PWG->new(
479            {
480                site_url       => $self->site_url,
481                site_username  => $self->site_username,
482                site_password  => $self->site_password,
483                http_username  => $self->http_username,
484                http_password  => $self->http_password,
485                branding       => $self->branding,
486                chunk_size     => $self->chunk_size,
487                use_offline    => $self->use_offline,
488            }
489        )
490    );
491
492    $rval;
493}
494
495sub _init_userdir {
496    my ( $self ) = @_;
497   
498    my $applicationName = $self->GetAppName ;
499    my $userdatadir = File::Spec->canonpath(
500        File::Spec->catfile(
501            File::HomeDir->my_data(), 
502            "\.$applicationName"
503        )
504    );
505
506    if(! -d $userdatadir){
507        if(! mkdir $userdatadir){
508            Wx::MessageBox( 
509                sprintf(
510                    "%s directory creation failed",
511                    $userdatadir,
512                ),
513                "pLoader working directory creation error",
514                wxOK | wxICON_EXCLAMATION, 
515            );
516
517            $userdatadir = File::Spec->canonpath(
518                File::Spec->catfile(
519                    File::Spec->tmpdir(), 
520                    "\.$applicationName"
521                )
522            );
523            mkdir $userdatadir;
524        }       
525    }
526
527    $self->userdata_dir($userdatadir);
528   
529    $self->conf_file(
530        File::Spec->catfile(
531            $self->userdata_dir, 
532            ".$applicationName.conf"
533        )
534    );
535
536    $self->layout_file(
537        File::Spec->catfile(
538            $self->userdata_dir, 
539            ".$applicationName.layout"
540        )
541    );
542
543    $self->storable_file(
544        File::Spec->catfile($self->userdata_dir, 'pLoader.dat')
545    );
546   
547    my $thumbdir = File::Spec->catfile($self->userdata_dir, 'thumbnails');
548    mkdir $thumbdir unless -d $thumbdir ;
549    $self->thumb_dir($thumbdir);
550
551    my $wxthumbdir = File::Spec->catfile($self->userdata_dir, 'wxthumbnails');
552    mkdir $wxthumbdir unless -d $wxthumbdir ;
553    $self->wx_thumb_dir($wxthumbdir);
554
555
556    my $resizedir = File::Spec->catfile($self->userdata_dir, 'resize');
557    mkdir $resizedir unless -d $resizedir ;
558    $self->resized_dir($resizedir);
559
560    my $previewdir = File::Spec->catfile($self->userdata_dir, 'preview');
561    mkdir $previewdir unless -d $previewdir ;
562    $self->preview_dir($previewdir);
563
564       
565}
566
567sub _init_thumbimagelist {
568    my ( $self ) = @_;
569
570   
571    $self->imagelist->wx_thumb_imglist(
572        Wx::ImageList->new( 
573            $self->imagelist->wx_thumb_size, 
574            $self->imagelist->wx_thumb_size, 
575            1,
576            0
577        )
578    );
579   
580    # reload images
581    $self->_reload_thumb_images;
582}
583
584
585sub _reload_thumb_images {
586    my ( $self ) = @_;
587   
588    my $wximagelist = $self->imagelist->wx_thumb_imglist;
589    my $sums = $self->imagelist->sums;
590
591    map {
592        my $image = $self->imagelist->image_sums->{$_};
593
594        $wximagelist->Add(
595            Wx::Bitmap->new( 
596                $image->wx_thumb_file, 
597                $self->GetWxBitmapType($self->imagelist->type), 
598            )
599        );
600    }
601    @$sums ;
602
603}
604
605sub GetWxBitmapType {
606    my ( $self, $type ) = @_;
607   
608    $self->{IMGTYPE}->{$type};
609}
610
611
612sub RescaleImage {
613    my ( $self, $image_file, $image_file_out, $type, $ratio, $width, $height, $quality ) = @_;
614   
615
616    my $image = Wx::Image->new(
617            $image_file, 
618            $self->GetWxBitmapType($type),
619            0
620    );
621   
622    my $w;
623    my $h;
624
625    my $img_w = $image->GetWidth;
626    my $img_h = $image->GetHeight;
627   
628    # use a ratio ( 25% default ) if defined
629    # default ratio is used for preview.
630    if($ratio){
631        $w = $ratio*$img_w/100 ;
632        $h = $ratio*$img_h/100 ;
633    }
634    # use specified width and height
635    else{
636        # portrait
637        if( $img_w < $img_h ){
638            $w = $height;
639        }
640        else{
641            $w = $width;
642        }
643        # to respect aspect ratio
644        $h = sprintf(
645            "%.0f",
646            ($w*$img_h)/$img_w
647        );
648    }
649
650    $image->Rescale(
651        $w,
652        $h,
653        wxIMAGE_QUALITY_HIGH
654    );
655   
656    $quality ||= 90;
657   
658    $image->SetOption( 
659        "quality", 
660        $quality 
661    );
662   
663    if(!$image->SaveFile(
664        $image_file_out,
665        $self->GetWxBitmapType($type),
666    )){
667        Wx::LogMessage(
668            gettext("An error has occured. Can not save file %s"),
669            $image_file_out,
670        )
671    };
672}
673
674sub ResizeImage {
675    my ( $self, $image_file, $image_file_out, $type, $width, $height, $quality ) = @_;
676   
677
678    my $image = Wx::Image->new(
679            $image_file, 
680            $self->GetWxBitmapType($type),
681            0
682    );
683
684    my $w;
685    my $h;
686
687    my $img_w = $image->GetWidth;
688    my $img_h = $image->GetHeight;
689   
690        # portrait
691        if( $img_w < $img_h ){
692            $w = $height;
693        }
694        else{
695            $w = $width;
696        }
697        # to respect aspect ratio
698        $h = sprintf(
699            "%.0f",
700            ($w*$img_h)/$img_w
701        );
702
703   
704
705    $image->Rescale(
706        $w,
707        $h,
708        wxIMAGE_QUALITY_HIGH
709    );
710
711    $image->Resize(
712        [ $width, $height ], [ 0, 20],
713    );
714   
715    $quality ||= 90;
716   
717    $image->SetOption( 
718        "quality", 
719        $quality 
720    );
721   
722    if(!$image->SaveFile(
723        $image_file_out,
724        $self->GetWxBitmapType($type),
725    )){
726        Wx::LogMessage(
727            gettext("An error has occured. Can not save file %s"),
728            $image_file_out,
729        )
730    };
731}
732
733# some labels differ with branding ( piwigo.com or piwigo.org )
734sub _init_branding {
735    my ( $self ) =@_;
736   
737    if( $self->site_url =~ /\.piwigo\.com/ ){
738        $self->branding(
739            {
740                category  => gettext("album"), 
741                Category  => gettext("Album"), 
742                categories => gettext("albums"),       
743                Categories => gettext("Albums"),
744                'Add new category' => gettext("Add new album"), 
745                'Category name' => gettext("Album name :"),
746                'New category' => gettext("New album"),
747            }
748        );
749    }
750    else{
751        $self->branding(
752            {
753                category  => gettext("categorie"),     
754                Category  => gettext("Categorie"),     
755                categories => gettext("categories"),   
756                Categories => gettext("Categories"),   
757                'Add new category' => gettext("Add new category"),
758                'Category name' => gettext("Category name :"),
759                'New category' => gettext("New category"),
760            }
761        );
762    }   
763}
764
765sub SaveConfig {
766    my ( $self, $params ) = @_; 
767
768   my $config = Wx::ConfigBase::Get;
769
770   map {
771       $config->WriteInt( $_, $params->{$_} )
772   } keys %$params;
773
774   $config->Write( 'Perspective', $params->{Perspective} )
775       
776}
777
778
779sub _init_frame {
780    my ( $self ) = @_; 
781
782    my $url = $self->site_url;
783   
784    if($self->use_offline){
785        $url = gettext("Work Offline");
786    }
787
788    $self->frame(
789        Uploader::GUI::wxFrameAUI->new( 
790            {
791                title     => sprintf("pLoader - Piwigo uploader %s - [%s]", $self->version, $url),
792                pwg       => $self->pwg,
793                imagelist => $self->imagelist,
794                perspective => $self->perspective,
795                imageviewer_index => $self->imageviewerIndex,
796                frameLayout => $self->frameLayout,
797            }
798        )
799    );
800 
801    $self->frame->Show( 1 );
802    $self->SetTopWindow( $self->frame );
803
804    my $icon = Wx::Icon->new();
805    $icon->LoadFile('../res/favicon.ico', wxBITMAP_TYPE_ICO);
806    $self->frame->SetIcon($icon);       
807}
808
809sub _readParams {
810        my( $self, $file ) = @_ ;
811
812
813        my $expr_params ;
814        eval { $expr_params = read_file( $file ); } ;
815       
816        my $paramValues = [] ;
817        if($expr_params){
818                my $expr = '$paramValues = ' ;
819                $expr .=  "$expr_params ; " ;
820                eval $expr ;
821        }
822       
823        return unless 'ARRAY' eq ref $paramValues ;
824       
825        if(scalar(@$paramValues )){
826            my $params = $paramValues->[0] ;
827            $self->SetKeyValues($params);
828        }
829}
830
831
832
833sub SetKeyValues {
834    my ( $self, $params )= @_; 
835
836    foreach( keys %$params ) {
837        $self->{$_} = $params->{$_} ;
838    }
839}
840
841
8421;
Note: See TracBrowser for help on using the repository browser.