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

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

bug 1201 fixed : pLoader crashes when path or filename contains unicode characters. All filename or path on windows must be ANSI converted when using perl file operators.

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