weft-qda 0.9.6 → 0.9.8
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/weft.rb +16 -1
- data/lib/weft/WEFT-VERSION-STRING.rb +1 -1
- data/lib/weft/application.rb +17 -74
- data/lib/weft/backend.rb +6 -32
- data/lib/weft/backend/sqlite.rb +222 -164
- data/lib/weft/backend/sqlite/category_tree.rb +52 -48
- data/lib/weft/backend/sqlite/database.rb +57 -0
- data/lib/weft/backend/sqlite/upgradeable.rb +7 -0
- data/lib/weft/broadcaster.rb +90 -0
- data/lib/weft/category.rb +139 -47
- data/lib/weft/codereview.rb +160 -0
- data/lib/weft/coding.rb +74 -23
- data/lib/weft/document.rb +23 -10
- data/lib/weft/exceptions.rb +10 -0
- data/lib/weft/filters.rb +47 -224
- data/lib/weft/filters/indexers.rb +137 -0
- data/lib/weft/filters/input.rb +118 -0
- data/lib/weft/filters/output.rb +101 -0
- data/lib/weft/filters/templates.rb +80 -0
- data/lib/weft/filters/win32backtick.rb +246 -0
- data/lib/weft/query.rb +169 -0
- data/lib/weft/wxgui.rb +349 -294
- data/lib/weft/wxgui/constants.rb +43 -0
- data/lib/weft/wxgui/controls.rb +6 -0
- data/lib/weft/wxgui/controls/category_dropdown.rb +192 -0
- data/lib/weft/wxgui/controls/category_tree.rb +314 -0
- data/lib/weft/wxgui/controls/document_list.rb +97 -0
- data/lib/weft/wxgui/controls/multitype_control.rb +37 -0
- data/lib/weft/wxgui/{inspectors → controls}/textcontrols.rb +235 -64
- data/lib/weft/wxgui/dialogs.rb +144 -41
- data/lib/weft/wxgui/error_handler.rb +116 -36
- data/lib/weft/wxgui/exceptions.rb +7 -0
- data/lib/weft/wxgui/inspectors.rb +61 -208
- data/lib/weft/wxgui/inspectors/category.rb +19 -16
- data/lib/weft/wxgui/inspectors/codereview.rb +90 -132
- data/lib/weft/wxgui/inspectors/document.rb +12 -8
- data/lib/weft/wxgui/inspectors/imagedocument.rb +56 -56
- data/lib/weft/wxgui/inspectors/query.rb +284 -0
- data/lib/weft/wxgui/inspectors/script.rb +147 -23
- data/lib/weft/wxgui/lang/en.rb +69 -0
- data/lib/weft/wxgui/sidebar.rb +90 -432
- data/lib/weft/wxgui/utilities.rb +70 -91
- data/lib/weft/wxgui/workarea.rb +150 -43
- data/share/icons/category.ico +0 -0
- data/share/icons/category.xpm +109 -0
- data/share/icons/codereview.ico +0 -0
- data/share/icons/codereview.xpm +54 -0
- data/share/icons/d_and_c.xpm +126 -0
- data/share/icons/document.ico +0 -0
- data/share/icons/document.xpm +70 -0
- data/share/icons/project.ico +0 -0
- data/share/icons/query.ico +0 -0
- data/share/icons/query.xpm +56 -0
- data/{lib/weft/wxgui → share/icons}/search.xpm +0 -0
- data/share/icons/weft.ico +0 -0
- data/share/icons/weft.xpm +62 -0
- data/share/icons/weft16.ico +0 -0
- data/share/icons/weft32.ico +0 -0
- data/share/templates/category_plain.html +18 -0
- data/share/templates/codereview_plain.html +18 -0
- data/share/templates/document_plain.html +13 -0
- data/share/templates/document_plain.txt +7 -0
- data/test/001-document.rb +55 -36
- data/test/002-category.rb +81 -6
- data/test/003-code.rb +8 -4
- data/test/004-application.rb +13 -34
- data/test/005-query_review.rb +139 -0
- data/test/006-filters.rb +54 -42
- data/test/007-output_filters.rb +113 -0
- data/test/009a-backend_sqlite_basic.rb +95 -24
- data/test/009b-backend_sqlite_complex.rb +43 -62
- data/test/009c_backend_sqlite_bench.rb +5 -10
- data/test/053-doc_inspector.rb +46 -0
- data/test/055-query_window.rb +50 -0
- data/test/all-tests.rb +1 -0
- data/test/test-common.rb +19 -0
- data/test/testdata/empty.qdp +0 -0
- data/test/testdata/simple with space.pdf +0 -0
- data/test/testdata/simple.pdf +0 -0
- data/weft-qda.rb +40 -7
- metadata +74 -14
- data/lib/weft/wxgui/category.xpm +0 -26
- data/lib/weft/wxgui/document.xpm +0 -25
- data/lib/weft/wxgui/inspectors/search.rb +0 -265
- data/lib/weft/wxgui/mondrian.xpm +0 -44
- data/lib/weft/wxgui/weft16.xpm +0 -31
@@ -0,0 +1,97 @@
|
|
1
|
+
module QDA::GUI
|
2
|
+
class DocumentList < Wx::ListBox
|
3
|
+
include ListLikeItemData
|
4
|
+
include QDA::Subscriber
|
5
|
+
attr_reader :client
|
6
|
+
|
7
|
+
def initialize(weft_client, *args)
|
8
|
+
@client = weft_client
|
9
|
+
super(*args)
|
10
|
+
evt_left_dclick() { | event | on_double_click(event) }
|
11
|
+
evt_key_down() { | e | on_key_down(e) }
|
12
|
+
evt_listbox( self.get_id ) { | e | on_item_selected(e) }
|
13
|
+
subscribe(@client, :document_added, :document_deleted, :document_changed)
|
14
|
+
|
15
|
+
# evt_context_menu() { | event | on_context_menu(event) }
|
16
|
+
# @menu = Wx::Menu.new()
|
17
|
+
# @menu.append(1234, 'Foo')
|
18
|
+
# @menu.append(1235, 'Bar')
|
19
|
+
end
|
20
|
+
|
21
|
+
def app()
|
22
|
+
@client.app
|
23
|
+
end
|
24
|
+
# add the document to the end of the list.
|
25
|
+
def append_item(doc)
|
26
|
+
push_item_data(doc)
|
27
|
+
append(doc.title)
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_item(item)
|
31
|
+
if i = value_to_ident(item)
|
32
|
+
data.delete_at(i)
|
33
|
+
delete(i)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def update_item(doc)
|
38
|
+
if i = value_to_ident(doc)
|
39
|
+
set_item_data(i, doc)
|
40
|
+
set_string( value_to_ident(doc), doc.title )
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_selection_data()
|
45
|
+
get_item_data( get_selection )
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete_selection()
|
49
|
+
# Hand back to the client to process, including confirmation checks
|
50
|
+
client.on_delete_document()
|
51
|
+
end
|
52
|
+
|
53
|
+
def on_item_selected(e)
|
54
|
+
@client.current_document = selected_document
|
55
|
+
e.skip()
|
56
|
+
end
|
57
|
+
|
58
|
+
def on_context_menu(e)
|
59
|
+
popup_menu_xy(@menu, e.get_x, e.get_y)
|
60
|
+
end
|
61
|
+
|
62
|
+
def on_double_click(e)
|
63
|
+
if string_selection.empty?
|
64
|
+
@client.import_document()
|
65
|
+
else
|
66
|
+
@client.on_document_open( selected_document() )
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def selected_document()
|
71
|
+
sel = get_selection()
|
72
|
+
return nil unless sel and sel != -1
|
73
|
+
get_item_data( sel )
|
74
|
+
end
|
75
|
+
|
76
|
+
def receive_document_deleted(doc)
|
77
|
+
remove_item(doc)
|
78
|
+
end
|
79
|
+
|
80
|
+
def receive_document_changed(doc)
|
81
|
+
update_item(doc)
|
82
|
+
end
|
83
|
+
|
84
|
+
def receive_document_added(doc)
|
85
|
+
append_item(doc)
|
86
|
+
end
|
87
|
+
|
88
|
+
def on_key_down(evt)
|
89
|
+
case evt.key_code()
|
90
|
+
when 127 # DEL
|
91
|
+
delete_selection()
|
92
|
+
else
|
93
|
+
evt.skip()
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module QDA::GUI
|
2
|
+
# A control which has multiple different forms which can be shown or hidden
|
3
|
+
class MultiTypedControl < Wx::BoxSizer
|
4
|
+
attr_reader :controls, :visible
|
5
|
+
|
6
|
+
#
|
7
|
+
def initialize( first_item )
|
8
|
+
super(Wx::HORIZONTAL)
|
9
|
+
@controls = [ first_item ]
|
10
|
+
@visible = 0
|
11
|
+
add(visible_item, 1, Wx::ALL)
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_control(control)
|
15
|
+
controls.push(control)
|
16
|
+
control.hide()
|
17
|
+
end
|
18
|
+
|
19
|
+
def visible_item()
|
20
|
+
controls[visible]
|
21
|
+
end
|
22
|
+
|
23
|
+
def show(i)
|
24
|
+
return if i == visible
|
25
|
+
if i < 0 or i >= controls.length
|
26
|
+
raise ArgumentError, "Bad Index"
|
27
|
+
end
|
28
|
+
visible_item.hide()
|
29
|
+
remove(visible_item)
|
30
|
+
@visible = i
|
31
|
+
add(visible_item, 1, Wx::ADJUST_MINSIZE|Wx::ALL)
|
32
|
+
visible_item.show()
|
33
|
+
layout()
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -3,41 +3,57 @@ module QDA::GUI
|
|
3
3
|
# source text - addresses issues with the cross-platform
|
4
4
|
# representation of newlines in multiline text controls.
|
5
5
|
class TrueSelectionTextCtrl < Wx::TextCtrl
|
6
|
-
|
7
|
-
|
8
|
-
if Wx::RUBY_PLATFORM == 'WXMSW'
|
6
|
+
|
7
|
+
if Wx::RUBY_PLATFORM == 'WXMSW' # Microsoft Windows
|
9
8
|
NEWLINE_CORRECTION_FACTOR = 1
|
10
|
-
|
9
|
+
|
10
|
+
def true_point(point)
|
11
|
+
point - get_range(0, point).count("\n")
|
12
|
+
end
|
13
|
+
|
14
|
+
# returns the start and end of the selection as indexes within
|
15
|
+
# the underlying string. This is handled differently on each platform,
|
16
|
+
# but the end result is the same.
|
17
|
+
def true_selection()
|
18
|
+
# On windows, we have to correct for the way WxWidgets returns
|
19
|
+
# newlines in TextCtrls as two characters.
|
20
|
+
lines = get_range(0, get_insertion_point()).count("\n")
|
21
|
+
[ get_insertion_point() - lines,
|
22
|
+
get_insertion_point() + get_string_selection().length - lines ]
|
23
|
+
end
|
24
|
+
else
|
25
|
+
# GTK and Mac OS X
|
11
26
|
NEWLINE_CORRECTION_FACTOR = 0
|
27
|
+
# a no-op
|
28
|
+
def true_point(point)
|
29
|
+
point
|
30
|
+
end
|
31
|
+
|
32
|
+
def true_selection()
|
33
|
+
# on Linux and Mac OS X, the representation of newlines is not a
|
34
|
+
# problem (a single \n character in both the textctrl string and the
|
35
|
+
# underlying string), but the fact that get_selection() is missing
|
36
|
+
# from the wxruby is a problem. Additionally, WxGTK (not WxMac) returns
|
37
|
+
# different values for get_insertion_point when a selection has been
|
38
|
+
# depending on whether the selection was made left-to-right or
|
39
|
+
# right-to-left. So we do a bit of guessing.
|
40
|
+
str = get_string_selection()
|
41
|
+
val = get_value()
|
42
|
+
ins = get_insertion_point()
|
43
|
+
if str == val[ ins, str.length ] # should be always true on WxMac
|
44
|
+
return [ ins, ins + str.length ]
|
45
|
+
elsif str == val[ ins - str.length, str.length ]
|
46
|
+
return [ ins - str.length, ins ]
|
47
|
+
else
|
48
|
+
Kernel.raise "Insertion Point: #{ins}, Selection #{str}"
|
49
|
+
end
|
50
|
+
end
|
12
51
|
end
|
13
52
|
|
14
|
-
# background colour doesn't seem to work in MSW
|
15
|
-
HEADER_STYLE = Wx::TextAttr.new(Wx::RED)
|
16
|
-
# SUBHEADER_STYLE = Wx::TextAttr.new(Wx::BLUE)
|
17
|
-
NORMAL_STYLE = Wx::TextAttr.new(Wx::BLACK)
|
18
|
-
HIGHLIGHTED_STYLE = Wx::TextAttr.new(Wx::BLUE)
|
19
|
-
|
20
|
-
def initialize(*args)
|
21
|
-
super
|
22
|
-
@highlights = []
|
23
|
-
end
|
24
|
-
|
25
|
-
# returns the start and end of the selection as indexes within
|
26
|
-
# the underlying string
|
27
|
-
def true_selection()
|
28
|
-
lines = get_range(0, get_insertion_point()).count("\n")
|
29
|
-
lines *= NEWLINE_CORRECTION_FACTOR
|
30
|
-
[ get_insertion_point() - lines,
|
31
|
-
get_insertion_point() + get_string_selection().length - lines ]
|
32
|
-
end
|
33
|
-
alias :get_true_selection :true_selection
|
34
|
-
|
35
53
|
# returns the current insertion point as an index within the
|
36
54
|
# underlying string
|
37
55
|
def true_insertion_point()
|
38
|
-
|
39
|
-
lines *= NEWLINE_CORRECTION_FACTOR
|
40
|
-
get_insertion_point() - lines
|
56
|
+
true_point( insertion_point )
|
41
57
|
end
|
42
58
|
alias :get_true_insertion_point :true_insertion_point
|
43
59
|
|
@@ -49,30 +65,6 @@ module QDA::GUI
|
|
49
65
|
index + adjustment
|
50
66
|
end
|
51
67
|
|
52
|
-
# remove all highlights
|
53
|
-
def unhighlight()
|
54
|
-
while extent = @highlights.shift()
|
55
|
-
from, to = *extent
|
56
|
-
true_from, true_to = true_index_to_pos(from), true_index_to_pos(to)
|
57
|
-
set_style( true_from, true_to, NORMAL_STYLE )
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# highlight the characters from +from+ to +to+. These are
|
62
|
-
# characters within the underlying text - this method will
|
63
|
-
# automatically translate those to real characters displayed within
|
64
|
-
# the text control.
|
65
|
-
def highlight(from, to)
|
66
|
-
true_from, true_to = true_index_to_pos(from), true_index_to_pos(to)
|
67
|
-
set_style( true_from, true_to, HIGHLIGHTED_STYLE )
|
68
|
-
@highlights.push( [from, to] )
|
69
|
-
end
|
70
|
-
|
71
|
-
def clear()
|
72
|
-
super()
|
73
|
-
@highlights = []
|
74
|
-
end
|
75
|
-
|
76
68
|
# call this with a block that alters the appearance or content of
|
77
69
|
# the text control - this includes call to set_style(), highlight()
|
78
70
|
# as well as changing text content. It reduces flicker and keeps the
|
@@ -100,8 +92,178 @@ module QDA::GUI
|
|
100
92
|
end
|
101
93
|
end
|
102
94
|
|
103
|
-
|
95
|
+
|
96
|
+
class HighlightingTextCtrl < TrueSelectionTextCtrl
|
97
|
+
# TODO - using set_style on GTK (1.2) seems to trigger a serious bug
|
98
|
+
# where the text is moved out of correct position, and multiple
|
99
|
+
# successive calls trigger a segfault. This module provides stub
|
100
|
+
# functionality to hide this problem on Linux
|
101
|
+
module NullHighlighter
|
102
|
+
# pale_yellow = Wx::Colour.new(255, 255, 192)
|
103
|
+
# HIGHLIGHTED_STYLE = Wx::TextAttr.new( Wx::BLACK, pale_yellow )
|
104
|
+
def highlight(from, to)
|
105
|
+
end
|
106
|
+
def unhighlight()
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Provide support for highlighting regions within the text control by
|
111
|
+
# changing the text foreground colour - background colour doesn't work
|
112
|
+
# on MS Windows WxWidgets.
|
113
|
+
module TextColourHighlighter
|
114
|
+
# background colour doesn't seem to work in MSW
|
115
|
+
HIGHLIGHTED_STYLE = Wx::TextAttr.new(Wx::BLUE)
|
116
|
+
NORMAL_STYLE = Wx::TextAttr.new(Wx::BLACK)
|
117
|
+
|
118
|
+
def initialize(*args)
|
119
|
+
super
|
120
|
+
@highlights = []
|
121
|
+
end
|
122
|
+
|
123
|
+
# highlight the characters from +from+ to +to+. These are
|
124
|
+
# characters within the underlying text - this method will
|
125
|
+
# automatically translate those to real characters displayed within
|
126
|
+
# the text control.
|
127
|
+
def highlight(from, to)
|
128
|
+
true_from, true_to = true_index_to_pos(from), true_index_to_pos(to)
|
129
|
+
set_style( true_from, true_to, HIGHLIGHTED_STYLE )
|
130
|
+
@highlights.push( [from, to] )
|
131
|
+
end
|
132
|
+
|
133
|
+
# remove all highlights
|
134
|
+
def unhighlight()
|
135
|
+
while extent = @highlights.shift()
|
136
|
+
from, to = *extent
|
137
|
+
true_from, true_to = true_index_to_pos(from), true_index_to_pos(to)
|
138
|
+
set_style( true_from, true_to, NORMAL_STYLE )
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def clear()
|
143
|
+
super()
|
144
|
+
@highlights = []
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
if Wx::RUBY_PLATFORM == 'WXGTK' # Linux
|
149
|
+
include NullHighlighter
|
150
|
+
else
|
151
|
+
include TextColourHighlighter
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
module FindableText
|
156
|
+
class UsefulFindReplaceData < Wx::FindReplaceData
|
157
|
+
attr_accessor :flags
|
158
|
+
def down?
|
159
|
+
! up?
|
160
|
+
end
|
161
|
+
|
162
|
+
def up?
|
163
|
+
( flags & Wx::FR_DOWN ).zero?
|
164
|
+
end
|
165
|
+
|
166
|
+
def no_matchcase?
|
167
|
+
( flags & Wx::FR_MATCHCASE).zero?
|
168
|
+
end
|
169
|
+
|
170
|
+
def matchcase?
|
171
|
+
! no_matchcase?
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def initialize(*args)
|
176
|
+
super(*args)
|
177
|
+
@f_dialog = nil
|
178
|
+
@f_data = UsefulFindReplaceData.new(1)
|
179
|
+
@hooked = nil
|
180
|
+
end
|
181
|
+
|
182
|
+
def start_find(parent_win)
|
183
|
+
if not @f_dialog
|
184
|
+
@f_dialog = Wx::FindReplaceDialog.new( parent_win, @f_data,
|
185
|
+
"Find text", Wx::FR_NOWHOLEWORD )
|
186
|
+
end
|
187
|
+
if not @hooked
|
188
|
+
# TextCtrl doesn't receive evt_find, so route through parent
|
189
|
+
parent_win.evt_find(-1) { | e | on_find(e) }
|
190
|
+
parent_win.evt_find_next(-1) { | e | on_find(e) }
|
191
|
+
parent_win.evt_find_close(-1) { | e | on_find_close(e) }
|
192
|
+
# ensure dialog is destroyed when parent is closed
|
193
|
+
parent_win.evt_close() { | e | on_find_close(e) }
|
194
|
+
@hooked = parent_win
|
195
|
+
end
|
196
|
+
@f_dialog.show()
|
197
|
+
end
|
198
|
+
|
199
|
+
def get_subject()
|
200
|
+
if @f_data.up?
|
201
|
+
subject = get_range( 0, insertion_point )
|
202
|
+
else
|
203
|
+
subject = get_range( insertion_point, last_position )
|
204
|
+
end
|
205
|
+
if @f_data.no_matchcase?
|
206
|
+
subject.downcase!
|
207
|
+
end
|
208
|
+
return subject
|
209
|
+
end
|
210
|
+
|
211
|
+
def searching_down?
|
212
|
+
@f_data.down?
|
213
|
+
end
|
214
|
+
|
215
|
+
def searching_up?
|
216
|
+
@f_data.up?
|
217
|
+
end
|
218
|
+
|
219
|
+
def on_find(evt)
|
220
|
+
# query? bug in WxRuby 0.6.0 FindReplaceData#get_flags -
|
221
|
+
# doesn't get automatically updated as documented
|
222
|
+
@f_data.flags = evt.flags
|
223
|
+
|
224
|
+
# get the string we're searching for, bail out if nothing there
|
225
|
+
sought = @f_data.find_string()
|
226
|
+
return if sought.empty?
|
227
|
+
|
228
|
+
sought.downcase! if @f_data.no_matchcase?
|
229
|
+
|
230
|
+
# get part of our contents in the right case ready to
|
231
|
+
return unless subject = get_subject()
|
232
|
+
adjustment = 0
|
233
|
+
# hack to avoid recapturing when searching down
|
234
|
+
if searching_down? and string_selection == sought
|
235
|
+
adjustment = sought.length
|
236
|
+
subject = subject[adjustment .. -1]
|
237
|
+
end
|
238
|
+
|
239
|
+
point = searching_down? ? subject.index( sought ) :
|
240
|
+
subject.rindex( sought )
|
241
|
+
if point
|
242
|
+
if searching_up?
|
243
|
+
self.insertion_point = true_point( point )
|
244
|
+
else
|
245
|
+
self.insertion_point = true_insertion_point + point + adjustment
|
246
|
+
end
|
247
|
+
|
248
|
+
sel_start = true_index_to_pos( insertion_point )
|
249
|
+
sel_end = true_index_to_pos( insertion_point + sought.length )
|
250
|
+
self.set_selection( sel_end, sel_start )
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def on_find_close(evt)
|
255
|
+
if @f_dialog
|
256
|
+
@f_dialog.destroy()
|
257
|
+
@f_dialog = nil
|
258
|
+
end
|
259
|
+
self.set_focus()
|
260
|
+
evt.skip()
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
class DocTextViewer < HighlightingTextCtrl
|
104
265
|
attr_reader :docid
|
266
|
+
include FindableText
|
105
267
|
DOCTEXT_STYLE = Wx::TE_MULTILINE|Wx::TE_READONLY|
|
106
268
|
Wx::TE_RICH|Wx::TE_NOHIDESEL
|
107
269
|
|
@@ -137,9 +299,13 @@ module QDA::GUI
|
|
137
299
|
end
|
138
300
|
|
139
301
|
# a text display that is made up of text fragments from multiple
|
140
|
-
# documents
|
141
|
-
#
|
142
|
-
|
302
|
+
# documents. It keeps track of which fragment is found at which point,
|
303
|
+
# so that when passages are marked they are routed back to the source
|
304
|
+
# document.
|
305
|
+
class CompositeText < HighlightingTextCtrl
|
306
|
+
include FindableText
|
307
|
+
HEADER_STYLE = Wx::TextAttr.new(Wx::RED)
|
308
|
+
NORMAL_STYLE = Wx::TextAttr.new(Wx::BLACK)
|
143
309
|
class TextTable < Hash
|
144
310
|
def initialize(*args)
|
145
311
|
@reverse_table = {}
|
@@ -205,6 +371,7 @@ module QDA::GUI
|
|
205
371
|
target = @reverse_table.keys.find do | frag |
|
206
372
|
frag.docid == docid && frag.contains?(point)
|
207
373
|
end
|
374
|
+
return nil if target.nil?
|
208
375
|
return @reverse_table[target] - target.length +
|
209
376
|
( point - target.offset )
|
210
377
|
end
|
@@ -231,16 +398,19 @@ module QDA::GUI
|
|
231
398
|
# sort by document title
|
232
399
|
save_position() do
|
233
400
|
fragments.each_title do | doc_title, frags |
|
234
|
-
frags.each
|
235
|
-
header = "#{doc_title} [#{frag.offset}-#{frag.end}]\n"
|
236
|
-
write_range(header, nil, HEADER_STYLE)
|
237
|
-
write_range(frag, frag)
|
238
|
-
write_range("\n\n", nil)
|
239
|
-
end
|
401
|
+
frags.each { | frag | write_frag(frag) }
|
240
402
|
write_range("\n", nil)
|
241
403
|
end
|
242
404
|
end
|
243
405
|
evt_left_dclick() { | e | jump_to_fragment(e) }
|
406
|
+
self.insertion_point = 0
|
407
|
+
end
|
408
|
+
|
409
|
+
def write_frag(frag)
|
410
|
+
header = "#{frag.doctitle} [#{frag.offset}-#{frag.end}]\n"
|
411
|
+
write_range(header, nil, HEADER_STYLE)
|
412
|
+
write_range(frag, frag)
|
413
|
+
write_range("\n\n", nil)
|
244
414
|
end
|
245
415
|
|
246
416
|
# writes the text +text+ to the control using the sytle +style+,
|
@@ -249,7 +419,7 @@ module QDA::GUI
|
|
249
419
|
set_default_style(style)
|
250
420
|
ins_start = get_last_position()
|
251
421
|
append_text(text)
|
252
|
-
ins_end = get_last_position
|
422
|
+
ins_end = get_last_position()
|
253
423
|
|
254
424
|
if style != NORMAL_STYLE
|
255
425
|
@saved_styles[style] ||= []
|
@@ -259,7 +429,7 @@ module QDA::GUI
|
|
259
429
|
@cursor += text.length
|
260
430
|
@table[ @cursor ] = bound_value
|
261
431
|
end
|
262
|
-
private :write_range
|
432
|
+
private :write_frag, :write_range
|
263
433
|
|
264
434
|
def jump_to_fragment(evt)
|
265
435
|
frag, offset = *@table.fetch(true_insertion_point)
|
@@ -285,6 +455,7 @@ module QDA::GUI
|
|
285
455
|
areas.each do | docid, codes |
|
286
456
|
codes.each do | code |
|
287
457
|
translated = @table.translate(docid, code.offset)
|
458
|
+
next if translated.nil?
|
288
459
|
highlight(translated, translated + code.length)
|
289
460
|
end
|
290
461
|
end
|