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

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

Bug 1027 fixed. New implementation using html window showing scrollbars when needed.

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