root/trunk/Padre/lib/Padre/Wx/Dialog/HelpSearch.pm @ 11120

Revision 11120, 10.3 KB (checked in by azawawi, 6 months ago)

Perl tidy (25 files)

Line 
1package Padre::Wx::Dialog::HelpSearch;
2
3use 5.008;
4use strict;
5use warnings;
6
7# package exports and version
8our $VERSION = '0.58';
9our @ISA     = 'Wx::Dialog';
10
11# module imports
12use Padre::Wx       ();
13use Padre::Wx::Icon ();
14
15# accessors
16use Class::XSAccessor {
17        accessors => {
18                _hbox           => '_hbox',           # horizontal box sizer
19                _topic_selector => '_topic_selector', # Topic selector
20                _search_text    => '_search_text',    # search text control
21                _list           => '_list',           # matches list
22                _index          => '_index',          # help topic list
23                _help_viewer    => '_help_viewer',    # HTML Help Viewer
24                _main           => '_main',           # Padre's main window
25                _topic          => '_topic',          # default help topic
26                _help_provider  => '_help_provider',  # Help Provider
27                _status         => '_status'          # status label
28        }
29};
30
31# -- constructor
32sub new {
33        my ( $class, $main, %opt ) = @_;
34
35        # create object
36        my $self = $class->SUPER::new(
37                $main,
38                -1,
39                Wx::gettext('Help Search'),
40                Wx::wxDefaultPosition,
41                Wx::wxDefaultSize,
42                Wx::wxDEFAULT_FRAME_STYLE | Wx::wxTAB_TRAVERSAL,
43        );
44
45        $self->_main($main);
46        $self->_topic( $opt{topic} || '' );
47
48        # Dialog's icon as is the same as Padre
49        $self->SetIcon(Padre::Wx::Icon::PADRE);
50
51        # create dialog
52        $self->_create;
53
54        # fit and center the dialog
55        $self->Fit;
56        $self->CentreOnParent;
57
58        return $self;
59}
60
61# Display a message in the help html window in big bold letters
62sub _display_msg {
63        my ( $self, $text ) = @_;
64        $self->_help_viewer->SetPage(qq{<b><font size="+2">$text</font></b>});
65}
66
67#
68# Fetches the current selection's help HTML
69#
70sub _display_help_in_viewer {
71        my $self = shift;
72
73        my ( $html, $location );
74        my $selection = $self->_list->GetSelection();
75        if ( $selection != -1 ) {
76                my $topic = $self->_list->GetClientData($selection);
77
78                if ( $topic && $self->_help_provider ) {
79                        eval { ( $html, $location ) = $self->_help_provider->help_render($topic); };
80                        if ($@) {
81                                $self->_display_msg( sprintf( Wx::gettext('Error while calling %s %s'), 'help_render', $@ ) );
82                                return;
83                        }
84                }
85        }
86
87        if ($html) {
88
89                # Highlights <pre> code sections with a grey background
90                $html =~ s/<pre>/<table border="0" width="100%" bgcolor="#EEEEEE"><tr><td><pre>/ig;
91                $html =~ s/<\/pre>/<\/pre\><\/td><\/tr><\/table>/ig;
92        } else {
93                $html = '<b><font size="+2">' . Wx::gettext('No Help found') . '</font></b>';
94        }
95
96        $self->SetTitle( Wx::gettext('Help Search') . ( defined $location ? ' - ' . $location : '' ) );
97        $self->_help_viewer->SetPage($html);
98
99        return;
100}
101
102#
103# create the dialog itself.
104#
105sub _create {
106        my $self = shift;
107
108        # create sizer that will host all controls
109        $self->_hbox( Wx::BoxSizer->new(Wx::wxHORIZONTAL) );
110
111        # create the controls
112        $self->_create_controls;
113
114        # wrap everything in a box to add some padding
115        $self->SetMinSize( [ 750, 550 ] );
116        $self->SetSizer( $self->_hbox );
117
118        return;
119}
120
121#
122# create controls in the dialog
123#
124sub _create_controls {
125        my $self = shift;
126
127        my $topic_label = Wx::StaticText->new(
128                $self, -1,
129                Wx::gettext('Select the help &topic')
130        );
131        my @topics = ('perl 5');
132        $self->_topic_selector(
133                Wx::Choice->new(
134                        $self, -1,
135                        Wx::wxDefaultPosition,
136                        Wx::wxDefaultSize,
137                        \@topics,
138                )
139        );
140
141        #Wx::Event::EVT_CHOICE($self, $topic_selector, \&select_topic);
142
143        # search textbox
144        my $search_label = Wx::StaticText->new(
145                $self, -1,
146                Wx::gettext('Type a help &keyword to read:')
147        );
148        $self->_search_text( Wx::TextCtrl->new( $self, -1, '' ) );
149
150        # matches result list
151        my $matches_label = Wx::StaticText->new(
152                $self, -1,
153                Wx::gettext('&Matching Help Topics:')
154        );
155        $self->_list(
156                Wx::ListBox->new(
157                        $self,
158                        -1,
159                        Wx::wxDefaultPosition,
160                        [ 180, -1 ],
161                        [],
162                        Wx::wxLB_SINGLE
163                )
164        );
165
166        # HTML Help Viewer
167        require Padre::Wx::HtmlWindow;
168        $self->_help_viewer(
169                Padre::Wx::HtmlWindow->new(
170                        $self,
171                        -1,
172                        Wx::wxDefaultPosition,
173                        Wx::wxDefaultSize,
174                        Wx::wxBORDER_STATIC
175                )
176        );
177        $self->_help_viewer->SetPage('');
178
179        my $close_button = Wx::Button->new( $self, Wx::wxID_CANCEL, Wx::gettext('&Close') );
180        $self->_status( Wx::StaticText->new( $self, -1, '' ) );
181
182        my $vbox = Wx::BoxSizer->new(Wx::wxVERTICAL);
183
184        $vbox->Add( $topic_label,           0, Wx::wxALL | Wx::wxEXPAND,     2 );
185        $vbox->Add( $self->_topic_selector, 0, Wx::wxALL | Wx::wxEXPAND,     2 );
186        $vbox->Add( $search_label,          0, Wx::wxALL | Wx::wxEXPAND,     2 );
187        $vbox->Add( $self->_search_text,    0, Wx::wxALL | Wx::wxEXPAND,     2 );
188        $vbox->Add( $matches_label,         0, Wx::wxALL | Wx::wxEXPAND,     2 );
189        $vbox->Add( $self->_list,           1, Wx::wxALL | Wx::wxEXPAND,     2 );
190        $vbox->Add( $self->_status,         0, Wx::wxALL | Wx::wxEXPAND,     0 );
191        $vbox->Add( $close_button,          0, Wx::wxALL | Wx::wxALIGN_LEFT, 0 );
192        $self->_hbox->Add( $vbox, 0, Wx::wxALL | Wx::wxEXPAND, 2 );
193        $self->_hbox->Add(
194                $self->_help_viewer,                                                        1,
195                Wx::wxALL | Wx::wxALIGN_TOP | Wx::wxALIGN_CENTER_HORIZONTAL | Wx::wxEXPAND, 1
196        );
197
198        $self->_setup_events();
199
200        return;
201}
202
203#
204# Adds various events
205#
206sub _setup_events {
207        my $self = shift;
208
209        Wx::Event::EVT_CHAR(
210                $self->_search_text,
211                sub {
212                        my $this  = shift;
213                        my $event = shift;
214                        my $code  = $event->GetKeyCode;
215
216                        if ( $code == Wx::WXK_DOWN || $code == Wx::WXK_PAGEDOWN ) {
217                                $self->_list->SetFocus();
218                        }
219
220                        $event->Skip(1);
221                }
222        );
223
224        Wx::Event::EVT_TEXT(
225                $self,
226                $self->_search_text,
227                sub {
228
229                        $self->_update_list_box;
230
231                        return;
232                }
233        );
234
235        Wx::Event::EVT_HTML_LINK_CLICKED(
236                $self,
237                $self->_help_viewer,
238                \&on_link_clicked,
239        );
240
241
242        Wx::Event::EVT_LISTBOX(
243                $self,
244                $self->_list,
245                sub {
246                        $self->_display_help_in_viewer;
247                }
248        );
249
250        return;
251}
252
253#
254# Focus on it if it shown or restart its state and show it if it is hidden.
255#
256sub show {
257        my ( $self, $topic ) = @_;
258
259        if ( not $self->IsShown ) {
260                if ( not $topic ) {
261                        $topic = $self->find_help_topic || '';
262                }
263                $self->_topic($topic);
264                $self->_search_text->ChangeValue( $self->_topic );
265                my $doc = Padre::Current->document;
266                if ($doc) {
267                        $self->_help_provider(undef);
268                }
269                $self->Show(1);
270                $self->_search_text->Enable(0);
271                $self->_topic_selector->Enable(0);
272                $self->_list->Enable(0);
273                $self->_display_msg( Wx::gettext('Reading items. Please wait') );
274                Wx::Event::EVT_IDLE(
275                        $self,
276                        sub {
277                                $self->_index(undef);
278                                if ( $self->_update_list_box ) {
279                                        $self->_search_text->Enable(1);
280                                        $self->_topic_selector->Enable(1);
281                                        $self->_list->Enable(1);
282                                        $self->_search_text->SetFocus();
283                                } else {
284                                        $self->_search_text->ChangeValue('');
285                                }
286                                Wx::Event::EVT_IDLE( $self, undef );
287                        }
288                );
289        }
290        $self->_search_text->SetFocus();
291
292        return;
293}
294
295#
296# Search for files and cache result
297#
298sub _search {
299        my $self = shift;
300
301        # Generate a sorted file-list based on filename
302        if ( not $self->_help_provider ) {
303                my $doc = Padre::Current->document;
304                if ($doc) {
305                        eval { $self->_help_provider( $doc->get_help_provider ); };
306                        if ($@) {
307                                $self->_display_msg( sprintf( Wx::gettext('Error while calling %s %s'), 'get_help_provider', $@ ) );
308                                return;
309                        }
310                        if ( not $self->_help_provider ) {
311                                $self->_display_msg( Wx::gettext("Could not find a help provider for ")
312                                                . Padre::MimeTypes->get_mime_type_name( $doc->mimetype ) );
313                                return;
314                        }
315                } else {
316
317                        # If there no document, use Perl 5 help provider
318                        require Padre::Document::Perl::Help;
319                        $self->_help_provider( Padre::Document::Perl::Help->new );
320                }
321        }
322        return unless $self->_help_provider;
323        eval { $self->_index( $self->_help_provider->help_list ); };
324        if ($@) {
325                $self->_display_msg( sprintf( Wx::gettext('Error while calling %s %s'), 'help_list', $@ ) );
326                return;
327        }
328
329        return 1;
330}
331
332#
333# Returns the selected or under the cursor help topic
334#
335sub find_help_topic {
336        my $self = shift;
337
338        my $doc = Padre::Current->document;
339        return '' unless $doc;
340
341        my $topic = $doc->find_help_topic;
342
343        #fallback
344        unless ($topic) {
345                my $editor = $doc->editor;
346                my $pos    = $editor->GetCurrentPos;
347
348                # The selected/under the cursor word is a help topic
349                $topic = $editor->GetSelectedText;
350                if ( not $topic ) {
351                        $topic = $editor->GetTextRange(
352                                $editor->WordStartPosition( $pos, 1 ),
353                                $editor->WordEndPosition( $pos, 1 )
354                        );
355                }
356
357                # trim whitespace
358                $topic =~ s/^\s*(.*?)\s*$/$1/;
359        }
360
361        return $topic;
362}
363
364#
365# Update matches list box from matched files list
366#
367sub _update_list_box {
368        my $self = shift;
369
370        # Clear the list and status
371        $self->_list->Clear();
372        $self->_status->SetLabel('');
373
374        # Try to fetch a help index and return nothing if otherwise
375        $self->_search unless $self->_index;
376        return unless $self->_index;
377
378        my $search_expr = $self->_search_text->GetValue();
379        $search_expr = quotemeta $search_expr;
380
381        #Populate the list box now
382        my $pos = 0;
383        foreach my $target ( @{ $self->_index } ) {
384                if ( $target =~ /^$search_expr$/i ) {
385                        $self->_list->Insert( $target, 0, $target );
386                        $pos++;
387                } elsif ( $target =~ /$search_expr/i ) {
388                        $self->_list->Insert( $target, $pos, $target );
389                        $pos++;
390                }
391        }
392        if ( $pos > 0 ) {
393                $self->_list->Select(0);
394        }
395        $self->_status->SetLabel( sprintf( Wx::gettext("Found %s help topic(s)\n"), $pos ) );
396        $self->_display_help_in_viewer;
397
398        return 1;
399}
400
401#
402# Called when the user clicks a link in the
403# help viewer HTML window
404#
405sub on_link_clicked {
406        my $self = shift;
407        require URI;
408        my $uri      = URI->new( $_[0]->GetLinkInfo->GetHref );
409        my $linkinfo = $_[0]->GetLinkInfo;
410        my $scheme   = $uri->scheme;
411        if ( $scheme eq 'perldoc' ) {
412
413                # handle 'perldoc' links
414                my $topic = $uri->path;
415                $topic =~ s/^\///;
416                $self->_search_text->SetValue($topic);
417        } else {
418
419                # otherwise, let the default browser handle it...
420                Padre::Wx::launch_browser($uri);
421        }
422}
423
4241;
425
426
427__END__
428
429=pod
430
431=head1 NAME
432
433Padre::Wx::Dialog::HelpSearch - Padre Shiny Help Search Dialog
434
435=head1 DESCRIPTION
436
437This opens a dialog where you can search for help topics...
438
439Note: This used to be Perl 6 Help Dialog (in C<Padre::Plugin::Perl6>) and but it
440has been moved to Padre core.
441
442In order to setup a help system see L<Padre::Help>.
443
444=head1 AUTHOR
445
446Ahmad M. Zawawi C<< <ahmad.zawawi at gmail.com> >>
447
448=head1 COPYRIGHT & LICENSE
449
450Copyright 2008-2010 The Padre development team as listed in Padre.pm.
451
452This program is free software; you can redistribute
453it and/or modify it under the same terms as Perl itself.
454
455=cut
456
457# Copyright 2008-2010 The Padre development team as listed in Padre.pm.
458# LICENSE
459# This program is free software; you can redistribute it and/or
460# modify it under the same terms as Perl 5 itself.
Note: See TracBrowser for help on using the browser.