line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Kephra::App::EditPanel::Fold;
|
2
|
|
|
|
|
|
|
our $VERSION = '0.05';
|
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
1887
|
use strict;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
42
|
|
5
|
1
|
|
|
1
|
|
6
|
use warnings;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1729
|
|
6
|
|
|
|
|
|
|
#
|
7
|
|
|
|
|
|
|
sub _ep_ref {
|
8
|
0
|
0
|
|
0
|
|
|
Kephra::App::EditPanel::is($_[0]) ? $_[0] : Kephra::App::EditPanel::_ref()
|
9
|
|
|
|
|
|
|
}
|
10
|
0
|
|
|
0
|
|
|
sub _config { Kephra::App::EditPanel::Margin::_config()->{fold} }
|
11
|
0
|
|
|
0
|
|
|
sub _attribute { 'folded_lines' }
|
12
|
|
|
|
|
|
|
#
|
13
|
|
|
|
|
|
|
sub _is_head_level { # is this the fold level of a head node ?
|
14
|
0
|
|
|
0
|
|
|
my $level = shift;
|
15
|
0
|
0
|
|
|
|
|
return 1 if ($level % 1024) < (($level >> 16) % 1024);
|
16
|
|
|
|
|
|
|
}
|
17
|
|
|
|
|
|
|
sub _is_node {
|
18
|
0
|
|
|
0
|
|
|
my $line = shift;
|
19
|
0
|
0
|
|
|
|
|
return 1 if _ep_ref()->GetFoldParent($line+1) == $line;
|
20
|
|
|
|
|
|
|
}
|
21
|
|
|
|
|
|
|
sub _get_line { #
|
22
|
0
|
|
|
0
|
|
|
my ($ep, $event) = @_;
|
23
|
0
|
|
|
|
|
|
$ep = _ep_ref();
|
24
|
0
|
|
|
|
|
|
my $line = Kephra::App::EditPanel::Margin::clicked_on_line($event);
|
25
|
|
|
|
|
|
|
# save position where context menu poped so we can fold there
|
26
|
0
|
0
|
|
|
|
|
if ($line == -1){
|
27
|
0
|
0
|
0
|
|
|
|
if (defined $event and ref $event eq 'Wx::StyledTextEvent'){
|
28
|
0
|
|
|
|
|
|
$line = $ep->LineFromPosition( $event->GetPosition() );
|
29
|
|
|
|
|
|
|
}
|
30
|
0
|
|
|
|
|
|
else { $line = $ep->GetCurrentLine() }
|
31
|
|
|
|
|
|
|
}
|
32
|
0
|
|
|
|
|
|
return $line;
|
33
|
|
|
|
|
|
|
}
|
34
|
|
|
|
|
|
|
#
|
35
|
|
|
|
|
|
|
sub store {
|
36
|
0
|
|
|
0
|
0
|
|
for my $doc_nr (@{Kephra::Document::Data::all_nr()}) {
|
|
0
|
|
|
|
|
|
|
37
|
0
|
|
|
|
|
|
my $ep = Kephra::Document::Data::_ep($doc_nr);
|
38
|
0
|
|
|
|
|
|
my @lines;
|
39
|
0
|
|
|
|
|
|
for (0 .. $ep->GetLineCount()-1) {
|
40
|
0
|
0
|
|
|
|
|
push @lines, $_ unless $ep->GetFoldExpanded( $_ );
|
41
|
|
|
|
|
|
|
}
|
42
|
0
|
|
|
|
|
|
Kephra::Document::Data::set_attribute( _attribute(), \@lines, $doc_nr);
|
43
|
|
|
|
|
|
|
}
|
44
|
|
|
|
|
|
|
}
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub restore {
|
47
|
0
|
|
|
0
|
0
|
|
my $doc_nr = Kephra::Document::Data::valid_or_current_doc_nr(shift);
|
48
|
0
|
|
|
|
|
|
my $ep = Kephra::Document::Data::_ep($doc_nr);
|
49
|
0
|
0
|
0
|
|
|
|
return if $doc_nr < 0 or not ref $ep;
|
50
|
0
|
|
|
|
|
|
my $lines = Kephra::Document::Data::get_attribute( _attribute(), $doc_nr);
|
51
|
0
|
0
|
|
|
|
|
return unless ref $lines eq 'ARRAY';
|
52
|
0
|
|
|
|
|
|
for (reverse @$lines){
|
53
|
0
|
0
|
|
|
|
|
$ep->ToggleFold($_) if $ep->GetFoldExpanded($_);
|
54
|
|
|
|
|
|
|
}
|
55
|
|
|
|
|
|
|
}
|
56
|
|
|
|
|
|
|
#
|
57
|
|
|
|
|
|
|
# folding functions
|
58
|
|
|
|
|
|
|
#
|
59
|
|
|
|
|
|
|
sub toggle_here {
|
60
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
61
|
0
|
|
|
|
|
|
my $line = _get_line(@_);
|
62
|
0
|
|
|
|
|
|
$ep->ToggleFold($line);
|
63
|
0
|
0
|
0
|
|
|
|
Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible}
|
64
|
|
|
|
|
|
|
and not $ep->GetFoldExpanded($line);
|
65
|
|
|
|
|
|
|
}
|
66
|
|
|
|
|
|
|
sub toggle_recursively {
|
67
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
68
|
0
|
|
|
|
|
|
my $line = _get_line(@_);
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
71
|
0
|
0
|
|
|
|
|
unless ( _is_node( $line ) ) {
|
72
|
0
|
|
|
|
|
|
$line = $ep->GetFoldParent($line);
|
73
|
0
|
0
|
|
|
|
|
return if $line == -1;
|
74
|
|
|
|
|
|
|
}
|
75
|
|
|
|
|
|
|
|
76
|
0
|
|
|
|
|
|
my $node_xpanded = not $ep->GetFoldExpanded($line);
|
77
|
0
|
|
|
|
|
|
my $cursor = $ep->GetLastChild($line, -1);
|
78
|
0
|
|
|
|
|
|
while ($cursor >= $line) {
|
79
|
0
|
0
|
0
|
|
|
|
$ep->ToggleFold($cursor) if $ep->GetFoldExpanded($cursor) xor $node_xpanded;
|
80
|
0
|
|
|
|
|
|
$cursor--;
|
81
|
|
|
|
|
|
|
}
|
82
|
0
|
0
|
0
|
|
|
|
Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible} and not $node_xpanded;
|
83
|
|
|
|
|
|
|
}
|
84
|
0
|
|
|
0
|
0
|
|
sub toggle_siblings { toggle_siblings_of_line( _get_line(@_) ) }
|
85
|
|
|
|
|
|
|
sub toggle_siblings_of_line {
|
86
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
87
|
0
|
|
|
|
|
|
my $line = shift;
|
88
|
0
|
0
|
0
|
|
|
|
return if $line < 0 or $line > ($ep->GetLineCount()-1);
|
89
|
0
|
|
|
|
|
|
my $level = $ep->GetFoldLevel($line);
|
90
|
0
|
|
|
|
|
|
my $parent = $ep->GetFoldParent($line);
|
91
|
0
|
|
|
|
|
|
my $xp = not $ep->GetFoldExpanded($line);
|
92
|
0
|
|
|
|
|
|
my $first_line = $parent;
|
93
|
0
|
|
|
|
|
|
my $cursor = $ep->GetLastChild($parent, -1 );
|
94
|
0
|
0
|
|
|
|
|
($first_line, $cursor) = (-1, $ep->GetLineCount()-2) if $parent == -1;
|
95
|
0
|
|
|
|
|
|
while ($cursor > $first_line){
|
96
|
0
|
0
|
0
|
|
|
|
$ep->ToggleFold($cursor) if $ep->GetFoldLevel($cursor) == $level
|
|
|
|
0
|
|
|
|
|
97
|
|
|
|
|
|
|
and ($ep->GetFoldExpanded($cursor) xor $xp);
|
98
|
0
|
|
|
|
|
|
$cursor--;
|
99
|
|
|
|
|
|
|
}
|
100
|
0
|
0
|
0
|
|
|
|
Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible}
|
101
|
|
|
|
|
|
|
and not $xp;
|
102
|
0
|
|
|
|
|
|
$ep->EnsureCaretVisible;
|
103
|
|
|
|
|
|
|
}
|
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub toggle_level {
|
106
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
107
|
0
|
|
|
|
|
|
my $line = _get_line(@_);
|
108
|
0
|
0
|
0
|
|
|
|
return if $line < 0 or $line > ($ep->GetLineCount()-1);
|
109
|
0
|
|
|
|
|
|
my $level = $ep->GetFoldLevel($line);
|
110
|
0
|
|
|
|
|
|
my $xp = not $ep->GetFoldExpanded($line);
|
111
|
0
|
|
|
|
|
|
for (0 .. $ep->GetLineCount()-1) {
|
112
|
0
|
0
|
0
|
|
|
|
$ep->ToggleFold($_) if $ep->GetFoldLevel($_) == $level
|
|
|
|
0
|
|
|
|
|
113
|
|
|
|
|
|
|
and ($ep->GetFoldExpanded($_) xor $xp);
|
114
|
|
|
|
|
|
|
}
|
115
|
0
|
0
|
0
|
|
|
|
Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible}
|
116
|
|
|
|
|
|
|
and not $xp;
|
117
|
0
|
|
|
|
|
|
$ep->EnsureCaretVisible;
|
118
|
|
|
|
|
|
|
}
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub toggle_all {
|
121
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
122
|
0
|
|
|
|
|
|
my $newline = my $oldline = $ep->GetLineCount();
|
123
|
|
|
|
|
|
|
# looking for the head of heads // capi di capi
|
124
|
0
|
|
0
|
|
|
|
while ($oldline == $newline and $oldline > 0){
|
125
|
0
|
|
|
|
|
|
$newline = --$oldline;
|
126
|
0
|
|
|
|
|
|
$newline = $ep->GetFoldParent($newline) while $ep->GetFoldParent($newline) > -1;
|
127
|
|
|
|
|
|
|
}
|
128
|
0
|
|
|
|
|
|
my $root_unfolded = $ep->GetFoldExpanded($newline);
|
129
|
0
|
0
|
|
|
|
|
$root_unfolded ? fold_all() : unfold_all();
|
130
|
0
|
0
|
0
|
|
|
|
Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible}
|
131
|
|
|
|
|
|
|
and $root_unfolded;
|
132
|
|
|
|
|
|
|
}
|
133
|
|
|
|
|
|
|
sub fold_all {
|
134
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
135
|
0
|
|
|
|
|
|
my $cursor = $ep->GetLineCount()-1;
|
136
|
0
|
|
|
|
|
|
while ($cursor > -1) {
|
137
|
0
|
0
|
|
|
|
|
$ep->ToggleFold($cursor) if $ep->GetFoldExpanded($cursor);
|
138
|
0
|
|
|
|
|
|
$cursor--;
|
139
|
|
|
|
|
|
|
}
|
140
|
|
|
|
|
|
|
}
|
141
|
|
|
|
|
|
|
sub unfold_all {
|
142
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
143
|
0
|
|
|
|
|
|
my $cursor = $ep->GetLineCount()-1;
|
144
|
0
|
|
|
|
|
|
while ($cursor > -1) {
|
145
|
0
|
0
|
|
|
|
|
$ep->ToggleFold($cursor) unless $ep->GetFoldExpanded($cursor);
|
146
|
0
|
|
|
|
|
|
$cursor--;
|
147
|
|
|
|
|
|
|
}
|
148
|
|
|
|
|
|
|
}
|
149
|
0
|
|
|
0
|
0
|
|
sub show_folded_children {
|
150
|
|
|
|
|
|
|
#my $ep = _ep_ref();
|
151
|
|
|
|
|
|
|
#my $parent = _get_line(@_);
|
152
|
|
|
|
|
|
|
#unless ( _is_head_level( $ep->GetFoldLevel($parent) ) ) {
|
153
|
|
|
|
|
|
|
#$parent = $ep->GetFoldParent($parent);
|
154
|
|
|
|
|
|
|
#return if $parent == -1;
|
155
|
|
|
|
|
|
|
#}
|
156
|
|
|
|
|
|
|
#$ep->ToggleFold($parent) unless $ep->GetFoldExpanded($parent);
|
157
|
|
|
|
|
|
|
#my $cursöor = $ep->GetLastChild( $parent, -1 );
|
158
|
|
|
|
|
|
|
#my $level = $ep->GetFoldLevel($parent) >> 16;
|
159
|
|
|
|
|
|
|
#while (@cursor > $parent) {
|
160
|
|
|
|
|
|
|
#$ep->ToggleFold($cursor) if $ep->GetFoldLevel($cursor) % 2048 == $level
|
161
|
|
|
|
|
|
|
#and $ep->GetFoldExpanded($cursor);
|
162
|
|
|
|
|
|
|
#$cursor--;
|
163
|
|
|
|
|
|
|
#}
|
164
|
|
|
|
|
|
|
}
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
1;
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=head1 NAME
|
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
Kephra::App::EditPanel::Fold - code folding functions
|
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=cut |