File Coverage

blib/lib/CPANPLUS/Shell/Wx/Configure.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             #TODO clean up Log Messages
2              
3             package CPANPLUS::Shell::Wx::Configure;
4 1     1   2037 use Wx;
  0            
  0            
5             use Data::Dumper;
6             use Wx::XRC;
7             use Cwd;
8             use CPANPLUS::Shell::Wx::util;
9              
10             #use CPANPLUS::Shell::Wx::prefsCheck;
11             use Wx::Event qw(EVT_CHECKBOX EVT_WINDOW_CREATE);
12             use Wx::Locale gettext => '_T';
13              
14             BEGIN {
15             use vars qw( @ISA $VERSION );
16             @ISA = qw( Wx::Dialog);
17             $VERSION = '0.01';
18             }
19              
20             use base 'Wx::Dialog';
21              
22             #when creating a new window, add the config property to it,
23             #and crete a new backend::configure object so we can manipulate it
24             sub new {
25             my $class = shift;
26             my $self = $class->SUPER::new(); # create an 'empty' Frame object
27              
28             $self->{cpan} = Wx::Window::FindWindowByName('main_window')->{cpan};
29             $self->{config} = $self->{cpan}->configure_object();
30              
31             #NOTE Freeze object so we can revert changes upon cancel
32             use Storable qw[dclone];
33             $self->{old_conf}=dclone($self->{config}->conf);
34             $self->_check_config_file();
35             return $self;
36              
37             }
38              
39             #this checks to see if user config file is present.
40             #if not, it creates one
41             sub _check_config_file{
42             my $self=shift;
43             my $file=_uGetPath($self->{config},'app_config');
44             unless (-e $file ){
45             if (open(F,">$file") ){
46             print F '';
47             close F;
48             }else{
49             Wx::LogError("Cannot create wxCPAN Preferences File: $file");
50             }
51             }else{
52             Wx::LogMessage("Using wxCPAN Preferences file: $file");
53             }
54             }
55              
56             ########################################
57             ############ LibListCtrl ###############
58             ########################################
59             package CPANPLUS::Shell::Wx::Configure::LibListCtrl;
60             use Wx::Event qw(EVT_WINDOW_CREATE EVT_BUTTON);
61             use Data::Dumper;
62             use Wx::Locale gettext => '_T';
63              
64             use base 'Wx::ListView';
65              
66             sub new {
67             my $class = shift;
68             my $self = $class->SUPER::new(); # create an 'empty' Frame object
69             EVT_WINDOW_CREATE( $self, $self, \&OnCreate );
70             $self->{cpan} = Wx::Window::FindWindowByName('prefs_window')->{cpan};
71             $self->{config} = $self->{cpan}->configure_object();
72              
73             #This is need because, for some unknown reason, OnCreate()
74             # is being called 3 times
75             $self->{'has_inited'} = 0;
76              
77             return $self;
78             }
79              
80             #this is called after new()
81             sub OnCreate {
82             my $self = shift;
83             return if $self->{'has_inited'};
84             my @vals = $self->{config}->get_conf('hosts');
85             $self->InsertColumn(0,_T("Library Path"));
86             $self->SetColumnWidth(0,-1);
87             $self->RePopulate();
88             $self->{'has_inited'} = 1;
89             }
90             sub RePopulate{
91             my $self = shift;
92             my $vals = $self->{config}->get_conf('lib');
93             $self->DeleteAllItems();
94             Wx::LogMessage Dumper $vals;
95             foreach $item ( @$vals ) {
96             $self->InsertStringItem( 0, $item );
97             }
98             $self->SetColumnWidth(0,-1); #resize the column to fit new width
99             }
100              
101             ########################################
102             ############## SpinCtrl ################
103             ########################################
104              
105             package CPANPLUS::Shell::Wx::Configure::SpinCtrl;
106             use Wx::Event qw(EVT_SPINCTRL EVT_WINDOW_CREATE);
107             use Wx::Locale gettext => '_T';
108              
109             BEGIN {
110             use vars qw( @ISA $VERSION );
111             @ISA = qw( Wx::SpinCtrl);
112             $VERSION = '0.01';
113             }
114              
115             use base 'Wx::SpinCtrl';
116              
117             sub new {
118             my $class = shift;
119             my $self = $class->SUPER::new(); # create an 'empty' Frame object
120             EVT_SPINCTRL( $self, $self, \&OnSpin );
121             EVT_WINDOW_CREATE( $self, $self, \&OnCreate );
122             $self->{config} = Wx::Window::FindWindowByName('prefs_window')->{config};
123             return $self;
124             }
125              
126             #this is called after new()
127             sub OnCreate {
128             my $self = shift;
129             my $name = $self->GetName();
130             $name =~ s|_|\('|; #for use with wxGlade
131             eval "\$self->SetValue(\$self->{config}->get_$name'))";
132             $self->SetRange(0,65535);
133             }
134              
135             #this method happens when a spinner is spinned.
136             #The name [GetName() in wxWidgets] is used to retrieve the value
137             #and category in the CPANPLUS::Configure module
138             sub OnSpin {
139             my $self = shift;
140             my ($event) = @_;
141             my $name = $self->GetName();
142             $name =~ s|_|\('|;
143             eval "\$self->{config}->set_$name'=>\$self->GetValue)";
144             }
145              
146             ########################################
147             ############## CheckBox ################
148             ########################################
149              
150             package CPANPLUS::Shell::Wx::Configure::CheckBox;
151             use Wx::Event qw(EVT_CHECKBOX EVT_WINDOW_CREATE);
152             use Wx::Locale gettext => '_T';
153              
154             use base 'Wx::CheckBox';
155              
156             sub new {
157             my $class = shift;
158             my $self = $class->SUPER::new(); # create an 'empty' Frame object
159             EVT_CHECKBOX( $self, $self, \&OnToggle );
160             EVT_WINDOW_CREATE( $self, $self, \&OnCreate );
161             $self->{config} = Wx::Window::FindWindowByName('prefs_window')->{config};
162             return $self;
163             }
164              
165             #this is called after new()
166             sub OnCreate {
167             my $self = shift;
168             my $name = $self->GetName();
169             $name =~ s|_|\('|; #for use with wxGlade
170             eval "\$self->SetValue(\$self->{config}->get_$name'))";
171             }
172              
173             #this method happens when a checkbox is toggled.
174             #The name [GetName() in wxWidgets] is used to retrieve the value
175             #and category in the CPANPLUS::Configure module
176             sub OnToggle {
177             my $self = shift;
178             my ($event) = @_;
179             my $name = $self->GetName();
180             $name =~ s|_|\('|; #for use with wxGlade
181             eval "\$self->{config}->set_$name'=>\$self->GetValue)";
182             }
183              
184             ########################################
185             ############## ComboBox ################
186             ########################################
187              
188             package CPANPLUS::Shell::Wx::Configure::ComboBox;
189             use Wx::Event qw(EVT_COMBOBOX EVT_TEXT EVT_WINDOW_CREATE);
190             use Data::Dumper;
191             use Wx::Locale gettext => '_T';
192              
193             use base 'Wx::ComboBox';
194              
195             sub new {
196             my $class = shift;
197             my $self = $class->SUPER::new(); # create an 'empty' Frame object
198             EVT_WINDOW_CREATE( $self, $self, \&OnCreate );
199             $self->{config} = Wx::Window::FindWindowByName('prefs_window')->{config};
200             return $self;
201             }
202              
203             #this is called after new()
204             sub OnCreate {
205             my $self = shift;
206             my $name = $self->GetName();
207             $name =~ s|_|\('|; #for use with wxGlade
208             my $val;
209             eval "\$val=\$self->{config}->get_$name')";
210             EVT_COMBOBOX( $self, $self, \&OnSelect ) if $name=~/prereqs/;
211             EVT_TEXT($self, $self, \&OnEdit) if $name=~/dist_type/;
212             $self->SetSelection($val) if $name=~/prereqs/;
213             $self->SetValue($val) if $name=~/dist_type/;
214             }
215              
216             #this method happens when a selection is made
217             sub OnSelect {
218             my $self = shift;
219             my ($event) = @_;
220             my $name = $self->GetName();
221             $name =~ s|_|\('|; #for use with wxGlade
222             eval "\$self->{config}->set_$name'=>\$self->GetSelection)";
223             }
224             #this is called when the edit box is edited. Only applies to dist_type
225             sub OnEdit {
226             my $self = shift;
227             my ($event) = @_;
228             my $name = $self->GetName();
229             $name =~ s|_|\('|; #for use with wxGlade
230             eval "\$self->{config}->set_$name'=>'".$self->GetValue."')";
231             }
232              
233             ########################################
234             ############## TextCtrl ################
235             ########################################
236             package CPANPLUS::Shell::Wx::Configure::TextCtrl;
237             use Wx::Event qw(EVT_KILL_FOCUS EVT_WINDOW_CREATE);
238             use Wx::Locale gettext => '_T';
239              
240             use base 'Wx::TextCtrl';
241              
242             sub new {
243             my $class = shift;
244             my $self = $class->SUPER::new(); # create an 'empty' Frame object
245             EVT_KILL_FOCUS( $self, \&OnBlur );
246             EVT_WINDOW_CREATE( $self, $self, \&OnCreate );
247             $self->{config} = Wx::Window::FindWindowByName('prefs_window')->{config};
248             return $self;
249             }
250              
251             #this is called after new()
252             sub OnCreate {
253             my $self = shift;
254             my $name = $self->GetName();
255             $name =~ s|_|\('|; #for use with wxGlade
256             eval "\$self->SetValue(\$self->{config}->get_$name'))";
257             }
258              
259             #this method happens when the textctrl loses focus.
260             #it sets the config value
261             sub OnBlur {
262             my $self = shift;
263             my ($event) = @_;
264             my $name = $self->GetName();
265             $name =~ s|_|\('|; #for use with wxGlade
266             eval "\$self->{config}->set_$name'=>'".$self->GetValue."')";
267             }
268              
269             ########################################
270             ############ HostListCtrl ##############
271             ########################################
272             package CPANPLUS::Shell::Wx::Configure::HostListCtrl;
273             use Wx::Event qw(EVT_WINDOW_CREATE EVT_BUTTON);
274             use Data::Dumper;
275             use Wx::Locale gettext => '_T';
276              
277             use base 'Wx::ListView';
278              
279             sub new {
280             my $class = shift;
281             my $self = $class->SUPER::new(); # create an 'empty' Frame object
282             EVT_WINDOW_CREATE( $self, $self, \&OnCreate );
283             $self->{cpan} = Wx::Window::FindWindowByName('prefs_window')->{cpan};
284             $self->{config} = $self->{cpan}->configure_object();
285              
286             #This is need because, for some unknown reason, OnCreate()
287             # is being called 3 times
288             $self->{'has_inited'} = 0;
289             return $self;
290             }
291              
292             #this is called after new()
293             sub OnCreate {
294             my $self = shift;
295             return if $self->{'has_inited'};
296             my @vals = $self->{config}->get_conf('hosts');
297              
298             $self->InsertColumn( 0, 'Host' );
299             $self->InsertColumn( 1, 'Path' );
300             $self->InsertColumn( 2, 'Scheme' );
301              
302             $self->RePopulate();
303              
304             $self->{'has_inited'} = 1;
305             }
306             sub RePopulate{
307             my $self = shift;
308             my @vals = $self->{config}->get_conf('hosts');
309             $self->DeleteAllItems();
310             foreach $item ( @{ $vals[0] } ) {
311             $self->InsertStringItem( 0, $item->{'host'} );
312             $self->SetItem( 0, 1, $item->{'path'} );
313             $self->SetItem( 0, 2, $item->{'scheme'} );
314             }
315             }
316              
317              
318             ########################################
319             ############### Button #################
320             ########################################
321              
322             package CPANPLUS::Shell::Wx::Configure::Button;
323             use Wx::Event qw(EVT_WINDOW_CREATE EVT_BUTTON);
324             use Data::Dumper;
325             use Wx::Locale gettext => '_T';
326              
327             use base 'Wx::Button';
328              
329             sub new {
330             my $class = shift;
331             my $self = $class->SUPER::new(); # create an 'empty' Frame object
332             EVT_WINDOW_CREATE( $self, $self, \&OnCreate );
333             $self->{cpan} = Wx::Window::FindWindowByName('prefs_window')->{cpan};
334             $self->{config} = $self->{cpan}->{config};
335             return $self;
336             }
337              
338             sub OnCreate {
339             my $self = shift;
340             my $name = $self->GetName();
341             my $id=$self->GetId();
342              
343             $self->{conflist} = Wx::Window::FindWindowByName('conf_hosts');
344             $self->{config} = $self->{conflist}->{config}; #
345             $self->{cpan} = $self->{conflist}->{cpan};
346             $self->{liblist} = Wx::Window::FindWindowByName('conf_lib');
347              
348             EVT_BUTTON( $self, $self, \&OnAdd ) if ( $name eq 'AddHost' );
349             EVT_BUTTON( $self, $self, \&OnRemove ) if ( $name eq 'RemoveHost' );
350             EVT_BUTTON( $self, $self, \&OnPrefsCancel ) if ( $name eq 'prefs_cancel' );
351             EVT_BUTTON( $self, $self, \&OnPrefsSave ) if ( $name eq 'prefs_save' );
352             EVT_BUTTON( $self, $self, \&OnAddLib ) if ( $name eq 'AddLib' );
353             EVT_BUTTON( $self, $self, \&OnRemoveLib ) if ( $name eq 'RemoveLib' );
354             EVT_BUTTON( $self, $self, \&OnSelectFile ) if ( $name =~ /^selectFile_/ );
355             EVT_BUTTON( $self, $self, \&OnSelectDir ) if ( $name =~ /^selectDir_/ );
356              
357             }
358              
359             sub OnSelectDir{
360             my $self = shift;
361             my $myName = $self->GetName();
362             my $textCtrlName=$myName;
363             $myName =~ s|selectDir_||; #remove item prefix
364             $myName =~ s|_|\('|; #make into function call
365             $textCtrlName=~s/selectDir_//;#name of textctrl to update
366             my $curDir='';
367             eval "\$curDir=\$self->{config}->get_$myName')";
368              
369             my $dlg=Wx::DirDialog->new($self,_T("Choose a Directory:"),$curDir);
370             if ($dlg->ShowModal()){
371             Wx::LogMessage _T("Setting ").$myName._T(" to ").$dlg->GetPath."\n";
372             eval "\$self->{config}->set_$myName'=>\$dlg->GetPath())";
373             my $textctrl=Wx::Window::FindWindowByName($textCtrlName);
374             $textctrl->SetValue($dlg->GetPath()) if $textctrl;
375             }
376             }
377             sub OnSelectFile{
378             my $self = shift;
379             my $myName = $self->GetName();
380             my $textCtrlName=$myName;
381             $myName =~ s|selectFile_||; #remove item prefix
382             $myName =~ s|_|\('|; #make into function call
383             $textCtrlName=~s/selectFile_//;#name of textctrl to update
384             my $curDir='';
385             eval "\$curDir=\$self->{config}->get_$myName')";
386              
387             my $dlg=Wx::FileDialog->new($self,_T("Choose a File:"),$curDir);
388             if ($dlg->ShowModal()){
389             eval "\$self->{config}->set_$myName'=>\$dlg->GetPath())";
390             my $textctrl=Wx::Window::FindWindowByName($textCtrlName);
391             $textctrl->SetValue($dlg->GetPath()) if $textctrl;
392             }
393             }
394              
395             sub OnRemoveLib {
396             my $self = shift;
397             my ($event) = @_;
398             my $selectedIdx=$self->{liblist}->GetFirstSelected();
399             my $selected = $self->{liblist}->GetItemText($selectedIdx);
400             $self->{liblist}->DeleteItem($selectedIdx);
401              
402             my $old_libs=$self->{config}->get_conf('lib');
403             my @new_libs=();
404             for (my $i=0;$i<@$old_libs;$i++){
405             push(@new_libs,$old_libs->[$i]) unless ($old_libs->[$i] eq $selected);
406             }
407             $self->{config}->set_conf(lib => \@new_libs);
408             }
409              
410             sub OnAddLib {
411             my $self = shift;
412             my ($event) = @_;
413             my $new_path=Wx::DirSelector( #get path from user
414             _T("Select a Path to add to @INC:"));
415             return unless $new_path; #if user cancelled, do nothing else
416              
417             $libCtrl = Wx::Window::FindWindowByName('conf_lib'); #get the lib list control
418             my $libs=$self->{config}->get_conf('lib'); #get curent libs array
419             push (@$libs,$new_path); #append to current libs array
420             $self->{config}->set_conf(lib => $libs); #set the libs array to new value
421             $libCtrl->InsertStringItem( 0,$new_path ); #Insert the new value into list
422             $libCtrl->SetColumnWidth(0,-1); #resize the column to fit new width
423              
424             }
425              
426             sub OnPrefsCancel {
427             my $self = shift;
428             my ($event) = @_;
429             # $self->{config}->init();
430             my $prefsWin=Wx::Window::FindWindowByName('prefs_window');
431              
432             #replace config object with a stored copy
433             $prefsWin->{config}->conf($prefsWin->{old_conf});
434              
435             $prefsWin->Destroy();
436             }
437              
438             sub OnPrefsSave {
439             my $self = shift;
440             my ($event) = @_;
441             Wx::LogMessage("Saving Prefs...");
442             my $prefsWin=Wx::Window::FindWindowByName('prefs_window');
443             my $thisConfig = $prefsWin->{config};
444             Wx::Window::FindWindowByName('main_window')->{config} = $thisConfig;
445             if ( $thisConfig->can_save() ) {
446             $thisConfig->save();
447             Wx::LogMessage(_T("Preferences Saved!"));
448             } else {
449             Wx::MessageBox( _T('Sorry! I cannot save your file!'),
450             _T('Save Failed'), wxOK | wxICON_INFORMATION, $self );
451             return;
452             }
453             $prefsWin->Destroy();
454             }
455              
456             #some code in this function is taken from CPANPLUS::Configure::Setup.
457             sub OnAdd {
458             my $self = shift;
459             my ($event) = @_;
460             use Wx qw(wxYES_NO wxID_YES wxYES wxID_NO wxNO wxCANCEL wxID_CANCEL wxICON_QUESTION);
461             my @cur_hosts=@{$self->{config}->get_conf('hosts')};
462              
463             #get what type we are adding - custom or mirror
464             my $qDialog=Wx::MessageDialog->new( $self, _T('Do You Want to add a custom entry(yes) or select from a list(no)?'),
465             _T('Select Entry Type'), (wxYES_NO | wxICON_QUESTION) );
466             if ($qDialog->ShowModal() == wxID_YES){
467             my $custom_dialog = Wx::TextEntryDialog->new(
468             $self, _T("Enter the URI of your custom source:"),
469             _T("Enter Custom Source")
470             );
471             my $custom_source=$custom_dialog->ShowModal;
472             return if( $custom_source == wxID_CANCEL );
473             $custom_source=$custom_dialog->GetValue();
474             my $href;
475             ($href->{scheme},$href->{host},$href->{path})=$custom_source =~ /\s*(.*)\:\/\/(.*?)(\/.*)\s*/;
476             push @cur_hosts,$href;
477             goto END;
478             }
479              
480             my %hosts = (); #hash containing host entries
481             my %location_tree = (); #a tree of locations
482              
483             use CPANPLUS::Module::Fake;
484             use CPANPLUS::Module::Author::Fake;
485              
486             my $file = $self->{cpan}->_fetch(
487             fetchdir => $self->{config}->get_conf('base'),
488             module => CPANPLUS::Module::Fake->new(
489             module => $self->{config}->_get_source('hosts'),
490             path => '',
491             package => $self->{config}->_get_source('hosts'),
492             author => CPANPLUS::Module::Author::Fake->new( _id => $self->{cpan}->_id ),
493             _id => $self->{cpan}->_id,
494             )
495             );
496              
497             #read in the MIRRORS.txt file and parse it
498             my $curhost = '';
499             open F, $file;
500             foreach $line () {
501             unless ( $line =~ /^\#/ ) { #skip lines that begin with a comment
502             $curhost = $1 if ( $line =~ /(^(\S+\.)+\S+)\:/ ); #lines that begin with x.y.z: mean a new entry
503             $hosts{$curhost}->{$1} = $2 if ( $line =~ /(\w*?)\s*=\s*\"(.*?)\"/ ); #add info to host
504             }
505             }
506             close F;
507              
508             foreach $key ( keys(%hosts) ) {
509             my @loc = split( ', ', $hosts{$key}->{'dst_location'} ); #split line like "city,state,country,region (lat long)"
510             $loc[-1] =~ s/\s*\((.*)\)//; #get rid of lat, long coord
511             $1 =~ /\s*(\-?\d+\.\d+)\s*(\-?\d+\.\d+)/; #search for lat, long
512             ($hosts{$key}->{'lat'},$hosts{$key}->{'long'}) = ($1,$2); #assign lat,long
513             $location_tree{ $loc[-1] }->{ $loc[-2] }->{ $loc[-3] } = $hosts{$key}; #all entries have at least depths
514             if ( $loc[-4] ){ #some entries have four depths
515             $location_tree{ $loc[-1] }->{ $loc[-2] }->{ $loc[-3] }={};
516             $location_tree{ $loc[-1] }->{ $loc[-2] }->{ $loc[-3] }->{ $loc[-4] }=$hosts{$key};
517             }
518             }
519              
520             my $selection = \%location_tree;
521             my @titles_tree = ( _T('Region'), _T('Country'), _T('State'), _T('City') );
522             until ( $selection->{'dst_location'} ) {
523             my $title = shift @titles_tree;
524             my $choice = Wx::GetSingleChoice( _T("Select ").$title,
525             _T("Select ").$title.":",
526             [ sort( keys( %{$selection} ) ) ], $self );
527             return unless $choice;
528             $selection = $selection->{$choice};
529             }
530              
531             my $href;
532             $selection=$selection->{'dst_http'};
533             ($href->{scheme},$href->{host},$href->{path})=$selection =~ /\s*(.*)\:\/\/(.*?)(\/.*)\s*/;
534             push @cur_hosts,$href;
535              
536             END:
537             $self->{config}->set_conf( hosts => \@cur_hosts );
538             $self->{conflist}->RePopulate();
539              
540             }
541              
542             sub OnRemove {
543             my $self = shift;
544             my ($event) = @_;
545             my $selected = $self->{conflist}->GetItemText($self->{conflist}->GetFirstSelected());
546             $self->{conflist}->DeleteItem($self->{conflist}->GetFirstSelected());
547              
548             my $old_hosts=$self->{config}->get_conf('hosts');
549             my @new_hosts=();
550             for (my $i=0;$i<@$old_hosts;$i++){
551             push(@new_hosts,$old_hosts->[$i]) unless ($old_hosts->[$i]->{'host'} eq $selected);
552             }
553              
554             $self->{config}->set_conf(hosts => \@new_hosts);
555             }
556             1;