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

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

Feature 1039 added. Feature 1040 added. Filter and add Piwigo tags.
The tag list is filtered based on user input ( tag beginning with same characters ) or tag status ( All, Selected, Not selected ).
When a search result is empty, user is asked for tag creation confirmation.
When a search result returns a single result, the user input is autocompleted and the tag is selected if user validates with Enter.

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