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

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

Bug 1322 fixed : clear photo properties panel after the last photo is deleted from photo selection.

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