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

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

Feature 1036 added. Rename a category from category list.

  • Property svn:eol-style set to LF
File size: 58.6 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             wxTR_EDIT_LABELS
63             wxMAXIMIZE
64             wxOK
65             wxICON_EXCLAMATION
66             wxICON_INFORMATION
67             WXK_DELETE
68             wxLANGUAGE_ABKHAZIAN   
69             wxLANGUAGE_AFAR   
70             wxLANGUAGE_AFRIKAANS   
71             wxLANGUAGE_ALBANIAN   
72             wxLANGUAGE_AMHARIC   
73             wxLANGUAGE_ARABIC   
74             wxLANGUAGE_ARABIC_ALGERIA   
75             wxLANGUAGE_ARABIC_BAHRAIN   
76             wxLANGUAGE_ARABIC_EGYPT   
77             wxLANGUAGE_ARABIC_IRAQ   
78             wxLANGUAGE_ARABIC_JORDAN   
79             wxLANGUAGE_ARABIC_KUWAIT   
80             wxLANGUAGE_ARABIC_LEBANON   
81             wxLANGUAGE_ARABIC_LIBYA   
82             wxLANGUAGE_ARABIC_MOROCCO   
83             wxLANGUAGE_ARABIC_OMAN   
84             wxLANGUAGE_ARABIC_QATAR   
85             wxLANGUAGE_ARABIC_SAUDI_ARABIA   
86             wxLANGUAGE_ARABIC_SUDAN   
87             wxLANGUAGE_ARABIC_SYRIA   
88             wxLANGUAGE_ARABIC_TUNISIA   
89             wxLANGUAGE_ARABIC_UAE   
90             wxLANGUAGE_ARABIC_YEMEN   
91             wxLANGUAGE_ARMENIAN   
92             wxLANGUAGE_ASSAMESE   
93             wxLANGUAGE_AYMARA   
94             wxLANGUAGE_AZERI   
95             wxLANGUAGE_AZERI_CYRILLIC   
96             wxLANGUAGE_AZERI_LATIN   
97             wxLANGUAGE_BASHKIR   
98             wxLANGUAGE_BASQUE   
99             wxLANGUAGE_BELARUSIAN   
100             wxLANGUAGE_BENGALI   
101             wxLANGUAGE_BHUTANI   
102             wxLANGUAGE_BIHARI   
103             wxLANGUAGE_BISLAMA   
104             wxLANGUAGE_BRETON   
105             wxLANGUAGE_BULGARIAN   
106             wxLANGUAGE_BURMESE   
107             wxLANGUAGE_CAMBODIAN   
108             wxLANGUAGE_CATALAN   
109             wxLANGUAGE_CHINESE   
110             wxLANGUAGE_CHINESE_SIMPLIFIED   
111             wxLANGUAGE_CHINESE_TRADITIONAL   
112             wxLANGUAGE_CHINESE_HONGKONG   
113             wxLANGUAGE_CHINESE_MACAU   
114             wxLANGUAGE_CHINESE_SINGAPORE   
115             wxLANGUAGE_CHINESE_TAIWAN   
116             wxLANGUAGE_CORSICAN   
117             wxLANGUAGE_CROATIAN   
118             wxLANGUAGE_CZECH   
119             wxLANGUAGE_DANISH   
120             wxLANGUAGE_DUTCH   
121             wxLANGUAGE_DUTCH_BELGIAN   
122             wxLANGUAGE_ENGLISH   
123             wxLANGUAGE_ENGLISH_UK   
124             wxLANGUAGE_ENGLISH_US   
125             wxLANGUAGE_ENGLISH_AUSTRALIA   
126             wxLANGUAGE_ENGLISH_BELIZE   
127             wxLANGUAGE_ENGLISH_BOTSWANA   
128             wxLANGUAGE_ENGLISH_CANADA   
129             wxLANGUAGE_ENGLISH_CARIBBEAN   
130             wxLANGUAGE_ENGLISH_DENMARK   
131             wxLANGUAGE_ENGLISH_EIRE   
132             wxLANGUAGE_ENGLISH_JAMAICA   
133             wxLANGUAGE_ENGLISH_NEW_ZEALAND   
134             wxLANGUAGE_ENGLISH_PHILIPPINES   
135             wxLANGUAGE_ENGLISH_SOUTH_AFRICA   
136             wxLANGUAGE_ENGLISH_TRINIDAD   
137             wxLANGUAGE_ENGLISH_ZIMBABWE   
138             wxLANGUAGE_ESPERANTO   
139             wxLANGUAGE_ESTONIAN   
140             wxLANGUAGE_FAEROESE   
141             wxLANGUAGE_FARSI   
142             wxLANGUAGE_FIJI   
143             wxLANGUAGE_FINNISH   
144             wxLANGUAGE_FRENCH   
145             wxLANGUAGE_FRENCH_BELGIAN   
146             wxLANGUAGE_FRENCH_CANADIAN   
147             wxLANGUAGE_FRENCH_LUXEMBOURG   
148             wxLANGUAGE_FRENCH_MONACO   
149             wxLANGUAGE_FRENCH_SWISS   
150             wxLANGUAGE_FRISIAN   
151             wxLANGUAGE_GALICIAN   
152             wxLANGUAGE_GEORGIAN   
153             wxLANGUAGE_GERMAN   
154             wxLANGUAGE_GERMAN_AUSTRIAN   
155             wxLANGUAGE_GERMAN_BELGIUM   
156             wxLANGUAGE_GERMAN_LIECHTENSTEIN   
157             wxLANGUAGE_GERMAN_LUXEMBOURG   
158             wxLANGUAGE_GERMAN_SWISS   
159             wxLANGUAGE_GREEK   
160             wxLANGUAGE_GREENLANDIC   
161             wxLANGUAGE_GUARANI   
162             wxLANGUAGE_GUJARATI   
163             wxLANGUAGE_HAUSA   
164             wxLANGUAGE_HEBREW   
165             wxLANGUAGE_HINDI   
166             wxLANGUAGE_HUNGARIAN   
167             wxLANGUAGE_ICELANDIC   
168             wxLANGUAGE_INDONESIAN   
169             wxLANGUAGE_INTERLINGUA   
170             wxLANGUAGE_INTERLINGUE   
171             wxLANGUAGE_INUKTITUT   
172             wxLANGUAGE_INUPIAK   
173             wxLANGUAGE_IRISH   
174             wxLANGUAGE_ITALIAN   
175             wxLANGUAGE_ITALIAN_SWISS   
176             wxLANGUAGE_JAPANESE   
177             wxLANGUAGE_JAVANESE   
178             wxLANGUAGE_KANNADA   
179             wxLANGUAGE_KASHMIRI   
180             wxLANGUAGE_KASHMIRI_INDIA   
181             wxLANGUAGE_KAZAKH   
182             wxLANGUAGE_KERNEWEK   
183             wxLANGUAGE_KINYARWANDA   
184             wxLANGUAGE_KIRGHIZ   
185             wxLANGUAGE_KIRUNDI   
186             wxLANGUAGE_KONKANI   
187             wxLANGUAGE_KOREAN   
188             wxLANGUAGE_KURDISH   
189             wxLANGUAGE_LAOTHIAN   
190             wxLANGUAGE_LATIN   
191             wxLANGUAGE_LATVIAN   
192             wxLANGUAGE_LINGALA   
193             wxLANGUAGE_LITHUANIAN   
194             wxLANGUAGE_MACEDONIAN   
195             wxLANGUAGE_MALAGASY   
196             wxLANGUAGE_MALAY   
197             wxLANGUAGE_MALAYALAM   
198             wxLANGUAGE_MALAY_BRUNEI_DARUSSALAM   
199             wxLANGUAGE_MALAY_MALAYSIA   
200             wxLANGUAGE_MALTESE   
201             wxLANGUAGE_MANIPURI   
202             wxLANGUAGE_MAORI   
203             wxLANGUAGE_MARATHI   
204             wxLANGUAGE_MOLDAVIAN   
205             wxLANGUAGE_MONGOLIAN   
206             wxLANGUAGE_NAURU   
207             wxLANGUAGE_NEPALI   
208             wxLANGUAGE_NEPALI_INDIA   
209             wxLANGUAGE_NORWEGIAN_BOKMAL   
210             wxLANGUAGE_NORWEGIAN_NYNORSK   
211             wxLANGUAGE_OCCITAN   
212             wxLANGUAGE_ORIYA   
213             wxLANGUAGE_OROMO   
214             wxLANGUAGE_PASHTO   
215             wxLANGUAGE_POLISH   
216             wxLANGUAGE_PORTUGUESE   
217             wxLANGUAGE_PORTUGUESE_BRAZILIAN   
218             wxLANGUAGE_PUNJABI   
219             wxLANGUAGE_QUECHUA   
220             wxLANGUAGE_RHAETO_ROMANCE   
221             wxLANGUAGE_ROMANIAN   
222             wxLANGUAGE_RUSSIAN   
223             wxLANGUAGE_RUSSIAN_UKRAINE   
224             wxLANGUAGE_SAMI   
225             wxLANGUAGE_SAMOAN   
226             wxLANGUAGE_SANGHO   
227             wxLANGUAGE_SANSKRIT   
228             wxLANGUAGE_SCOTS_GAELIC   
229             wxLANGUAGE_SERBIAN   
230             wxLANGUAGE_SERBIAN_CYRILLIC   
231             wxLANGUAGE_SERBIAN_LATIN   
232             wxLANGUAGE_SERBO_CROATIAN   
233             wxLANGUAGE_SESOTHO   
234             wxLANGUAGE_SETSWANA   
235             wxLANGUAGE_SHONA   
236             wxLANGUAGE_SINDHI   
237             wxLANGUAGE_SINHALESE   
238             wxLANGUAGE_SISWATI   
239             wxLANGUAGE_SLOVAK   
240             wxLANGUAGE_SLOVENIAN   
241             wxLANGUAGE_SOMALI   
242             wxLANGUAGE_SPANISH   
243             wxLANGUAGE_SPANISH_ARGENTINA   
244             wxLANGUAGE_SPANISH_BOLIVIA   
245             wxLANGUAGE_SPANISH_CHILE   
246             wxLANGUAGE_SPANISH_COLOMBIA   
247             wxLANGUAGE_SPANISH_COSTA_RICA   
248             wxLANGUAGE_SPANISH_DOMINICAN_REPUBLIC   
249             wxLANGUAGE_SPANISH_ECUADOR   
250             wxLANGUAGE_SPANISH_EL_SALVADOR   
251             wxLANGUAGE_SPANISH_GUATEMALA   
252             wxLANGUAGE_SPANISH_HONDURAS   
253             wxLANGUAGE_SPANISH_MEXICAN   
254             wxLANGUAGE_SPANISH_MODERN   
255             wxLANGUAGE_SPANISH_NICARAGUA   
256             wxLANGUAGE_SPANISH_PANAMA   
257             wxLANGUAGE_SPANISH_PARAGUAY   
258             wxLANGUAGE_SPANISH_PERU   
259             wxLANGUAGE_SPANISH_PUERTO_RICO   
260             wxLANGUAGE_SPANISH_URUGUAY   
261             wxLANGUAGE_SPANISH_US   
262             wxLANGUAGE_SPANISH_VENEZUELA   
263             wxLANGUAGE_SUNDANESE   
264             wxLANGUAGE_SWAHILI   
265             wxLANGUAGE_SWEDISH   
266             wxLANGUAGE_SWEDISH_FINLAND   
267             wxLANGUAGE_TAGALOG   
268             wxLANGUAGE_TAJIK   
269             wxLANGUAGE_TAMIL   
270             wxLANGUAGE_TATAR   
271             wxLANGUAGE_TELUGU   
272             wxLANGUAGE_THAI   
273             wxLANGUAGE_TIBETAN   
274             wxLANGUAGE_TIGRINYA   
275             wxLANGUAGE_TONGA   
276             wxLANGUAGE_TSONGA   
277             wxLANGUAGE_TURKISH   
278             wxLANGUAGE_TURKMEN   
279             wxLANGUAGE_TWI   
280             wxLANGUAGE_UIGHUR   
281             wxLANGUAGE_UKRAINIAN   
282             wxLANGUAGE_URDU   
283             wxLANGUAGE_URDU_INDIA   
284             wxLANGUAGE_URDU_PAKISTAN   
285             wxLANGUAGE_UZBEK   
286             wxLANGUAGE_UZBEK_CYRILLIC   
287             wxLANGUAGE_UZBEK_LATIN   
288             wxLANGUAGE_VALENCIAN   
289             wxLANGUAGE_VIETNAMESE   
290             wxLANGUAGE_VOLAPUK   
291             wxLANGUAGE_WELSH   
292             wxLANGUAGE_WOLOF   
293             wxLANGUAGE_XHOSA   
294             wxLANGUAGE_YIDDISH   
295             wxLANGUAGE_YORUBA   
296             wxLANGUAGE_ZHUANG   
297             wxLANGUAGE_ZULU 
298         /;
299use base qw/Wx::Frame Class::Accessor::Fast/;
300use File::Spec;
301use Wx::Locale qw/:default/;
302use Encode qw/encode decode is_utf8/;;
303
304
305my @properties = 
306    qw/
307          progressdlg
308          upload_progressdlg
309          imageviewer
310          tree
311          tree_root
312          treeimglist
313          tree_item_default
314          topsizer
315          pwg
316          manager
317          logwnd
318          oldlogwnd
319          htmlhome
320          notebook
321          categories
322          imagelist
323          image_preview
324          image_prop_piwigo
325          image_prop_exif
326          notebook_image_properties
327          notebook_global_settings
328          general_settings_panel
329          resized_settings_panel
330          thumbnail_settings_panel
331          preview_settings_panel
332          piwigo_properties
333          exif_properties
334          general_settings
335          resized_settings
336          thumbnail_settings
337          preview_settings
338          toolbar
339          branding
340          perspective
341          current_imageviewer_index
342          imageviewer_mnu
343          tree_mnu
344          imageviewer_select_multi
345          frameLayout
346      /;
347__PACKAGE__->mk_accessors( @properties );
348
349use Wx::Event 
350    qw/
351          EVT_MENU
352          EVT_TREE_SEL_CHANGED
353          EVT_TREE_END_LABEL_EDIT
354          EVT_CLOSE
355          EVT_LIST_END_LABEL_EDIT
356          EVT_LIST_ITEM_SELECTED
357          EVT_LIST_ITEM_ACTIVATED
358          EVT_LIST_ITEM_RIGHT_CLICK
359          EVT_TREE_ITEM_RIGHT_CLICK
360          EVT_LIST_KEY_DOWN
361          EVT_UPDATE_UI       
362      /;
363     
364use Uploader::GUI::wxImageListCtrl;
365use Uploader::GUI::wxImageProcessingProgressDlg;
366use Wx::Html;
367use Uploader::GUI::wxHtmlWindow;
368use Data::Dumper;
369use Wx::AUI;
370use Storable;
371use Uploader::GUI::wxPropertyGridPanel;
372use Encode qw/encode decode is_utf8/;
373
374$|=1;
375
376my $ID_TREE_CTX_MENU = 20000 ;
377my $ID_IMAGEVIEWER_CTX_MENU = 20100 ;
378
379sub new {
380  my( $class, $params ) = @_;
381  my( $self ) = $class->SUPER::new( 
382                                      undef, 
383                                      -1, 
384                                      $params->{title},
385                                      wxDefaultPosition,
386                                      wxDefaultSize, 
387                                      wxDEFAULT_FRAME_STYLE
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        Wx::HtmlWindow->new(
868            $self,
869            -1,
870            [-1,-1],
871            [-1,-1],
872        )
873    );
874
875
876    $self->image_prop_piwigo->Show(0);
877   
878    $self->image_prop_exif->Show(0);
879       
880}
881
882sub init_panels {
883    my ( $self ) = @_; 
884
885    my $file = sprintf(
886        "../locale/%s/gs.html",
887        wxTheApp->locale->GetCanonicalName
888    );
889
890    $self->htmlhome(
891        Uploader::GUI::wxHtmlWindow->new(
892            $self, -1, [-1, -1], [450, 450]
893        )
894    );
895   
896    $self->htmlhome->LoadPage($file) if -e $file ;
897   
898    $self->htmlhome->InitHrefCallbacks(
899        {
900            new_album => sub {$self->OnAddCategories(@_) },
901            add_photos => sub { $self->OnAddImages(@_) },
902            upload_photos => sub { $self->ProcessImageSelection(@_)},   
903        }
904    );
905   
906    $self->imageviewer(
907        Uploader::GUI::wxImageListCtrl->new( 
908            { 
909                parentwnd => $self,
910                imagelist => $self->imagelist,
911            }
912        )
913    );
914   
915    $self->_init_settings_panels;       
916}
917
918sub init_dnd_targets {
919    my ( $self ) = @_; 
920
921    $self->imageviewer->SetDropTarget( 
922        DNDImageListDropTarget->new(
923            $self->imageviewer
924        ) 
925    );
926    #$self->htmlhome->SetDropTarget(
927    #    DNDImageListDropTarget->new(
928    #        $self->imageviewer
929    #    )
930    #);
931
932
933    $self->tree->SetDropTarget( 
934        DNDCategoryTreeDropTarget->new(
935            $self->tree
936        )
937    );
938       
939}
940
941sub init_aui {
942    my ( $self ) = @_;
943
944    my $url = wxTheApp->site_url;
945   
946    $url = gettext("empty - work Offline") if wxTheApp->use_offline;
947
948    $self->manager->AddPane
949      ( $self->create_notebook_imagelist, Wx::AuiPaneInfo->new->Name( "ImageViewer" )
950        ->CenterPane->Resizable->CloseButton(0) );
951
952    $self->manager->AddPane( 
953        $self->create_tree, 
954        Wx::AuiPaneInfo->new->Name( "categories" )
955        ->Right->Position( 0 )->Resizable->CloseButton(0), 
956    );
957
958
959
960    $self->_init_aui_settings_panels;
961
962    $self->toolbar(
963        $self->create_toolbar
964    );
965
966    $self->manager->AddPane
967      ( $self->toolbar, Wx::AuiPaneInfo->new->Name( "tb1" )
968        ->ToolbarPane->Top->Row( 1 )->LeftDockable( 0 )->RightDockable( 0 ) ) if defined $self->toolbar;
969
970    $self->SetSize( 
971            $self->frameLayout->{pX}, 
972            $self->frameLayout->{pY}, 
973            $self->frameLayout->{W}, 
974            $self->frameLayout->{H}, 
975    );
976
977
978    if($self->perspective){
979        $self->manager->LoadPerspective($self->perspective);
980    }
981    else {
982        $self->manager->GetPane("categories")->MinSize(300,100);
983
984        $self->manager->GetPane("tb1")->Caption( gettext("Tools") );
985        $self->manager->GetPane("image_preview")->Caption(gettext("Preview"))->Show(0);
986        $self->manager->GetPane("getting_started")->Caption(gettext("Getting started"))->Float->Show(1);
987        $self->manager->GetPane("photo_properties")->Caption(gettext("Photo properties"))->Float->Show(0);
988        $self->manager->GetPane("global_settings")->Caption(gettext("Global settings"))->Float->Show(0);
989    }
990
991    $self->manager->GetPane("categories")->Caption(
992          sprintf("%s - %s", sprintf("Piwigo %s", wxTheApp->branding->{categories}), $url )
993    );
994   
995    $self->manager->Update;
996
997}
998
999
1000sub _init_aui_settings_panels {
1001    my ( $self ) = @_; 
1002
1003    $self->manager->AddPane
1004      ( $self->image_preview, Wx::AuiPaneInfo->new->Name( "image_preview" )
1005        ->Floatable(1)->Resizable->CloseButton(1));
1006
1007    $self->manager->AddPane
1008      ( $self->htmlhome, Wx::AuiPaneInfo->new->Name( "getting_started" )
1009       ->Floatable(1)->Resizable->CloseButton(1) );
1010
1011    $self->manager->AddPane
1012      ( $self->create_notebook_image_properties, Wx::AuiPaneInfo->new->Name( "photo_properties" )
1013        ->Floatable(1)->Resizable->CloseButton(1) );
1014
1015    $self->manager->AddPane
1016      ( $self->create_notebook_global_settings, Wx::AuiPaneInfo->new->Name( "global_settings" )
1017        ->Floatable(1)->Resizable->CloseButton(1) );
1018
1019}
1020
1021sub OnPhotoProperties {
1022    my ( $self ) = @_;
1023
1024    $self->manager->GetPane("photo_properties")->Show(1);
1025    $self->manager->Update();   
1026       
1027}
1028
1029sub OnPreview {
1030    my ( $self ) = @_;
1031
1032    $self->manager->GetPane("image_preview")->Float->Show(1);
1033    $self->manager->Update();   
1034       
1035}
1036
1037sub OnGettingStarted {
1038    my ( $self ) = @_;
1039
1040    $self->toolbar->EnableTool(100, 0 );
1041    $self->manager->GetPane("getting_started")->Float->Show(1);
1042    $self->manager->Update();   
1043       
1044}
1045
1046sub OnGlobalSettings {
1047    my ( $self ) = @_;
1048
1049    $self->toolbar->EnableTool(104, 0 );
1050    $self->manager->GetPane("global_settings")->Float->Show(1);
1051    $self->manager->Update();   
1052}
1053
1054sub OnChooseLanguage {
1055    my ( $self ) = @_; 
1056
1057  my $languages = [
1058             ['Dutch', wxLANGUAGE_DUTCH, ],   
1059             ['English', wxLANGUAGE_ENGLISH, ],   
1060             ['French', wxLANGUAGE_FRENCH, ],   
1061             ['German', wxLANGUAGE_GERMAN, ],   
1062             ['Italian', wxLANGUAGE_ITALIAN, ],   
1063             ['Polish', wxLANGUAGE_POLISH, ],   
1064             ['Portuguese', wxLANGUAGE_PORTUGUESE, ],   
1065             ['Russian', wxLANGUAGE_RUSSIAN, ],   
1066             ['Spanish', wxLANGUAGE_SPANISH, ],   
1067  ];
1068
1069  my $dialog = new Wx::SingleChoiceDialog
1070    ( undef, gettext( "Choose a language" ), gettext( "Choose a language" ),
1071      [ map { Wx::GetTranslation( ${$_}[0] ) } @$languages ] );
1072
1073  if( $dialog->ShowModal() == wxID_OK ) {
1074    wxTheApp->current_language(
1075        $languages->[$dialog->GetSelection][1]
1076    );
1077    wxTheApp->init_locale();
1078    $self->_refreshFrame;
1079  }
1080
1081  $dialog->Destroy;
1082
1083}
1084
1085
1086sub create_notebook_imagelist {
1087    my( $self ) = @_;
1088    my $book = Wx::AuiNotebook->new( $self, -1, [-1, -1], [300, 450],
1089                                     wxBORDER_NONE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT);
1090
1091        my $imglistpage = [
1092            [
1093                $self->imageviewer, 
1094                gettext("Photo selection"),
1095                '../res/images.png', 
1096                wxBITMAP_TYPE_PNG,
1097            ],
1098        ];
1099
1100    $self->notebook($book);
1101    $self->_populate_notebook($self->notebook, $imglistpage, 0);
1102    return $book;
1103}
1104
1105sub create_notebook_image_properties {
1106    my( $self ) = @_;
1107    my $book = Wx::AuiNotebook->new( $self, -1, [-1, -1], [450, 450],
1108                                     wxBORDER_NONE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT);
1109    my $pages = [   
1110        [
1111            $self->image_prop_piwigo, 
1112            "Piwigo",
1113        ],
1114        [
1115            $self->image_prop_exif, 
1116            "Exif",
1117        ],
1118    ];
1119   
1120    $self->_populate_notebook( $book, $pages );
1121
1122    $self->notebook_image_properties($book);
1123
1124    return $book;
1125}
1126
1127sub create_notebook_global_settings {
1128    my( $self ) = @_;
1129    my $book = Wx::AuiNotebook->new( $self, -1, [-1, -1], [450, 450],
1130                                     wxBORDER_NONE|wxAUI_NB_TAB_MOVE|wxAUI_NB_TAB_SPLIT);
1131    my $pages = [   
1132        [
1133            $self->general_settings_panel, 
1134            gettext("General"),
1135        ],
1136        [
1137            $self->resized_settings_panel, 
1138            gettext("Resized"),
1139        ],
1140        [
1141            $self->thumbnail_settings_panel, 
1142            gettext("Thumbnail"),
1143        ],
1144        [
1145            $self->preview_settings_panel, 
1146            gettext("Preview"),
1147        ],
1148    ];
1149   
1150    $self->_populate_notebook( $book, $pages );
1151
1152    $self->notebook_global_settings($book);
1153
1154    return $book;
1155}
1156
1157
1158
1159
1160sub create_tree {
1161    my ( $self ) = @_;
1162
1163    my $images = [
1164        map {
1165            Wx::Bitmap->new( $_, wxBITMAP_TYPE_PNG )
1166               
1167        }
1168        (
1169          '../res/tree_pwg.png',
1170          '../res/tree_folder.png',
1171        )   
1172    ];
1173
1174    $self->treeimglist( Wx::ImageList->new( 16, 16, 1 ) );
1175    map {
1176        $self->treeimglist->Add($_);
1177    }
1178    @$images;
1179
1180   
1181    $self->tree( 
1182        Wx::TreeCtrl->new( 
1183           $self, 
1184           -1, 
1185           wxDefaultPosition, 
1186           wxDefaultSize, 
1187           wxBORDER_NONE|
1188           wxCLIP_CHILDREN|
1189           wxTR_HAS_BUTTONS|
1190           wxTR_EDIT_LABELS
1191        ) 
1192    );
1193
1194    $self->tree->SetImageList( $self->treeimglist );
1195    $self->populate_tree_categories if !wxTheApp->use_offline;
1196    $self->tree ;
1197}
1198
1199
1200sub populate_tree_categories {
1201    my ( $self ) = @_;
1202
1203    $self->populate_tree(
1204        $self->tree,
1205        wxTheApp->pwg->categories,
1206    ) if defined wxTheApp->pwg ;
1207   
1208    #$self->tree->ExpandAll;
1209
1210}
1211
1212
1213# returns a valid itemData
1214sub itemData { Wx::TreeItemData->new( $_[0] ) }
1215
1216sub populate_tree {
1217    my ( $self, $tree, $tree_items ) = @_;
1218    my $root = shift @{$tree_items};
1219
1220    $self->tree_root(
1221        $tree->AddRoot( 
1222            $root->[0], 
1223            $root->[3], 
1224            $root->[4], 
1225            itemData( $root->[2] ) 
1226        )
1227    );
1228
1229  $self->populate_tree_helper( $tree, $self->tree_root, $tree_items );
1230 
1231  $tree->SelectItem( $self->tree_root );
1232  $tree->Expand( $self->tree_root );
1233}
1234
1235sub populate_tree_helper {
1236  my ( $self, $tree, $parent_id, $tree_items ) = @_;
1237
1238  my $id;
1239
1240  map {
1241      my $name = $_->[0];
1242      eval {
1243        $name = is_utf8($name) ?  decode('UTF-8', $name) : $name;
1244      };
1245      if($@){
1246          $name = $_->[0];
1247      }
1248
1249      $id = $tree->AppendItem( 
1250                                   $parent_id, 
1251                                   $name,
1252                                   defined($_->[3]) ? $_->[3] : 0, 
1253                                   defined($_->[4]) ? $_->[4] : 0, 
1254                                   itemData( $_->[2]) 
1255                              );
1256      $self->tree_item_default($id) if ! defined $self->tree_item_default;
1257      # current item has children
1258      if( ref( $_->[1] ) eq 'ARRAY' ) {
1259          $self->populate_tree_helper( $tree, $id, $_->[1] );
1260      } 
1261  }
1262  @{$tree_items};
1263
1264}
1265
1266
1267
1268
1269sub _populate_notebook {
1270    my ( $self, $book, $pages, $position ) = @_;       
1271
1272    my $i = 0;
1273    map {
1274        my $icon = Wx::Icon->new();
1275        eval { $icon->LoadFile($_->[2], $_->[3]) ; }
1276            if defined $_->[2];
1277        my $nb_icon = Wx::Bitmap->new( $icon );
1278        defined $position ?
1279            $book->InsertPage($position, $_->[0],
1280                    $_->[1], 1, $nb_icon )
1281                          :
1282            $book->AddPage($_->[0],
1283                    $_->[1], 0, $nb_icon );
1284
1285        $i++;
1286    } @$pages;
1287
1288}
1289
1290
1291sub _initMenus {
1292    my ( $self ) = @_ ;
1293
1294    $self->_tree_mnu;
1295    $self->_imageviewer_mnu;   
1296}
1297
1298
1299sub _tree_mnu {
1300    my ( $self ) = @_; 
1301
1302    my $ctx_mnu = Wx::Menu->new;
1303   
1304    map {
1305        $ctx_mnu->Append(
1306            @$_[0..2], wxITEM_NORMAL
1307        )->SetBitmap(Wx::Bitmap->new($_->[3],wxBITMAP_TYPE_PNG));
1308    }
1309    (
1310        # workaround : first item does not show bitmap
1311        [
1312            0, 
1313            "",
1314            "",
1315            '../res/mnu_folder_new.png',
1316        ],
1317        [
1318            1+$ID_TREE_CTX_MENU, 
1319            wxTheApp->branding->{'Add new category'},
1320            sprintf(
1321                "%s %s %s %s", 
1322                gettext("Add a new"), 
1323                wxTheApp->branding->{category},
1324                gettext("to the currently selected"),
1325                wxTheApp->branding->{category},
1326            ),
1327            '../res/mnu_folder_new.png',
1328        ],
1329        [
1330            2+$ID_TREE_CTX_MENU, 
1331            gettext("Refresh"),
1332            sprintf(
1333                "Refresh %s list.",
1334                wxTheApp->branding->{category},
1335            ),
1336            '../res/mnu_refresh.png',
1337        ],
1338        [
1339            3+$ID_TREE_CTX_MENU, 
1340            gettext("Expand all"),
1341            sprintf(
1342                "Expand %s list.",
1343                wxTheApp->branding->{category},
1344            ),
1345            '../res/mnu_expandall.png',
1346        ],
1347        [
1348            4+$ID_TREE_CTX_MENU, 
1349            gettext("Collapse all"),
1350            sprintf(
1351                "Collapse %s list.",
1352                wxTheApp->branding->{category},
1353            ),
1354            '../res/mnu_collapseall.png',
1355        ],
1356    );
1357
1358    $ctx_mnu->Delete(0);
1359    $self->tree_mnu(
1360         $ctx_mnu
1361    ); 
1362}       
1363
1364sub _imageviewer_mnu {
1365    my ( $self ) = @_; 
1366
1367    my $ctx_mnu = Wx::Menu->new;
1368   
1369    map {
1370        $ctx_mnu->Append(
1371            @$_[0..2]
1372        )->SetBitmap(Wx::Bitmap->new($_->[3],wxBITMAP_TYPE_PNG));
1373    }
1374    (
1375        # workaround : first item does not show bitmap
1376        [
1377            0, 
1378            "",
1379            "",
1380            '../res/mnu_properties.png',
1381        ],
1382        [
1383            1+$ID_IMAGEVIEWER_CTX_MENU, 
1384            gettext("Properties"),
1385            gettext("Modify photo properties"),
1386            '../res/mnu_properties.png',
1387        ],
1388        [
1389            2+$ID_IMAGEVIEWER_CTX_MENU, 
1390            gettext("Preview"),
1391            gettext("Display photo preview"),
1392            '../res/mnu_preview.png',
1393        ],
1394    );
1395       
1396    $ctx_mnu->Delete(0);
1397    $self->imageviewer_mnu(
1398         $ctx_mnu
1399    ); 
1400}
1401
1402sub _initEventHandlers {
1403    my ( $self ) = @_ ;
1404       
1405    Wx::Event::EVT_MENU( $self, 100, \&OnGettingStarted );
1406    Wx::Event::EVT_MENU( $self, 101, \&OnAddImages );
1407    Wx::Event::EVT_MENU( $self, 102, \&OnRemoveImages );
1408    Wx::Event::EVT_MENU( $self, 103, \&OnUploadImages );
1409    Wx::Event::EVT_MENU( $self, 104, \&OnGlobalSettings );
1410    Wx::Event::EVT_MENU( $self, 105, \&OnChooseLanguage );
1411    EVT_TREE_SEL_CHANGED( $self, $self->tree, \&OnTreeSelChanged );
1412    EVT_TREE_ITEM_RIGHT_CLICK( $self, $self->tree, \&OnTreeItemRightClick );
1413    EVT_TREE_END_LABEL_EDIT( $self, $self->tree, \&OnTreeEndLabelEdit );
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->SetPage(
1487        "<html></html>"
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
1546sub OnTreeEndLabelEdit {
1547    my( $self, $event ) = @_;
1548
1549
1550    my $category = $self->tree->GetPlData($event->GetItem);
1551    my $category_id;
1552   
1553    $category_id = $category->{id} if 'HASH' eq ref($category) ;
1554    my $comment;
1555    my ( $success, $status_msg, $content ) = $self->pwg->SetInfoCategories( $event->GetLabel, $comment, $category_id);
1556
1557    my $ok = 1;
1558   
1559    if(!$success){
1560        $ok = 0;
1561    }
1562
1563    if('fail' eq $content->{stat}){
1564        $ok = 0;
1565    }
1566
1567    # method call failed
1568    if(!$ok){
1569        $event->Veto;
1570        Wx::MessageBox( 
1571            sprintf(
1572                "%s %s", 
1573                gettext("Update failed : "),
1574                $status_msg
1575            ),
1576            gettext("Piwigo update error"),
1577            wxOK | wxICON_EXCLAMATION, 
1578        );
1579        Wx::LogMessage("%s\n\n%s", Dumper($content), gettext("This function is not available. A Piwigo upgrade may resolve this issue."));
1580    }
1581}
1582
1583sub OnImageViewerItemRightClick {
1584    my( $self, $event ) = @_;
1585
1586   
1587    $self->PopupMenu($self->imageviewer_mnu, wxDefaultPosition);
1588       
1589       
1590}
1591
1592sub OnExpandCategories {
1593    my ( $self, $event ) = @_;
1594
1595    my $parent_item = $self->tree->GetSelection;
1596    $self->tree->ExpandAllChildren($parent_item);
1597    $self->tree->EnsureVisible($parent_item);
1598}
1599
1600sub OnCollapseCategories {
1601    my ( $self, $event ) = @_;
1602
1603    my $parent_item = $self->tree->GetSelection;
1604    $self->tree->CollapseAllChildren($parent_item);
1605    $self->tree->Expand($parent_item) if -1 == $self->tree->GetPlData($parent_item);
1606}
1607
1608sub OnAddCategories {
1609    my ( $self, $event ) = @_;
1610
1611    my $parent_item = $self->tree->GetSelection;
1612
1613    my $category = $self->tree->GetPlData($parent_item);
1614    my $category_id;
1615   
1616    $category_id = $category->{id} if 'HASH' eq ref($category) ;
1617
1618    my $dialog = Wx::TextEntryDialog->new( 
1619        $self, 
1620        wxTheApp->branding->{'Category name'}, 
1621        wxTheApp->branding->{'Add new category'},
1622        wxTheApp->branding->{'New category'}, 
1623    );
1624
1625    if( $dialog->ShowModal != wxID_CANCEL ) {
1626        my $name = $dialog->GetValue;
1627        my ( $success, $status_msg, $content ) = $self->pwg->AddCategories( $name, $category_id);
1628
1629        if($success){
1630            $self->_append_category($parent_item, $name, $content->{result}{id});
1631        }
1632    }
1633    $dialog->Destroy;
1634}
1635
1636sub OnRefreshCategories {
1637    my ( $self, $event ) = @_;
1638
1639    $self->_refresh_all_categories_helper;
1640}
1641
1642
1643sub _refresh_all_categories_helper {
1644    my ( $self ) = @_; 
1645
1646    my $busycursor = Wx::BusyCursor->new();
1647    $self->tree->CollapseAll;
1648    $self->tree->DeleteAllItems;
1649    $self->imagelist->categories([]);
1650    $self->pwg->RefreshCategories();
1651    $self->populate_tree_categories;
1652}
1653
1654sub _append_category {
1655    my ( $self, $parent_id, $name, $id ) = @_;
1656
1657    $self->tree->SelectItem(
1658        $self->tree->AppendItem(
1659            $parent_id, 
1660            $name, 
1661            1, 
1662            -1, 
1663            Wx::TreeItemData->new( { id => $id } )
1664        )
1665    );
1666}
1667
1668sub OnImageViewerEndLabelEdit {
1669    my( $self, $event ) = @_;
1670 
1671    my $image = $self->imagelist->GetImage($event->GetIndex);
1672    $image->site_name(
1673        $event->GetLabel
1674    );
1675       
1676    $self->image_prop_piwigo->Refresh;
1677}
1678
1679sub OnImageViewerItemActivated {
1680    my( $self, $event ) = @_;
1681   
1682    $self->current_imageviewer_index(
1683        $event->GetIndex
1684    );
1685
1686    $self->OnPhotoProperties;
1687}
1688
1689
1690sub OnImageViewerItemSelected {
1691    my( $self, $event ) = @_;
1692 
1693    my $indx = $event->GetIndex;
1694
1695    $self->_on_imageviewer_item_selected($indx);
1696
1697    $event->Skip;
1698}
1699
1700sub _on_imageviewer_item_selected {
1701    my ( $self, $index ) = @_; 
1702
1703    $self->current_imageviewer_index($index);
1704    $self->imagelist->SetCurrentImage($index);
1705   
1706    $self->imagelist->image_selection(
1707        $self->imageviewer->GetSelectedItems
1708    );
1709
1710    $self->_image_preview_refresh if @{$self->imagelist->image_selection} < 2;
1711   
1712    $self->manager->Update;
1713   
1714    $self->image_prop_piwigo->Refresh;
1715    $self->image_prop_exif->Refresh;
1716
1717}
1718
1719sub _image_preview_refresh {
1720    my ( $self ) = @_; 
1721
1722
1723    my $html_src = sprintf("
1724      <html>
1725         <body>
1726             <img src=\"%s\"/>
1727         </body>
1728      </html>
1729      ",
1730      $self->imagelist->current_image->preview_file, 
1731    );
1732       
1733    $self->image_preview->SetPage(
1734        $html_src
1735    );
1736
1737    my $bmp = Wx::Bitmap->new( 
1738            $self->imagelist->current_image->preview_file, 
1739            $self->GetWxBitmapType($self->imagelist->type), 
1740        );
1741
1742    my $size = [40+$bmp->GetWidth, 60+$bmp->GetHeight];
1743
1744    $self->manager->GetPane("image_preview")->FloatingSize($size);
1745   
1746}
1747
1748sub OnImageViewerKeyDown {
1749    my( $self, $event ) = @_;
1750
1751    if(WXK_DELETE == $event->GetKeyCode){
1752        $self->OnRemoveImages();
1753       
1754        my $index = $self->current_imageviewer_index < $self->imageviewer->GetItemCount ?
1755            $self->current_imageviewer_index : $self->imageviewer->GetItemCount -1 ;
1756        $self->imageviewer->SelectItem(
1757            $index
1758        );
1759    }   
1760
1761}
1762
1763sub OnUploadImages {
1764    my( $self, $event ) = @_;
1765
1766    eval {
1767        $self->ProcessImageSelection();   
1768    };
1769}
1770
1771# remove image from imagelist when uploaded
1772sub UploadImagesViewerRefresh {
1773    my ( $self ) = @_; 
1774
1775    $self->imageviewer->Refresh;
1776    Wx::Yield();
1777}
1778
1779sub UploadProgressMessageRefresh {
1780    my ( $self, $msg ) = @_;   
1781
1782    $self->upload_progressdlg->processing(
1783        $msg   
1784    ); 
1785
1786    Wx::Yield();
1787}
1788
1789sub UploadProgressThumbnailRefresh {
1790    my ( $self ) = @_; 
1791
1792    my $imagelist = $self->imagelist ;
1793
1794 
1795    $self->upload_progressdlg->image->SetBitmap(wxNullBitmap);
1796    $self->upload_progressdlg->image->SetBitmap(
1797        Wx::Bitmap->new( 
1798            $self->imagelist->current_image->wx_thumb_file, 
1799            $self->GetWxBitmapType($self->imagelist->type), 
1800        )
1801    );
1802
1803    Wx::Yield();
1804}
1805
1806sub UploadProgressBarRefresh {
1807    my ( $self, $ratio ) = @_; 
1808
1809    $ratio = $self->imagelist->count > 1 ? 1 : $ratio; 
1810    eval {
1811        $self->upload_progressdlg->progress(
1812            $ratio*$self->imagelist->count * ( 100/scalar @{$self->imagelist->image_selection} )
1813        );
1814        $self->upload_progressdlg->LogProgress();
1815    };
1816    croak gettext("Upload cancelled") if $@;
1817
1818    Wx::Yield();
1819}
1820
1821sub SetNewFilesDisplayEndInfo {
1822    my ( $self, $msg ) = @_;   
1823       
1824    $self->progressdlg->DisplayEndInfo($msg);
1825}
1826
1827sub UploadDisplayEndInfo {
1828    my ( $self, $msg ) = @_;   
1829   
1830    my $imagelist = $self->imagelist ;
1831   
1832    $self->upload_progressdlg->DisplayEndInfo($msg);
1833}
1834
1835sub ShowImageViewer {
1836    my ( $self ) = @_; 
1837
1838    if(!$self->imageviewer->IsShown){
1839        #my $imglistpage = [
1840        #    [
1841        #        $self->imageviewer,
1842        #        gettext("Photo selection"),
1843        #        '../res/images.png',
1844        #        wxBITMAP_TYPE_PNG,
1845        #    ],
1846        #];
1847        #$self->notebook->DeletePage(0);
1848   
1849        $self->imageviewer->Show(1);
1850        #$self->_populate_notebook($self->notebook, $imglistpage, 0);
1851        # load imagelist with loading.jpg
1852    }
1853       
1854}
1855
1856
1857sub ActivateImageViewer {
1858    my ( $self ) = @_; 
1859       
1860}
1861
1862
1863sub SetNewFilesViewerRefresh {
1864
1865    my ( $self ) = @_; 
1866
1867    my $wximagelist = $self->imagelist->wx_thumb_imglist;
1868
1869    my $indx = $wximagelist->Add(
1870        Wx::Bitmap->new( 
1871            $self->imagelist->current_image->wx_thumb_file, 
1872            $self->GetWxBitmapType($self->imagelist->type), 
1873        )
1874    ) if defined $self->imagelist->current_image->wx_thumb_file;
1875    print $self->imagelist->current_image->wx_thumb_file, " added with index ", $indx, "\n";   
1876    $self->imageviewer->Refresh(
1877        $wximagelist
1878    );
1879
1880    Wx::Yield();
1881}
1882
1883
1884
1885# prepare and upload image_selection
1886sub ProcessImageSelection {
1887    my ( $self ) = @_;
1888
1889    return if !scalar @{$self->imagelist->sums};
1890
1891    if( scalar @{$self->imagelist->categories} ){
1892        # all selected is implicit
1893        if(!scalar @{$self->imageviewer->GetSelectedItems}){
1894       
1895            $self->imagelist->image_selection(
1896                $self->imageviewer->GetAllItems
1897            );
1898        }
1899       
1900        return if( !defined $self->imagelist->image_selection );
1901        return if( !scalar @{$self->imagelist->image_selection} );
1902       
1903        $self->upload_progressdlg(
1904            Uploader::GUI::wxImageProcessingProgressDlg->new(
1905                { 
1906                    title    => gettext("Image upload progress information"),
1907                    bt_label => gettext("Cancel upload"), 
1908                 }
1909            )       
1910        );
1911        # modeless dialog
1912        $self->upload_progressdlg->Show(1);
1913        Wx::Yield();
1914        eval {
1915            $self->imagelist->UploadSelection;
1916        };
1917        if($@){
1918            Wx::MessageBox( 
1919                sprintf(
1920                    gettext("Upload cancelled"),
1921                ),
1922                gettext("Piwigo upload information"),
1923                wxOK | wxICON_INFORMATION, 
1924            );
1925        }
1926    }
1927    else {
1928        Wx::MessageBox( 
1929            sprintf(
1930                "%s %s", 
1931                gettext("Please select a valid target"),
1932                wxTheApp->branding->{category}
1933            ),
1934            gettext("Piwigo upload error"),
1935            wxOK | wxICON_EXCLAMATION, 
1936        );
1937    }
1938}
1939
1940
1941sub SetNewFilesProgress {
1942    my ( $self ) = @_;
1943
1944    my $imagelist = $self->imagelist;
1945
1946    $self->progressdlg->processing(
1947        sprintf(
1948            $imagelist->progress_msg, 
1949            $imagelist->current_image->file,
1950        )
1951    );
1952
1953    eval {
1954        $self->progressdlg->image->SetSize([ $imagelist->wx_thumb_size, $imagelist->wx_thumb_size]);
1955        $self->progressdlg->image->SetBitmap(wxNullBitmap);
1956        $self->progressdlg->image->SetBitmap(
1957            Wx::Bitmap->new( 
1958                $imagelist->current_image->wx_thumb_file,
1959                $self->GetWxBitmapType( $imagelist->type )
1960            )
1961        );
1962        $self->progressdlg->progress(
1963            $imagelist->count * ( 100/scalar @{$imagelist->new_files} )
1964        );
1965        $self->progressdlg->LogProgress();
1966    };
1967    Wx::Yield();
1968}
1969
1970sub OnClose {
1971  my $self = shift;
1972
1973
1974    # Restaure previous log wnd
1975    Wx::Log::SetActiveTarget( $self->oldlogwnd );
1976
1977    # allways store
1978 
1979    wxTheApp->StoreConnectionProperties;
1980   
1981    $self->imagelist->Store;
1982    wxTheApp->login_dlg->Destroy;       
1983
1984    wxTheApp->perspective(
1985        $self->manager->SavePerspective
1986    );
1987   
1988    wxTheApp->imageviewerIndex(
1989        $self->current_imageviewer_index
1990    );
1991   
1992    my $frameLayout = {};
1993   
1994    ( $frameLayout->{pX}, $frameLayout->{pY}, $frameLayout->{W}, $frameLayout->{H} ) = ( $self->GetPositionXY, $self->GetSizeWH ) ; 
1995   
1996    wxTheApp->frameLayout(
1997        $frameLayout
1998    );
1999
2000    wxTheApp->StoreLayoutProperties;
2001
2002    $self->Destroy;
2003}
2004
2005
2006sub create_toolbar {
2007    my( $self ) = @_;
2008
2009    my $tb = Wx::ToolBar->new( $self, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT );
2010    $tb->SetToolBitmapSize( wxSIZE( 32, 32 ) );
2011    map {
2012        my $icon1 = Wx::Icon->new();
2013        eval {
2014            $icon1->LoadFile($_->[2], $_->[3]);
2015        };
2016        my $tb_icon1 = Wx::Bitmap->new( $icon1 );
2017
2018        my $icon2 = Wx::Icon->new();
2019        eval {
2020            $icon2->LoadFile($_->[5], $_->[3]);
2021        };
2022        my $tb_icon2 = Wx::Bitmap->new( $icon2 );
2023
2024
2025        $tb->AddTool( $_->[0], $_->[1], $tb_icon1, $tb_icon2, wxITEM_NORMAL, $_->[1] );
2026        $tb->EnableTool( $_->[0], $_->[4]);
2027    }
2028    (
2029        [
2030            100, 
2031            gettext("Getting started"), 
2032            '../res/tb_getting_started.png', 
2033            wxBITMAP_TYPE_PNG, 
2034            1, 
2035            '../res/tb_getting_started.png', 
2036            gettext("Display getting started panel")
2037        ],
2038        [
2039            101, 
2040            gettext("Add photo to selection"), 
2041            '../res/tb_add.png', 
2042            wxBITMAP_TYPE_PNG, 
2043            1, 
2044            '../res/tb_add.png', 
2045            gettext("Add photo to selection for resizing and uploading")
2046        ],
2047        [
2048            102, 
2049            gettext("Remove photo from selection"), 
2050            '../res/tb_remove.png', 
2051            wxBITMAP_TYPE_PNG, 
2052            1, 
2053            '../res/tb_remove.png',
2054            gettext("Remove photo from selection. Files are not deleted ")
2055        ],
2056        [
2057            103, 
2058            gettext("Upload to Piwigo"), 
2059            '../res/tb_upload.png', 
2060            wxBITMAP_TYPE_PNG, 
2061            wxTheApp->use_offline ? 0 : 1, 
2062            '../res/tb_upload.png',
2063            gettext("Upload photos to Piwigo.")
2064        ],
2065        [
2066            104, 
2067            gettext("Global settings"), 
2068            '../res/tb_settings.png', 
2069            wxBITMAP_TYPE_PNG, 
2070            0, 
2071            '../res/tb_settings.png',
2072            gettext("Change global settings.")
2073        ],
2074        [
2075            105, 
2076            gettext("Language choice"), 
2077            '../res/tb_i18n.png', 
2078            wxBITMAP_TYPE_PNG, 
2079            1, 
2080            '../res/tb_i18n.png',
2081            gettext("Language choice")
2082        ],
2083   
2084    );
2085
2086    if($@){
2087        undef $tb;
2088    }
2089    else{
2090        $tb->Realize;
2091    }
2092
2093    return $tb;
2094}
2095
2096
2097sub _create_textctrl {
2098    my( $self, $parent, $text, $size ) = @_;
2099
2100    return Wx::TextCtrl->new( $parent, -1, $text, [0, 0], $size,
2101                              wxNO_BORDER | wxTE_MULTILINE | wxTE_READONLY  );
2102}
2103
2104sub create_textctrl {
2105    my( $self, $text, $size ) = @_;
2106
2107    return $self->_create_textctrl( $self, $text, $size );
2108}
2109
2110sub DESTROY {
2111    my( $self ) = @_;
2112
2113    $self->manager->UnInit;
2114}
2115
2116
2117
21181;
2119
2120
2121
2122
2123
2124package DNDImageListDropTarget;
2125use Wx qw/wxTheApp/;
2126use base qw(Wx::FileDropTarget Class::Accessor::Fast);
2127
2128__PACKAGE__->mk_accessors( 
2129    qw/
2130          imageviewer
2131      /
2132);
2133
2134sub new {
2135  my $class = shift;
2136  my $imageviewer = shift;
2137  my $self = $class->SUPER::new( @_ );
2138
2139  $self->imageviewer($imageviewer);
2140
2141  return $self;
2142}
2143
2144sub OnDropFiles {
2145  my( $self, $x, $y, $files ) = @_;
2146
2147  wxTheApp->frame->SetNewFiles($files) ;
2148}
2149
2150
2151
2152
21531;
2154
2155
2156package DNDCategoryTreeDropTarget;
2157
2158use base qw(Wx::TextDropTarget Class::Accessor::Fast);
2159use Data::Dumper;
2160use Wx qw/
2161              wxDragNone
2162              wxDragCopy
2163              wxDragMove
2164         /;
2165
2166__PACKAGE__->mk_accessors( 
2167    qw/
2168          tree
2169          frame
2170      /
2171);
2172
2173sub new {
2174  my ( $class, $tree ) = @_;
2175  my $self = $class->SUPER::new();
2176
2177  $self->tree($tree);
2178  $self->frame($tree->GetParent);
2179  return $self;
2180}
2181
2182
2183
2184sub OnDropText {
2185  my( $self, $x, $y, $textdata ) = @_;
2186
2187  # must be $VAR1 because $textdata is the result of Data::Dumper
2188  my $VAR1;
2189  eval $textdata;
2190  eval {
2191      if(scalar @$VAR1){
2192           my @items;
2193           if(scalar @items < 2) {
2194               my ($dropItem, $flag) = $self->tree->HitTest([$x, $y]);
2195                push @items, $dropItem;
2196           }
2197           else {
2198                @items = $self->tree->GetSelections;
2199           }
2200           
2201           # remove root item which is not a valid category
2202           @items = grep { $self->tree->GetPlData( $_ ) != -1 } @items;
2203           
2204           $self->frame->imagelist->categories(
2205               [
2206                   map {
2207                       $self->tree->GetPlData( $_ )->{id};
2208                   }
2209                   @items
2210               ]
2211           );
2212           
2213           $self->frame->imagelist->image_selection($VAR1);
2214           $self->frame->ProcessImageSelection ;
2215      } 
2216  };
2217}
2218
22191;
Note: See TracBrowser for help on using the repository browser.