#!/usr/bin/perl #----------------------------------------------------------------------------- # # piper # # http://www.remote.org/jochen/software/piper/ # #----------------------------------------------------------------------------- # # 2003-11-06 version 0.1 # #----------------------------------------------------------------------------- # # Copyright (C) 2003 Jochen Topf # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA # #----------------------------------------------------------------------------- use strict; use Tk; use Tk::NoteBook; undef $/; my $TMPDIR = $ENV{'TMP'} || $ENV{'TEMP'} || '/tmp'; system("cp $ARGV[0] $TMPDIR/piper.$$.0"); #----------------------------------------------------------------------------- # GUI stuff #----------------------------------------------------------------------------- my $main = MainWindow->new(); my $menu = $main->Frame(-borderwidth => 1, -relief => 'raised'); $menu->pack(-side => 'top', -fill => 'x', -expand => 0); my $m_file = $menu->Menubutton(-text => 'File', -tearoff => 0); $m_file->pack(-side => 'left', -padx => 2); #my $m_edit = $menu->Menubutton(-text => 'Edit', -tearoff => 0); #$m_edit->pack(-side => 'left', -padx => 2); $m_file->command(-label => 'Open', -command => sub { open_file(); } ); $m_file->command(-label => 'Quit', -command => sub { end(); }); $main->Tk::bind('all', '', sub { end(); }); my $nb = $main->NoteBook(); open(IN, '<', "$TMPDIR/piper.$$.0"); my $text = ; close(IN); new_tab($nb, 'Input', $text); $nb->pack(-expand => 1, -fill => 'both'); MainLoop(); exit(0); #----------------------------------------------------------------------------- my @tabs = (); sub open_file { my $file = $main->getOpenFile(); system("cp $file $TMPDIR/piper.$$.0"); foreach my $i (0..$#tabs) { update_tab($i); } } sub update_tab { my ($n) = @_; print "DEBUG: update_tab() n=$n\n"; open(IN, '<', "$TMPDIR/piper.$$.$n"); my $content = ; close(IN); my $out = $tabs[$n]->{'out'}; $out->configure(-state => 'normal'); $out->delete("1.0", "end"); $out->insert("1.0", $content); $out->configure(-state => 'disabled'); my $command = $tabs[$n]->{'entry'}->get(); my $next = $n+1; system("$command <$TMPDIR/piper.$$.$n >$TMPDIR/piper.$$.$next"); } sub new_tab { my ($notebook, $label, $content) = @_; my $tabnum = $#tabs+1; print "DEBUG: new_tab() tabnum=$tabnum label=$label\n"; my $tab = $notebook->add("$tabnum", -label => $label, -raisecmd => sub { raise_entry($tabnum) } ); my $out = $tab->Text( -width => 80, -height => 25); $out->insert("1.0", $content); $out->configure(-state => 'disabled'); $out->pack( -side => 'top'); my $entry = $tab->Entry( -width => 80); $entry->pack( -side => 'top'); $entry->focus(); my $ok = $tab->Button( -text => 'OK', -command => sub { new_command($notebook, $tabnum); } ); $ok->pack( -side => 'left'); my $del; if ($tabnum > 0) { $del = $tab->Button( -text => 'Delete', -command => sub { delete_tab($notebook, $tabnum) } ); $del->pack( -side => 'right'); } $entry->Tk::bind('', sub { new_command($notebook, $tabnum); }); push(@tabs, { tab => $tab, out => $out, entry => $entry, ok => $ok, del => $del } ); $notebook->raise($tabnum); } sub raise_entry { my ($num) = @_; $tabs[$num]->{'entry'}->focus(); } sub delete_tab { my ($notebook, $num) = @_; print "DEBUG: delete: $num\n"; if ($num == 0) { print "DEBUG: can't delete file tab\n"; return; } my $delnum = $#tabs - $num + 1; while ($delnum-- > 0) { my $tab = pop(@tabs); $tab->{'tab'}->destroy(); } $notebook->raise($#tabs); } sub new_command { my ($notebook, $num) = @_; my $tab = $tabs[$num]; print "DEBUG: new_command() num=$num tab=$tab\n"; my $command = $tab->{'entry'}->get(); my $next = $num+1; return if ($command eq ''); if ($tabs[$next]) { delete_tab($notebook, $next); } print "DEBUG: ok $num: $command\n"; system("$command <$TMPDIR/piper.$$.$num >$TMPDIR/piper.$$.$next"); if ($? == -1) { print "failed to execute: $!\n"; return; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; return; } elsif ($? != 0) { printf "child exited with value %d\n", $? >> 8; return; } open(IN, '<', "$TMPDIR/piper.$$.$next"); my $text = ; close(IN); new_tab($notebook, $command, $text); } # close down program after cleaning up # prints entered commands as series of piped commands for easy cut and # paste sub end() { foreach my $i (0 .. $#tabs) { unlink("$TMPDIR/piper.$$.$i"); } pop(@tabs); print(join(' | ', map { $_->{'entry'}->get() } @tabs), "\n"); exit(0); } #-- THE END ------------------------------------------------------------------