line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Kephra::App::SearchBar;
|
2
|
|
|
|
|
|
|
our $VERSION = '0.15';
|
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
1279
|
use strict;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
42
|
|
5
|
1
|
|
|
1
|
|
7
|
use warnings;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2702
|
|
6
|
|
|
|
|
|
|
|
7
|
0
|
|
|
0
|
|
|
sub _ID { 'searchbar' }
|
8
|
0
|
|
|
0
|
|
|
sub _ref { Kephra::ToolBar::_ref( _ID(), $_[0]) }
|
9
|
0
|
|
|
0
|
|
|
sub _config { Kephra::API::settings()->{app}{ _ID() } }
|
10
|
0
|
|
|
0
|
|
|
sub _search_config { Kephra::API::settings()->{search} }
|
11
|
|
|
|
|
|
|
my $highlight_search; # set 1 if searchbar turns red
|
12
|
|
|
|
|
|
|
#
|
13
|
|
|
|
|
|
|
sub create {
|
14
|
|
|
|
|
|
|
# load searchbar definition
|
15
|
0
|
|
|
0
|
0
|
|
my $bar_def = Kephra::Config::File::load_from_node_data( _config() );
|
16
|
0
|
0
|
|
|
|
|
unless ($bar_def) {
|
17
|
0
|
|
|
|
|
|
$bar_def = Kephra::Config::Tree::get_subtree
|
18
|
|
|
|
|
|
|
( Kephra::Config::Default::toolbars(), _ID() );
|
19
|
|
|
|
|
|
|
}
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# create searchbar with buttons
|
22
|
0
|
|
|
|
|
|
my $rest_widgets = Kephra::ToolBar::create_new( _ID(), $bar_def);
|
23
|
0
|
|
|
|
|
|
my $bar = _ref();
|
24
|
|
|
|
|
|
|
# apply special searchbar widgets
|
25
|
0
|
|
|
|
|
|
for my $item_data (@$rest_widgets){
|
26
|
0
|
|
|
|
|
|
my $ctrl;
|
27
|
0
|
0
|
0
|
|
|
|
if ($item_data->{type} eq 'combobox' and $item_data->{id} eq 'find'){
|
|
|
0
|
0
|
|
|
|
|
28
|
0
|
|
|
|
|
|
my $find_input = $bar->{find_input} = Wx::ComboBox->new (
|
29
|
|
|
|
|
|
|
$bar , -1, '', [-1,-1], [$item_data->{size},-1], [],
|
30
|
|
|
|
|
|
|
&Wx::wxTE_PROCESS_ENTER
|
31
|
|
|
|
|
|
|
);
|
32
|
0
|
|
|
|
|
|
$find_input->SetDropTarget
|
33
|
|
|
|
|
|
|
( Kephra::Edit::Search::InputTarget->new($find_input, 'find'));
|
34
|
0
|
|
|
|
|
|
$find_input->SetValue( Kephra::Edit::Search::get_find_item() );
|
35
|
0
|
0
|
|
|
|
|
$find_input->SetSize($item_data->{size},-1) if $item_data->{size};
|
36
|
0
|
0
|
|
|
|
|
if ( _search_config()->{history}{use} ){
|
37
|
0
|
|
|
|
|
|
$find_input->Append($_) for @{ Kephra::Edit::Search::get_find_history() }
|
|
0
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
}
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
Wx::Event::EVT_TEXT( $bar, $find_input, sub {
|
41
|
0
|
|
|
0
|
|
|
my ($bar, $event) = @_;
|
42
|
0
|
|
|
|
|
|
my $old = Kephra::Edit::Search::get_find_item();
|
43
|
0
|
|
|
|
|
|
my $new = $find_input->GetValue;
|
44
|
0
|
0
|
|
|
|
|
if ($new ne $old){
|
45
|
0
|
|
|
|
|
|
Kephra::Edit::Search::set_find_item( $new );
|
46
|
0
|
0
|
0
|
|
|
|
Kephra::Edit::Search::first_increment()
|
47
|
|
|
|
|
|
|
if _search_config()->{attribute}{incremental}
|
48
|
|
|
|
|
|
|
and Wx::Window::FindFocus() eq $find_input;
|
49
|
|
|
|
|
|
|
}
|
50
|
0
|
|
|
|
|
|
} );
|
51
|
|
|
|
|
|
|
Wx::Event::EVT_KEY_DOWN( $find_input, sub {
|
52
|
0
|
|
|
0
|
|
|
my ( $fi, $event ) = @_;
|
53
|
0
|
|
|
|
|
|
my $key = $event->GetKeyCode;
|
54
|
0
|
|
|
|
|
|
my $found_something;
|
55
|
0
|
|
|
|
|
|
my $ep = Kephra::App::EditPanel::_ref();
|
56
|
0
|
0
|
0
|
|
|
|
if ( $key == &Wx::WXK_RETURN ) {
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
57
|
0
|
0
|
0
|
|
|
|
if ($event->ControlDown and $event->ShiftDown)
|
|
0
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
58
|
0
|
|
|
|
|
|
{Kephra::Edit::Search::find_last() }
|
59
|
0
|
|
|
|
|
|
elsif ($event->ControlDown){Kephra::Edit::Search::find_first()}
|
60
|
0
|
|
|
|
|
|
elsif ($event->ShiftDown) {Kephra::Edit::Search::find_prev() }
|
61
|
|
|
|
|
|
|
else {Kephra::Edit::Search::find_next() }
|
62
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_F3){
|
63
|
0
|
0
|
|
|
|
|
$event->ShiftDown
|
64
|
|
|
|
|
|
|
? Kephra::Edit::Search::find_prev()
|
65
|
|
|
|
|
|
|
: Kephra::Edit::Search::find_next();
|
66
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_ESCAPE) {
|
67
|
0
|
|
|
|
|
|
give_editpanel_focus_back(); switch_visibility();
|
|
0
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
} elsif ($key == 65 and $event->ControlDown) {# A
|
69
|
0
|
|
|
|
|
|
$bar->{find_input}->SetSelection
|
70
|
|
|
|
|
|
|
(0, $bar->{find_input}->GetLastPosition);
|
71
|
|
|
|
|
|
|
} elsif ($key == 70 and $event->ControlDown) {# F
|
72
|
0
|
|
|
|
|
|
give_editpanel_focus_back()
|
73
|
|
|
|
|
|
|
} elsif ( $key == 71 ) { # G
|
74
|
0
|
0
|
0
|
|
|
|
if ($event->ControlDown and $event->ShiftDown){
|
75
|
0
|
|
|
|
|
|
give_editpanel_focus_back();
|
76
|
0
|
|
|
|
|
|
Kephra::Edit::Goto::last_edit();
|
77
|
|
|
|
|
|
|
}
|
78
|
|
|
|
|
|
|
} elsif ($key == 81) { # Q
|
79
|
0
|
0
|
|
|
|
|
switch_visibility() if $event->ControlDown;
|
80
|
|
|
|
|
|
|
#} elsif ( $key == &Wx::WXK_LEFT ){ &Wx::wxSTC_CMD_CHARLEFT return
|
81
|
|
|
|
|
|
|
#} elsif ($key == &Wx::WXK_RIGHT ){ &Wx::wxSTC_CMD_CHARRIGHT return;
|
82
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_UP){
|
83
|
0
|
0
|
|
|
|
|
if ($event->ControlDown) {
|
84
|
0
|
|
|
|
|
|
$ep->CmdKeyExecute( &Wx::wxSTC_CMD_LINESCROLLUP ); return;
|
|
0
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
}
|
86
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_DOWN) {
|
87
|
0
|
0
|
|
|
|
|
if ($event->ControlDown) {
|
88
|
0
|
|
|
|
|
|
$ep->CmdKeyExecute( &Wx::wxSTC_CMD_LINESCROLLDOWN ); return;
|
|
0
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
}
|
90
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_PAGEUP) {
|
91
|
0
|
0
|
|
|
|
|
if ($event->ControlDown) {
|
92
|
0
|
|
|
|
|
|
my $pos = $bar->{find_input}->GetInsertionPoint;
|
93
|
0
|
|
|
|
|
|
Kephra::Document::Change::tab_left();
|
94
|
0
|
|
|
|
|
|
Wx::Window::SetFocus($bar->{find_input});
|
95
|
0
|
|
|
|
|
|
$bar->{find_input}->SetInsertionPoint($pos);
|
96
|
|
|
|
|
|
|
} else {
|
97
|
0
|
|
|
|
|
|
$ep->CmdKeyExecute( &Wx::wxSTC_CMD_PAGEUP );
|
98
|
|
|
|
|
|
|
}
|
99
|
0
|
|
|
|
|
|
return;
|
100
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_PAGEDOWN){
|
101
|
0
|
0
|
|
|
|
|
if ($event->ControlDown) {
|
102
|
0
|
|
|
|
|
|
my $pos = $bar->{find_input}->GetInsertionPoint;
|
103
|
0
|
|
|
|
|
|
Kephra::Document::Change::tab_right();
|
104
|
0
|
|
|
|
|
|
Wx::Window::SetFocus($bar->{find_input});
|
105
|
0
|
|
|
|
|
|
$bar->{find_input}->SetInsertionPoint($pos);
|
106
|
|
|
|
|
|
|
} else {
|
107
|
0
|
|
|
|
|
|
$ep->CmdKeyExecute( &Wx::wxSTC_CMD_PAGEDOWN );
|
108
|
|
|
|
|
|
|
}
|
109
|
0
|
|
|
|
|
|
return;
|
110
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_HOME and $event->ControlDown) {
|
111
|
0
|
|
|
|
|
|
$ep->CmdKeyExecute( &Wx::wxSTC_CMD_DOCUMENTSTART ); return;
|
|
0
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_END and $event->ControlDown) {
|
113
|
0
|
|
|
|
|
|
$ep->CmdKeyExecute( &Wx::wxSTC_CMD_DOCUMENTEND ); return;
|
|
0
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
} elsif ($key == &Wx::WXK_BACK and $event->ControlDown and $event->ShiftDown) {
|
115
|
0
|
|
|
|
|
|
my $pos = $bar->{find_input}->GetInsertionPoint;
|
116
|
0
|
|
|
|
|
|
Kephra::Document::Change::switch_back();
|
117
|
0
|
|
|
|
|
|
Wx::Window::SetFocus($bar->{find_input});
|
118
|
0
|
|
|
|
|
|
$bar->{find_input}->SetInsertionPoint($pos);
|
119
|
|
|
|
|
|
|
} else {
|
120
|
|
|
|
|
|
|
#print "$key\n"
|
121
|
|
|
|
|
|
|
}
|
122
|
0
|
|
|
|
|
|
$event->Skip;
|
123
|
0
|
|
|
|
|
|
} );
|
124
|
|
|
|
|
|
|
#Wx::Event::EVT_COMBOBOX( $find_input, -1, sub{ } );
|
125
|
|
|
|
|
|
|
Wx::Event::EVT_ENTER_WINDOW( $find_input, sub {
|
126
|
0
|
0
|
|
0
|
|
|
Wx::Window::SetFocus($find_input) if _config()->{autofocus};
|
127
|
0
|
|
|
|
|
|
disconnect_find_input();
|
128
|
0
|
|
|
|
|
|
});
|
129
|
0
|
|
|
0
|
|
|
Wx::Event::EVT_LEAVE_WINDOW( $find_input,sub{connect_find_input($find_input) });
|
|
0
|
|
|
|
|
|
|
130
|
0
|
|
|
|
|
|
connect_find_input($find_input);
|
131
|
0
|
|
|
|
|
|
$highlight_search = 1;
|
132
|
0
|
|
|
|
|
|
$ctrl = $find_input;
|
133
|
|
|
|
|
|
|
}
|
134
|
|
|
|
|
|
|
elsif ($item_data->{type} eq 'combobox' and $item_data->{id} eq 'replace'){
|
135
|
0
|
|
|
|
|
|
my $replace_input = $bar->{replace_input} = Wx::ComboBox->new (
|
136
|
|
|
|
|
|
|
$bar , -1, '', [-1,-1], [$item_data->{size},-1], [],
|
137
|
|
|
|
|
|
|
&Wx::wxTE_PROCESS_ENTER
|
138
|
|
|
|
|
|
|
);
|
139
|
0
|
|
|
|
|
|
$replace_input->SetDropTarget
|
140
|
|
|
|
|
|
|
( Kephra::Edit::Search::InputTarget->new($replace_input, 'replace'));
|
141
|
0
|
|
|
|
|
|
$replace_input->SetValue( Kephra::Edit::Search::get_replace_item() );
|
142
|
0
|
0
|
|
|
|
|
$replace_input->SetSize($item_data->{size},-1) if $item_data->{size};
|
143
|
0
|
0
|
|
|
|
|
if ( _search_config()->{history}{use} ){
|
144
|
0
|
|
|
|
|
|
$replace_input->Append($_) for @{ Kephra::Edit::Search::get_replace_history() }
|
|
0
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
}
|
146
|
0
|
|
|
|
|
|
$ctrl = $replace_input;
|
147
|
|
|
|
|
|
|
}
|
148
|
0
|
0
|
|
|
|
|
if (ref $ctrl) {
|
149
|
0
|
|
|
|
|
|
$bar->InsertControl( $item_data->{pos}, $ctrl );
|
150
|
|
|
|
|
|
|
}
|
151
|
|
|
|
|
|
|
}
|
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
Wx::Event::EVT_MIDDLE_DOWN( $bar, sub {
|
154
|
0
|
|
|
0
|
|
|
my ($widget, $event) = @_;
|
155
|
0
|
|
|
|
|
|
my $ep = Kephra::App::EditPanel::_ref();
|
156
|
0
|
0
|
|
|
|
|
if ($ep->GetSelectedText){
|
157
|
0
|
|
|
|
|
|
Kephra::Edit::Search::set_selection_as_find_item();
|
158
|
0
|
|
|
|
|
|
Kephra::Edit::Search::find_next();
|
159
|
|
|
|
|
|
|
} else {
|
160
|
0
|
|
|
|
|
|
Kephra::Edit::Goto::last_edit();
|
161
|
|
|
|
|
|
|
}
|
162
|
0
|
|
|
|
|
|
} );
|
163
|
|
|
|
|
|
|
Wx::Event::EVT_RIGHT_DOWN ( $bar, sub {
|
164
|
0
|
0
|
|
0
|
|
|
return unless get_contextmenu_visibility();
|
165
|
0
|
|
|
|
|
|
my ($widget, $event) = @_;
|
166
|
0
|
|
|
|
|
|
my ($x, $y) = ($event->GetX, $event->GetY);
|
167
|
0
|
|
|
|
|
|
my $menu = Kephra::App::ContextMenu::get(_config()->{contextmenu});
|
168
|
0
|
0
|
|
|
|
|
$bar->PopupMenu($menu, $x, $y) if Kephra::Menu::is($menu);
|
169
|
0
|
|
|
|
|
|
} );
|
170
|
0
|
|
|
|
|
|
Wx::Event::EVT_LEAVE_WINDOW($bar, \&leave_focus);
|
171
|
0
|
|
|
|
|
|
$bar->Realize;
|
172
|
0
|
|
|
|
|
|
$bar;
|
173
|
|
|
|
|
|
|
}
|
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
|
176
|
0
|
|
|
0
|
0
|
|
sub destroy{ Kephra::ToolBar::destroy ( _ID() ) }
|
177
|
|
|
|
|
|
|
#
|
178
|
|
|
|
|
|
|
sub connect_find_input {
|
179
|
0
|
|
|
0
|
0
|
|
my $find_input = shift;
|
180
|
0
|
|
|
|
|
|
my $ID = _ID();
|
181
|
0
|
|
|
|
|
|
my $add_call = \&Kephra::EventTable::add_call;
|
182
|
|
|
|
|
|
|
&$add_call( 'find.item.changed', $ID.'_input_refresh', sub {
|
183
|
0
|
|
|
0
|
|
|
my $value = Kephra::Edit::Search::get_find_item();
|
184
|
0
|
0
|
|
|
|
|
return if $value eq $find_input->GetValue;
|
185
|
0
|
|
|
|
|
|
$find_input->SetValue( $value );
|
186
|
0
|
|
|
|
|
|
my $pos = $find_input->GetLastPosition;
|
187
|
0
|
|
|
|
|
|
$find_input->SetSelection($pos,$pos);
|
188
|
0
|
|
|
|
|
|
}, $ID);
|
189
|
|
|
|
|
|
|
&$add_call( 'find.item.history.changed', $ID.'_popupmenu', sub {
|
190
|
0
|
|
|
0
|
|
|
$find_input->Clear();
|
191
|
0
|
|
|
|
|
|
$find_input->Append($_) for @{ Kephra::Edit::Search::get_find_history() };
|
|
0
|
|
|
|
|
|
|
192
|
0
|
|
|
|
|
|
$find_input->SetValue( Kephra::Edit::Search::get_find_item() );
|
193
|
0
|
|
|
|
|
|
$find_input->SetInsertionPointEnd;
|
194
|
0
|
|
|
|
|
|
}, $ID);
|
195
|
0
|
|
|
|
|
|
&$add_call( 'find', $ID.'_color_refresh', \&colour_find_input, $ID);
|
196
|
|
|
|
|
|
|
}
|
197
|
0
|
|
|
0
|
0
|
|
sub disconnect_find_input{ Kephra::EventTable::del_own_subscriptions(_ID()) }
|
198
|
|
|
|
|
|
|
#
|
199
|
|
|
|
|
|
|
sub colour_find_input {
|
200
|
0
|
|
|
0
|
0
|
|
my $find_input = _ref()->{find_input};
|
201
|
0
|
0
|
|
|
|
|
my $found_something = Kephra::Edit::Search::_find_pos() > -1
|
202
|
|
|
|
|
|
|
? 1 : 0;
|
203
|
0
|
0
|
|
|
|
|
return if $highlight_search eq $found_something;
|
204
|
0
|
|
|
|
|
|
$highlight_search = $found_something;
|
205
|
0
|
0
|
|
|
|
|
if ($found_something){
|
206
|
0
|
|
|
|
|
|
$find_input->SetForegroundColour( Wx::Colour->new( 0x00, 0x00, 0x55 ) );
|
207
|
0
|
|
|
|
|
|
$find_input->SetBackgroundColour( Wx::Colour->new( 0xff, 0xff, 0xff ) );
|
208
|
|
|
|
|
|
|
} else {
|
209
|
0
|
|
|
|
|
|
$find_input->SetForegroundColour( Wx::Colour->new( 0xff, 0x33, 0x33 ) );
|
210
|
0
|
|
|
|
|
|
$find_input->SetBackgroundColour( Wx::Colour->new( 0xff, 0xff, 0xff ) );
|
211
|
|
|
|
|
|
|
}
|
212
|
0
|
|
|
|
|
|
$find_input->Refresh;
|
213
|
|
|
|
|
|
|
}
|
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub enter_focus {
|
216
|
0
|
|
|
0
|
0
|
|
my $bar = _ref();
|
217
|
0
|
0
|
|
|
|
|
switch_visibility() unless get_visibility();
|
218
|
0
|
0
|
|
|
|
|
Wx::Window::SetFocus($bar->{find_input}) if defined $bar->{find_input};
|
219
|
|
|
|
|
|
|
}
|
220
|
0
|
0
|
|
0
|
0
|
|
sub leave_focus { switch_visibility() if _config()->{autohide} }
|
221
|
|
|
|
|
|
|
#
|
222
|
|
|
|
|
|
|
sub give_editpanel_focus_back{
|
223
|
0
|
|
|
0
|
0
|
|
leave_focus();
|
224
|
0
|
|
|
|
|
|
Wx::Window::SetFocus( Kephra::App::EditPanel::_ref() );
|
225
|
|
|
|
|
|
|
}
|
226
|
|
|
|
|
|
|
|
227
|
0
|
|
|
0
|
0
|
|
sub position { _config()->{position} }
|
228
|
|
|
|
|
|
|
#
|
229
|
|
|
|
|
|
|
# set visibility
|
230
|
|
|
|
|
|
|
sub show {
|
231
|
0
|
|
0
|
0
|
0
|
|
my $visible = shift || get_visibility();
|
232
|
0
|
|
|
|
|
|
my $bar = _ref();
|
233
|
0
|
0
|
|
|
|
|
return unless $bar;
|
234
|
0
|
|
|
|
|
|
my $sizer = $bar->GetParent->GetSizer;
|
235
|
0
|
|
|
|
|
|
$sizer->Show( $bar, $visible );
|
236
|
0
|
|
|
|
|
|
$sizer->Layout();
|
237
|
0
|
|
|
|
|
|
_config()->{visible} = $visible;
|
238
|
|
|
|
|
|
|
}
|
239
|
0
|
|
|
0
|
0
|
|
sub get_visibility { _config()->{visible} }
|
240
|
0
|
|
|
0
|
0
|
|
sub switch_visibility { _config()->{visible} ^= 1; show(); }
|
|
0
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
|
242
|
0
|
|
|
0
|
0
|
|
sub get_contextmenu_visibility { _config()->{contextmenu_visible} }
|
243
|
0
|
|
|
0
|
0
|
|
sub switch_contextmenu_visibility { _config()->{contextmenu_visible} ^= 1 }
|
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
1; |