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

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

Feature 1369 added : no longer use relative path to access resource and locale directories.

  • Property svn:eol-style set to LF
File size: 60.0 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 = wxTheApp->locale_catalog_path('gs.html');
817
818    $self->htmlhome(
819        Uploader::GUI::wxHtmlWindow->new(
820            $self, -1, [-1, -1], [450, 450]
821        )
822    );
823   
824    $self->htmlhome->LoadPage($file) if -e $file ;
825   
826    $self->htmlhome->InitHrefCallbacks(
827        {
828            new_album => sub {$self->OnAddCategories(@_) },
829            add_photos => sub { $self->OnAddImages(@_) },
830            upload_photos => sub { $self->ProcessImageSelection(@_)},   
831        }
832    );
833   
834    $self->imageviewer(
835        Uploader::GUI::wxImageListCtrl->new( 
836            { 
837                parentwnd => $self,
838                imagelist => $self->imagelist,
839                image_size => $self->imagelist->wx_thumb_size,
840                columns => $self->piwigo_property_list,
841            }
842        )
843    );
844   
845    $self->_init_settings_panels;   
846}
847
848sub init_dnd_targets {
849    my ( $self ) = @_;   
850
851    $self->imageviewer->SetDropTarget( 
852        DNDImageListDropTarget->new(
853            $self->imageviewer
854        ) 
855    );
856
857    $self->tree->SetDropTarget( 
858        DNDCategoryTreeDropTarget->new(
859            $self->tree
860        )
861    );
862   
863}
864
865sub init_aui {
866    my ( $self ) = @_;
867
868    my $url = wxTheApp->site_url;
869   
870    $url = gettext("empty - work Offline") if wxTheApp->use_offline;
871
872    $self->manager->AddPane( 
873        $self->imageviewer, 
874        Wx::AuiPaneInfo->new->Name( "ImageViewer" )
875        ->Left->Position(1)->DefaultPane
876        ->Caption(gettext("Photo selection"))->CaptionVisible
877        ->CloseButton(0)
878        ->MinSize([200, 200])
879    );
880
881    $self->manager->AddPane( 
882        $self->dlg_piwigo_photo_properties, 
883        Wx::AuiPaneInfo->new->Name( "piwigo_photo_properties" )
884        ->CenterPane->Position(0)
885        ->Caption(gettext("Photo properties"))->CaptionVisible
886        ->CloseButton(0)
887    );
888
889    $self->manager->AddPane( 
890        $self->create_tree, 
891        Wx::AuiPaneInfo->new->Name( "categories" )
892        ->CenterPane->Position( 1 ) 
893    );
894
895    $self->_init_aui_settings_panels;
896
897    $self->toolbar(
898        $self->create_toolbar
899    );
900
901    $self->manager->AddPane
902      ( $self->toolbar, Wx::AuiPaneInfo->new->Name( "tb1" )
903        ->ToolbarPane->Top->Row( 1 )->LeftDockable( 0 )->RightDockable( 0 ) ) if defined $self->toolbar;
904
905    $self->SetSize( 
906            $self->frameLayout->{pX}, 
907            $self->frameLayout->{pY}, 
908            $self->frameLayout->{W}, 
909            $self->frameLayout->{H}, 
910    );
911
912
913    if($self->perspective){
914        $self->manager->LoadPerspective($self->perspective);
915    }
916    else {
917        $self->manager->GetPane("tb1")->Caption( gettext("Tools") );
918        $self->manager->GetPane("image_preview")->Caption(gettext("Preview"));
919        $self->manager->GetPane("getting_started")->Caption(gettext("Getting started"));
920        $self->manager->GetPane("photo_properties")->Caption(gettext("Photo exif properties"));
921        $self->manager->GetPane("global_settings")->Caption(gettext("Global settings"));
922    }
923
924    $self->manager->GetPane("categories")->Caption(
925          sprintf("%s", sprintf("Piwigo %s", wxTheApp->branding->{categories}))
926    );
927   
928    $self->manager->Update;
929
930}
931
932
933sub _init_aui_settings_panels {
934    my ( $self ) = @_;   
935
936    $self->manager->AddPane
937      ( $self->image_preview, Wx::AuiPaneInfo->new->Name( "image_preview" )
938        ->DefaultPane->MaximizeButton(1)->MinSize([400,300])->Float->Hide);
939
940    $self->manager->AddPane
941      ( $self->htmlhome, Wx::AuiPaneInfo->new->Name( "getting_started" )
942       ->Left->Position(0)->DefaultPane->CloseButton(1)->Float );
943
944    $self->manager->AddPane
945      ( $self->image_prop_exif, Wx::AuiPaneInfo->new->Name( "photo_properties" )
946        ->DefaultPane->CloseButton(1)->MinSize([200,150])->Float->Hide );
947
948    $self->manager->AddPane
949      ( 
950        $self->global_settings_panel,
951        Wx::AuiPaneInfo->new->Name( "global_settings" )
952        ->Floatable(1)->Dockable(0)->CloseButton(1)->Float->Hide );
953
954}
955
956sub OnPhotoProperties {
957    my ( $self ) = @_;
958
959    $self->manager->GetPane("photo_properties")->Show(1);
960    $self->manager->Update();
961   
962}
963
964sub OnPreview {
965    my ( $self ) = @_;
966
967    my $preview_pane = $self->manager->GetPane("image_preview");
968    if (! $preview_pane->IsShown){
969        $preview_pane->Show(1);
970        $self->manager->Update();
971
972        $self->set_preview_image; 
973        $self->image_preview->Refresh;
974    };
975
976}
977
978sub OnGettingStarted {
979    my ( $self ) = @_;
980
981    $self->manager->GetPane("getting_started")->Show(1);
982    $self->manager->Update();
983   
984}
985
986sub OnGlobalSettings {
987    my ( $self ) = @_;
988
989    $self->manager->GetPane("global_settings")->Show(1);
990    $self->manager->Update();
991}
992
993sub OnChooseLanguage {
994    my ( $self ) = @_;   
995
996  my $languages = wxTheApp->available_languages;
997
998
999  my $dialog = new Wx::SingleChoiceDialog( 
1000    undef, 
1001    gettext( "Choose a language" ), 
1002    gettext( "Choose a language" ),
1003    [ map { sprintf($_->[0], gettext($_->[2])) } @$languages ] 
1004  );
1005
1006  if( $dialog->ShowModal() == wxID_OK ) {
1007    wxTheApp->current_language(
1008        $languages->[$dialog->GetSelection][1]
1009    );
1010
1011    Wx::LogMessage(
1012        sprintf(
1013            "%s : %s", 
1014            gettext("pLoader needs to be restarted to display the new selected language"),
1015            gettext($languages->[$dialog->GetSelection][2])
1016        )
1017    );
1018    wxTheApp->layout_clean(1);
1019  }
1020
1021  $dialog->Destroy;
1022
1023}
1024
1025sub OnDefaultPhotoNameChanged {
1026    my ( $self ) = @_;
1027   
1028    Wx::LogMessage("New default_photo_name %s", $self->imagelist->default_photo_name);   
1029}
1030
1031sub OnGeneralSettingsClose {
1032    my ( $self, $event ) = @_;
1033
1034    $self->manager->GetPane("global_settings")->Hide;
1035    $self->manager->Update();
1036}
1037
1038sub create_tree {
1039    my ( $self ) = @_;
1040
1041    my $images = [
1042        map {
1043            Wx::Bitmap->new( $_, wxBITMAP_TYPE_PNG )
1044           
1045        }
1046        (
1047          wxTheApp->resource_path('tree_pwg.png'),
1048          wxTheApp->resource_path('tree_folder.png'),
1049        )   
1050    ];
1051
1052    $self->treeimglist( Wx::ImageList->new( 16, 16, 1 ) );
1053    map {
1054        $self->treeimglist->Add($_);
1055    }
1056    @$images;
1057   
1058    $self->tree( 
1059        Wx::TreeCtrl->new( 
1060           $self, 
1061           -1, 
1062           wxDefaultPosition, 
1063           wxDefaultSize, 
1064           wxBORDER_NONE|
1065           wxCLIP_CHILDREN|
1066           wxTR_HAS_BUTTONS|
1067           wxTR_EDIT_LABELS
1068        ) 
1069    );
1070
1071    $self->tree->SetImageList( $self->treeimglist );
1072    $self->populate_tree_categories($self->tree) if !wxTheApp->use_offline;
1073    $self->tree ;
1074}
1075
1076
1077sub populate_tree_categories {
1078    my ( $self, $tree ) = @_;
1079
1080    $self->populate_tree(
1081        $tree,
1082        wxTheApp->pwg->categories,
1083    ) if defined wxTheApp->pwg ;
1084   
1085
1086}
1087
1088
1089# returns a valid itemData
1090sub itemData { Wx::TreeItemData->new( $_[0] ) }
1091
1092sub populate_tree {
1093    my ( $self, $tree, $tree_items ) = @_;
1094    my $root = shift @{$tree_items};
1095
1096    $self->tree_root(
1097        $tree->AddRoot( 
1098            $root->[0], 
1099            $root->[3], 
1100            $root->[4], 
1101            itemData( $root->[2] ) 
1102        )
1103    );
1104
1105  $self->populate_tree_helper( $tree, $self->tree_root, $tree_items );
1106 
1107  $tree->SelectItem( $self->tree_root );
1108  $tree->Expand( $self->tree_root );
1109}
1110
1111sub populate_tree_helper {
1112  my ( $self, $tree, $parent_id, $tree_items ) = @_;
1113
1114  my $id;
1115
1116  map {
1117      my $name = $_->[0];
1118
1119      $id = $tree->AppendItem( 
1120                                   $parent_id, 
1121                                   $name,
1122                                   defined($_->[3]) ? $_->[3] : 0, 
1123                                   defined($_->[4]) ? $_->[4] : 0, 
1124                                   itemData( $_->[2]) 
1125                              );
1126      $self->tree_item_default($id) if ! defined $self->tree_item_default;
1127      # current item has children
1128      if( ref( $_->[1] ) eq 'ARRAY' ) {
1129          $self->populate_tree_helper( $tree, $id, $_->[1] );
1130      } 
1131  }
1132  @{$tree_items};
1133
1134}
1135
1136
1137
1138
1139sub _populate_notebook {
1140    my ( $self, $book, $pages, $position ) = @_;   
1141
1142    my $i = 0;
1143    map {
1144        my $icon = Wx::Icon->new();
1145        eval { $icon->LoadFile($_->[2], $_->[3]) ; }
1146            if defined $_->[2];
1147        my $nb_icon = Wx::Bitmap->new( $icon );
1148        defined $position ?
1149            $book->InsertPage($position, $_->[0],
1150                    $_->[1], 1, $nb_icon )
1151                          :
1152            $book->AddPage($_->[0],
1153                    $_->[1], 0, $nb_icon );
1154
1155        $i++;
1156    } @$pages;
1157
1158}
1159
1160
1161sub _initMenus {
1162    my ( $self ) = @_ ;
1163
1164    $self->_tree_mnu;
1165    $self->_imageviewer_mnu;   
1166}
1167
1168
1169sub _tree_mnu {
1170    my ( $self ) = @_;   
1171
1172    my $ctx_mnu = Wx::Menu->new;
1173   
1174    map {
1175        $ctx_mnu->Append(
1176            @$_[0..2], wxITEM_NORMAL
1177        )->SetBitmap(Wx::Bitmap->new($_->[3],wxBITMAP_TYPE_PNG));
1178    }
1179    (
1180        # workaround : first item does not show bitmap
1181        [
1182            0, 
1183            "",
1184            "",
1185            wxTheApp->resource_path('mnu_folder_new.png'),
1186        ],
1187        [
1188            1+$ID_TREE_CTX_MENU, 
1189            wxTheApp->branding->{'Add new category'},
1190            sprintf(
1191                "%s %s %s %s", 
1192                gettext("Add a new"), 
1193                wxTheApp->branding->{category},
1194                gettext("to the currently selected"),
1195                wxTheApp->branding->{category},
1196            ),
1197            wxTheApp->resource_path('mnu_folder_new.png'),
1198        ],
1199        [
1200            2+$ID_TREE_CTX_MENU, 
1201            gettext("Refresh"),
1202            sprintf(
1203                "Refresh %s list.",
1204                wxTheApp->branding->{category},
1205            ),
1206            wxTheApp->resource_path('mnu_refresh.png'),
1207        ],
1208        [
1209            3+$ID_TREE_CTX_MENU, 
1210            gettext("Expand all"),
1211            sprintf(
1212                "Expand %s list.",
1213                wxTheApp->branding->{category},
1214            ),
1215            wxTheApp->resource_path('mnu_expandall.png'),
1216        ],
1217        [
1218            4+$ID_TREE_CTX_MENU, 
1219            gettext("Collapse all"),
1220            sprintf(
1221                "Collapse %s list.",
1222                wxTheApp->branding->{category},
1223            ),
1224            wxTheApp->resource_path('mnu_collapseall.png'),
1225        ],
1226    );
1227
1228    $ctx_mnu->Delete(0);
1229    $self->tree_mnu(
1230         $ctx_mnu
1231    );   
1232}   
1233
1234sub _imageviewer_mnu {
1235    my ( $self ) = @_;   
1236
1237    my $ctx_mnu = Wx::Menu->new;
1238   
1239    map {
1240        $ctx_mnu->Append(
1241            @$_[0..2]
1242        )->SetBitmap(Wx::Bitmap->new($_->[3],wxBITMAP_TYPE_PNG));
1243    }
1244    (
1245        # workaround : first item does not show bitmap
1246        [
1247            0, 
1248            "",
1249            "",
1250            wxTheApp->resource_path('mnu_properties.png'),
1251        ],
1252        [
1253            1+$ID_IMAGEVIEWER_CTX_MENU, 
1254            gettext("Properties"),
1255            gettext("Modify photo properties"),
1256            wxTheApp->resource_path('mnu_properties.png'),
1257        ],
1258        [
1259            2+$ID_IMAGEVIEWER_CTX_MENU, 
1260            gettext("Preview"),
1261            gettext("Display photo preview"),
1262            wxTheApp->resource_path('mnu_preview.png'),
1263        ],
1264    );
1265   
1266    $ctx_mnu->Delete(0);
1267    $self->imageviewer_mnu(
1268         $ctx_mnu
1269    );   
1270}
1271
1272sub _initEventHandlers {
1273    my ( $self ) = @_ ;
1274   
1275    Wx::Event::EVT_MENU( $self, 100, \&OnGettingStarted );
1276    Wx::Event::EVT_MENU( $self, 101, \&OnAddImages );
1277    Wx::Event::EVT_MENU( $self, 102, \&OnRemoveImages );
1278    Wx::Event::EVT_MENU( $self, 103, \&OnUploadImages );
1279    Wx::Event::EVT_MENU( $self, 104, \&OnGlobalSettings );
1280    Wx::Event::EVT_MENU( $self, 105, \&OnChooseLanguage );
1281    Wx::Event::EVT_CHOICE( $self, 106, \&OnPhotoSelMode );
1282    EVT_TREE_SEL_CHANGED( $self, $self->tree, \&OnTreeSelChanged );
1283    EVT_TREE_ITEM_RIGHT_CLICK( $self, $self->tree, \&OnTreeItemRightClick );
1284    EVT_TREE_END_LABEL_EDIT( $self, $self->tree, \&OnTreeEndLabelEdit );
1285
1286    EVT_LIST_END_LABEL_EDIT( $self, $self->imageviewer, \&OnImageViewerEndLabelEdit );
1287    EVT_LIST_ITEM_ACTIVATED( $self, $self->imageviewer, \&OnImageViewerItemActivated );
1288    EVT_LIST_ITEM_SELECTED($self, $self->imageviewer, \&OnImageViewerItemSelected) ;
1289    EVT_LIST_ITEM_RIGHT_CLICK($self, $self->imageviewer, \&OnImageViewerItemRightClick) ;
1290
1291    EVT_LIST_KEY_DOWN($self, $self->imageviewer, \&OnImageViewerKeyDown) ;
1292
1293    EVT_CLOSE( $self, \&OnClose );
1294
1295
1296    Wx::Event::EVT_MENU( $self, 1+$ID_TREE_CTX_MENU, \&OnAddCategories );
1297    Wx::Event::EVT_MENU( $self, 2+$ID_TREE_CTX_MENU, \&OnRefreshCategories );
1298    Wx::Event::EVT_MENU( $self, 3+$ID_TREE_CTX_MENU, \&OnExpandCategories );
1299    Wx::Event::EVT_MENU( $self, 4+$ID_TREE_CTX_MENU, \&OnCollapseCategories );
1300
1301    Wx::Event::EVT_MENU( $self, 1+$ID_IMAGEVIEWER_CTX_MENU, \&OnPhotoProperties );
1302    Wx::Event::EVT_MENU( $self, 2+$ID_IMAGEVIEWER_CTX_MENU, \&OnPreview );
1303    EVT_BUTTON( $self, $main::GS_CLOSE, \&OnGeneralSettingsClose );
1304
1305
1306
1307}
1308
1309{
1310  my $prevdir;
1311  my $prevfile;
1312
1313  sub OnAddImages {
1314    my( $self, $event ) = @_;
1315    my $dialog = Wx::FileDialog->new
1316      ( $self, gettext("Select photos for upload"), $prevfile, $prevdir,
1317        sprintf("%s (*.jpg)|*.jpg|All(*.*)|*.*", gettext("JPEG files")),
1318        wxFD_OPEN|wxFD_MULTIPLE );
1319
1320    my $file_paths = [];
1321    if( $dialog->ShowModal != wxID_CANCEL ) {
1322        @$file_paths = $dialog->GetPaths;
1323        $self->SetNewFiles($file_paths) ;
1324    }
1325    $dialog->Destroy;
1326    $event->Skip;
1327  }
1328}
1329
1330sub OnUpdateToolbar {
1331    my( $self ) = @_;
1332   
1333    if( $self->manager ){
1334        if($self->manager->GetPane("global_settings")->IsShown){
1335            $self->toolbar->EnableTool(104, 0);
1336        }
1337        else{
1338            $self->toolbar->EnableTool(104, 1);
1339        }
1340
1341        if($self->manager->GetPane("getting_started")->IsShown){
1342            $self->toolbar->EnableTool(100, 0);
1343        }
1344        else{
1345            $self->toolbar->EnableTool(100, 1);
1346        }
1347    }
1348
1349}
1350
1351sub OnRemoveImages {
1352    my( $self, $event ) = @_;
1353
1354   
1355    $self->imagelist->RemoveImageSelection;
1356    $self->imageviewer->Refresh;   
1357
1358    if (!$self->imageviewer->GetItemCount){
1359        $self->image_preview->image(
1360            0
1361        ); 
1362        # have to reset
1363        $self->dlg_piwigo_photo_properties->ClearProperties;
1364        $self->piwigo_photo_properties_tags->ClearAllSelection;
1365        $self->imagelist->SetCurrentImage(-1);
1366    }
1367
1368    $self->image_preview->Refresh;
1369}
1370
1371sub SetNewFiles {
1372    my ( $self, $file_paths ) = @_;
1373
1374    $self->ShowImageViewer();
1375    $self->progressdlg( 
1376        Uploader::GUI::wxImageProcessingProgressDlg->new(
1377            { 
1378                title => gettext("Image processing progress information"),
1379                bt_label => gettext("Cancel image processing"), 
1380                bt_close_label => gettext("Close"), 
1381             }
1382        )       
1383    );
1384    $self->progressdlg->Show(1);
1385    Wx::Yield();
1386
1387   
1388    my $files = [
1389        map {
1390            # to make sure that unicode chars in filenames are supported
1391            {
1392                ANSIPathName => $^O =~ /MSWin32/ ? Win32::GetANSIPathName($_) : $_,
1393                PathName => $_,
1394            },
1395        }@$file_paths   
1396    ];
1397
1398    @$files = sort { $a->{PathName} cmp $b->{PathName} } @$files;   
1399
1400    $self->imagelist->SetNewFiles(
1401        $files
1402    );
1403
1404   
1405}
1406
1407sub OnTreeSelChanged {
1408    my( $self, $event ) = @_;
1409 
1410    my @items = $self->tree->GetSelections;
1411
1412    $self->imagelist->categories(
1413        [
1414            map {
1415                my $category = $self->tree->GetPlData( $_ );
1416                $category->{id} if $category != -1;
1417            }
1418            @items
1419        ]
1420    );
1421}
1422
1423sub OnTreeItemRightClick {
1424    my( $self, $event ) = @_;
1425
1426
1427    $self->PopupMenu($self->tree_mnu, wxDefaultPosition);
1428   
1429}
1430
1431sub OnTreeEndLabelEdit {
1432    my( $self, $event ) = @_;
1433
1434    my $label = $event->GetLabel;
1435   
1436    $label =~ s/^\s+$//;
1437
1438    if(defined($label) and !( "" eq $label )){
1439        $self->_SetLabel($event)
1440    }
1441    else{
1442        $event->Veto;
1443    }
1444}
1445
1446sub _SetLabel {
1447    my( $self, $event ) = @_;
1448   
1449    my $category = $self->tree->GetPlData($event->GetItem);
1450    my $category_id;
1451   
1452    $category_id = $category->{id} if 'HASH' eq ref($category) ;
1453    my $comment;
1454    my ( $success, $status_msg, $content ) = $self->pwg->SetInfoCategories( 
1455        $event->GetLabel, 
1456        $comment, 
1457        $category_id
1458    );
1459
1460    my $ok = 1;
1461   
1462    if(!$success){
1463        $ok = 0;
1464    }
1465
1466    if('fail' eq $content->{stat}){
1467        $ok = 0;
1468    }
1469
1470    # method call failed
1471    if(!$ok){
1472        $event->Veto;
1473        Wx::MessageBox( 
1474            sprintf(
1475                "%s %s", 
1476                gettext("Update failed : "),
1477                $status_msg
1478            ),
1479            gettext("Piwigo update error"),
1480            wxOK | wxICON_EXCLAMATION, 
1481        );
1482        Wx::LogMessage("%s\n\n%s", Dumper($content), gettext("This function is not available. A Piwigo upgrade may resolve this issue."));
1483    }
1484}
1485
1486sub OnImageViewerItemRightClick {
1487    my( $self, $event ) = @_;
1488
1489   
1490    $self->PopupMenu($self->imageviewer_mnu, wxDefaultPosition);
1491   
1492   
1493}
1494
1495sub OnExpandCategories {
1496    my ( $self, $event ) = @_;
1497
1498    my $parent_item = $self->tree->GetSelection;
1499    $self->tree->ExpandAllChildren($parent_item);
1500    $self->tree->EnsureVisible($parent_item);
1501}
1502
1503sub OnCollapseCategories {
1504    my ( $self, $event ) = @_;
1505
1506    my $parent_item = $self->tree->GetSelection;
1507    $self->tree->CollapseAllChildren($parent_item);
1508    $self->tree->Expand($parent_item) if -1 == $self->tree->GetPlData($parent_item);
1509}
1510
1511sub OnAddCategories {
1512    my ( $self, $event ) = @_;
1513
1514    my $parent_item = $self->tree->GetSelection;
1515
1516    my $category = $self->tree->GetPlData($parent_item);
1517    my $category_id;
1518   
1519    $category_id = $category->{id} if 'HASH' eq ref($category) ;
1520
1521    my $dialog = Wx::TextEntryDialog->new( 
1522        $self, 
1523        wxTheApp->branding->{'Category name'}, 
1524        wxTheApp->branding->{'Add new category'},
1525        wxTheApp->branding->{'New category'}, 
1526    );
1527
1528    if( $dialog->ShowModal != wxID_CANCEL ) {
1529        my $name = $dialog->GetValue;
1530        my ( $success, $status_msg, $content ) = $self->pwg->AddCategories( $name, $category_id);
1531
1532        if($success){
1533            $self->_append_category($parent_item, $name, $content->{result}{id});
1534        }
1535    }
1536    $dialog->Destroy;
1537}
1538
1539sub OnRefreshCategories {
1540    my ( $self, $event ) = @_;
1541
1542    $self->_refresh_all_categories_helper;
1543}
1544
1545
1546sub _refresh_all_categories_helper {
1547    my ( $self ) = @_;   
1548
1549    my $busycursor = Wx::BusyCursor->new();
1550    $self->tree->CollapseAll;
1551    $self->tree->DeleteAllItems;
1552    $self->imagelist->categories([]);
1553    $self->pwg->RefreshCategories();
1554    $self->populate_tree_categories;
1555}
1556
1557sub _append_category {
1558    my ( $self, $parent_id, $name, $id ) = @_;
1559
1560    $self->tree->SelectItem(
1561        $self->tree->AppendItem(
1562            $parent_id, 
1563            $name, 
1564            1, 
1565            -1, 
1566            Wx::TreeItemData->new( { id => $id } )
1567        )
1568    );
1569}
1570
1571sub OnImageViewerEndLabelEdit {
1572    my( $self, $event ) = @_;
1573 
1574    my $image = $self->imagelist->GetImage($event->GetIndex);
1575    $image->site_name(
1576        $event->GetLabel
1577    );
1578       
1579    $self->dlg_piwigo_photo_properties->SetProperties;
1580}
1581
1582sub OnImageViewerItemActivated {
1583    my( $self, $event ) = @_;
1584   
1585    $self->current_imageviewer_index(
1586        $event->GetIndex
1587    );
1588
1589    $self->OnPhotoProperties;
1590}
1591
1592
1593sub OnImageViewerItemSelected {
1594    my( $self, $event ) = @_;
1595
1596    my $bc = Wx::BusyCursor->new;
1597    my $indx = $event->GetIndex;
1598    $self->_on_imageviewer_item_selected($indx);
1599
1600    $event->Skip;
1601
1602}
1603
1604sub _on_imageviewer_item_selected {
1605    my ( $self, $index ) = @_;   
1606    $self->current_imageviewer_index($index);
1607    $self->imagelist->SetCurrentImage($index);
1608   
1609    $self->imagelist->image_selection(
1610        $self->imageviewer->GetSelectedItems
1611    );
1612
1613    # process image_preview in idle time
1614    # and when current event is processed
1615    # see call to EVT_IDLE
1616    $self->image_preview_refresh(1);
1617
1618    $self->dlg_piwigo_photo_properties->SetProperties if defined $self->dlg_piwigo_photo_properties;
1619    $self->image_prop_exif->Refresh;
1620    $self->piwigo_photo_properties_tags->Refresh;
1621
1622}
1623
1624sub set_preview_image {
1625    my ( $self ) = @_;   
1626
1627    my $current_image = $self->imagelist->current_image;
1628    my $image = Wx::Image->new;
1629    $image->LoadFile(
1630        $current_image->file, 
1631        wxBITMAP_TYPE_ANY
1632    );
1633 
1634    if($self->imagelist->auto_rotate){
1635        # exif from original image
1636        my $orientation = $current_image->exif_metadata->{Orientation};
1637
1638        # Valid for Rotate 180, Rotate 90 CW, Rotate 270 CW
1639        if( $orientation =~ m/Rotate (\d+)/ ){
1640            for(my $i=0; $i < floor($1/90) ; $i++){
1641                $image = $image->Rotate90;
1642            }               
1643        }
1644    }
1645
1646    $self->image_preview->image_size(
1647        [$image->GetWidth, $image->GetHeight, ]
1648    );       
1649
1650    $self->image_preview->image(
1651        $image
1652    );       
1653}
1654
1655sub OnImageViewerKeyDown {
1656    my( $self, $event ) = @_;
1657
1658    if(WXK_DELETE == $event->GetKeyCode){
1659        $self->OnRemoveImages();
1660       
1661        my $index = $self->current_imageviewer_index < $self->imageviewer->GetItemCount ?
1662            $self->current_imageviewer_index : $self->imageviewer->GetItemCount -1 ;
1663        $self->imageviewer->SelectItem(
1664            $index
1665        );
1666        $self->imageviewer->EnsureVisible(
1667            $index
1668        );
1669    }   
1670
1671}
1672
1673sub OnUploadImages {
1674    my( $self, $event ) = @_;
1675
1676    eval {
1677        $self->ProcessImageSelection();   
1678    };
1679}
1680
1681# remove image from imagelist when uploaded
1682sub UploadImagesViewerRefresh {
1683    my ( $self ) = @_;   
1684
1685
1686    $self->imageviewer->Refresh;
1687
1688    $self->image_preview->image(
1689        0
1690    ) if !$self->imageviewer->GetItemCount;
1691
1692
1693    $self->image_preview->Refresh;
1694    Wx::Yield();
1695}
1696
1697sub UploadProgressMessageRefresh {
1698    my ( $self, $msg ) = @_;   
1699
1700    Wx::Yield();
1701
1702    $self->upload_progressdlg->processing(
1703        $msg   
1704    );   
1705    $self->upload_progressdlg->LogProgress();
1706
1707    Wx::Yield();
1708}
1709
1710sub UploadProgressMessageDetailsRefresh {
1711    my ( $self, $msg ) = @_;   
1712
1713    Wx::Yield();
1714
1715    $self->upload_progressdlg->processing_details(
1716        $msg   
1717    );   
1718    $self->upload_progressdlg->LogProgress();
1719
1720    Wx::Yield();
1721}
1722
1723
1724sub UploadProgressThumbnailRefresh {
1725    my ( $self ) = @_;   
1726
1727    my $imagelist = $self->imagelist ;
1728
1729 
1730    $self->upload_progressdlg->image->SetBitmap(wxNullBitmap);
1731    $self->upload_progressdlg->image->SetBitmap(
1732        Wx::Bitmap->new( 
1733            $self->imagelist->current_image->wx_thumb_file, 
1734            $self->GetWxBitmapType($self->imagelist->type), 
1735        )
1736    );
1737
1738    Wx::Yield();
1739}
1740
1741sub UploadProgressBarRefresh {
1742    my ( $self, $value ) = @_;   
1743
1744    eval {
1745        $self->upload_progressdlg->progress(
1746            $value
1747        );
1748        $self->upload_progressdlg->LogProgress();
1749    };
1750    #croak gettext("Upload cancelled") if $@;
1751
1752    Wx::Yield();
1753}
1754
1755sub SetNewFilesDisplayEndInfo {
1756    my ( $self, $msg ) = @_;   
1757   
1758    $self->progressdlg->DisplayEndInfo($msg);
1759}
1760
1761sub UploadDisplayEndInfo {
1762    my ( $self, $msg ) = @_;   
1763   
1764    my $imagelist = $self->imagelist ;
1765   
1766    $self->upload_progressdlg->DisplayEndInfo($msg);
1767}
1768
1769sub ShowImageViewer {
1770    my ( $self ) = @_;   
1771
1772    if(!$self->imageviewer->IsShown){
1773        $self->imageviewer->Show(1);
1774    }
1775}
1776
1777
1778sub ActivateImageViewer {
1779    my ( $self ) = @_;   
1780   
1781}
1782
1783
1784sub SetNewFilesViewerRefresh {
1785
1786    my ( $self ) = @_;   
1787
1788    my $wximagelist = $self->imagelist->wx_thumb_imglist;
1789    #print Dumper "SetNewFilesViewerRefresh", $self->imagelist->current_image;
1790    my $indx = $wximagelist->Add(
1791        Wx::Bitmap->new( 
1792            $self->imagelist->current_image->wx_thumb_file, 
1793            $self->GetWxBitmapType($self->imagelist->type), 
1794        )
1795    ) if defined $self->imagelist->current_image->wx_thumb_file;
1796    print $self->imagelist->current_image->wx_thumb_file, " added with index ", $indx, "\n";   
1797   
1798    $self->imageviewer->Refresh(
1799        $wximagelist
1800    );
1801
1802    Wx::Yield();
1803}
1804
1805
1806
1807# prepare and upload image_selection
1808sub ProcessImageSelection {
1809    my ( $self ) = @_;
1810
1811    return if !scalar @{$self->imagelist->sums};
1812
1813    if( scalar @{$self->imagelist->categories} ){
1814        # all selected is implicit
1815        if(!scalar @{$self->imageviewer->GetSelectedItems}){
1816       
1817            $self->imagelist->image_selection(
1818                $self->imageviewer->GetAllItems
1819            );
1820        }
1821       
1822        return if( !defined $self->imagelist->image_selection );
1823        return if( !scalar @{$self->imagelist->image_selection} );
1824       
1825        $self->upload_progressdlg(
1826            Uploader::GUI::wxImageProcessingProgressDlg->new(
1827                { 
1828                    title    => gettext("Image upload progress information"),
1829                    bt_label => gettext("Cancel upload"),
1830                    bt_close_label => gettext("Close"), 
1831                 }
1832            )       
1833        );
1834        # modeless dialog
1835        $self->upload_progressdlg->Show(1);
1836        Wx::Yield();
1837        eval {
1838            $self->imagelist->UploadSelection;
1839        };
1840        if($@){
1841            Wx::MessageBox( 
1842                sprintf(
1843                    gettext("Upload cancelled"),
1844                ),
1845                gettext("Piwigo upload information"),
1846                wxOK | wxICON_INFORMATION, 
1847            );
1848        }
1849    }
1850    else {
1851        Wx::MessageBox( 
1852            sprintf(
1853                "%s %s", 
1854                gettext("Please select a valid target"),
1855                wxTheApp->branding->{category}
1856            ),
1857            gettext("Piwigo upload error"),
1858            wxOK | wxICON_EXCLAMATION, 
1859        );
1860    }
1861}
1862
1863
1864sub SetNewFilesProgress {
1865    my ( $self ) = @_;
1866
1867    my $imagelist = $self->imagelist;
1868
1869    $self->progressdlg->processing(
1870        sprintf(
1871            $imagelist->progress_msg, 
1872            $imagelist->current_image->file,
1873        )
1874    );
1875
1876    eval {
1877        $self->progressdlg->image->SetSize([ $imagelist->wx_thumb_size, $imagelist->wx_thumb_size]);
1878        $self->progressdlg->image->SetBitmap(wxNullBitmap);
1879        $self->progressdlg->image->SetBitmap(
1880            Wx::Bitmap->new( 
1881                $imagelist->current_image->wx_thumb_file,
1882                $self->GetWxBitmapType( $imagelist->type )
1883            )
1884        );
1885        $self->progressdlg->progress(
1886            $imagelist->count * ( 100/scalar @{$imagelist->new_files} )
1887        );
1888        $self->progressdlg->LogProgress();
1889    };
1890    Wx::Yield();
1891}
1892
1893sub OnClose {
1894  my $self = shift;
1895
1896
1897    # Restaure previous log wnd
1898    Wx::Log::SetActiveTarget( $self->oldlogwnd );
1899
1900    # allways store
1901 
1902    wxTheApp->StoreConnectionProperties;
1903   
1904    $self->imagelist->Store;
1905    wxTheApp->login_dlg->Destroy;   
1906
1907    wxTheApp->perspective(
1908        $self->manager->SavePerspective
1909    );
1910   
1911    wxTheApp->imageviewerIndex(
1912        $self->current_imageviewer_index
1913    );
1914   
1915    my $frameLayout = {};
1916   
1917    ( $frameLayout->{pX}, $frameLayout->{pY}, $frameLayout->{W}, $frameLayout->{H} ) = ( $self->GetPositionXY, $self->GetSizeWH ) ; 
1918   
1919    wxTheApp->frameLayout(
1920        $frameLayout
1921    );
1922
1923    wxTheApp->StoreLayoutProperties;
1924
1925    $self->manager->UnInit;
1926    $self->Destroy;
1927}
1928
1929
1930sub create_toolbar {
1931    my( $self ) = @_;
1932
1933    my $tb = Wx::ToolBar->new( $self, -1, wxDefaultPosition, [600, -1], wxTB_FLAT );
1934    $tb->SetToolBitmapSize( wxSIZE( 32, 32 ) );
1935    map {
1936        my $icon1 = Wx::Icon->new();
1937        eval {
1938            $icon1->LoadFile($_->[2], $_->[3]);
1939        };
1940        my $tb_icon1 = Wx::Bitmap->new( $icon1 );
1941
1942        my $icon2 = Wx::Icon->new();
1943        eval {
1944            $icon2->LoadFile($_->[5], $_->[3]);
1945        };
1946        my $tb_icon2 = Wx::Bitmap->new( $icon2 );
1947
1948
1949        $tb->AddTool( $_->[0], $_->[1], $tb_icon1, $tb_icon2, wxITEM_NORMAL, $_->[1] );
1950        $tb->EnableTool( $_->[0], $_->[4]);
1951    }
1952    (
1953        [
1954            100, 
1955            gettext("Getting started"), 
1956            wxTheApp->resource_path('tb_getting_started.png'), 
1957            wxBITMAP_TYPE_PNG, 
1958            1, 
1959            wxTheApp->resource_path('tb_getting_started.png'), 
1960            gettext("Display getting started panel")
1961        ],
1962        [
1963            101, 
1964            gettext("Add photo to selection"), 
1965            wxTheApp->resource_path('tb_add.png'), 
1966            wxBITMAP_TYPE_PNG, 
1967            1, 
1968            wxTheApp->resource_path('tb_add.png'), 
1969            gettext("Add photo to selection for resizing and uploading")
1970        ],
1971        [
1972            102, 
1973            gettext("Remove photo from selection"), 
1974            wxTheApp->resource_path('tb_remove.png'), 
1975            wxBITMAP_TYPE_PNG, 
1976            1, 
1977            wxTheApp->resource_path('tb_remove.png'),
1978            gettext("Remove photo from selection. Files are not deleted ")
1979        ],
1980        [
1981            103, 
1982            gettext("Upload to Piwigo"), 
1983            wxTheApp->resource_path('tb_upload.png'), 
1984            wxBITMAP_TYPE_PNG, 
1985            wxTheApp->use_offline ? 0 : 1, 
1986            wxTheApp->resource_path('tb_upload.png'),
1987            gettext("Upload photos to Piwigo.")
1988        ],
1989        [
1990            104, 
1991            gettext("Global settings"), 
1992            wxTheApp->resource_path('tb_settings.png'), 
1993            wxBITMAP_TYPE_PNG, 
1994            0, 
1995            wxTheApp->resource_path('tb_settings.png'),
1996            gettext("Change global settings.")
1997        ],
1998        [
1999            105, 
2000            gettext("Language choice"), 
2001            wxTheApp->resource_path('tb_i18n.png'), 
2002            wxBITMAP_TYPE_PNG, 
2003            1, 
2004            wxTheApp->resource_path('tb_i18n.png'),
2005            gettext("Language choice")
2006        ],
2007   
2008    );
2009   
2010    $tb->AddSeparator;
2011   
2012    $tb->AddControl(
2013        Wx::Choice->new(
2014        $tb,
2015            106,
2016            wxDefaultPosition,
2017            [300, -1],
2018            [],
2019        )
2020    );
2021    my $ch = $tb->FindWindow(106);
2022    $ch->SetToolTip(gettext("How photo selection is displayed"));
2023    map {
2024        $ch->Append(gettext($_), $_);
2025    }(
2026        "Thumbnail and caption",
2027        "Thumbnail",
2028        "Property list"
2029    );
2030   
2031    $ch->SetStringSelection(gettext($self->imagelist->display_mode));
2032    $tb->Realize;
2033
2034    return $tb;
2035}
2036
2037sub OnPhotoSelMode {
2038    my ( $self, $event )= @_;
2039   
2040    $self->imagelist->display_mode(
2041        $event->GetClientData
2042    );
2043
2044    $self->imageviewer->change_display_mode(1);
2045}
2046
2047sub _create_textctrl {
2048    my( $self, $parent, $text, $size ) = @_;
2049
2050    return Wx::TextCtrl->new( $parent, -1, $text, [0, 0], $size,
2051                              wxNO_BORDER | wxTE_MULTILINE | wxTE_READONLY  );
2052}
2053
2054sub create_textctrl {
2055    my( $self, $text, $size ) = @_;
2056
2057    return $self->_create_textctrl( $self, $text, $size );
2058}
2059
2060sub DESTROY {
2061    my( $self ) = @_;
2062
2063}
2064
2065
2066
20671;
2068
2069
2070
2071
2072
2073package DNDImageListDropTarget;
2074use Wx qw/wxTheApp/;
2075use base qw(Wx::FileDropTarget Class::Accessor::Fast);
2076
2077__PACKAGE__->mk_accessors( 
2078    qw/
2079          imageviewer
2080      /
2081);
2082
2083sub new {
2084  my $class = shift;
2085  my $imageviewer = shift;
2086  my $self = $class->SUPER::new( @_ );
2087
2088  $self->imageviewer($imageviewer);
2089
2090  return $self;
2091}
2092
2093sub OnDropFiles {
2094  my( $self, $x, $y, $files ) = @_;
2095
2096  wxTheApp->frame->SetNewFiles($files) ;
2097}
2098
2099
2100
2101
21021;
2103
2104
2105package DNDCategoryTreeDropTarget;
2106
2107use base qw(Wx::TextDropTarget Class::Accessor::Fast);
2108use Data::Dumper;
2109use Wx qw/
2110              wxDragNone
2111              wxDragCopy
2112              wxDragMove
2113         /;
2114
2115__PACKAGE__->mk_accessors( 
2116    qw/
2117          tree
2118          frame
2119      /
2120);
2121
2122sub new {
2123  my ( $class, $tree ) = @_;
2124  my $self = $class->SUPER::new();
2125
2126  $self->tree($tree);
2127  $self->frame($tree->GetParent);
2128  return $self;
2129}
2130
2131
2132
2133sub OnDropText {
2134  my( $self, $x, $y, $textdata ) = @_;
2135
2136  # must be $VAR1 because $textdata is the result of Data::Dumper
2137  my $VAR1;
2138  eval $textdata;
2139  eval {
2140      if(scalar @$VAR1){
2141             my @items;
2142             if(scalar @items < 2) {
2143               my ($dropItem, $flag) = $self->tree->HitTest([$x, $y]);
2144                 push @items, $dropItem;
2145             }
2146             else {
2147                 @items = $self->tree->GetSelections;
2148             }
2149             
2150             # remove root item which is not a valid category
2151             @items = grep { $self->tree->GetPlData( $_ ) != -1 } @items;
2152             
2153           $self->frame->imagelist->categories(
2154               [
2155                   map {
2156                       $self->tree->GetPlData( $_ )->{id};
2157                   }
2158                   @items
2159               ]
2160           );
2161           
2162             $self->frame->imagelist->image_selection($VAR1);
2163             $self->frame->ProcessImageSelection ;
2164      }   
2165  };
2166}
2167
2168
21691;
Note: See TracBrowser for help on using the repository browser.