~ubuntu-branches/ubuntu/precise/padre/precise

« back to all changes in this revision

Viewing changes to lib/Padre/Wx/Dialog/Goto.pm

  • Committer: Bazaar Package Importer
  • Author(s): Damyan Ivanov
  • Date: 2010-05-08 09:17:22 UTC
  • mfrom: (1.2.1 upstream) (10.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20100508091722-y6008jtk0ap6znyn
Tags: 0.60.ds1-3
rules: run tests with HOME=$fake_home to avoud failing when $HOME points
to a non-existent location. Closes: #579289

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package Padre::Wx::Dialog::Goto;
 
2
 
 
3
use 5.008;
 
4
use strict;
 
5
use warnings;
 
6
use Padre::Wx                  ();
 
7
use Padre::Wx::Role::MainChild ();
 
8
 
 
9
our $VERSION = '0.60';
 
10
our @ISA     = qw{
 
11
        Padre::Wx::Role::MainChild
 
12
        Wx::Dialog
 
13
};
 
14
 
 
15
=pod
 
16
 
 
17
=head1 NAME
 
18
 
 
19
Padre::Wx::Dialog::Goto - a dialog to jump to a user-specified line/position
 
20
 
 
21
=head1 PUBLIC API
 
22
 
 
23
=head2 C<new>
 
24
 
 
25
  my $goto = Padre::Wx::Dialog::Goto->new($main);
 
26
 
 
27
Returns a new C<Padre::Wx::Dialog::Goto> instance
 
28
 
 
29
=cut
 
30
 
 
31
sub new {
 
32
        my $class = shift;
 
33
        my $main  = shift;
 
34
 
 
35
        # Create the Wx dialog
 
36
        my $self = $class->SUPER::new(
 
37
                $main,
 
38
                -1,
 
39
                Wx::gettext('Goto'),
 
40
                Wx::wxDefaultPosition,
 
41
                Wx::wxDefaultSize,
 
42
                Wx::wxRESIZE_BORDER | Wx::wxSYSTEM_MENU | Wx::wxCAPTION | Wx::wxCLOSE_BOX
 
43
        );
 
44
 
 
45
        # Minimum dialog size
 
46
        $self->SetMinSize( [ 330, 180 ] );
 
47
 
 
48
        # create sizer that will host all controls
 
49
        my $sizer = Wx::BoxSizer->new(Wx::wxHORIZONTAL);
 
50
 
 
51
        # Create the controls
 
52
        $self->_create_controls($sizer);
 
53
 
 
54
        # Bind the control events
 
55
        $self->_bind_events;
 
56
 
 
57
        # wrap everything in a vbox to add some padding
 
58
        $self->SetSizer($sizer);
 
59
        $self->Fit;
 
60
        $self->CentreOnParent;
 
61
 
 
62
        return $self;
 
63
}
 
64
 
 
65
#
 
66
# Create dialog controls
 
67
#
 
68
sub _create_controls {
 
69
        my ( $self, $sizer ) = @_;
 
70
 
 
71
 
 
72
        # a label to display current line/position
 
73
        $self->{current} = Wx::StaticText->new( $self, -1, '' );
 
74
 
 
75
        # Goto line label
 
76
        $self->{goto_label} = Wx::StaticText->new( $self, -1, '' );
 
77
 
 
78
        # Text field for the line number/position
 
79
        $self->{goto_text} = Wx::TextCtrl->new( $self, -1, '' );
 
80
 
 
81
        # Status label
 
82
        $self->{status_line} = Wx::StaticText->new( $self, -1, '' );
 
83
 
 
84
        # Line or position choice
 
85
        $self->{line_mode} = Wx::RadioBox->new(
 
86
                $self,                 -1, Wx::gettext('Position type'),
 
87
                Wx::wxDefaultPosition, Wx::wxDefaultSize,
 
88
                [ Wx::gettext('Line number'), Wx::gettext('Character position') ]
 
89
        );
 
90
 
 
91
        # OK button (obviously)
 
92
        $self->{button_ok} = Wx::Button->new(
 
93
                $self, Wx::wxID_OK, Wx::gettext('&OK'),
 
94
        );
 
95
        $self->{button_ok}->SetDefault;
 
96
        $self->{button_ok}->Enable(0);
 
97
 
 
98
        # Cancel button (obviously)
 
99
        $self->{button_cancel} = Wx::Button->new(
 
100
                $self, Wx::wxID_CANCEL, Wx::gettext('&Cancel'),
 
101
        );
 
102
 
 
103
        #----- Dialog Layout
 
104
 
 
105
        # Main button sizer
 
106
        my $button_sizer = Wx::BoxSizer->new(Wx::wxHORIZONTAL);
 
107
        $button_sizer->Add( $self->{button_ok},     1, 0,          0 );
 
108
        $button_sizer->Add( $self->{button_cancel}, 1, Wx::wxLEFT, 5 );
 
109
        $button_sizer->AddSpacer(5);
 
110
 
 
111
        # Create the main vertical sizer
 
112
        my $vsizer = Wx::BoxSizer->new(Wx::wxVERTICAL);
 
113
        $vsizer->Add( $self->{line_mode},   0, Wx::wxALL | Wx::wxEXPAND, 3 );
 
114
        $vsizer->Add( $self->{current},     0, Wx::wxALL | Wx::wxEXPAND, 3 );
 
115
        $vsizer->Add( $self->{goto_label},  0, Wx::wxALL | Wx::wxEXPAND, 3 );
 
116
        $vsizer->Add( $self->{goto_text},   0, Wx::wxALL | Wx::wxEXPAND, 3 );
 
117
        $vsizer->Add( $self->{status_line}, 0, Wx::wxALL | Wx::wxEXPAND, 2 );
 
118
        $vsizer->AddSpacer(5);
 
119
        $vsizer->Add( $button_sizer, 0, Wx::wxALIGN_RIGHT, 5 );
 
120
        $vsizer->AddSpacer(5);
 
121
 
 
122
        # Wrap with a horizontal sizer to get left/right padding
 
123
        $sizer->Add( $vsizer, 1, Wx::wxALL | Wx::wxEXPAND, 5 );
 
124
 
 
125
        return;
 
126
 
 
127
}
 
128
 
 
129
#
 
130
# Binds control events
 
131
#
 
132
sub _bind_events {
 
133
        my $self = shift;
 
134
 
 
135
        Wx::Event::EVT_ACTIVATE(
 
136
                $self,
 
137
                sub {
 
138
                        my $self = shift;
 
139
                        $self->_update_from_editor;
 
140
                        $self->_update_label;
 
141
                        $self->_validate;
 
142
                        return;
 
143
                }
 
144
        );
 
145
 
 
146
        Wx::Event::EVT_TEXT(
 
147
                $self,
 
148
                $self->{goto_text},
 
149
                sub {
 
150
                        $_[0]->_validate;
 
151
                        return;
 
152
                }
 
153
        );
 
154
 
 
155
        Wx::Event::EVT_RADIOBOX(
 
156
                $self,
 
157
                $self->{line_mode},
 
158
                sub {
 
159
                        my $self = shift;
 
160
                        $self->_update_label;
 
161
                        $self->_validate;
 
162
                        return;
 
163
                },
 
164
        );
 
165
 
 
166
        Wx::Event::EVT_BUTTON(
 
167
                $self,
 
168
                $self->{button_cancel},
 
169
                sub {
 
170
                        $_[0]->Hide;
 
171
                        return;
 
172
                }
 
173
        );
 
174
 
 
175
        Wx::Event::EVT_BUTTON(
 
176
                $self,
 
177
                $self->{button_ok},
 
178
                sub {
 
179
                        $_[0]->_on_ok_button;
 
180
                        return;
 
181
                },
 
182
        );
 
183
 
 
184
}
 
185
 
 
186
#
 
187
# Private method to handle the pressing of the OK button
 
188
#
 
189
sub _on_ok_button {
 
190
        my $self = shift;
 
191
 
 
192
        # Fetch values
 
193
        my $line_mode = $self->{line_mode}->GetStringSelection eq Wx::gettext('Line number');
 
194
        my $value     = $self->{goto_text}->GetValue;
 
195
        my $editor    = $self->current->editor;
 
196
 
 
197
        # Bounds checking
 
198
        my $max_value = $line_mode ? $self->{max_line_number} : $self->{max_position};
 
199
        $value = $max_value if $value > $max_value;
 
200
        $value--;
 
201
 
 
202
        # Destroy the dialog
 
203
        $self->Hide;
 
204
 
 
205
        # And then goto to the line or position
 
206
        # keeping it in the center of the editor
 
207
        # if possible
 
208
        if ($line_mode) {
 
209
                $editor->goto_line_centerize($value);
 
210
        } else {
 
211
                $editor->goto_pos_centerize($value);
 
212
        }
 
213
 
 
214
        return;
 
215
}
 
216
 
 
217
#
 
218
# Private method to update the goto line/position label
 
219
#
 
220
sub _update_label {
 
221
        my $self      = shift;
 
222
        my $line_mode = $self->{line_mode}->GetStringSelection;
 
223
        if ( $line_mode eq Wx::gettext('Line number') ) {
 
224
                $self->{goto_label}
 
225
                        ->SetLabel( sprintf( Wx::gettext('&Enter a line number between 1 and %s:'), $self->{max_line_number} ) );
 
226
                $self->{current}->SetLabel( sprintf( Wx::gettext('Current line number: %s'), $self->{current_line_number} ) );
 
227
        } elsif ( $line_mode eq Wx::gettext('Character position') ) {
 
228
                $self->{goto_label}
 
229
                        ->SetLabel( sprintf( Wx::gettext('&Enter a position between 1 and %s:'), $self->{max_position} ) );
 
230
                $self->{current}->SetLabel( sprintf( Wx::gettext('Current position: %s'), $self->{current_position} ) );
 
231
        } else {
 
232
                warn "Invalid choice value '$line_mode'\n";
 
233
        }
 
234
}
 
235
 
 
236
#
 
237
# Private method to validate user input
 
238
#
 
239
sub _validate {
 
240
        my $self = shift;
 
241
 
 
242
        my $line_mode = $self->{line_mode}->GetStringSelection eq Wx::gettext('Line number');
 
243
        my $value = $self->{goto_text}->GetValue;
 
244
 
 
245
        # If it is empty, do not warn about it but disable it though
 
246
        if ( $value eq '' ) {
 
247
                $self->{status_line}->SetLabel('');
 
248
                $self->{button_ok}->Enable(0);
 
249
                return;
 
250
        }
 
251
 
 
252
        # Should be an integer number
 
253
        if ( $value !~ /^\d+$/ ) {
 
254
                $self->{status_line}->SetLabel( Wx::gettext('Not a positive number!') );
 
255
                $self->{button_ok}->Enable(0);
 
256
                return;
 
257
        }
 
258
 
 
259
        # Bounds checking
 
260
        my $editor = $self->current->editor;
 
261
        my $max_value = $line_mode ? $self->{max_line_number} : $self->{max_position};
 
262
        if ( $value == 0 or $value > $max_value ) {
 
263
                $self->{status_line}->SetLabel( Wx::gettext('Out of range!') );
 
264
                $self->{button_ok}->Enable(0);
 
265
 
 
266
                return;
 
267
        }
 
268
 
 
269
        # Not problem, enable everything and clear errors
 
270
        $self->{button_ok}->Enable(1);
 
271
        $self->{status_line}->SetLabel('');
 
272
}
 
273
 
 
274
#
 
275
# Private method to update statistics from the current editor
 
276
#
 
277
sub _update_from_editor {
 
278
        my $self = shift;
 
279
 
 
280
        # Get the current editor
 
281
        my $editor = $self->current->editor;
 
282
        unless ($editor) {
 
283
                $self->Hide;
 
284
                return 0;
 
285
        }
 
286
 
 
287
        # Update max line number and position fields
 
288
        $self->{max_line_number}     = $editor->GetLineCount;
 
289
        $self->{max_position}        = $editor->GetLength + 1;
 
290
        $self->{current_line_number} = $editor->GetCurrentLine + 1;
 
291
        $self->{current_position}    = $editor->GetCurrentPos + 1;
 
292
 
 
293
        return 1;
 
294
}
 
295
 
 
296
 
 
297
=pod
 
298
 
 
299
=head2 C<show>
 
300
 
 
301
  $goto->show($main);
 
302
 
 
303
Show the dialog that the user can use to go to to a line number or character
 
304
position. Returns C<undef>.
 
305
 
 
306
=cut
 
307
 
 
308
sub show {
 
309
        my $self = shift;
 
310
 
 
311
        # Update current, and max bounds from the current editor
 
312
        return unless $self->_update_from_editor;
 
313
 
 
314
        # Update Goto labels
 
315
        $self->_update_label;
 
316
 
 
317
        # Select all of the line number/position so the user can overwrite
 
318
        # it quickly if he wants it
 
319
        $self->{goto_text}->SetSelection( -1, -1 );
 
320
 
 
321
        unless ( $self->IsShown ) {
 
322
 
 
323
                # If it is not shown, show the dialog
 
324
                $self->Show;
 
325
        }
 
326
 
 
327
        # Win32 tip: Always focus on wxwidgets controls only after
 
328
        # showing the dialog, otherwise you will lose the focus
 
329
        $self->{goto_text}->SetFocus;
 
330
 
 
331
        return;
 
332
}
 
333
 
 
334
1;
 
335
 
 
336
=pod
 
337
 
 
338
=head1 COPYRIGHT & LICENSE
 
339
 
 
340
Copyright 2008-2010 The Padre development team as listed in Padre.pm.
 
341
 
 
342
This program is free software; you can redistribute
 
343
it and/or modify it under the same terms as Perl itself.
 
344
 
 
345
The full text of the license can be found in the
 
346
LICENSE file included with this module.
 
347
 
 
348
=cut
 
349
 
 
350
# Copyright 2008-2010 The Padre development team as listed in Padre.pm.
 
351
# LICENSE
 
352
# This program is free software; you can redistribute it and/or
 
353
# modify it under the same terms as Perl 5 itself.