source: extensions/pLoader/trunk/src/Uploader/GUI/wxChoiceFilteredPanel.pm @ 4800

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

Photo properties layout management. Use adaptive sizes with stretch factors.

  • Property svn:eol-style set to LF
File size: 10.5 KB
Line 
1# +-----------------------------------------------------------------------+
2# | pLoader - a Perl photo uploader for Piwigo                            |
3# +-----------------------------------------------------------------------+
4# | Copyright(C) 2008-2010 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::wxChoiceFilteredPanel;
21use strict;
22use Wx qw/
23             wxDefaultSize
24             wxDefaultPosition
25             wxVERTICAL
26             wxALIGN_CENTER_VERTICAL
27             wxALL
28             wxSHAPED
29             wxALIGN_CENTER
30             wxTE_PROCESS_ENTER
31             wxRA_SPECIFY_ROWS
32             wxGROW
33             wxEXPAND
34         /;
35
36use base qw/Wx::Panel Uploader::Object2/;
37use Wx::Locale qw/:default/;
38
39use Data::Dumper;
40__PACKAGE__->mk_accessors(     
41    qw/
42        frame_callbacks
43        choices
44        selection
45        id_lookup
46        row_lookup
47        id_from_name
48        search
49        listchoices
50        btn_show
51        show_method
52        is_selected
53        creation_callback
54        search_result
55        previous_autocompleted
56        autocomplete_from
57        autocomplete_to
58        autocomplete_set_selection
59      /
60);
61
62
63sub new {
64    my ($this, $params) = @_;
65    #on recupere le nom de la classe en fonction du type d'appel de la méthode.
66    my $class = ref($this) || $this;
67
68
69    my $self = $class->SUPER::new( $params->{parentwnd}, $params->{id}||-1, wxDefaultPosition, wxDefaultSize );
70    $self->_init_panel;
71    $self->_init_properties($params);
72
73    $self->Refresh;
74
75    Wx::Event::EVT_CHECKLISTBOX( $self, $self->listchoices, \&OnCheck );
76    Wx::Event::EVT_LISTBOX( $self, $self->listchoices, \&OnSelected );
77    Wx::Event::EVT_SEARCHCTRL_SEARCH_BTN( $self, $self->search, \&OnSearch );
78    Wx::Event::EVT_SEARCHCTRL_CANCEL_BTN( $self, $self->search, \&OnCancel );
79    Wx::Event::EVT_TEXT( $self, $self->search, \&OnSearch );
80    Wx::Event::EVT_TEXT_ENTER( $self, $self->search, \&OnSearchEnter );
81    Wx::Event::EVT_RADIOBOX( $self, $self->btn_show, \&OnShow );
82    # fix for linux : can not call SetSelection before the current event is processed.
83    # call when idle
84    Wx::Event::EVT_IDLE(
85        $self,
86        sub {
87            my ($self, $event)=@_;
88            $self->search->SetSelection(
89                $self->autocomplete_from,
90                $self->autocomplete_to
91            ) if $self->autocomplete_set_selection;
92            $self->autocomplete_set_selection(0);
93        }
94    );
95
96    $self;
97}
98
99sub _init_properties {
100    my ( $self, $params ) = @_;   
101   
102    $self->choices(
103        $params->{choices}|| sub { [] }
104    );
105
106    $self->selection(
107        $params->{selection}|| sub{ [] }
108    );
109
110    my $choices = $self->choices->();
111    $self->search_result(
112        []
113    );
114   
115   
116   
117    $self->is_selected({});
118   
119    $self->creation_callback(
120        $params->{creation_callback}
121    ) if 'CODE' eq ref($params->{creation_callback});
122
123    $self->show_method(
124        {
125            gettext("All") => sub { $self->_show_all(@_) },
126            gettext("Selected") => sub { $self->_show_selected(@_) },
127            gettext("Not selected") => sub { $self->_show_notselected(@_) },
128        }
129    );
130}
131
132sub _init_panel {
133    my ( $self ) = @_;   
134
135    my( $vsizer ) = Wx::BoxSizer->new( wxVERTICAL );
136   
137    $self->search(
138        Wx::SearchCtrl->new( $self, -1, "", wxDefaultPosition, [-1,-1],wxTE_PROCESS_ENTER )
139    );
140
141    $self->search->ShowCancelButton( 1 );
142
143    $vsizer->AddWindow( $self->search, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 2 );
144
145    $self->btn_show(
146        Wx::RadioBox->new( $self, -1, sprintf("%s :", gettext("Show")), wxDefaultPosition, [-1, -1], 
147            [gettext("All"),gettext("Selected"),gettext("Not selected")] , 1, wxRA_SPECIFY_ROWS )
148    );
149    $vsizer->AddWindow( $self->btn_show, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 2 );
150
151
152    $self->listchoices(
153        Wx::CheckListBox->new( $self, -1, wxDefaultPosition, [-1,-1], [], 0 )
154    );
155    $vsizer->AddWindow( $self->listchoices, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 2 );
156
157    $self->SetSizer( $vsizer );
158    $vsizer->SetSizeHints( $self );
159         
160}
161
162sub _init_choices {
163    my ( $self, $choices ) = @_;
164
165    $self->listchoices->Freeze;
166    $self->listchoices->Clear;
167    $self->id_lookup({});
168    $self->row_lookup({});
169    $self->id_from_name({});
170    $self->is_selected({});
171
172    my $row = 0;
173    #print Dumper $self->properties;
174    map {
175        $self->listchoices->Append(
176            $_->{name},
177        );
178        $self->id_lookup->{$row} = $_->{id};
179        $self->row_lookup->{$_->{id}} = $row;
180        $self->id_from_name->{$_->{name}} = $_->{id};
181        $row++;   
182    }@{$choices};
183    $self->listchoices->Thaw;
184
185}
186
187sub Refresh {
188    my ( $self, $choices, $selected ) = @_;
189
190   
191
192    if (!defined $choices){
193        $self->btn_show->SetStringSelection(gettext("All"));
194        $choices = $self->choices->();
195    }
196
197    $self->_init_choices($choices);
198    $self->SetSelection($selected);
199   
200}
201
202sub ClearAllSelection {
203    my ( $self ) = @_;
204
205    my $row = 0;
206   
207    my $choices = $self->choices->();
208    $self->listchoices->Freeze;
209    map {
210        $self->listchoices->Check($row, 0) ;   
211        $row++;
212    }@$choices;
213    $self->listchoices->Thaw;
214}
215
216sub SetSelection {
217    my ( $self, $selected ) = @_;
218
219    my $selection = $self->selection->()||[];
220
221    push @$selection, $self->id_from_name->{$selected} if defined $selected;
222
223    $self->listchoices->Freeze;
224    map {
225        $self->listchoices->Check(
226            $self->row_lookup->{$_},
227            exists $self->row_lookup->{$_},
228        ) if defined $self->row_lookup->{$_};
229        $self->is_selected->{$_} = 1;   
230    }
231    @{$selection};   
232    $self->listchoices->Thaw;
233}
234
235sub GetSelection {
236    my ( $self ) = @_;
237
238    my $row = 0;
239    my $selection = [];
240   
241    my $choices = $self->choices->();
242    map {
243           
244        my $id = $self->id_lookup->{$row};
245        $self->is_selected->{$id} = $self->listchoices->IsChecked($row) ;   
246        $row++;
247    }@$choices;
248
249    [
250        grep { $self->is_selected->{$_} } keys %{$self->is_selected}
251    ];   
252}
253
254sub OnCheck {
255    my ( $self ) = @_;
256   
257    $self->selection->(
258        $self->GetSelection
259    );   
260}
261
262sub OnSelected {
263    my ( $self, $event ) = @_;
264
265    my $row = $event->GetInt;
266    $self->listchoices->Check(
267        $row,
268        !$self->listchoices->IsChecked($row)   
269    );
270
271    $self->OnCheck;
272
273    $event->Skip;   
274}
275
276sub OnShow {
277    my( $self, $event ) = @_;
278
279    my $show = $event->GetString();
280   
281    $self->show_method->{$show}->();                               
282}
283
284sub OnSearchEnter {
285    my( $self, $event ) = @_;
286
287    my $searched = $self->search->GetValue;
288    $searched =~ s/\s+$//;
289    $searched = $searched eq "" ? undef : $searched ;
290
291    my $cleanup;
292    if(defined($searched)){
293   
294        my $busy = Wx::BusyCursor->new();
295   
296        if(!scalar @{$self->search_result}){
297            $self->creation_callback->(
298                $searched   
299            );
300   
301            $self->_refresh_selected_searched($searched);
302            $cleanup = 1;
303        }
304   
305        if( 1 == scalar @{$self->search_result}){
306            $self->_refresh_selected_searched($searched);
307            $cleanup = 1;
308        }
309   
310    }
311    else{
312        $cleanup = 1;
313    }
314
315    if($cleanup){   
316        $self->search->ChangeValue("");
317        $self->search->SetFocus;
318    }
319}
320
321sub _refresh_selected_searched {
322    my ( $self, $searched ) = @_;       
323
324    $self->Refresh;
325    $self->SetSelection($searched);
326    $self->_show_selected;
327    $self->btn_show->SetStringSelection(gettext("Selected"));
328}
329
330sub OnSearch {
331    my( $self, $event ) = @_;
332
333    $self->btn_show->SetStringSelection(gettext("All"));
334
335    my $searched = $self->search->GetValue;
336
337    $self->search_result(
338        $self->_filter_choices(
339            $searched
340        )
341    );
342
343    $self->Refresh(
344        $self->search_result
345    );
346   
347    # autocompletion
348    if(1== scalar @{$self->search_result}){
349        my $value = $self->search_result->[0]->{name};
350        unless(  $value eq $self->previous_autocompleted ){
351            $self->autocomplete_from(
352                $self->search->GetLastPosition
353            );
354            $self->search->ChangeValue($value);
355            $self->autocomplete_to(
356                $self->search->GetLastPosition
357            );
358            $self->autocomplete_set_selection(1);
359            $self->previous_autocompleted($value);
360        }   
361    }
362    else{
363        $self->previous_autocompleted(undef);
364    }
365   
366    $event->Skip;
367}
368
369sub OnCancel {
370    my( $self, $event ) = @_;
371
372    $self->Refresh(
373        $self->choices->()
374    );
375   
376    $self->btn_show->SetStringSelection(gettext("All"));
377}
378
379
380sub _filter_choices {
381    my ( $self, $searched ) = @_;
382   
383    my $choices = $self->choices->()||[];
384    [
385       grep { $_->{name} =~ /^$searched/} @$choices
386    ]
387}
388
389sub _show_notselected {
390    my ( $self ) = @_;   
391
392    $self->Refresh(
393        $self->_filter_notselected()
394    );
395}
396
397sub _show_selected {
398    my ( $self ) = @_;   
399
400    $self->Refresh(
401        $self->_filter_selected()
402    );
403}
404
405sub _show_all {
406    my ( $self ) = @_;   
407
408    $self->Refresh(
409        $self->choices->()
410    );
411}
412
413sub _filter_selected {
414    my ( $self ) = @_;
415
416    my $choices = $self->choices->()||[];
417    [
418        grep { $self->is_selected->{$_->{id}} } @$choices
419    ]   
420}
421
422sub _filter_notselected {
423    my ( $self ) = @_;
424
425    my $choices = $self->choices->()||[];
426    [
427        grep { !$self->is_selected->{$_->{id}} } @$choices
428    ]   
429}
430
431
4321;
Note: See TracBrowser for help on using the repository browser.