weft-qda 0.9.6 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|