#!/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 #
#######