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

Revision 4468, 58.8 KB checked in by ronosman, 10 years ago (diff)

Remove reference to missing module wxPhotoProperties.

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