<?xml version="1.0" encoding="windows-1252"?>
<node id="596543" title="Undesired window in ptked.pl" created="2007-01-25 11:47:27" updated="2007-01-25 06:47:27">
<type id="115">
perlquestion</type>
<author id="266955">
jdtoronto</author>
<data>
<field name="doctext">
Esteemed monks,&lt;p&gt;
Our much missed contributor, Nick Ing-Simmons, contributed a rather nice little text editor in Perl/Tk. I found it in c:\perl\bin and the file is ptked.pl.&lt;p&gt;
When I use it I found it creates a MainWindow (at line 104) which is iconified at line 135. This process leaves a toolbar icon present on Win32 machines. A search through the code did not reveal any place where the $top (MainWindow) is de-iconified, so I decided to try withdrawing the $top:
&lt;code&gt;
$top-&gt;iconify;
$top-&gt;withdraw;
&lt;/code&gt;
Now, I don't see any problems, but maybe someone more expert in Perl/Tk might take issue with what I have done and be prepared to tell me if this is appropriate.&lt;p&gt;
Here is the complete code: &lt;readmore&gt;
&lt;code&gt;
#!/usr/local/bin/perl -w
use strict;
use Socket;
use IO::Socket;
use Cwd;
use Getopt::Long;

use vars qw($VERSION $portfile);
$VERSION = sprintf '4.%03d', q$Revision: #29 $ =~ /\D(\d+)\s*$/;

my %opt;
INIT
 {
  my $home = $ENV{'HOME'} || $ENV{'HOMEDRIVE'}.$ENV{'HOMEPATH'};
  $portfile = "$home/.ptkedsn";
  my $port = $ENV{'PTKEDPORT'};
  return if $^C;
  GetOptions(\%opt,qw(server! encoding=s));
  unless (defined $port)
   {
    if (open(SN,"$portfile"))
     {
      $port = &lt;SN&gt;;
      close(SN);
     }
   }
  if (defined $port)
   {
    my $sock = IO::Socket::INET-&gt;new(PeerAddr =&gt; 'localhost',
               PeerPort =&gt; $port, Proto    =&gt; 'tcp');
    if ($sock)
     {
      binmode($sock);
      $sock-&gt;autoflush;
      foreach my $file (@ARGV)
       {
        unless  (print $sock "$file\n")
         {
          die "Cannot print $file to socket:$!";
         }
        print "Requested '$file'\n";
       }
      $sock-&gt;close || die "Cannot close socket:$!";
      exit(0);
     }
    else
     {
      warn "Cannot connect to server on $port:$!";
     }
   }
 }

use Tk;
use Tk::DropSite qw(XDND Sun);
use Tk::DragDrop qw(XDND Sun);
use Tk::widgets qw(TextUndo Scrollbar Menu Dialog);
# use Tk::ErrorDialog;

{
 package Tk::TextUndoPtked;
 @Tk::TextUndoPtked::ISA = qw(Tk::TextUndo);
 Construct Tk::Widget 'TextUndoPtked';

 sub Save {
  my $w = shift;
  $w-&gt;SUPER::Save(@_);
  $w-&gt;toplevel-&gt;title($w-&gt;FileName);
 }

 sub Load {
  my $w = shift;
  $w-&gt;SUPER::Load(@_);
  $w-&gt;toplevel-&gt;title($w-&gt;FileName);
 }

 sub MenuLabels { shift-&gt;SUPER::MenuLabels, 'Encoding' }

 sub Encoding
 {
  my ($w,$enc) = @_;
  if (@_ &gt; 1)
   {
    $enc = $w-&gt;getEncoding($enc) unless ref($enc);
    $w-&gt;{ENCODING} = $enc;
    $enc = $enc-&gt;name;
    $w-&gt;PerlIO_layers(":encoding($enc)");
   }
  return $w-&gt;{ENCODING};
 }

 sub EncodingMenuItems
 {
  my ($w) = @_;
  return [ [ command =&gt; 'System', -command =&gt; [ $w, Encoding =&gt; Tk::SystemEncoding()-&gt;name ]],
           [ command =&gt; 'UTF-8',  -command =&gt; [ $w, Encoding =&gt; 'UTF-8'] ],
           [ command =&gt; 'iso-8859-1', -command =&gt; [ $w, Encoding =&gt; 'iso8859-1'] ],
           [ command =&gt; 'iso-8859-15', -command =&gt; [ $w, Encoding =&gt; 'iso8859-15'] ],
         ];

 }

}

my $top = MainWindow-&gt;new();

if ($opt{'server'})
 {
  my $sock = IO::Socket::INET-&gt;new(Listen =&gt; 5, Proto =&gt; 'tcp');
  die "Cannot open listen socket:$!" unless defined $sock;
  binmode($sock);

  my $port = $sock-&gt;sockport;
  $ENV{'PTKEDPORT'} = $port;
  open(SN,"&gt;$portfile") || die "Cannot open $portfile:$!";
  print SN $port;
  close(SN);
  print "Accepting connections on $port\n";
  $top-&gt;fileevent($sock,'readable',
  sub
  {
   print "accepting $sock\n";
   my $client = $sock-&gt;accept;
   if (defined $client)
    {
     binmode($client);
     print "Connection $client\n";
     $top-&gt;fileevent($client,'readable',[\&amp;EditRequest,$client]);
    }
   });
 }

Tk::Event::HandleSignals();
$SIG{'INT'} = sub { $top-&gt;WmDeleteWindow };

$top-&gt;iconify;
$top-&gt;withdraw;
$top-&gt;optionAdd('*TextUndoPtked.Background' =&gt; '#fff5e1');
$top-&gt;fontCreate('ptked',-family =&gt; 'courier', -size =&gt; ($^O eq 'MSWin32' ? 11 : -12),
                 -weight =&gt; 'normal', -slant =&gt; 'roman');
$top-&gt;optionAdd('*TextUndoPtked.Font' =&gt; 'ptked');

foreach my $file (@ARGV)
 {
  Create_Edit($file);
 }


sub EditRequest
{
 my ($client) = @_;
 local $_;
 while (&lt;$client&gt;)
  {
   chomp($_);
   print "'$_'\n",
   Create_Edit($_);
  }
 warn "Odd $!" unless eof($client);
 $top-&gt;fileevent($client,'readable','');
 print "Close $client\n";
 $client-&gt;close;
}

MainLoop;
unlink("$portfile");
exit(0);

sub Create_Edit
{
 my $path = shift;
 my $ed   = $top-&gt;Toplevel(-title =&gt; $path);
 $ed-&gt;withdraw;
 $top-&gt;{'Edits'}++;
 $ed-&gt;OnDestroy([\&amp;RemoveEdit,$top]);
 my $t = $ed-&gt;Scrolled('TextUndoPtked', -wrap =&gt; 'none',
           -scrollbars =&gt; 'se', # both required till optional fixed!
         );
 $t-&gt;pack(-expand =&gt; 1, -fill =&gt; 'both');
 $t = $t-&gt;Subwidget('scrolled');

 $t-&gt;Encoding($opt{encoding}) if $opt{encoding};

 my $menu = $t-&gt;menu;
 $menu-&gt;cascade(-label =&gt; '~Help', -menuitems =&gt; [
                [Button =&gt; '~About...', -command =&gt; [\&amp;About,$ed]],
               ]);
 $ed-&gt;configure(-menu =&gt; $menu);
 my $dd = $t-&gt;DragDrop(-event =&gt; '&lt;Meta-B1-Motion&gt;');
 $t-&gt;bind(ref($t),'&lt;Meta-B1-Motion&gt;',\&amp;Ouch);
 $t-&gt;bind(ref($t),'&lt;Meta-ButtonPress&gt;',\&amp;Ouch);
 $t-&gt;bind(ref($t),'&lt;Meta-ButtonRelease&gt;',\&amp;Ouch);
 $dd-&gt;configure(-startcommand =&gt;
                sub
                 {
                  return 1 unless (eval { $t-&gt;tagNextrange(sel =&gt; '1.0','end')});
                  $dd-&gt;configure(-text =&gt; $t-&gt;get('sel.first','sel.last'));
                 });

 $t-&gt;DropSite(-motioncommand =&gt;
               sub
                { my ($x,$y) = @_;
                  $t-&gt;markSet(insert =&gt; "\@$x,$y");
                },
               -dropcommand =&gt; [\&amp;HandleDrop,$t],
              );



 $ed-&gt;protocol('WM_DELETE_WINDOW',[ConfirmExit =&gt; $t]);
 $t-&gt;bind('&lt;F3&gt;',\&amp;DoFind);

 $ed-&gt;idletasks;
 if (-e $path)
  {
   $t-&gt;Load($path);
  }
 else
  {
   $t-&gt;FileName($path);
  }
 $ed-&gt;deiconify;
 $t-&gt;update;
 $t-&gt;focus;
}

sub Ouch
{
 warn join(',','Ouch',@_);
}

sub RemoveEdit
{
 my $top = shift;
 if (--$top-&gt;{'Edits'} == 0)
  {
   $top-&gt;destroy unless $opt{'s'};
  }
}

sub HandleDrop
{my ($t,$seln,$x,$y) = @_;
 # warn join(',',Drop =&gt; @_);
 my $string;
 Tk::catch { $string = $t-&gt;SelectionGet(-selection =&gt; $seln,'FILE_NAME') };
 if ($@)
  {
   Tk::catch { $string = $t-&gt;SelectionGet(-selection =&gt; $seln) };
   if ($@)
    {
     my @targets = $t-&gt;SelectionGet(-selection =&gt; $seln, 'TARGETS');
     $t-&gt;messageBox(-text =&gt; "Targets : ".join(' ',@targets));
    }
   else
    {
     $t-&gt;markSet(insert =&gt; "\@$x,$y");
     $t-&gt;insert(insert =&gt; $string);
    }
  }
 else
  {
   Create_Edit($string);
  }
}


my $str;

sub DoFind
{
 my $t = shift;
 $str = shift if (@_);
 my $posn = $t-&gt;index('insert+1c');
 $t-&gt;tag('remove','sel','1.0','end');
 local $_;
 while ($t-&gt;compare($posn,'&lt;','end'))
  {
   my ($line,$col) = split(/\./,$posn);
   $_ = $t-&gt;get("$line.0","$posn lineend");
   pos($_) = $col;
   if (/\G(.*)$str/g)
    {
     $col += length($1);
     $posn = "$line.$col";
     $t-&gt;SetCursor($posn);
     $t-&gt;tag('add','sel',$posn,"$line.".pos($_));
     $t-&gt;focus;
     return;
    }
   $posn = $t-&gt;index("$posn lineend + 1c");
  }
}

sub AskFind
{
 my ($t) = @_;
 unless (exists $t-&gt;{'AskFind'})
  {
   my $d = $t-&gt;{'AskFind'} = $t-&gt;Toplevel(-popover =&gt; 'cursor', -popanchor =&gt; 'nw');
   $d-&gt;title('Find...');
   $d-&gt;withdraw;
   $d-&gt;transient($t-&gt;toplevel);
   my $e = $d-&gt;Entry-&gt;pack;
   $e-&gt;bind('&lt;Return&gt;', sub { $d-&gt;withdraw; DoFind($t,$e-&gt;get); });
   $d-&gt;protocol(WM_DELETE_WINDOW =&gt;[withdraw =&gt; $d]);
  }
 $t-&gt;{'AskFind'}-&gt;Popup;
 $t-&gt;update;
 $t-&gt;{'AskFind'}-&gt;focusNext;
}

sub About
{
 my $mw = shift;

 $mw-&gt;Dialog(-text =&gt; &lt;&lt;"END",-popover =&gt; $mw)-&gt;Show;
$0 version $VERSION
perl$]/Tk$Tk::VERSION

Copyright © 1995-2004 Nick Ing-Simmons. All rights reserved.
This package is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
END
}

__END__

=head1 NAME

ptked - an editor in Perl/Tk

=head1 SYNOPSIS

S&lt;  &gt;B&lt;ptked&gt; [I&lt;file-to-edit&gt;]

=head1 DESCRIPTION

B&lt;ptked&gt; is a simple text editor based on perl/Tk's TextUndo widget.

=cut
&lt;/code&gt;
&lt;/readmore&gt;
[jdtoronto]

</field>
</data>
</node>
