home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 March / PCWorld_2003-03_cd.bin / Software / Topware / activeperl / ActivePerl / Perl / bin / ptked < prev    next >
Encoding:
Text File  |  2000-05-16  |  6.3 KB  |  294 lines

  1. #!/usr/local/bin/perl -w
  2. use strict;
  3. use IO;
  4. use Socket;
  5. use IO::Socket;
  6. use Cwd;
  7.  
  8. use vars qw($VERSION $portfile);
  9. $VERSION = '3.006'; # $Id: //depot/Tk8/ptked#23 $
  10.  
  11. my %opt;
  12. INIT
  13.  {
  14.   my $home = $ENV{'HOME'} || $ENV{'HOMEDRIVE'}.$ENV{'HOMEPATH'};
  15.   $portfile = "$home/.ptkedsn";
  16.   my $port = $ENV{'PTKEDPORT'};
  17.   return if $^C;
  18.   getopts("s",\%opt);
  19.   unless (defined $port)
  20.    {
  21.     if (open(SN,"$portfile"))
  22.      {
  23.       $port = <SN>;
  24.       close(SN);
  25.      }
  26.    }
  27.   if (defined $port)
  28.    {
  29.     my $sock = IO::Socket::INET->new(PeerAddr => 'localhost',
  30.                PeerPort => $port, Proto    => 'tcp');
  31.     if ($sock)
  32.      {
  33.       binmode($sock);
  34.       $sock->autoflush;
  35.       foreach my $file (@ARGV)
  36.        {
  37.         unless  (print $sock "$file\n")
  38.          {
  39.           die "Cannot print $file to socket:$!";
  40.          }
  41.         print "Requested '$file'\n";
  42.        }
  43.       $sock->close || die "Cannot close socket:$!";
  44.       exit(0);
  45.      }
  46.     else
  47.      {
  48.       warn "Cannot connect to server on $port:$!";
  49.      }
  50.    }
  51.  }
  52.  
  53. use Tk;
  54. use Tk::DropSite qw(XDND KDE Sun);
  55. use Tk::DragDrop qw(XDND KDE Sun);
  56. use Tk::widgets qw(TextUndo Scrollbar Menu);
  57. use Getopt::Std;
  58. # use Tk::ErrorDialog;
  59.  
  60.  
  61. my $top = MainWindow->new();
  62.  
  63. if ($opt{'s'})
  64.  {
  65.   my $sock = IO::Socket::INET->new(Listen => 5, Proto => 'tcp');
  66.   die "Cannot open listen socket:$!" unless defined $sock;
  67.   binmode($sock);
  68.  
  69.   my $port = $sock->sockport;
  70.   $ENV{'PTKEDPORT'} = $port;
  71.   open(SN,">$portfile") || die "Cannot open $portfile:$!";
  72.   print SN $port;
  73.   close(SN);
  74.   print "Accepting connections on $port\n";
  75.   $top->fileevent($sock,'readable',
  76.   sub
  77.   {
  78.    print "accepting $sock\n";
  79.    my $client = $sock->accept;
  80.    if (defined $client)
  81.     {
  82.      binmode($client);
  83.      print "Connection $client\n";
  84.      $top->fileevent($client,'readable',[\&EditRequest,$client]);
  85.     }
  86.    });
  87.  }
  88.  
  89. Tk::Event::HandleSignals();
  90. $SIG{'INT'} = sub { $top->WmDeleteWindow };
  91.  
  92. $top->iconify;
  93. $top->optionAdd('*TextUndo.Background' => '#fff5e1');
  94. $top->fontCreate('ptked',-family => 'courier', -size => ($^O eq 'MSWin32' ? 11 : -12),
  95.                  -weight => 'normal', -slant => 'roman');
  96. $top->optionAdd('*TextUndo.Font' => 'ptked');
  97.  
  98. foreach my $file (@ARGV)
  99.  {
  100.   Create_Edit($file);
  101.  }
  102.  
  103.  
  104. sub EditRequest
  105. {
  106.  my ($client) = @_;
  107.  local $_;
  108.  while (<$client>)
  109.   {
  110.    chomp($_);
  111.    print "'$_'\n",
  112.    Create_Edit($_);
  113.   }
  114.  warn "Odd $!" unless eof($client);
  115.  $top->fileevent($client,'readable','');
  116.  print "Close $client\n";
  117.  $client->close;
  118. }
  119.  
  120. MainLoop;
  121. unlink("$portfile");
  122. exit(0);
  123.  
  124. sub Create_Edit
  125. {
  126.  my $path = shift;
  127.  my $ed   = $top->Toplevel(-title => $path);
  128.  $ed->withdraw;
  129.  $top->{'Edits'}++;
  130.  $ed->OnDestroy([\&RemoveEdit,$top]);
  131.  my $t = $ed->Scrolled('TextUndo', -wrap => 'none', -scrollbars => 'osre');
  132.  $t->pack(-expand => 1, -fill => 'both');
  133.  $t = $t->Subwidget('textundo');
  134.  my $menu = $t->menu;
  135.  $menu->cascade(-label => '~Help', -menuitems => [
  136.                 [Button => '~About...', -command => [\&About,$ed]],
  137.                ]);
  138.  $ed->configure(-menu => $menu);
  139.  my $dd = $t->DragDrop(-event => '<Meta-B1-Motion>');
  140.  $t->bind(ref($t),'<Meta-B1-Motion>',\&Ouch);
  141.  $t->bind(ref($t),'<Meta-ButtonPress>',\&Ouch);
  142.  $t->bind(ref($t),'<Meta-ButtonRelease>',\&Ouch);
  143.  $dd->configure(-startcommand =>
  144.                 sub
  145.                  {
  146.                   return 1 unless (eval { $t->tagNextrange(sel => '1.0','end')});
  147.                   $dd->configure(-text => $t->get('sel.first','sel.last'));
  148.                  });
  149.  
  150.  $t->DropSite(-motioncommand =>
  151.                sub
  152.                 { my ($x,$y) = @_;
  153.                   $t->markSet(insert => "\@$x,$y");
  154.                 },
  155.                -dropcommand => [\&HandleDrop,$t],
  156.               );
  157.  
  158.  
  159.  
  160.  $ed->protocol('WM_DELETE_WINDOW',[ConfirmExit => $t]);
  161.  $t->bind('<F3>',\&DoFind);
  162.  
  163.  $ed->idletasks;
  164.  if (-e $path)
  165.   {
  166.    $t->Load($path);
  167.   }
  168.  else
  169.   {
  170.    $t->FileName($path);
  171.   }
  172.  $ed->deiconify;
  173.  $t->update;
  174.  $t->focus;
  175. }
  176.  
  177. sub Ouch
  178. {
  179.  warn join(',','Ouch',@_);
  180. }
  181.  
  182. sub RemoveEdit
  183. {
  184.  my $top = shift;
  185.  if (--$top->{'Edits'} == 0)
  186.   {
  187.    $top->destroy unless $opt{'s'};
  188.   }
  189. }
  190.  
  191. sub HandleDrop
  192. {my ($t,$seln,$x,$y) = @_;
  193.  # warn join(',',Drop => @_);
  194.  my $string;
  195.  Tk::catch { $string = $t->SelectionGet(-selection => $seln,'FILE_NAME') };
  196.  if ($@)
  197.   {
  198.    Tk::catch { $string = $t->SelectionGet(-selection => $seln) };
  199.    if ($@)
  200.     {
  201.      my @targets = $t->SelectionGet(-selection => $seln, 'TARGETS');
  202.      $t->messageBox(-text => "Targets : ".join(' ',@targets));
  203.     }
  204.    else
  205.     {
  206.      $t->markSet(insert => "\@$x,$y");
  207.      $t->insert(insert => $string);
  208.     }
  209.   }
  210.  else
  211.   {
  212.    Create_Edit($string);
  213.   }
  214. }
  215.  
  216.  
  217. my $str;
  218.  
  219. sub DoFind
  220. {
  221.  my $t = shift;
  222.  $str = shift if (@_);
  223.  my $posn = $t->index('insert+1c');
  224.  $t->tag('remove','sel','1.0','end');
  225.  local $_;
  226.  while ($t->compare($posn,'<','end'))
  227.   {
  228.    my ($line,$col) = split(/\./,$posn);
  229.    $_ = $t->get("$line.0","$posn lineend");
  230.    pos($_) = $col;
  231.    if (/\G(.*)$str/g)
  232.     {
  233.      $col += length($1);
  234.      $posn = "$line.$col";
  235.      $t->SetCursor($posn);
  236.      $t->tag('add','sel',$posn,"$line.".pos($_));
  237.      $t->focus;
  238.      return;
  239.     }
  240.    $posn = $t->index("$posn lineend + 1c");
  241.   }
  242. }
  243.  
  244. sub AskFind
  245. {
  246.  my ($t) = @_;
  247.  unless (exists $t->{'AskFind'})
  248.   {
  249.    my $d = $t->{'AskFind'} = $t->Toplevel(-popover => 'cursor', -popanchor => 'nw');
  250.    $d->title('Find...');
  251.    $d->withdraw;
  252.    $d->transient($t->toplevel);
  253.    my $e = $d->Entry->pack;
  254.    $e->bind('<Return>', sub { $d->withdraw; DoFind($t,$e->get); });
  255.    $d->protocol(WM_DELETE_WINDOW =>[withdraw => $d]);
  256.   }
  257.  $t->{'AskFind'}->Popup;
  258.  $t->update;
  259.  $t->{'AskFind'}->focusNext;
  260. }
  261.  
  262. sub About
  263. {
  264.  my $mw = shift;
  265.  $mw->Dialog(-text => <<"END",-popover => $mw)->Show;
  266. $0 version $VERSION
  267. perl$]/Tk$Tk::VERSION
  268.  
  269. Copyright ⌐ 1995-2000 Nick Ing-Simmons. All rights reserved.
  270. This package is free software; you can redistribute it and/or
  271. modify it under the same terms as Perl itself.
  272. END
  273. }
  274.  
  275. __END__
  276.  
  277. =head1 NAME
  278.  
  279. ptked - an editor in Perl/Tk
  280.  
  281. =head1 SYNOPSIS
  282.  
  283. S<  >B<ptked> [I<file-to-edit>]
  284.  
  285. =head1 DESCRIPTION
  286.  
  287. B<ptked> is a simple text editor based on perl/Tk's TextUndo widget.
  288.  
  289. =cut
  290.  
  291.  
  292.  
  293.  
  294.