#!perl -w use blib; use strict; use Win32::GUI; use Cwd; my $VERSION = "0.14.00"; my %objects = (); my %varobjects = (); my %TreeStruct; my $EM_SCROLLCARET = 183; my $EM_LINESCROLL = 182; my $EM_SETSEL = 177; my $EM_EXLINEFROMCHAR = 1078; my ($DOS) = Win32::GUI::GetPerlWindow(); #Win32::GUI::Hide($DOS); my $Menu = new Win32::GUI::Menu( "&File" => "File", " > &New" => "FileNew", " > &Open" => "FileOpen", " > &Save" => "FileSave", " > Save &As" => "FileSaveAs", " > &Close" => "FileClose", " > -" => 0, " > &Repride" => "FileRepride", " > -" => 0, " > E&xit" => "FileExit", "&Edit" => "Edit", " > &Undo" => "EditUndo", " > -" => 0, " > Cu&t" => "EditCut", " > &Copy" => "EditCopy", " > &Paste" => "EditPaste", "&Program" => "Program", " > &View Structure" => { -name => "ProgramViewStructure", -checked => 1 }, " > &Rebuild Structure" => "ProgramRebuildStructure", "&Run" => "Run", " > &Execute" => "RunExecute", " > &Debug" => "RunDebug", ); my $EditorFont = new Win32::GUI::Font( -name => "Courier New", -height => 16, ); my $EditorClass = new Win32::GUI::Class( -name => "PRIDE_${VERSION}_Editor", -extends => "RichEdit", -widget => "RichEdit", ); my $Window = new Win32::GUI::Window( -name => "Window", -left => 100, -top => 100, -width => 800, -height => 500, -title => "PRIDE version ".$VERSION, -menu => $Menu, ); $Window->AddStatusBar( -name => "Status", -text => "PRIDE version $VERSION - Ready", ); $Window->AddRichEdit( -class => $EditorClass, -name => "Editor", -multiline => 1, -left => 150, -top => 28, -width => $Window->ScaleWidth, -height => $Window->ScaleHeight-28-$Window->Status->Height, -font => $EditorFont, -exstyle => WS_EX_CLIENTEDGE, -style => WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, ); $Window->Editor->SendMessage(1093, 0, 1); $Window->AddTreeView( -name => "ProgStruct", -pos => [0, 0], -size => [ 150, $Window->ScaleHeight-28-$Window->Status->Height ], -lines => 1, -buttons => 1, -rootlines => 1, ); # #$Window->AddCombobox( # -name => "SelectObj", # -left => 0, # -top => 5, # -width => $Window->ScaleWidth/2, # -height => 300, # -style => Win32::GUI::constant("WS_VISIBLE", 0) | 3 | Win32::GUI::constant("WS_NOTIFY", 0), #); # #$Window->AddCombobox( # -name => "SelectSub", # -left => $Window->ScaleWidth/2, # -top => 5, # -width => $Window->ScaleWidth/2, # -height => 300, # -style => Win32::GUI::constant("WS_VISIBLE", 0) | 3 | Win32::GUI::constant("WS_NOTIFY", 0), #); # my $GotoWindow = new Win32::GUI::DialogBox( -name => "GotoWindow", -text => "Goto line...", -left => 150, -top => 150, -width => 200, -height => 100, ); $GotoWindow->AddLabel( -name => "GotoLabel", -text => "Line:", -left => 5, -top => 10, ); $GotoWindow->AddTextfield( -name => "GotoLine", -left => 5, -top => 25, -width => 190, -height => 22, -tabstop => 1, ); $GotoWindow->AddButton( -name => "GotoOK", -text => "OK", -left => 5, -top => 50, -height => 22, -width => 90, -tabstop => 1, -ok => 1, -default => 1, ); $GotoWindow->AddButton( -name => "GotoCancel", -text => "Cancel", -left => 100, -top => 50, -height => 22, -width => 90, -tabstop => 1, -cancel => 1, ); $Window->Show(); my $FILE = ($ARGV[0] or $0); LoadFile($FILE); $Window->{-dialogui} = 1; print "DIALOGUI: $Window->{-dialogui}\n";; Win32::GUI::Dialog(); Win32::GUI::Show($DOS); print "Bye bye from PRIDE version $VERSION...\n"; sub Window_Terminate { if(OkToClose()) { return -1; } else { return 1; } } sub Window_Resize { my $Width = $Window->ScaleWidth; my $Height = $Window->ScaleHeight; $Window->Editor->Resize($Width, $Height-28-$Window->Status->Height); $Window->Status->Resize($Width, $Window->Status->Height); # $Window->SelectObj->Resize($Width/2, $Window->SelectObj->Height); # $Window->SelectSub->Resize($Width/2, $Window->SelectSub->Height); # $Window->SelectSub->Move($Width/2, 5); $Window->Status->Move(0, $Window->ScaleHeight-$Window->Status->Height); } sub Window_Activate { $Window->Editor->SetFocus(); } sub LoadFile { ($FILE) = @_; my $DEBUG = 1; print "FILE: $FILE\n" if $DEBUG; open(FILE, $FILE) or return 0; my $file = ""; my $object; my $parent; my $sub; my $defo; my $var; my $what; my $name; my $c = 1; %objects = ("" => []); %varobjects = (); # $Window->SelectObj->Clear(); # $Window->SelectSub->Clear(); # $Window->SelectObj->AddString(""); $Window->ProgStruct->Clear(); $TreeStruct{""} = $Window->ProgStruct->InsertItem(-text => ""); while() { chomp; # converts tabs in 4 spaces s/\t/ /g; if(/^\s*#/) { $file .= $_."\r\n"; } else { if(/\$(.+)\s*=\s*new (Win32::)?GUI::/) { $var = $1; $var =~ s/^\s*//; $var =~ s/\s*$//; print "Found variable: [$var]\n" if $DEBUG; $object = "[TBD]"; $what = "X"; $defo = length($file); } # $Window->SelectObj->AddString($object); # $Window->SelectObj->Text($object); # if(exists($objects{$object})) { # push(@{$objects{$object}}, ";".length($file)); # } else { # $objects{$object} = [ ";".length($file) ]; # } #} if(/\s*\$(\S+)->Add/) { $parent = $1; $parent =~ s/^\s*//; $parent =~ s/\s*$//; print "Found child of [$parent]\n" if $DEBUG; print "varobjects(parent): $varobjects{$parent}\n" if $DEBUG; if(exists($varobjects{$parent})) { $object = "[TBD]"; $what = ""; $defo = length($file); } else { print "Skipping because [$parent] doesn't exists...\n" if $DEBUG; } } if(/-name\s*=>\s*["']?([^,"']+)["']?,?/ and $object eq "[TBD]") { $object = $1; $object =~ s/^\s*//; $object =~ s/\s*$//; print "Found name: [$object]\n" if $DEBUG; if(exists($objects{$object})) { push(@{$objects{$object}}, ";".$defo); } else { $objects{$object} = [ ";".$defo ]; } if($var) { #$Window->SelectObj->AddString($object." (\$".$var.")"); #$Window->SelectObj->Text($object." (\$".$var.")"); $TreeStruct{$object} = $Window->ProgStruct->InsertItem( -text => "$object (\$$var)", ); $varobjects{$var} = $object; } else { $TreeStruct{$object} = $Window->ProgStruct->InsertItem( -text => "$object", ); #$Window->SelectObj->AddString($object); #$Window->SelectObj->Text($object); } $object = ""; $var = ""; $what = ""; } if(/\$(.+)\s*=\s*\$(.+)->Add/) { $object = $1; $parent = $2; $object =~ s/^\s*//; $object =~ s/\s*$//; $parent =~ s/^\s*//; $parent =~ s/\s*$//; print "Found object: [$object] (parent: [$parent])\n" if $DEBUG; print "objects(parent): $objects{$parent}\n" if $DEBUG; #if(exists($objects{$parent})) { # $Window->SelectObj->AddString($object); # $Window->SelectObj->Text($object); # push(@{$objects{$object}}, ";".length($file)); #} if(exists($varobjects{$parent})) { $object = "[TBD]"; $what = ""; $defo = length($file); } else { print "Skipping because [$parent] doesn't exists...\n" if $DEBUG; } } if(/^\s*sub ([^\s{]+)_([^\s{]+)/) { $parent = $1; $sub = $2; if(exists($objects{$parent})) { push(@{$objects{$parent}}, $sub.";".length($file)); } else { $parent = ""; $sub = $1."_".$2; if(exists($objects{$parent})) { push(@{$objects{$parent}}, $sub.";".length($file)); } } } else { if(/^\s*sub ([^\s{]+)/) { $parent = ""; $sub = $1; if(exists($objects{$parent})) { push(@{$objects{$parent}}, $sub.";".length($file)); } } } # $file .= $c++." ".$_."\r\n"; $file .= $_."\r\n"; } } close(FILE); foreach $object (keys %objects) { foreach $sub (@{$objects{$object}}) { ($name, undef) = split(/;/, $sub, 2); $TreeStruct{$object."-".$name} = $Window->ProgStruct->InsertItem( -text => $name, -parent => $TreeStruct{$object}, ); } } $Window->Editor->Text($file); $Window->Caption("PRIDE Version $VERSION - $FILE"); $Window->Editor->SetFocus(); return 1; } sub SelectObj_Change { my $object = $Window->SelectObj->GetString($Window->SelectObj->SelectedItem); $object =~ s/ \(\$.*\)$//; print "Selected object: $object\n"; $Window->SelectSub->Clear(); my $sub; my $name; foreach $sub (@{$objects{$object}}) { ($name, undef) = split(/;/, $sub, 2); $Window->SelectSub->AddString($name); } $Window->SelectSub->Select(0); SelectSub_Change(); } sub SelectSub_Change { my $object; my $ssub; my $issub = $Window->SelectSub->SelectedItem; my $isobject = $Window->SelectObj->SelectedItem; if($isobject >= 0) { $object = $Window->SelectObj->GetString($Window->SelectObj->SelectedItem); $object =~ s/ \(\$.*\)$//; } else { return 1; } if($issub >= 0) { $ssub = $Window->SelectSub->GetString($Window->SelectSub->SelectedItem); } else { return 1; } my $sub; my $name; my $pos; foreach $sub (@{$objects{$object}}) { ($name, $pos) = split(/;/, $sub, 2); if($name eq $ssub) { GotoLine($Window->Editor->LineFromChar($pos)); #print "Object: $object / Sub: $ssub / Pos: $pos\n"; ## $Window->Editor->Select($pos-1, $pos+1); #$Window->Editor->SendMessage($EM_SETSEL, $pos, $pos); #$Window->Editor->SendMessage($EM_SCROLLCARET, 0, 0); $Window->Editor->Update(); $Window->Editor->SetFocus(); } } } sub FileRepride_Click { # system("perl $0"); if(OkToClose()) { system("start /min perl $0"); #my $pid = 0; #my $file; #if($FILE !~ /^[a-z]:\\/i) { # $file = Win32::GetCwd."\\".$FILE; #} else { # $file = $FILE; #} #print "Executing p:\\perl5\\bin\\perl.exe $file ...\n"; #my $r = Win32::Spawn("perl", "$file", $pid); #my $err = Win32::GetLastError(); #print "Repride r=$r err=$err pid=$pid\n"; return -1; } else { return 1; } } sub FileExit_Click { if(OkToClose()) { return -1; } else { return 1; } } sub FileSave_Click { # make a backup copy open(BAKFILE, ">$FILE.bak"); open(OLDFILE, "<$FILE"); while() { print ; } close(BAKFILE); close(OLDFILE); open(FILE, ">$FILE"); my $text = $Window->Editor->Text(); $text =~ s/\r\n/\n/g; print FILE $text; close(FILE); $text = $Window->Text(); if($text =~ s/ \*$//) { $Window->Text($text); } } sub FileClose_Click { if(OkToClose()) { $Window->Editor->Text(""); $FILE = "untitled.pl"; $Window->Text("PRIDE version $VERSION - untitled.pl"); } } sub FileNew_Click { if(OkToClose()) { $Window->Editor->Text(""); $FILE = "untitled.pl"; $Window->Text("PRIDE version $VERSION - untitled.pl"); } } sub FileOpen_Click { my $file = GUI::GetOpenFileName(-directory => Win32::GetCwd()); if($file) { LoadFile($file); } } sub FileSaveAs_Click { my $file = GUI::GetSaveFileName(-directory => Win32::GetCwd()); if($file) { open(BAKFILE, ">$FILE.bak"); open(OLDFILE, "<$FILE"); while() { print ; } close(BAKFILE); close(OLDFILE); open(FILE, ">$file"); my $text = $Window->Editor->Text(); $text =~ s/\r\n/\n/g; print FILE $text; close(FILE); $text = $Window->Text(); if($text =~ s/ \*$//) { $Window->Text($text); } } } sub Editor_KeyPress { my($key) = @_; if($key == 7) { $GotoWindow->Move( $Window->Left+($Window->ScaleWidth-$GotoWindow->Width)/2, $Window->Top+($Window->ScaleHeight-$GotoWindow->Height)/2, ); $GotoWindow->Show(); $GotoWindow->GotoLine->SetFocus(); $Window->Disable(); return 0; } else { print "Editor_KeyPress got $key\n"; my($pos, undef) = $Window->Editor->Selection(); my $line = 1 + $Window->Editor->LineFromChar($pos); $Window->Status->Text("on line $line"); return 1; } } sub GotoWindow_Terminate { GotoCancel_Click(); } sub GotoCancel_Click { $GotoWindow->Hide(); $Window->Enable(); $Window->SetForegroundWindow(); return 1; } sub GotoOK_Click { $GotoWindow->Hide(); $Window->Enable(); GotoLine($GotoWindow->GotoLine->Text); return 1; } sub GotoLine { my($line) = @_; print "Line=$line\n"; my $fvl = $Window->Editor->FirstVisibleLine; print "FVL=$fvl\n"; my $diff = ($line-1) - $fvl; print "DIFF=$diff\n"; $Window->Editor->SendMessage($EM_LINESCROLL, 0, $diff); my ($ci, $li) = $Window->Editor->CharFromPos(1, 1); print "CI=$ci\n"; $Window->Editor->Select($ci, $ci); $Window->Editor->SendMessage($EM_SCROLLCARET, 0, 0); $Window->Editor->SetFocus(); } sub Editor_Change { my $text = $Window->Text; if($text !~ /\*$/) { $Window->Text($text." *"); } return 1; } sub OkToClose { # if($Window->Editor->Modified()) { if($Window->Text =~ /\*$/) { my $answer = $Window->MessageBox("Save changes to $FILE ?", "PRIDE", 3+48); if($answer == 3) { # IDCANCEL return 0; } elsif($answer == 6) { FileSave_Click(); return 1; } elsif($answer == 7) { return 1; } } else { return 1; } return 0; } #======================= sub ProgStruct_KeyDown { #======================= my($key) = @_; if($key == 13) { ProgStruct_DblClick(); } } #======================== sub ProgStruct_DblClick { #======================== my $sub = $Window->ProgStruct->SelectedItem; print "ProgStruct_DblClick: sub=$sub\n"; my %sub = $Window->ProgStruct->GetItem($sub); my $obj = $Window->ProgStruct->GetParent($sub); print "ProgStruct_DblClick: obj=$obj\n"; my %obj = $Window->ProgStruct->GetItem($obj); $obj{-text} =~ s/\s\(.*\)$//; if(exists $TreeStruct{$obj{-text}."-".$sub{-text}}) { foreach my $o (@{$objects{$obj{-text}}}) { my ($name, $pos) = split(/;/, $o, 2); if($name eq $sub{-text}) { GotoLine($Window->Editor->LineFromChar($pos)); $Window->Editor->Update(); $Window->Editor->SetFocus(); } } } else { print "not a child: $obj{-text}-$sub{-text}\n"; } return 0; }