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

Last change on this file since 3458 was 3458, checked in by ronosman, 15 years ago

Feature 1014 added : save layout configuration in a .pLoader.layout file.

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