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

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

Bug 1355 fixed : missing properties for thumbnail in Global Settings panel.

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