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

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

Feature 1055 added : preparation of high definition images ( HD ).

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