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