#!/usr/bin/perl ############################################################################# ## Name: PodBrowser.pl ## Purpose: POD Browser ## Author: Graciliano M. P. ## Modified by: ## Created: 1/05/2003 ## RCS-ID: ## Copyright: (c) 2003 Graciliano M. P. ## Licence: This program is free software; you can redistribute it and/or ## modify it under the same terms as Perl itself ############################################################################# use Wx; use FindBin; use vars qw($VERSION); $VERSION = '0.01'; our $TITLE = "POD-Browser $VERSION" ; our @MODULES ; our $BASE = $FindBin::RealBin ; require "pod2html.mod" ; ######### # MYAPP # ######### package MyApp; use vars qw(@ISA); @ISA=qw(Wx::App); sub OnInit { my( $this ) = @_; my $frame = MyFrame->new( $TITLE , [50,50],[600,400]); $this->SetTopWindow( $frame ); $frame->Show( 1 ); $frame->Maximize( 1 ); 1; } ########### # MYFRAME # ########### package MyFrame; use strict; use vars qw(@ISA); @ISA=qw(Wx::Frame); use Wx::Event qw(EVT_MENU EVT_BUTTON EVT_TEXT_ENTER EVT_COMBOBOX); use Wx qw(wxBITMAP_TYPE_ICO wxMENU_TEAROFF); use Wx qw(:sizer); use Wx::ActiveX::IE ; use Wx::ActiveX::Event qw(EVT_ACTIVEX_IE_STATUSTEXTCHANGE) ; use Wx qw(wxCB_SIMPLE wxCB_DROPDOWN wxCB_READONLY wxTE_PROCESS_ENTER wxCB_SORT) ; use Wx qw(:filedialog) ; use Wx qw(wxID_OK wxID_CANCEL wxID_YES wxID_NO wxITALIC wxBOLD); use Wx qw(wxOK wxICON_INFORMATION wxVERSION_STRING); my ($LASTDIR,$LASTPOD) ; my %HISTORY = ( '<' => [] , '>' => [] ) ; sub new { my( $class ) = shift; my( $this ) = $class->SUPER::new( undef, -1, $_[0], $_[1], $_[2] ); $this->SetIcon( Wx::GetWxPerlIcon() ); my( $mfile ) = Wx::Menu->new( undef, wxMENU_TEAROFF ); my( $medit ) = Wx::Menu->new(); my( $meinc ) = Wx::Menu->new(); my( $mhelp ) = Wx::Menu->new(); my( $ID_ABOUT, $ID_COPY , $ID_EXIT , $ID_INC_ADD , $ID_INC_SHOW) = (1..99); $mhelp->Append( $ID_ABOUT, "&About...\tCtrl-A", "Show about dialog" ); $medit->Append( $ID_COPY, "&Copy\tCtrl-C", "Copy Text" ); $mfile->Append( $ID_EXIT, "E&xit\tAlt-X", "Quit this program" ); $meinc->Append( $ID_INC_ADD, "Add PATH", "Add a new path directory to \@INC" ); $meinc->Append( $ID_INC_SHOW, "Show \@INC", "Show \@INC content" ); my( $mbar ) = Wx::MenuBar->new() ; $mbar->Append( $mfile, "&File" ); $mbar->Append( $medit, "&Edit" ); $mbar->Append( $meinc, "\@&INC" ); $mbar->Append( $mhelp, "&Help" ); $this->SetMenuBar( $mbar ); my $sz = Wx::BoxSizer->new( wxVERTICAL ); my $szh = Wx::BoxSizer->new( wxHORIZONTAL ); my $textctrl = Wx::TextCtrl->new( $this, -1, '', [-1,-1], [-1, -1]) ; my $select = Wx::ComboBox->new($this , -1 , '' , [-1,-1] , [-1,-1] , [@MODULES] , wxCB_DROPDOWN|wxTE_PROCESS_ENTER ) ; my $button_go = Wx::Button->new( $this, -1 , 'GO' , [-1,-1], [30, -1]) ; my $button_browse = Wx::Button->new( $this, -1 , 'Browse' , [-1,-1], [60, -1] ) ; my $button_back = Wx::Button->new( $this, -1 , '<<' , [-1,-1], [30, -1] ) ; my $button_next = Wx::Button->new( $this, -1 , '>>' , [-1,-1], [30, -1] ) ; my $IE = Wx::ActiveX::IE->new( $this , -1 , [-1,-1] , [-1,-1] ) ; $this->{TEXT} = $textctrl ; $this->{SELECT} = $select ; $this->{IE} = $IE ; $szh->Add( $button_back , 0 , wxALL , 0 ) ; $szh->Add( $button_next , 0 , wxALL , 0 ) ; $szh->Add( $textctrl , 2 , wxGROW , 0 ) ; $szh->Add( $select , 5 , wxGROW , 0 ) ; $szh->Add( $button_go , 0 , wxALL , 0 ) ; $szh->Add( $button_browse , 0 , wxALL , 0 ) ; $sz->Add( $szh , 0 , wxGROW , 0 ) ; $sz->Add( $IE , 1 , wxGROW , 0 ) ; EVT_TEXT_ENTER($this, $textctrl , \&OnGO ) ; EVT_COMBOBOX($this , $select , \&OnSelect) ; EVT_BUTTON( $this, $button_back , \&OnBack ); EVT_BUTTON( $this, $button_next , \&OnNext ); EVT_BUTTON( $this, $button_go , \&OnGO ); EVT_BUTTON( $this, $button_browse , \&OnBrowse ); EVT_ACTIVEX_IE_STATUSTEXTCHANGE($this,$IE, \&OnStatusChange) ; EVT_MENU( $this, $ID_EXIT, \&OnQuit ); EVT_MENU( $this, $ID_ABOUT, \&OnAbout ); EVT_MENU( $this, $ID_COPY, \&OnCopy ); EVT_MENU( $this, $ID_INC_ADD, \&INC_AddPath ); EVT_MENU( $this, $ID_INC_SHOW, \&INC_Show ); $this->CreateStatusBar( 2 ); $this->SetStatusText( "Welcome to $TITLE!", 0 ); $this->SetAutoLayout( 1 ); $this->SetSizer( $sz ); $this->{IE}->LoadUrl("file:///$BASE/README.html") ; $this; } sub OnBack { my( $this ) = shift ; if (!@{$HISTORY{'<'}}) { return ;} my $next = $HISTORY{'.'} ; my $now = pop @{$HISTORY{'<'}} ; push(@{$HISTORY{'>'}} , $next) ; $HISTORY{'.'} = $now ; &GO($this , $HISTORY{'.'} , 1) ; } sub OnNext { my( $this ) = shift ; if (!@{$HISTORY{'>'}}) { return ;} my $now = pop @{$HISTORY{'>'}} ; my $prev = $HISTORY{'.'} ; push(@{$HISTORY{'<'}} , $prev) ; $HISTORY{'.'} = $now ; &GO($this , $HISTORY{'.'} , 1) ; } sub INC_Show { my( $this ) = shift ; Wx::MessageBox("\@INC:\n\n". join ("\n", @INC) ."\n" , "\@INC", wxOK | wxICON_INFORMATION, $this ); } sub INC_AddPath { my( $this ) = shift ; my $dialog = Wx::DirDialog->new($this , "$TITLE - \@INC -> Add PATH" , $LASTDIR ) ; my $dir ; if( $dialog->ShowModal == wxID_CANCEL ) { $dir = undef ;} else { $dir = $dialog->GetPath ;} $dir =~ s/[\\\/]+/\//gs ; push(@INC , $dir) ; Wx::MessageBox("Path Added:\n$dir", "\@INC -> New PATH", wxOK | wxICON_INFORMATION, $this ); } sub OnStatusChange { my ( $this , $evt ) = @_ ; my $txt = $evt->{Text} ; if ($txt =~ /^POD-GO:\s+(.*)/ ) { &GO($this , $1 , undef , 1) ;} } sub OnCopy { my( $this ) = shift ; my $sel = $this->{IE}->GetStringSelection() ; use Wx::DND ; use Wx qw(wxTheClipboard) ; wxTheClipboard->Open ; my $data = Wx::TextDataObject->new($sel) ; wxTheClipboard->SetData( $data ) ; wxTheClipboard->Close; } sub OnSelect { my( $this ) = shift; my $sel = $this->{SELECT}->GetValue() ; $this->{TEXT}->SetValue($sel) ; } sub OnGO { my( $this ) = shift; my $pm = $this->{TEXT}->GetValue() ; @{$HISTORY{'>'}} = () ; &GO($this , $pm) ; } sub GO { my ( $this , $pm , $nohistory , $setvalue) = @_ ; # print "\n<<< @{$HISTORY{'<'}}\n" ; # print "$HISTORY{'.'}\n" ; # print ">>> @{$HISTORY{'>'}}\n" ; if ($pm !~ /\S/s) { return ;} if ($setvalue || $nohistory) { $this->{TEXT}->SetValue($pm) ;} my $stat ; $this->SetStatusText("Finding POD..." , 1 ); my @files = PodBrowser::pod2html::find_pm($pm) ; if (!@files) { $this->SetStatusText("Can't find file!!!" , 1 ); $this->{IE}->LoadString("Can't find file for:
$pm") ; $LASTPOD = '' ; $stat = 2 ; } if (!$stat) { foreach my $file ( @files ) { $this->SetStatusText("Bulding HTML..." , 1 ); my ($title,$html,$content) = PodBrowser::pod2html::pod2html($file) ; if ($content =~ /\S/s) { my $flhtml = "$BASE/pod.html" ; open (LOG,">$flhtml") ; print LOG $html ; close (LOG) ; $this->SetTitle("$title - $TITLE") ; $this->SetStatusText( "OK: $file" , 1 ) ; if ($LASTPOD && $LASTPOD eq $file) { $this->{IE}->Refresh(0) ;} else { $this->{IE}->LoadUrl("file:///$flhtml") ; $LASTPOD = $file ; } $stat = 1 ; last ; } } } if (!$nohistory) { push(@{$HISTORY{'<'}} , $HISTORY{'.'} ) if ($HISTORY{'.'} && $HISTORY{'.'} ne @{$HISTORY{'<'}}[-1]) ; $HISTORY{'.'} = $pm ; } if (!$stat) { $this->{IE}->LoadString("Null POD at:
\n" . join("
\n", @files , '')) ; $this->SetStatusText( "Blank POD!!!" , 1 ) ; $LASTPOD = '' ; } return $stat ; } sub OnBrowse { my( $this ) = shift; my $dialog = Wx::FileDialog->new($this , "$TITLE - File Browser" , $LASTDIR , undef, 'POD Files|*.pm;*.pod' , wxOPEN) ; my $file ; if( $dialog->ShowModal == wxID_CANCEL ) { $file = undef ;} else { $file = $dialog->GetPath ;} $LASTDIR = $dialog->GetDirectory ; $dialog->Destroy ; $this->{TEXT}->SetValue($file) ; @{$HISTORY{'>'}} = () ; &OnGO($this) ; } sub OnCreateStatusBar { my( $this ) = shift; my( $status ) = Wx::StatusBar->new( $this, -1 ); $status->SetFieldsCount( 2 ); $status; } sub OnQuit { my( $this, $event ) = @_; $this->Close( 1 ); } sub OnAbout { my( $this, $event ) = @_; Wx::MessageBox(qq`$TITLE\nBy: Graciliano M. P.\n\nwxPerl $Wx::VERSION\n` . wxVERSION_STRING, "$TITLE - About", wxOK | wxICON_INFORMATION, $this ); } ######## # MAIN # ######## package main; open (INCINI,"$BASE/INC.ini") ; my @inc_ini = ; close (INCINI) ; foreach my $inc_ini_i ( @inc_ini ) { chomp($inc_ini_i); push(@INC , $inc_ini_i) if ($inc_ini_i =~ /\S/s && $inc_ini_i !~ /^\s*#/s) ; } @MODULES = &scan_modules ; my( $app ) = MyApp->new(); $app->MainLoop(); exit ; ################ # SCAN_MODULES # ################ sub scan_modules { my @DIR = @INC ; my %inc = map { $_ => 1 } @DIR ; my @modules ; foreach my $DIR ( @DIR ) { opendir (DIRLOG, $DIR); while (my $filename = readdir DIRLOG) { if ($filename ne "\." && $filename ne "\.\.") { my $file = "$DIR/$filename" ; if (-d $file) { push(@DIR , $file) ;} elsif ($filename =~ /(?:pm|pod)$/i && -s $file) { my $pm = $file ; foreach my $INC_i ( @INC ) { $pm =~ s/^\Q$INC_i\E//s ;} $pm =~ s/[\\\/]+/::/gs ; $pm =~ s/^:+//s ; $pm =~ s/:+$//s ; $pm =~ s/\.pm$//si ; push(@modules , $pm) ; } } } closedir (DIRLOG); } return( sort @modules ) ; } ####### # END # #######