File Coverage

blib/lib/Gtk2/Ex/TextBufferBits.pm
Criterion Covered Total %
statement 9 51 17.6
branch 0 22 0.0
condition 0 8 0.0
subroutine 3 6 50.0
pod 1 1 100.0
total 13 88 14.7


line stmt bran cond sub pod time code
1             # Copyright 2010, 2011, 2012 Kevin Ryde
2              
3             # This file is part of Gtk2-Ex-WidgetBits.
4             #
5             # Gtk2-Ex-WidgetBits is free software; you can redistribute it and/or modify
6             # it under the terms of the GNU General Public License as published by the
7             # Free Software Foundation; either version 3, or (at your option) any later
8             # version.
9             #
10             # Gtk2-Ex-WidgetBits is distributed in the hope that it will be useful, but
11             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13             # for more details.
14             #
15             # You should have received a copy of the GNU General Public License along
16             # with Gtk2-Ex-WidgetBits. If not, see .
17              
18              
19             package Gtk2::Ex::TextBufferBits;
20 1     1   996 use 5.008;
  1         5  
  1         48  
21 1     1   7 use strict;
  1         2  
  1         38  
22 1     1   7 use warnings;
  1         3  
  1         1378  
23              
24             # uncomment this to run the ### lines
25             #use Smart::Comments;
26              
27             our $VERSION = 48;
28              
29             sub replace_lines {
30 0     0 1   my ($textbuf, $str) = @_;
31              
32 0           require Glib::Ex::FreezeNotify;
33 0           my $freezer = Glib::Ex::FreezeNotify->new ($textbuf,
34             $textbuf->get_insert,
35             $textbuf->get_selection_bound);
36              
37 0           my ($ins_line, $ins_col) = _mark_to_lineandcol ($textbuf->get_insert);
38 0           my ($sel_line, $sel_col) = _mark_to_lineandcol ($textbuf->get_selection_bound);
39             ### ins/sel: "$ins_line,$ins_col $sel_line,$sel_col "
40              
41 0           my $pos = 0;
42 0           my $iter = $textbuf->get_start_iter;
43 0 0         if (! $iter->is_end) {
44 0           for (;;) {
45             ### at: $pos, $iter->get_offset
46              
47 0           my $endpos = index ($str, "\n", $pos);
48 0 0         if ($endpos < 0) {
49             ### str no more newlines, delete through: $textbuf->get_end_iter->get_offset
50 0           $textbuf->delete ($iter, $textbuf->get_end_iter);
51 0           last;
52             }
53             ### endpos: $endpos
54              
55             # forward_to_line_end() goes to next line if already at line end, so test
56 0 0         if (! $iter->ends_line) {
57 0           my $enditer = $iter->copy;
58 0           $enditer->forward_to_line_end;
59             ### delete to enditer: $enditer->get_offset, $textbuf->get_text($iter,$enditer,1)
60 0           $textbuf->delete ($iter, $enditer);
61             }
62              
63             ### insert: substr($str, $pos, $endpos-$pos)
64 0           $textbuf->insert ($iter, substr($str, $pos, $endpos-$pos));
65              
66 0           $pos = $endpos;
67 0 0         if ($iter->is_end) {
68             ### buffer end, no final newline
69 0           last;
70             }
71 0           $pos++;
72 0 0         if (! $iter->forward_line) {
73             ### buffer end, with final newline
74 0           last;
75             }
76             }
77             }
78              
79             ### insert final: $pos, substr($str, $pos)
80 0 0         if ($pos < length($str)) {
81 0           $textbuf->insert ($iter, substr ($str, $pos));
82             }
83              
84 0           $textbuf->select_range (_lineandcol_to_iter ($textbuf, $ins_line, $ins_col),
85             _lineandcol_to_iter ($textbuf, $sel_line, $sel_col));
86             }
87              
88             # $mark is a Gtk2::TextMark
89             # return ($line, $column) of its current position
90             sub _mark_to_lineandcol {
91 0     0     my ($mark) = @_;
92 0   0       my $textbuf = $mark->get_buffer || return;
93 0           my $iter = $textbuf->get_iter_at_mark ($mark);
94             ### _mark_to_lineandcol(): $iter->get_offset
95 0 0         if ($iter->is_end) {
96 0           return (-1, -1);
97             } else {
98 0 0 0       return ($iter->get_line,
99             ! $mark->get_left_gravity && $iter->ends_line
100             ? -1 : $iter->get_line_offset);
101             }
102             }
103              
104             # $textbuf is a Gtk2::TextBuffer
105             # return a Gtk2::TextIter at $line,$column in that buffer
106             sub _lineandcol_to_iter {
107 0     0     my ($textbuf, $line, $column) = @_;
108 0 0         if ($line == -1) {
109 0           return $textbuf->get_end_iter;
110             }
111 0           my $iter = $textbuf->get_iter_at_line ($line);
112 0 0 0       if ($column == -1 || $column >= $iter->get_chars_in_line) {
113 0 0         unless ($iter->ends_line) { $iter->forward_to_line_end; }
  0            
114             } else {
115 0           $iter->forward_chars ($column);
116             }
117             ### result: "$line,$column -> ".$iter->get_offset
118 0           return $iter;
119             }
120              
121              
122             1;
123             __END__