home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Editores / Perl5 / perl / lib / site / Tk / TextUndo.pm < prev    next >
Encoding:
Perl POD Document  |  1997-08-10  |  4.3 KB  |  219 lines

  1. # Copyright (c) 1995-1997 Nick Ing-Simmons. All rights reserved.
  2. # This program is free software; you can redistribute it and/or
  3. # modify it under the same terms as Perl itself.
  4. package Tk::TextUndo;
  5. require Tk::Text;
  6. use AutoLoader;
  7.  
  8. @ISA = qw(Tk::Text);
  9.  
  10. Construct Tk::Widget 'TextUndo';
  11.  
  12. sub ClassInit
  13. {
  14.  my ($class,$mw) = @_;
  15.  $mw->bind($class,'<L4>','undo');
  16.  return $class->SUPER::ClassInit($mw);
  17. }
  18.  
  19. sub undo
  20. {
  21.  my ($w) = @_; 
  22.  if (exists $w->{UNDO})
  23.   {
  24.    if (@{$w->{UNDO}})
  25.     {
  26.      my ($op,@args) = @{pop(@{$w->{UNDO}})};
  27.      $w->$op(@args);   
  28.      $w->SetCursor($args[0]);
  29.      return;
  30.     }
  31.   }
  32.  $w->bell;
  33. }
  34.  
  35. sub addUndo
  36. {
  37.  my ($w,$op,@args) = @_;
  38.  $w->{UNDO} = [] unless (exists $w->{UNDO});
  39.  push(@{$w->{UNDO}},['SUPER::'.$op,@args]);
  40.  # print "add(",join(',',$op,@args),")\n";
  41. }
  42.  
  43. sub topUndo
  44. {
  45.  my ($w) = @_;
  46.  return undef unless (exists $w->{UNDO});
  47.  return $w->{UNDO}[-1];
  48. }
  49.  
  50. sub insert
  51. {
  52.  my ($w,$index,$str,@tags) = @_;
  53.  my $s = $w->index($index);
  54.  $w->markSet('notepos' => $s);
  55.  $w->SUPER::insert($s,$str,@tags);
  56.  # Combine 'trivial' inserts into clumps
  57.  if (length($str) == 1 && $str ne "\n")
  58.   {
  59.    my $t = $w->topUndo;
  60.    if ($t && $t->[0] =~ /delete$/ && $w->compare($t->[2],'==',$s))
  61.     {
  62.      $t->[2] = $w->index('notepos');
  63.      return;
  64.     }
  65.   }
  66.  $w->addUndo('delete',$s,$w->index('notepos'));
  67. }
  68.  
  69. sub delete
  70. {
  71.  my $w = shift;
  72.  my $str = $w->get(@_);
  73.  my $s = $w->index(shift);
  74.  $w->SUPER::delete($s,@_);
  75.  $w->addUndo('insert',$s,$str);
  76. }
  77.  
  78. 1;
  79. __END__
  80.  
  81. sub Save
  82. {
  83.  my $text = shift;
  84.  my $file = (@_) ? shift : $text->{FILE};
  85.  $text->BackTrace("No filename defined") unless (defined $file);
  86.  if (open(FILE,">$file"))
  87.   {
  88.    my $index = '1.0';
  89.    while ($text->compare($index,'<','end'))
  90.     {
  91.      my $end = $text->index("$index + 1024 chars");
  92.      print FILE $text->get($index,$end);
  93.      $index = $end;
  94.     }
  95.    delete $text->{UNDO} if (close(FILE));
  96.   }
  97.  else
  98.   {
  99.    $text->BackTrace("Cannot open $file:$!");
  100.   }
  101. }
  102.  
  103.  
  104.  
  105. sub OldSave
  106. {
  107.  my $text = shift;
  108.  my $file = (@_) ? shift : $text->{FILE};
  109.  $text->BackTrace("No filename defined") unless (defined $file);
  110.  if (open(FILE,">$file"))
  111.   {
  112.    print FILE $text->get('1.0','end');
  113.    delete $text->{UNDO} if (close(FILE));
  114.   }
  115.  else
  116.   {
  117.    $text->BackTrace("Cannot open $file:$!");
  118.   }
  119. }
  120.  
  121. sub Load
  122. {
  123.  my ($text,$file) = @_;
  124.  if (open(FILE,"<$file"))
  125.   {
  126.    $text->MainWindow->Busy;
  127.    $text->SUPER::delete('1.0','end');
  128.    delete $text->{UNDO};
  129.    while (<FILE>)
  130.     {
  131.      $text->SUPER::insert('end',$_);
  132.     }
  133.    close(FILE);
  134.    $text->{FILE} = $file;
  135.    $text->MainWindow->Unbusy;
  136.   }
  137.  else
  138.   {
  139.    $text->BackTrace("Cannot open $file:$!");
  140.   }
  141. }
  142.  
  143. #   Should one add/document a Filename(?$newfilename?) method, or
  144. #   document the $text->{FILE} instance variable, or
  145. #   leave the housekeeping to the programmer?
  146.  
  147. #   We have here no <L4> on our keyboard :-(  So TextUndo needs
  148.  
  149. #    - document the 'undo' method. so other can use Bind
  150. #    - an BindUndo method
  151. #    - or use/document *textUndo.undo resource (defaults
  152. #      to <L4>
  153.  
  154. =head1 NAME
  155.  
  156. Tk::TextUndo - perl/tk text widget with bindings to undo changes.
  157.  
  158. =head1 SYNOPSIS
  159.  
  160.     use Tk::TextUndo;
  161.     ...
  162.     $testundo = $parent->TextUndo(?option => value, ...?);
  163.     ...
  164.  
  165. =head1 DESCRIPTION
  166.  
  167. This IS-A text widget with an unlimited 'undo' history but without
  168. a re'undo' capability.
  169.  
  170. =head2 Bindings
  171.  
  172. The C<TextUndo> widget has the same bindings as the L<Text> widget.
  173. Additionally to the L<Text> widget there are the following bindings:
  174.  
  175. =over 4
  176.  
  177. =item Event <L4>
  178.  
  179. undo the last change.  Pressing <L4> several times undo
  180. step by step the changes made to the text widget.
  181.  
  182.  
  183. =back
  184.  
  185. =head2 Methods
  186.  
  187. The C<TextUndo> widget has the same methods as C<Text> widget.
  188. Additional method for the C<TextUndo> widget are:
  189.  
  190. =over 4
  191.  
  192. =item $text->Load($filename);
  193.  
  194. Loads the contents of the $filename into the text widget. Load()
  195. delete the previous contents of the text widget as well as it's
  196. undo history of the previous file.
  197.  
  198. =item $text->Save(?$otherfilename?)
  199.  
  200. Save contents of the text widget to a file. If the
  201. $otherfilename is not specified, the text widget contents
  202. writes the file of $filename used in the last Load()
  203. call.  If no file was previously Load()'ed an error message
  204. pops up.  The default filename of the last Load() call
  205. is not overwriten by $otherfilename.
  206.  
  207. =back
  208.  
  209. =head1 KEYS
  210.  
  211. widget, text, undo
  212.  
  213. =head1 SEE ALSO
  214.  
  215. Tk::Text(3), Tk::ROText(3)
  216.  
  217. =cut
  218.  
  219.