source: extensions/pLoader/trunk/src/Uploader/GUI/wxFrameAUI.pm @ 4467

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

Feature 1052 added : photo re-upload management. When uploading an already added photo, the user is warned and has a choice on action for files, simple properties and multi-values properties.

  • Property svn:eol-style set to LF
File size: 58.9 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::wxFrameAUI;
21use strict;
22use Carp;
23use Wx;
24use Wx::DND;
25use Wx qw/
26             wxYES_NO
27             wxYES
28             wxICON_QUESTION
29             wxITEM_NORMAL
30             wxNullBitmap
31             wxID_OK
32             wxDEFAULT_FRAME_STYLE
33             wxVERTICAL
34             wxGROW
35             wxBITMAP_TYPE_JPEG
36             wxBITMAP_TYPE_GIF
37             wxBITMAP_TYPE_PNG
38                         wxBITMAP_TYPE_ANY
39             wxTB_FLAT
40             wxSIZE
41             wxWHITE
42             wxBLACK
43             wxID_CANCEL
44             wxFD_OPEN
45             wxFD_MULTIPLE
46             wxLI_HORIZONTAL
47             wxALIGN_CENTER_VERTICAL
48             wxALL
49             wxDefaultPosition
50             wxDefaultSize
51             wxTheApp
52             wxIMAGE_LIST_NORMAL
53             wxAUI_NB_TAB_MOVE
54             wxAUI_NB_TAB_SPLIT
55             wxNO_BORDER
56             wxTE_MULTILINE
57             wxTE_READONLY
58             wxITEM_NORMAL
59             wxCLIP_CHILDREN
60             wxBORDER_NONE
61             wxNullBitmap
62             wxTR_MULTIPLE
63             wxTR_EXTENDED
64             wxTR_HIDE_ROOT
65             wxTR_HAS_BUTTONS
66             wxTR_EDIT_LABELS
67             wxMAXIMIZE
68             wxOK
69             wxICON_EXCLAMATION
70             wxICON_INFORMATION
71             WXK_DELETE
72         /;
73use base qw/Wx::Frame Class::Accessor::Fast/;
74use File::Spec;
75use Wx::Locale qw/:default/;
76use POSIX qw(ceil floor);
77
78require Win32 if($^O =~ /MSWin32/);
79
80
81my @properties = 
82    qw/
83          progressdlg
84          upload_progressdlg
85          imageviewer
86          tree
87          tree_root
88          treeimglist
89          tree_item_default
90          topsizer
91          pwg
92          manager
93          logwnd
94          oldlogwnd
95          htmlhome
96          notebook
97          categories
98          imagelist
99          image_preview
100          image_prop_piwigo
101          image_prop_exif
102          image_prop_tags
103          notebook_image_properties
104          notebook_global_settings
105          general_settings_panel
106          resized_settings_panel
107          thumbnail_settings_panel
108                  hd_settings_panel
109          advanced_settings_panel
110          watermark_settings_panel
111          piwigo_properties
112          exif_properties
113          general_settings
114          resized_settings
115          thumbnail_settings
116                  hd_settings
117          advanced_settings
118          watermark_settings
119          toolbar
120          branding
121          perspective
122          current_imageviewer_index
123          imageviewer_mnu
124          tree_mnu
125          imageviewer_select_multi
126          frameLayout
127          piwigo_tags
128          image_tags
129      /;
130__PACKAGE__->mk_accessors( @properties );
131
132use Wx::Event 
133    qw/
134          EVT_MENU
135          EVT_TREE_SEL_CHANGED
136          EVT_TREE_END_LABEL_EDIT
137          EVT_CLOSE
138          EVT_LIST_END_LABEL_EDIT
139          EVT_LIST_ITEM_SELECTED
140          EVT_LIST_ITEM_ACTIVATED
141          EVT_LIST_ITEM_RIGHT_CLICK
142          EVT_TREE_ITEM_RIGHT_CLICK
143          EVT_LIST_KEY_DOWN
144          EVT_UPDATE_UI       
145      /;
146     
147use Uploader::GUI::wxImageListCtrl;
148use Uploader::GUI::wxImageProcessingProgressDlg;
149use Uploader::GUI::wxChoiceFilteredPanel;
150use Uploader::GUI::wxImageReuploadDlg;
151use Wx::Html;
152use Uploader::GUI::wxImagePreview;
153use Uploader::GUI::wxHtmlWindow;
154use Data::Dumper;
155use Wx::AUI;
156use Storable;
157use Uploader::GUI::wxPropertyGridPanel;
158use Uploader::GUI::wxPhotoProperties;
159use utf8;
160$|=1;
161
162my $ID_TREE_CTX_MENU = 20000 ;
163my $ID_IMAGEVIEWER_CTX_MENU = 20100 ;
164
165sub new {
166  my( $class, $params ) = @_;
167  my( $self ) = $class->SUPER::new( 
168                                      undef, 
169                                      -1, 
170                                      $params->{title},
171                                      wxDefaultPosition,
172                                      wxDefaultSize, 
173                                      wxDEFAULT_FRAME_STYLE
174                                   );
175
176    $self->perspective(
177        $params->{perspective}
178    );
179   
180    $self->current_imageviewer_index(
181        $params->{imageviewer_index}||0
182    );
183   
184    $self->frameLayout(
185        $params->{frameLayout} || { 'pX' => -1, 'pY' => -1, W => 800, H => 600 }
186    );
187
188    $self->pwg( $params->{pwg} );
189    $self->imagelist( $params->{imagelist} );
190
191    # callback for GUI refresh : add thumbnail images to the imageviewer control
192    $self->imagelist->SetNewFilesViewerRefreshCallback(
193        sub { $self->SetNewFilesViewerRefresh(@_) }
194    );
195
196    # callback for GUI refresh : progress dialog display of thumbnail image being created
197    $self->imagelist->SetNewFilesProgressCallback(
198        sub { $self->SetNewFilesProgress(@_) }
199    );
200
201    $self->imagelist->SetNewFilesDisplayEndInfoCallback(
202        sub { $self->SetNewFilesDisplayEndInfo(@_) }
203    );
204
205
206    # callback for GUI refresh : remove thumbnail images from imageviewer control
207    $self->imagelist->UploadImagesViewerCallback(
208        sub { $self->UploadImagesViewerRefresh(@_) }
209    );
210       
211        $self->imagelist->ReuploadCallback(
212            sub {
213                    Uploader::GUI::wxImageReuploadDlg->new(
214            { 
215                                title      => gettext("Photo update management"),
216                properties => {
217                                        $main::ID_REUPLOAD_ACTION_FILES        => { 
218                                                                                                                    selection=>sub {$self->imagelist->reupload_action_files(@_)},
219                                                                                                                                                                label=>gettext("What shall we do with files? (thumbnail, resized, high resolution)"),
220                                                                                labels=>[
221                                                                                                                                                                           gettext("nothing"),
222                                                                                                                                                                           gettext("replace"),
223                                                                                                                                                                       ],                                                                                                                                                               
224                                                                                                            },
225                                                                    $main::ID_REUPLOAD_ACTION_PROPERTIES   => { 
226                                                                                                                    selection=>sub{$self->imagelist->reupload_action_properties(@_)},
227                                                                                                                                                                label=>gettext("What shall we do with single value properties?(caption, comment, author, create date)"),
228                                                                                labels=>[
229                                                                                                                                                                           gettext("nothing"),
230                                                                                                                                                                           gettext("fill if empty (only replace properties currently empty in Piwigo)"),
231                                                                                                                                                                           gettext("replace"),
232                                                                                                                                                                       ],                                                                                                                                                               
233                                                                                                                  },
234                                                                        $main::ID_REUPLOAD_ACTION_PROPERTIES_M => { 
235                                                                                                                    selection=>sub{$self->imagelist->reupload_action_properties_m(@_)},
236                                                                                                                                                                label=>gettext("What shall we do with multiple values properties? (categories, tags)"),
237                                                                                labels=>[
238                                                                                                                                                                           gettext("nothing"),
239                                                                                                                                                                           gettext("append (keep existing and add new)"),
240                                                                                                                                                                           gettext("replace"),
241                                                                                                                                                                       ],                                                                                                                                                               
242                                                                                                                  },
243                                                                        $main::ID_REUPLOAD_NOT_ASK             => { 
244                                                                                                                    value=>sub{$self->imagelist->reupload_not_ask(@_)}, 
245                                                                                label=>gettext("Do not ask me again"),                                                                                                                                                         
246                                                                                                                  },
247                                                                        $main::ID_REUPLOAD_TEXT                => { 
248                                                                                label=>gettext("A least one photo has already been added in the past."),                                                                                                                                                               
249                                                                                                                  },
250                                                },
251            }
252                        )->ShowModal();
253                }
254        );
255
256
257    # callback for GUI refresh : progress dialog display current uploaded image
258    $self->imagelist->progress_thumbnail_refresh(
259        sub { $self->UploadProgressThumbnailRefresh(@_) }
260    );
261
262    $self->imagelist->progress_msg_refresh(
263        sub { $self->UploadProgressMessageRefresh(@_) }
264    );
265
266    $self->imagelist->progress_msg_details_refresh(
267        sub { $self->UploadProgressMessageDetailsRefresh(@_) }
268    );
269
270    $self->imagelist->progressbar_refresh(
271        sub { $self->UploadProgressBarRefresh(@_) }
272    );
273   
274    $self->imagelist->progress_endinfo_refresh(
275        sub { $self->UploadDisplayEndInfo(@_) }
276    );
277
278
279    $self->imagelist->pwg(
280        $self->pwg
281    );
282
283    $self->imagelist->categories(
284        []
285    );
286
287
288    $self->manager( Wx::AuiManager->new );
289    $self->manager->SetManagedWindow( $self );
290    $self->_set_setting_properties;
291    $self->_initFrame;
292    $self->_initMenus;
293    $self->_initEventHandlers;
294    $self->_initImgTypes;   
295
296
297    $self->imageviewer->SelectItem(
298        $self->current_imageviewer_index
299    ) if $self->imageviewer->GetItemCount;
300   
301    $self;
302}
303
304
305sub _initImgTypes {
306    my ( $self ) = @_;
307
308    $self->{IMGTYPE} = {
309             'jpg' => wxBITMAP_TYPE_JPEG,
310             'gif' => wxBITMAP_TYPE_GIF,
311             'png' => wxBITMAP_TYPE_PNG,
312    };
313}
314
315
316sub GetWxBitmapType {
317    my ( $self, $type ) = @_;
318   
319    $self->{IMGTYPE}->{$type};
320}
321
322
323
324sub _set_setting_properties {
325    my ( $self ) = @_;
326       
327
328    $self->piwigo_properties(
329        [
330            {
331                label          => gettext("Photo caption :"),
332                value          => sub { $self->imagelist->current_image->site_name(@_) },
333                frame_callback => sub { $self->imageviewer->Refresh() },
334            },
335            {
336                label => gettext("Comment :"),
337                value => sub { $self->imagelist->current_image->site_comment(@_) },
338                type  => "LongText",
339            },
340            {
341                label => gettext("Author :"),
342                value => sub { $self->imagelist->current_image->site_author(@_) },
343            },
344            {
345                label    => gettext("File name :"),
346                value    => sub { $self->imagelist->current_image->file(@_) },
347                readonly => 1,
348            },
349            {
350                label    => gettext("Create date :"),
351                value    => sub { $self->imagelist->current_image->create_date(@_) },
352                readonly => 1,
353            },
354        ]   
355    );
356
357    $self->exif_properties(
358        [
359            {
360                label    => gettext("Create date :"),
361                value    => sub { $self->imagelist->current_image->create_date }, 
362                readonly => 1,
363            }, 
364            {
365                label    => gettext("Model :"),
366                value    => sub { $self->imagelist->current_image->exif_tag('Model') }, 
367                readonly => 1,
368            }, 
369            {
370                label    => gettext("Width :"),
371                value    => sub { $self->imagelist->current_image->exif_tag('ImageWidth') }, 
372                readonly => 1,
373            }, 
374            {
375                label    => gettext("Height :"),
376                value    => sub { $self->imagelist->current_image->exif_tag('ImageHeight') }, 
377                readonly => 1,
378            }, 
379            {
380                label    => gettext("Orientation :"),
381                value    => sub { $self->imagelist->current_image->exif_tag('Orientation') }, 
382                readonly => 1,
383            }, 
384            {
385                label    => "ISO :",
386                value    => sub { $self->imagelist->current_image->exif_tag('ISO') }, 
387                readonly => 1,
388            }, 
389            {
390                label    => gettext("Shutter speed :"),
391                value    => sub { $self->imagelist->current_image->exif_tag('ExposureTime') }, 
392                readonly => 1,
393            }, 
394            {
395                label    => gettext("Aperture :"),
396                value    => sub { $self->imagelist->current_image->exif_tag('ApertureValue') }, 
397                readonly => 1,
398            }, 
399            {
400                label    => gettext("Focal length :"),
401                value    => sub { $self->imagelist->current_image->exif_tag('FocalLength') }, 
402                readonly => 1,
403            }, 
404            {
405                label    => gettext("Lens :"),
406                value    => sub { $self->imagelist->current_image->exif_tag('Lens') }, 
407                readonly => 1,
408            }, 
409        ]
410    );   
411
412
413    $self->general_settings(
414        [
415            {
416                label     => gettext("Default author :"),
417                value   => sub { $self->imagelist->author(@_) },
418            },
419            {
420                label     => gettext("Default photo caption :"),
421                type      => 'Choice',
422                value   => sub { $self->imagelist->default_photo_name(@_) },
423                choice  => [
424                               map { gettext $_ } @{wxTheApp->default_photo_names}
425                           ],
426                pre_process => sub { my ( $value ) = @_; wxTheApp->eng_default_photo_names->{$value} },
427            },
428            {
429                label     => gettext("Photo caption  prefix :"),
430                value   => sub { $self->imagelist->default_name_prefix(@_) },
431            },
432            {
433                label     => gettext("Resize site image :"),
434                type      => 'Bool',
435                value   => sub { $self->imagelist->create_resized(@_) },
436            },
437            {
438                label     => gettext("Auto rotate image :"),
439                type      => 'Bool',
440                value   => sub { $self->imagelist->auto_rotate(@_) },
441            },
442            {
443                label     => gettext("Upload high definition  :"),
444                type      => 'Choice',
445                choice  => [
446                               map { gettext $_ } @{wxTheApp->upload_hd}
447                           ],
448                pre_process => sub { my ( $value ) = @_; wxTheApp->eng_upload_hd->{$value} },
449                value   => sub { $self->imagelist->upload_hd(@_) },
450            },
451            {
452                label     => gettext("Remove uploaded photo from selection :"),
453                type      => 'Bool',
454                value   => sub { $self->imagelist->remove_uploaded_from_selection(@_) },
455            },
456        ]   
457    );
458   
459    $self->resized_settings(
460        [
461            {
462                label     => gettext("Site image width :"),
463                type      => 'Number',
464                value   => sub { $self->imagelist->resize_w(@_) },
465            },
466            {
467                label     => gettext("Site image height :"),
468                type      => 'Number',
469                value   => sub { $self->imagelist->resize_h(@_) },
470            },
471            {
472                label     => gettext("Site image jpeg quality :"),
473                type      => 'Number',
474                value   => sub { $self->imagelist->quality(@_) },
475            },
476            {
477                label     => gettext("Site image filter :"),
478                type      => 'Choice',
479                value   => sub { $self->imagelist->filter(@_) },
480                choice    => [ qw/Point Box Triangle Hermite Hanning Hamming Blackman Gaussian Quadratic Cubic Catrom Mitchell Lanczos Bessel Sinc/ ],
481            },
482            {
483                label     => gettext("Site image blur :"),
484                type      => 'Float',
485                value   => sub { $self->imagelist->blur(@_) },
486            },
487            {
488                label     => gettext("Site image interlace :"),
489                type      => 'Choice',
490                value   => sub { $self->imagelist->interlace(@_) },
491                choice    => [ qw/None Line Plane Partition JPEG GIF PNG/ ],
492            },
493        ]   
494    );
495
496    $self->hd_settings(
497        [
498            {
499                label     => gettext("HD image width :"),
500                type      => 'Number',
501                value   => sub { $self->imagelist->hd_w(@_) },
502            },
503            {
504                label     => gettext("HD image height :"),
505                type      => 'Number',
506                value   => sub { $self->imagelist->hd_h(@_) },
507            },
508            {
509                label     => gettext("HD image jpeg quality :"),
510                type      => 'Number',
511                value   => sub { $self->imagelist->hd_quality(@_) },
512            },
513            {
514                label     => gettext("HD image filter :"),
515                type      => 'Choice',
516                value   => sub { $self->imagelist->hd_filter(@_) },
517                choice    => [ qw/Point Box Triangle Hermite Hanning Hamming Blackman Gaussian Quadratic Cubic Catrom Mitchell Lanczos Bessel Sinc/ ],
518            },
519            {
520                label     => gettext("HD image blur :"),
521                type      => 'Float',
522                value   => sub { $self->imagelist->hd_blur(@_) },
523            },
524            {
525                label     => gettext("HD image interlace :"),
526                type      => 'Choice',
527                value   => sub { $self->imagelist->hd_interlace(@_) },
528                choice    => [ qw/None Line Plane Partition JPEG GIF PNG/ ],
529            },
530        ]   
531    );
532       
533    $self->thumbnail_settings(
534        [
535            {
536                label     => gettext("Site thumbnail size :"),
537                type      => 'Number',
538                value   => sub { $self->imagelist->thumb_size(@_) },
539            },
540            {
541                label     => gettext("Site thumbnail jpeg quality :"),
542                type      => 'Number',
543                value   => sub { $self->imagelist->th_quality(@_) },
544            },
545            {
546                label     => gettext("Photo selection thumbnail size :"),
547                type      => 'Number',
548                value   => sub { $self->imagelist->wx_thumb_size(@_) },
549            },
550            {
551                label     => gettext("Photo selection thumbnail jpeg quality :"),
552                type      => 'Number',
553                value   => sub { $self->imagelist->wx_quality(@_) },
554            },
555        ]   
556    );
557   
558
559    $self->advanced_settings(
560        [
561            {
562                label     => gettext("Transfert chunk size :"),
563                type      => 'Number',
564                value   => sub { wxTheApp->chunk_size(@_) },
565            },
566        ]   
567    );
568
569    $self->watermark_settings(
570        [
571            {
572              label  => gettext("Activate watermark :"),
573              type   => 'Bool',
574              value  => sub { $self->imagelist->watermark_activate(@_) },
575            },
576            {
577              label => gettext("Activate watermark on high definition :"),
578              type  => 'Bool',
579              value => sub { $self->imagelist->watermark_activate_pwg_high(@_) },
580            },
581            {
582              label  => gettext("Text :"),
583              value  => sub { $self->imagelist->watermark_text(@_) },
584            },
585            {
586                label     => gettext("Text size :"),
587                type      => 'Number',
588                value   => sub { $self->imagelist->watermark_text_size(@_) },
589            },
590            {
591                label     => gettext("Color :"),
592                type      => 'Choice',
593                value     => sub { $self->imagelist->watermark_color(@_) },
594                choice    => [
595                               map { gettext $_ } @{wxTheApp->colors}
596                             ],
597                pre_process => sub { my ( $value ) = @_; wxTheApp->eng_colors->{$value} },
598            },           
599            {
600                label     => gettext("Position :"),
601                type      => 'Choice',
602                value   => sub { $self->imagelist->watermark_position(@_) },
603                choice  => [
604                               map { gettext $_ } @{wxTheApp->positions}
605                           ],
606                pre_process => sub { my ( $value ) = @_; wxTheApp->eng_positions->{$value} },
607            },
608            {
609                label     => gettext("Top margin :"),
610                type      => 'Number',
611                value   => sub { $self->imagelist->watermark_y(@_) },
612            },
613            {
614                label     => gettext("Left margin :"),
615                type      => 'Number',
616                value   => sub { $self->imagelist->watermark_x(@_) },
617            },           
618        ]
619    );
620
621    $self->image_tags(
622        sub { eval { $self->imagelist->current_image->site_tags(@_) } }
623    );
624
625    $self->piwigo_tags(
626        sub { wxTheApp->pwg->tags }
627    ); 
628}
629
630sub _create_piwigo_tag {
631    my ( $self, $name ) = @_;
632   
633    if(
634        Wx::MessageBox( 
635            sprintf(
636                gettext("Do you want to create \"%s\" ?"), 
637                $name,
638            ),
639            gettext("Piwigo search information"),
640            wxYES_NO | wxICON_QUESTION, 
641        ) == wxYES
642    ){   
643        $self->pwg->AddTags($name);
644        $self->pwg->RefreshTags;
645    }
646}
647
648sub _refreshFrame {
649    my ( $self ) = @_;
650   
651    $self->_set_setting_properties;
652    $self->_refresh_settings_panels_properties;
653    map {
654        $_->Refresh;   
655    }
656    (
657        $self->image_prop_piwigo,
658        $self->image_prop_exif,
659        $self->image_prop_tags,
660        $self->general_settings_panel,
661        $self->resized_settings_panel,
662        $self->thumbnail_settings_panel,
663        $self->hd_settings_panel,
664        $self->advanced_settings_panel,
665        $self->watermark_settings_panel,
666    );
667   
668    $self->manager->Update;
669}
670
671
672sub _destroy_settings_panels {
673    my ( $self ) = @_;
674
675
676
677    map {
678        $self->manager->DetachPane(
679            $_
680        );
681        $_->Show(0);
682        $_->Destroy;
683    }(
684        $self->notebook_global_settings,
685        $self->notebook_image_properties,
686    );
687}
688
689#
690sub _initFrame {
691    my ( $self ) = @_;
692   
693 
694    $self->init_panels;
695
696    $self->init_aui;
697    $self->init_dnd_targets;
698
699    if( $self->imagelist->wx_thumb_imglist->GetImageCount){
700        printf("%s images\n", $self->imagelist->wx_thumb_imglist->GetImageCount); 
701        $self->ShowImageViewer;
702       
703        $self->imageviewer->Refresh(
704            $self->imagelist->wx_thumb_imglist
705        );
706       
707    }
708
709}
710
711sub _refresh_settings_panels_properties {
712    my ( $self ) = @_; 
713       
714    $self->image_prop_piwigo->properties(
715        $self->piwigo_properties
716    );
717   
718    $self->image_prop_exif->properties(
719        $self->exif_properties
720    );
721
722
723    $self->general_settings_panel->properties(
724        $self->general_settings
725    );   
726
727    $self->resized_settings_panel->properties(
728        $self->resized_settings
729    );   
730
731    $self->thumbnail_settings_panel->properties(
732        $self->thumbnail_settings,
733    );   
734
735    $self->hd_settings_panel->properties(
736        $self->hd_settings,
737    );   
738
739    $self->advanced_settings_panel->properties(
740        $self->advanced_settings,
741    );   
742
743    $self->watermark_settings_panel->properties(
744        $self->watermark_settings,
745    ); 
746       
747}
748
749sub _init_settings_panels {
750    my ( $self ) = @_; 
751
752
753    $self->image_prop_piwigo(
754        Uploader::GUI::wxPropertyGridPanel->new( 
755            { 
756                parentwnd       => $self,
757                properties      => $self->piwigo_properties,
758            }
759        )
760    );
761
762    $self->image_prop_exif(
763        Uploader::GUI::wxPropertyGridPanel->new( 
764            { 
765                parentwnd       => $self,
766                properties      => $self->exif_properties,
767            }
768        )
769    );
770
771
772    $self->general_settings_panel(
773        Uploader::GUI::wxPropertyGridPanel->new( 
774            { 
775                parentwnd       => $self,
776                properties      => $self->general_settings,
777            }
778        )
779    );   
780
781    $self->resized_settings_panel(
782        Uploader::GUI::wxPropertyGridPanel->new( 
783            { 
784                parentwnd       => $self,
785                properties      => $self->resized_settings,
786
787            }
788        )   
789    );   
790
791    $self->thumbnail_settings_panel(
792        Uploader::GUI::wxPropertyGridPanel->new( 
793            { 
794                parentwnd       => $self,
795                properties      => $self->thumbnail_settings,
796            }
797        )   
798    );   
799    $self->hd_settings_panel(
800        Uploader::GUI::wxPropertyGridPanel->new( 
801            { 
802                parentwnd       => $self,
803                properties      => $self->hd_settings,
804            }
805        )   
806    );   
807
808    $self->watermark_settings_panel(
809        Uploader::GUI::wxPropertyGridPanel->new(
810            {
811                parentwnd   => $self,
812                properties  => $self->watermark_settings,
813            }
814        )
815    );
816       
817    $self->advanced_settings_panel(
818        Uploader::GUI::wxPropertyGridPanel->new( 
819            { 
820                parentwnd       => $self,
821                properties      => $self->advanced_settings,
822            }
823        )   
824    );   
825
826    $self->image_prop_tags(
827        Uploader::GUI::wxChoiceFilteredPanel->new( 
828            { 
829                parentwnd    => $self,
830                choices      => $self->piwigo_tags,
831                selection    => $self->image_tags,
832                creation_callback => sub { $self->_create_piwigo_tag(@_) }, 
833            }
834        )   
835    );   
836
837   
838    $self->general_settings_panel->Show(0);
839
840    $self->image_preview(
841        Uploader::GUI::wxImagePreview->new(
842            { 
843                parentwnd    => $self,
844            }
845        )
846    );
847
848
849    $self->image_prop_piwigo->Show(0);
850   
851    $self->image_prop_exif->Show(0);
852       
853}
854
855sub init_panels {
856    my ( $self ) = @_; 
857
858    my $file = sprintf(
859        "../locale/%s/gs.html",
860        wxTheApp->locale->GetCanonicalName
861    );
862
863    $self->htmlhome(
864        Uploader::GUI::wxHtmlWindow->new(
865            $self, -1, [-1, -1], [450, 450]
866        )
867    );
868   
869    $self->htmlhome->LoadPage($file) if -e $file ;
870   
871    $self->htmlhome->InitHrefCallbacks(
872        {
873            new_album => sub {$self->OnAddCategories(@_) },
874            add_photos => sub { $self->OnAddImages(@_) },
875            upload_photos => sub { $self->ProcessImageSelection(@_)},   
876        }
877    );
878   
879    $self->imageviewer(
880        Uploader::GUI::wxImageListCtrl->new( 
881            { 
882                parentwnd => $self,
883                imagelist => $self->imagelist,
884            }
885        )
886    );
887   
888    $self->_init_settings_panels;       
889}
890
891sub init_dnd_targets {
892    my ( $self ) = @_; 
893
894    $self->imageviewer->SetDropTarget( 
895        DNDImageListDropTarget->new(
896            $self->imageviewer
897        ) 
898    );
899
900    $self->tree->SetDropTarget( 
901        DNDCategoryTreeDropTarget->new(
902            $self->tree
903        )
904    );
905       
906}
907
908sub init_aui {
909    my ( $self ) = @_;
910
911    my $url = wxTheApp->site_url;
912   
913    $url = gettext("empty - work Offline") if wxTheApp->use_offline;
914
915    $self->manager->AddPane
916      ( $self->create_notebook_imagelist, Wx::AuiPaneInfo->new->Name( "ImageViewer" )
917        ->CenterPane->Resizable->CloseButton(0) );
918
919               
920    $self->manager->AddPane( 
921        $self->create_tree, 
922        Wx::AuiPaneInfo->new->Name( "categories" )
923        ->Right->Position( 0 )->Resizable->CloseButton(0), 
924    );
925
926
927
928    $self->_init_aui_settings_panels;
929
930    $self->toolbar(
931        $self->create_toolbar
932    );
933
934    $self->manager->AddPane
935      ( $self->toolbar, Wx::AuiPaneInfo->new->Name( "tb1" )
936        ->ToolbarPane->Top->Row( 1 )->LeftDockable( 0 )->RightDockable( 0 ) ) if defined $self->toolbar;
937
938    $self->SetSize( 
939            $self->frameLayout->{pX}, 
940            $self->frameLayout->{pY}, 
941            $self->frameLayout->{W}, 
942            $self->frameLayout->{H}, 
943    );
944
945
946    if($self->perspective){
947        $self->manager->LoadPerspective($self->perspective);
948    }
949    else {
950        $self->manager->GetPane("categories")->MinSize(300,100);
951
952        $self->manager->GetPane("tb1")->Caption( gettext("Tools") );
953        $self->manager->GetPane("image_preview")->Caption(gettext("Preview"))->Show(0);
954        $self->manager->GetPane("getting_started")->Caption(gettext("Getting started"))->Float->Show(1);
955        $self->manager->GetPane("photo_properties")->Caption(gettext("Photo properties"))->Float->Show(0);
956        $self->manager->GetPane("global_settings")->Caption(gettext("Global settings"))->Float->Show(0);
957    }
958
959    $self->manager->GetPane("categories")->Caption(
960          sprintf("%s - %s", sprintf("Piwigo %s", wxTheApp->branding->{categories}), $url )
961    );
962   
963    $self->manager->Update;
964
965}
966
967
968sub _init_aui_settings_panels {
969    my ( $self ) = @_; 
970
971    $self->manager->AddPane
972      ( $self->image_preview, Wx::AuiPaneInfo->new->Name( "image_preview" )
973        ->Floatable(1)->Resizable->CloseButton(1));
974
975    $self->manager->AddPane
976      ( $self->htmlhome, Wx::AuiPaneInfo->new->Name( "getting_started" )
977       ->Floatable(1)->Resizable->CloseButton(1) );
978
979    $self->manager->AddPane
980      ( $self->create_notebook_image_properties, Wx::AuiPaneInfo->new->Name( "photo_properties" )
981        ->Floatable(1)->Resizable->CloseButton(1) );
982
983    $self->manager->AddPane
984      ( $self->create_notebook_global_settings, Wx::AuiPaneInfo->new->Name( "global_settings" )
985        ->Floatable(1)->Resizable->CloseButton(1) );
986
987}
988
989sub OnPhotoProperties {
990    my ( $self ) = @_;
991
992    $self->manager->GetPane("photo_properties")->Show(1);
993    $self->manager->Update();   
994       
995}
996
997sub OnPreview {
998    my ( $self ) = @_;
999
1000        my $preview_pane = $self->manager->GetPane("image_preview");
1001    if (! $preview_pane->IsShown){
1002            $preview_pane->MinSize(100,75)->Float->Show(1);
1003        $self->manager->Update();   
1004
1005        $self->_image_preview_refresh; 
1006        $self->image_preview->Refresh;         
1007        };
1008       
1009}
1010
1011sub OnGettingStarted {
1012    my ( $self ) = @_;
1013
1014    $self->toolbar->EnableTool(100, 0 );
1015    $self->manager->GetPane("getting_started")->Float->Show(1);
1016    $self->manager->Update();   
1017       
1018}
1019
1020sub OnGlobalSettings {
1021    my ( $self ) = @_;
1022
1023    $self->toolbar->EnableTool(104, 0 );
1024    $self->manager->GetPane("global_settings")->Float->Show(1);
1025    $self->manager->Update();   
1026}
1027
1028sub OnChooseLanguage {
1029    my ( $self ) = @_; 
1030
1031  my $languages = wxTheApp->available_languages;
1032
1033
1034  my $dialog = new Wx::SingleChoiceDialog( 
1035    undef, 
1036    gettext( "Choose a language" ), 
1037    gettext( "Choose a language" ),
1038    [ map { sprintf($_->[0], gettext($_->[2])) } @$languages ] 
1039  );
1040
1041  if( $dialog->ShowModal() == wxID_OK ) {
1042    wxTheApp->current_language(
1043        $languages->[$dialog->GetSelection][1]
1044    );
1045
1046    Wx::LogMessage(
1047        sprintf(
1048            "%s : %s", 
1049            gettext("pLoader needs to be restarted to display the new selected language"),
1050            gettext($languages->[$dialog->GetSelection][2])
1051        )
1052    );
1053    wxTheApp->layout_clean(1);
1054  }
1055
1056  $dialog->Destroy;
1057
1058}
1059
1060sub OnDefaultPhotoNameChanged {
1061    my ( $self ) = @_;
1062   
1063    Wx::LogMessage("New default_photo_name %s", $self->imagelist->default_photo_name); 
1064}
1065
1066
1067sub create_notebook_imagelist {
1068    my( $self ) = @_;
1069    my $book = Wx::AuiNotebook->new( $self, -1, [-1, -1], [300, 450],
1070                                     wxBORDER_NONE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT);
1071
1072        my $imglistpage = [
1073            [
1074                $self->imageviewer, 
1075                gettext("Photo selection"),
1076                '../res/images.png', 
1077                wxBITMAP_TYPE_PNG,
1078            ],
1079        ];
1080
1081    $self->notebook($book);
1082    $self->_populate_notebook($self->notebook, $imglistpage, 0);
1083    return $book;
1084}
1085
1086sub create_notebook_image_properties {
1087    my( $self ) = @_;
1088    my $book = Wx::AuiNotebook->new( $self, -1, [-1, -1], [450, 450],
1089                                     wxBORDER_NONE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT);
1090    my $pages = [   
1091        [
1092            $self->image_prop_piwigo, 
1093            "Piwigo",
1094        ],
1095        [
1096            $self->image_prop_tags, 
1097            "Tags",
1098        ],
1099        [
1100            $self->image_prop_exif, 
1101            "Exif",
1102        ],
1103    ];
1104   
1105    $self->_populate_notebook( $book, $pages );
1106
1107    $self->notebook_image_properties($book);
1108
1109    return $book;
1110}
1111
1112sub create_notebook_global_settings {
1113    my( $self ) = @_;
1114    my $book = Wx::AuiNotebook->new( $self, -1, [-1, -1], [450, 450],
1115                                     wxBORDER_NONE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT);
1116    my $pages = [   
1117        [
1118            $self->general_settings_panel, 
1119            gettext("General"),
1120        ],
1121        [
1122            $self->resized_settings_panel, 
1123            gettext("Resized"),
1124        ],
1125        [
1126            $self->thumbnail_settings_panel, 
1127            gettext("Thumbnail"),
1128        ],
1129        [
1130            $self->hd_settings_panel, 
1131            gettext("High definition"),
1132        ],
1133        [
1134            $self->watermark_settings_panel,
1135            gettext("Watermark"),
1136        ],   
1137        [
1138            $self->advanced_settings_panel, 
1139            gettext("Advanced"),
1140        ],
1141    ];
1142   
1143    $self->_populate_notebook( $book, $pages );
1144
1145    $self->notebook_global_settings($book);
1146
1147    return $book;
1148}
1149
1150
1151
1152
1153sub create_tree {
1154    my ( $self ) = @_;
1155
1156    my $images = [
1157        map {
1158            Wx::Bitmap->new( $_, wxBITMAP_TYPE_PNG )
1159               
1160        }
1161        (
1162          '../res/tree_pwg.png',
1163          '../res/tree_folder.png',
1164        )   
1165    ];
1166
1167    $self->treeimglist( Wx::ImageList->new( 16, 16, 1 ) );
1168    map {
1169        $self->treeimglist->Add($_);
1170    }
1171    @$images;
1172
1173   
1174    $self->tree( 
1175        Wx::TreeCtrl->new( 
1176           $self, 
1177           -1, 
1178           wxDefaultPosition, 
1179           wxDefaultSize, 
1180           wxBORDER_NONE|
1181           wxCLIP_CHILDREN|
1182           wxTR_HAS_BUTTONS|
1183           wxTR_EDIT_LABELS
1184        ) 
1185    );
1186
1187    $self->tree->SetImageList( $self->treeimglist );
1188    $self->populate_tree_categories if !wxTheApp->use_offline;
1189    $self->tree ;
1190}
1191
1192
1193sub populate_tree_categories {
1194    my ( $self ) = @_;
1195
1196    $self->populate_tree(
1197        $self->tree,
1198        wxTheApp->pwg->categories,
1199    ) if defined wxTheApp->pwg ;
1200   
1201    #$self->tree->ExpandAll;
1202
1203}
1204
1205
1206# returns a valid itemData
1207sub itemData { Wx::TreeItemData->new( $_[0] ) }
1208
1209sub populate_tree {
1210    my ( $self, $tree, $tree_items ) = @_;
1211    my $root = shift @{$tree_items};
1212
1213    $self->tree_root(
1214        $tree->AddRoot( 
1215            $root->[0], 
1216            $root->[3], 
1217            $root->[4], 
1218            itemData( $root->[2] ) 
1219        )
1220    );
1221
1222  $self->populate_tree_helper( $tree, $self->tree_root, $tree_items );
1223 
1224  $tree->SelectItem( $self->tree_root );
1225  $tree->Expand( $self->tree_root );
1226}
1227
1228sub populate_tree_helper {
1229  my ( $self, $tree, $parent_id, $tree_items ) = @_;
1230
1231  my $id;
1232
1233  map {
1234      my $name = $_->[0];
1235
1236      $id = $tree->AppendItem( 
1237                                   $parent_id, 
1238                                   $name,
1239                                   defined($_->[3]) ? $_->[3] : 0, 
1240                                   defined($_->[4]) ? $_->[4] : 0, 
1241                                   itemData( $_->[2]) 
1242                              );
1243      $self->tree_item_default($id) if ! defined $self->tree_item_default;
1244      # current item has children
1245      if( ref( $_->[1] ) eq 'ARRAY' ) {
1246          $self->populate_tree_helper( $tree, $id, $_->[1] );
1247      } 
1248  }
1249  @{$tree_items};
1250
1251}
1252
1253
1254
1255
1256sub _populate_notebook {
1257    my ( $self, $book, $pages, $position ) = @_;       
1258
1259    my $i = 0;
1260    map {
1261        my $icon = Wx::Icon->new();
1262        eval { $icon->LoadFile($_->[2], $_->[3]) ; }
1263            if defined $_->[2];
1264        my $nb_icon = Wx::Bitmap->new( $icon );
1265        defined $position ?
1266            $book->InsertPage($position, $_->[0],
1267                    $_->[1], 1, $nb_icon )
1268                          :
1269            $book->AddPage($_->[0],
1270                    $_->[1], 0, $nb_icon );
1271
1272        $i++;
1273    } @$pages;
1274
1275}
1276
1277
1278sub _initMenus {
1279    my ( $self ) = @_ ;
1280
1281    $self->_tree_mnu;
1282    $self->_imageviewer_mnu;   
1283}
1284
1285
1286sub _tree_mnu {
1287    my ( $self ) = @_; 
1288
1289    my $ctx_mnu = Wx::Menu->new;
1290   
1291    map {
1292        $ctx_mnu->Append(
1293            @$_[0..2], wxITEM_NORMAL
1294        )->SetBitmap(Wx::Bitmap->new($_->[3],wxBITMAP_TYPE_PNG));
1295    }
1296    (
1297        # workaround : first item does not show bitmap
1298        [
1299            0, 
1300            "",
1301            "",
1302            '../res/mnu_folder_new.png',
1303        ],
1304        [
1305            1+$ID_TREE_CTX_MENU, 
1306            wxTheApp->branding->{'Add new category'},
1307            sprintf(
1308                "%s %s %s %s", 
1309                gettext("Add a new"), 
1310                wxTheApp->branding->{category},
1311                gettext("to the currently selected"),
1312                wxTheApp->branding->{category},
1313            ),
1314            '../res/mnu_folder_new.png',
1315        ],
1316        [
1317            2+$ID_TREE_CTX_MENU, 
1318            gettext("Refresh"),
1319            sprintf(
1320                "Refresh %s list.",
1321                wxTheApp->branding->{category},
1322            ),
1323            '../res/mnu_refresh.png',
1324        ],
1325        [
1326            3+$ID_TREE_CTX_MENU, 
1327            gettext("Expand all"),
1328            sprintf(
1329                "Expand %s list.",
1330                wxTheApp->branding->{category},
1331            ),
1332            '../res/mnu_expandall.png',
1333        ],
1334        [
1335            4+$ID_TREE_CTX_MENU, 
1336            gettext("Collapse all"),
1337            sprintf(
1338                "Collapse %s list.",
1339                wxTheApp->branding->{category},
1340            ),
1341            '../res/mnu_collapseall.png',
1342        ],
1343    );
1344
1345    $ctx_mnu->Delete(0);
1346    $self->tree_mnu(
1347         $ctx_mnu
1348    ); 
1349}       
1350
1351sub _imageviewer_mnu {
1352    my ( $self ) = @_; 
1353
1354    my $ctx_mnu = Wx::Menu->new;
1355   
1356    map {
1357        $ctx_mnu->Append(
1358            @$_[0..2]
1359        )->SetBitmap(Wx::Bitmap->new($_->[3],wxBITMAP_TYPE_PNG));
1360    }
1361    (
1362        # workaround : first item does not show bitmap
1363        [
1364            0, 
1365            "",
1366            "",
1367            '../res/mnu_properties.png',
1368        ],
1369        [
1370            1+$ID_IMAGEVIEWER_CTX_MENU, 
1371            gettext("Properties"),
1372            gettext("Modify photo properties"),
1373            '../res/mnu_properties.png',
1374        ],
1375        [
1376            2+$ID_IMAGEVIEWER_CTX_MENU, 
1377            gettext("Preview"),
1378            gettext("Display photo preview"),
1379            '../res/mnu_preview.png',
1380        ],
1381    );
1382       
1383    $ctx_mnu->Delete(0);
1384    $self->imageviewer_mnu(
1385         $ctx_mnu
1386    ); 
1387}
1388
1389sub _initEventHandlers {
1390    my ( $self ) = @_ ;
1391       
1392    Wx::Event::EVT_MENU( $self, 100, \&OnGettingStarted );
1393    Wx::Event::EVT_MENU( $self, 101, \&OnAddImages );
1394    Wx::Event::EVT_MENU( $self, 102, \&OnRemoveImages );
1395    Wx::Event::EVT_MENU( $self, 103, \&OnUploadImages );
1396    Wx::Event::EVT_MENU( $self, 104, \&OnGlobalSettings );
1397    Wx::Event::EVT_MENU( $self, 105, \&OnChooseLanguage );
1398    EVT_TREE_SEL_CHANGED( $self, $self->tree, \&OnTreeSelChanged );
1399    EVT_TREE_ITEM_RIGHT_CLICK( $self, $self->tree, \&OnTreeItemRightClick );
1400    EVT_TREE_END_LABEL_EDIT( $self, $self->tree, \&OnTreeEndLabelEdit );
1401
1402    EVT_LIST_END_LABEL_EDIT( $self, $self->imageviewer, \&OnImageViewerEndLabelEdit );
1403    EVT_LIST_ITEM_ACTIVATED( $self, $self->imageviewer, \&OnImageViewerItemActivated );
1404    EVT_LIST_ITEM_SELECTED($self, $self->imageviewer, \&OnImageViewerItemSelected) ;
1405    EVT_LIST_ITEM_RIGHT_CLICK($self, $self->imageviewer, \&OnImageViewerItemRightClick) ;
1406
1407    EVT_LIST_KEY_DOWN($self, $self->imageviewer, \&OnImageViewerKeyDown) ;
1408
1409    EVT_CLOSE( $self, \&OnClose );
1410    Wx::Event::EVT_UPDATE_UI( $self, $self, \&OnUpdateUI );
1411
1412
1413    Wx::Event::EVT_MENU( $self, 1+$ID_TREE_CTX_MENU, \&OnAddCategories );
1414    Wx::Event::EVT_MENU( $self, 2+$ID_TREE_CTX_MENU, \&OnRefreshCategories );
1415    Wx::Event::EVT_MENU( $self, 3+$ID_TREE_CTX_MENU, \&OnExpandCategories );
1416    Wx::Event::EVT_MENU( $self, 4+$ID_TREE_CTX_MENU, \&OnCollapseCategories );
1417
1418    Wx::Event::EVT_MENU( $self, 1+$ID_IMAGEVIEWER_CTX_MENU, \&OnPhotoProperties );
1419    Wx::Event::EVT_MENU( $self, 2+$ID_IMAGEVIEWER_CTX_MENU, \&OnPreview );
1420
1421
1422}
1423
1424{
1425  my $prevdir;
1426  my $prevfile;
1427
1428  sub OnAddImages {
1429    my( $self, $event ) = @_;
1430    my $dialog = Wx::FileDialog->new
1431      ( $self, gettext("Select photos for upload"), $prevfile, $prevdir,
1432        sprintf("%s (*.jpg)|*.jpg|All(*.*)|*.*", gettext("JPEG files")),
1433        wxFD_OPEN|wxFD_MULTIPLE );
1434
1435    my $file_paths = [];
1436    if( $dialog->ShowModal != wxID_CANCEL ) {
1437        @$file_paths = $dialog->GetPaths;
1438        $self->SetNewFiles($file_paths) ;
1439    }
1440    $dialog->Destroy;
1441#    $event->Skip;
1442  }
1443}
1444
1445sub OnUpdateUI {
1446    my( $self, $event ) = @_;
1447   
1448    if( $self->manager ){
1449        if($self->manager->GetPane("global_settings")->IsShown){
1450            $self->toolbar->EnableTool(104, 0);                 
1451        }
1452        else{
1453            $self->toolbar->EnableTool(104, 1);                 
1454        }
1455
1456        if($self->manager->GetPane("getting_started")->IsShown){
1457            $self->toolbar->EnableTool(100, 0);                 
1458        }
1459        else{
1460            $self->toolbar->EnableTool(100, 1);                 
1461        }
1462    }
1463
1464}
1465
1466sub OnRemoveImages {
1467    my( $self, $event ) = @_;
1468
1469   
1470    $self->imagelist->RemoveImageSelection;
1471    $self->imageviewer->Refresh;       
1472
1473    $self->image_preview->image(
1474        0
1475    ) if !$self->imageviewer->GetItemCount;
1476
1477    $self->image_preview->Refresh;
1478}
1479
1480sub SetNewFiles {
1481    my ( $self, $file_paths ) = @_;
1482
1483    $self->ShowImageViewer();
1484    $self->progressdlg( 
1485        Uploader::GUI::wxImageProcessingProgressDlg->new(
1486            { 
1487                title => gettext("Image processing progress information"),
1488                bt_label => gettext("Cancel image processing"), 
1489                bt_close_label => gettext("Close"), 
1490             }
1491        )       
1492    );
1493    $self->progressdlg->Show(1);
1494    Wx::Yield();
1495
1496   
1497    my $files = [
1498        map {
1499            # to make sure that unicode chars in filenames are supported
1500            {
1501                ANSIPathName => $^O =~ /MSWin32/ ? Win32::GetANSIPathName($_) : $_,
1502                PathName => $_,
1503            },
1504        }@$file_paths   
1505    ];
1506
1507    @$files = sort { $a->{PathName} cmp $b->{PathName} } @$files;   
1508
1509    $self->imagelist->SetNewFiles(
1510        $files
1511    );
1512
1513   
1514}
1515
1516sub OnTreeSelChanged {
1517    my( $self, $event ) = @_;
1518 
1519    my @items = $self->tree->GetSelections;
1520
1521    $self->imagelist->categories(
1522        [
1523            map {
1524                my $category = $self->tree->GetPlData( $_ );
1525                $category->{id} if $category != -1;
1526            }
1527            @items
1528        ]
1529    );
1530}
1531
1532sub OnTreeItemRightClick {
1533    my( $self, $event ) = @_;
1534
1535
1536    $self->PopupMenu($self->tree_mnu, wxDefaultPosition);
1537       
1538}
1539
1540sub OnTreeEndLabelEdit {
1541    my( $self, $event ) = @_;
1542
1543    my $label = $event->GetLabel;
1544   
1545    $label =~ s/^\s+$//;
1546
1547    if(defined($label) and !( "" eq $label )){
1548        $self->_SetLabel($event)
1549    }
1550    else{
1551        $event->Veto;
1552    }
1553}
1554
1555sub _SetLabel {
1556    my( $self, $event ) = @_;
1557       
1558    my $category = $self->tree->GetPlData($event->GetItem);
1559    my $category_id;
1560   
1561    $category_id = $category->{id} if 'HASH' eq ref($category) ;
1562    my $comment;
1563    my ( $success, $status_msg, $content ) = $self->pwg->SetInfoCategories( 
1564        $event->GetLabel, 
1565        $comment, 
1566        $category_id
1567    );
1568
1569    my $ok = 1;
1570   
1571    if(!$success){
1572        $ok = 0;
1573    }
1574
1575    if('fail' eq $content->{stat}){
1576        $ok = 0;
1577    }
1578
1579    # method call failed
1580    if(!$ok){
1581        $event->Veto;
1582        Wx::MessageBox( 
1583            sprintf(
1584                "%s %s", 
1585                gettext("Update failed : "),
1586                $status_msg
1587            ),
1588            gettext("Piwigo update error"),
1589            wxOK | wxICON_EXCLAMATION, 
1590        );
1591        Wx::LogMessage("%s\n\n%s", Dumper($content), gettext("This function is not available. A Piwigo upgrade may resolve this issue."));
1592    }
1593}
1594
1595sub OnImageViewerItemRightClick {
1596    my( $self, $event ) = @_;
1597
1598   
1599    $self->PopupMenu($self->imageviewer_mnu, wxDefaultPosition);
1600       
1601       
1602}
1603
1604sub OnExpandCategories {
1605    my ( $self, $event ) = @_;
1606
1607    my $parent_item = $self->tree->GetSelection;
1608    $self->tree->ExpandAllChildren($parent_item);
1609    $self->tree->EnsureVisible($parent_item);
1610}
1611
1612sub OnCollapseCategories {
1613    my ( $self, $event ) = @_;
1614
1615    my $parent_item = $self->tree->GetSelection;
1616    $self->tree->CollapseAllChildren($parent_item);
1617    $self->tree->Expand($parent_item) if -1 == $self->tree->GetPlData($parent_item);
1618}
1619
1620sub OnAddCategories {
1621    my ( $self, $event ) = @_;
1622
1623    my $parent_item = $self->tree->GetSelection;
1624
1625    my $category = $self->tree->GetPlData($parent_item);
1626    my $category_id;
1627   
1628    $category_id = $category->{id} if 'HASH' eq ref($category) ;
1629
1630    my $dialog = Wx::TextEntryDialog->new( 
1631        $self, 
1632        wxTheApp->branding->{'Category name'}, 
1633        wxTheApp->branding->{'Add new category'},
1634        wxTheApp->branding->{'New category'}, 
1635    );
1636
1637    if( $dialog->ShowModal != wxID_CANCEL ) {
1638        my $name = $dialog->GetValue;
1639        my ( $success, $status_msg, $content ) = $self->pwg->AddCategories( $name, $category_id);
1640
1641        if($success){
1642            $self->_append_category($parent_item, $name, $content->{result}{id});
1643        }
1644    }
1645    $dialog->Destroy;
1646}
1647
1648sub OnRefreshCategories {
1649    my ( $self, $event ) = @_;
1650
1651    $self->_refresh_all_categories_helper;
1652}
1653
1654
1655sub _refresh_all_categories_helper {
1656    my ( $self ) = @_; 
1657
1658    my $busycursor = Wx::BusyCursor->new();
1659    $self->tree->CollapseAll;
1660    $self->tree->DeleteAllItems;
1661    $self->imagelist->categories([]);
1662    $self->pwg->RefreshCategories();
1663    $self->populate_tree_categories;
1664}
1665
1666sub _append_category {
1667    my ( $self, $parent_id, $name, $id ) = @_;
1668
1669    $self->tree->SelectItem(
1670        $self->tree->AppendItem(
1671            $parent_id, 
1672            $name, 
1673            1, 
1674            -1, 
1675            Wx::TreeItemData->new( { id => $id } )
1676        )
1677    );
1678}
1679
1680sub OnImageViewerEndLabelEdit {
1681    my( $self, $event ) = @_;
1682 
1683    my $image = $self->imagelist->GetImage($event->GetIndex);
1684    $image->site_name(
1685        $event->GetLabel
1686    );
1687       
1688    $self->image_prop_piwigo->Refresh;
1689}
1690
1691sub OnImageViewerItemActivated {
1692    my( $self, $event ) = @_;
1693   
1694    $self->current_imageviewer_index(
1695        $event->GetIndex
1696    );
1697
1698    $self->OnPhotoProperties;
1699}
1700
1701
1702sub OnImageViewerItemSelected {
1703    my( $self, $event ) = @_;
1704 
1705    my $bc = Wx::BusyCursor->new;
1706
1707    my $indx = $event->GetIndex;
1708
1709    $self->_on_imageviewer_item_selected($indx);
1710
1711    $event->Skip;
1712}
1713
1714sub _on_imageviewer_item_selected {
1715    my ( $self, $index ) = @_; 
1716    $self->current_imageviewer_index($index);
1717    $self->imagelist->SetCurrentImage($index);
1718   
1719    $self->imagelist->image_selection(
1720        $self->imageviewer->GetSelectedItems
1721    );
1722       
1723        # image preview has a cost, don't do if useless.
1724        if ( $self->image_preview->IsShown ){
1725        $self->_image_preview_refresh; 
1726        $self->image_preview->Refresh;
1727        }
1728
1729    $self->image_prop_piwigo->Refresh;
1730    $self->image_prop_exif->Refresh;
1731    $self->image_prop_tags->Refresh;
1732
1733}
1734
1735sub _image_preview_refresh {
1736    my ( $self ) = @_; 
1737
1738        my $current_image = $self->imagelist->current_image;
1739    my $image = Wx::Image->new;
1740    $image->LoadFile(
1741        $current_image->file, 
1742        wxBITMAP_TYPE_ANY
1743    );
1744 
1745    if($self->imagelist->auto_rotate){
1746        # exif from original image
1747        my $orientation = $current_image->exif_metadata->{Orientation};
1748
1749        # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
1750        if( $orientation =~ m/Rotate (\d+)/ ){
1751                        for(my $i=0; $i < floor($1/90) ; $i++){
1752                $image = $image->Rotate90;
1753            }                           
1754        }
1755    }
1756
1757  $self->image_preview->image_size(
1758      [$image->GetWidth, $image->GetHeight, ]
1759  );       
1760
1761  $self->image_preview->image(
1762      $image
1763  );       
1764 
1765}
1766
1767sub OnImageViewerKeyDown {
1768    my( $self, $event ) = @_;
1769
1770    if(WXK_DELETE == $event->GetKeyCode){
1771        $self->OnRemoveImages();
1772       
1773        my $index = $self->current_imageviewer_index < $self->imageviewer->GetItemCount ?
1774            $self->current_imageviewer_index : $self->imageviewer->GetItemCount -1 ;
1775        $self->imageviewer->SelectItem(
1776            $index
1777        );
1778        $self->imageviewer->EnsureVisible(
1779            $index
1780        );
1781    }   
1782
1783}
1784
1785sub OnUploadImages {
1786    my( $self, $event ) = @_;
1787
1788    eval {
1789        $self->ProcessImageSelection();   
1790    };
1791}
1792
1793# remove image from imagelist when uploaded
1794sub UploadImagesViewerRefresh {
1795    my ( $self ) = @_; 
1796
1797
1798    $self->imageviewer->Refresh;
1799
1800    $self->image_preview->image(
1801        0
1802    ) if !$self->imageviewer->GetItemCount;
1803
1804
1805    $self->image_preview->Refresh;
1806    Wx::Yield();
1807}
1808
1809sub UploadProgressMessageRefresh {
1810    my ( $self, $msg ) = @_;   
1811
1812    Wx::Yield();
1813
1814    $self->upload_progressdlg->processing(
1815        $msg   
1816    ); 
1817    $self->upload_progressdlg->LogProgress();
1818
1819    Wx::Yield();
1820}
1821
1822sub UploadProgressMessageDetailsRefresh {
1823    my ( $self, $msg ) = @_;   
1824
1825    Wx::Yield();
1826
1827    $self->upload_progressdlg->processing_details(
1828        $msg   
1829    ); 
1830    $self->upload_progressdlg->LogProgress();
1831
1832    Wx::Yield();
1833}
1834
1835
1836sub UploadProgressThumbnailRefresh {
1837    my ( $self ) = @_; 
1838
1839    my $imagelist = $self->imagelist ;
1840
1841 
1842    $self->upload_progressdlg->image->SetBitmap(wxNullBitmap);
1843    $self->upload_progressdlg->image->SetBitmap(
1844        Wx::Bitmap->new( 
1845            $self->imagelist->current_image->wx_thumb_file, 
1846            $self->GetWxBitmapType($self->imagelist->type), 
1847        )
1848    );
1849
1850    Wx::Yield();
1851}
1852
1853sub UploadProgressBarRefresh {
1854    my ( $self, $value ) = @_; 
1855
1856    eval {
1857        $self->upload_progressdlg->progress(
1858            $value
1859        );
1860        $self->upload_progressdlg->LogProgress();
1861    };
1862    #croak gettext("Upload cancelled") if $@;
1863
1864    Wx::Yield();
1865}
1866
1867sub SetNewFilesDisplayEndInfo {
1868    my ( $self, $msg ) = @_;   
1869       
1870    $self->progressdlg->DisplayEndInfo($msg);
1871}
1872
1873sub UploadDisplayEndInfo {
1874    my ( $self, $msg ) = @_;   
1875   
1876    my $imagelist = $self->imagelist ;
1877   
1878    $self->upload_progressdlg->DisplayEndInfo($msg);
1879}
1880
1881sub ShowImageViewer {
1882    my ( $self ) = @_; 
1883
1884    if(!$self->imageviewer->IsShown){
1885        $self->imageviewer->Show(1);
1886    }
1887}
1888
1889
1890sub ActivateImageViewer {
1891    my ( $self ) = @_; 
1892       
1893}
1894
1895
1896sub SetNewFilesViewerRefresh {
1897
1898    my ( $self ) = @_; 
1899
1900    my $wximagelist = $self->imagelist->wx_thumb_imglist;
1901    #print Dumper "SetNewFilesViewerRefresh", $self->imagelist->current_image;
1902    my $indx = $wximagelist->Add(
1903        Wx::Bitmap->new( 
1904            $self->imagelist->current_image->wx_thumb_file, 
1905            $self->GetWxBitmapType($self->imagelist->type), 
1906        )
1907    ) if defined $self->imagelist->current_image->wx_thumb_file;
1908    print $self->imagelist->current_image->wx_thumb_file, " added with index ", $indx, "\n";   
1909       
1910    $self->imageviewer->Refresh(
1911        $wximagelist
1912    );
1913
1914    Wx::Yield();
1915}
1916
1917
1918
1919# prepare and upload image_selection
1920sub ProcessImageSelection {
1921    my ( $self ) = @_;
1922
1923    return if !scalar @{$self->imagelist->sums};
1924
1925    if( scalar @{$self->imagelist->categories} ){
1926        # all selected is implicit
1927        if(!scalar @{$self->imageviewer->GetSelectedItems}){
1928       
1929            $self->imagelist->image_selection(
1930                $self->imageviewer->GetAllItems
1931            );
1932        }
1933       
1934        return if( !defined $self->imagelist->image_selection );
1935        return if( !scalar @{$self->imagelist->image_selection} );
1936       
1937        $self->upload_progressdlg(
1938            Uploader::GUI::wxImageProcessingProgressDlg->new(
1939                { 
1940                    title    => gettext("Image upload progress information"),
1941                    bt_label => gettext("Cancel upload"),
1942                    bt_close_label => gettext("Close"), 
1943                 }
1944            )       
1945        );
1946        # modeless dialog
1947        $self->upload_progressdlg->Show(1);
1948        Wx::Yield();
1949        eval {
1950            $self->imagelist->UploadSelection;
1951        };
1952        if($@){
1953            Wx::MessageBox( 
1954                sprintf(
1955                    gettext("Upload cancelled"),
1956                ),
1957                gettext("Piwigo upload information"),
1958                wxOK | wxICON_INFORMATION, 
1959            );
1960        }
1961    }
1962    else {
1963        Wx::MessageBox( 
1964            sprintf(
1965                "%s %s", 
1966                gettext("Please select a valid target"),
1967                wxTheApp->branding->{category}
1968            ),
1969            gettext("Piwigo upload error"),
1970            wxOK | wxICON_EXCLAMATION, 
1971        );
1972    }
1973}
1974
1975
1976sub SetNewFilesProgress {
1977    my ( $self ) = @_;
1978
1979    my $imagelist = $self->imagelist;
1980
1981    $self->progressdlg->processing(
1982        sprintf(
1983            $imagelist->progress_msg, 
1984            $imagelist->current_image->file,
1985        )
1986    );
1987
1988    eval {
1989        $self->progressdlg->image->SetSize([ $imagelist->wx_thumb_size, $imagelist->wx_thumb_size]);
1990        $self->progressdlg->image->SetBitmap(wxNullBitmap);
1991        $self->progressdlg->image->SetBitmap(
1992            Wx::Bitmap->new( 
1993                $imagelist->current_image->wx_thumb_file,
1994                $self->GetWxBitmapType( $imagelist->type )
1995            )
1996        );
1997        $self->progressdlg->progress(
1998            $imagelist->count * ( 100/scalar @{$imagelist->new_files} )
1999        );
2000        $self->progressdlg->LogProgress();
2001    };
2002    Wx::Yield();
2003}
2004
2005sub OnClose {
2006  my $self = shift;
2007
2008
2009    # Restaure previous log wnd
2010    Wx::Log::SetActiveTarget( $self->oldlogwnd );
2011
2012    # allways store
2013 
2014    wxTheApp->StoreConnectionProperties;
2015   
2016    $self->imagelist->Store;
2017    wxTheApp->login_dlg->Destroy;       
2018
2019    wxTheApp->perspective(
2020        $self->manager->SavePerspective
2021    );
2022   
2023    wxTheApp->imageviewerIndex(
2024        $self->current_imageviewer_index
2025    );
2026   
2027    my $frameLayout = {};
2028   
2029    ( $frameLayout->{pX}, $frameLayout->{pY}, $frameLayout->{W}, $frameLayout->{H} ) = ( $self->GetPositionXY, $self->GetSizeWH ) ; 
2030   
2031    wxTheApp->frameLayout(
2032        $frameLayout
2033    );
2034
2035    wxTheApp->StoreLayoutProperties;
2036
2037    $self->manager->UnInit;
2038    $self->Destroy;
2039}
2040
2041
2042sub create_toolbar {
2043    my( $self ) = @_;
2044
2045    my $tb = Wx::ToolBar->new( $self, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT );
2046    $tb->SetToolBitmapSize( wxSIZE( 32, 32 ) );
2047    map {
2048        my $icon1 = Wx::Icon->new();
2049        eval {
2050            $icon1->LoadFile($_->[2], $_->[3]);
2051        };
2052        my $tb_icon1 = Wx::Bitmap->new( $icon1 );
2053
2054        my $icon2 = Wx::Icon->new();
2055        eval {
2056            $icon2->LoadFile($_->[5], $_->[3]);
2057        };
2058        my $tb_icon2 = Wx::Bitmap->new( $icon2 );
2059
2060
2061        $tb->AddTool( $_->[0], $_->[1], $tb_icon1, $tb_icon2, wxITEM_NORMAL, $_->[1] );
2062        $tb->EnableTool( $_->[0], $_->[4]);
2063    }
2064    (
2065        [
2066            100, 
2067            gettext("Getting started"), 
2068            '../res/tb_getting_started.png', 
2069            wxBITMAP_TYPE_PNG, 
2070            1, 
2071            '../res/tb_getting_started.png', 
2072            gettext("Display getting started panel")
2073        ],
2074        [
2075            101, 
2076            gettext("Add photo to selection"), 
2077            '../res/tb_add.png', 
2078            wxBITMAP_TYPE_PNG, 
2079            1, 
2080            '../res/tb_add.png', 
2081            gettext("Add photo to selection for resizing and uploading")
2082        ],
2083        [
2084            102, 
2085            gettext("Remove photo from selection"), 
2086            '../res/tb_remove.png', 
2087            wxBITMAP_TYPE_PNG, 
2088            1, 
2089            '../res/tb_remove.png',
2090            gettext("Remove photo from selection. Files are not deleted ")
2091        ],
2092        [
2093            103, 
2094            gettext("Upload to Piwigo"), 
2095            '../res/tb_upload.png', 
2096            wxBITMAP_TYPE_PNG, 
2097            wxTheApp->use_offline ? 0 : 1, 
2098            '../res/tb_upload.png',
2099            gettext("Upload photos to Piwigo.")
2100        ],
2101        [
2102            104, 
2103            gettext("Global settings"), 
2104            '../res/tb_settings.png', 
2105            wxBITMAP_TYPE_PNG, 
2106            0, 
2107            '../res/tb_settings.png',
2108            gettext("Change global settings.")
2109        ],
2110        [
2111            105, 
2112            gettext("Language choice"), 
2113            '../res/tb_i18n.png', 
2114            wxBITMAP_TYPE_PNG, 
2115            1, 
2116            '../res/tb_i18n.png',
2117            gettext("Language choice")
2118        ],
2119   
2120    );
2121
2122    if($@){
2123        undef $tb;
2124    }
2125    else{
2126        $tb->Realize;
2127    }
2128
2129    return $tb;
2130}
2131
2132
2133sub _create_textctrl {
2134    my( $self, $parent, $text, $size ) = @_;
2135
2136    return Wx::TextCtrl->new( $parent, -1, $text, [0, 0], $size,
2137                              wxNO_BORDER | wxTE_MULTILINE | wxTE_READONLY  );
2138}
2139
2140sub create_textctrl {
2141    my( $self, $text, $size ) = @_;
2142
2143    return $self->_create_textctrl( $self, $text, $size );
2144}
2145
2146sub DESTROY {
2147    my( $self ) = @_;
2148
2149}
2150
2151
2152
21531;
2154
2155
2156
2157
2158
2159package DNDImageListDropTarget;
2160use Wx qw/wxTheApp/;
2161use base qw(Wx::FileDropTarget Class::Accessor::Fast);
2162
2163__PACKAGE__->mk_accessors( 
2164    qw/
2165          imageviewer
2166      /
2167);
2168
2169sub new {
2170  my $class = shift;
2171  my $imageviewer = shift;
2172  my $self = $class->SUPER::new( @_ );
2173
2174  $self->imageviewer($imageviewer);
2175
2176  return $self;
2177}
2178
2179sub OnDropFiles {
2180  my( $self, $x, $y, $files ) = @_;
2181
2182  wxTheApp->frame->SetNewFiles($files) ;
2183}
2184
2185
2186
2187
21881;
2189
2190
2191package DNDCategoryTreeDropTarget;
2192
2193use base qw(Wx::TextDropTarget Class::Accessor::Fast);
2194use Data::Dumper;
2195use Wx qw/
2196              wxDragNone
2197              wxDragCopy
2198              wxDragMove
2199         /;
2200
2201__PACKAGE__->mk_accessors( 
2202    qw/
2203          tree
2204          frame
2205      /
2206);
2207
2208sub new {
2209  my ( $class, $tree ) = @_;
2210  my $self = $class->SUPER::new();
2211
2212  $self->tree($tree);
2213  $self->frame($tree->GetParent);
2214  return $self;
2215}
2216
2217
2218
2219sub OnDropText {
2220  my( $self, $x, $y, $textdata ) = @_;
2221
2222  # must be $VAR1 because $textdata is the result of Data::Dumper
2223  my $VAR1;
2224  eval $textdata;
2225  eval {
2226      if(scalar @$VAR1){
2227           my @items;
2228           if(scalar @items < 2) {
2229               my ($dropItem, $flag) = $self->tree->HitTest([$x, $y]);
2230                push @items, $dropItem;
2231           }
2232           else {
2233                @items = $self->tree->GetSelections;
2234           }
2235           
2236           # remove root item which is not a valid category
2237           @items = grep { $self->tree->GetPlData( $_ ) != -1 } @items;
2238           
2239           $self->frame->imagelist->categories(
2240               [
2241                   map {
2242                       $self->tree->GetPlData( $_ )->{id};
2243                   }
2244                   @items
2245               ]
2246           );
2247           
2248           $self->frame->imagelist->image_selection($VAR1);
2249           $self->frame->ProcessImageSelection ;
2250      } 
2251  };
2252}
2253
22541;
Note: See TracBrowser for help on using the repository browser.