weft-qda 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/lib/weft.rb +21 -0
  2. data/lib/weft/WEFT-VERSION-STRING.rb +1 -0
  3. data/lib/weft/application.rb +130 -0
  4. data/lib/weft/backend.rb +39 -0
  5. data/lib/weft/backend/marshal.rb +26 -0
  6. data/lib/weft/backend/mysql.rb +267 -0
  7. data/lib/weft/backend/n6.rb +366 -0
  8. data/lib/weft/backend/sqlite.rb +633 -0
  9. data/lib/weft/backend/sqlite/category_tree.rb +104 -0
  10. data/lib/weft/backend/sqlite/schema.rb +152 -0
  11. data/lib/weft/backend/sqlite/upgradeable.rb +55 -0
  12. data/lib/weft/category.rb +157 -0
  13. data/lib/weft/coding.rb +355 -0
  14. data/lib/weft/document.rb +118 -0
  15. data/lib/weft/filters.rb +243 -0
  16. data/lib/weft/wxgui.rb +687 -0
  17. data/lib/weft/wxgui/category.xpm +26 -0
  18. data/lib/weft/wxgui/dialogs.rb +128 -0
  19. data/lib/weft/wxgui/document.xpm +25 -0
  20. data/lib/weft/wxgui/error_handler.rb +52 -0
  21. data/lib/weft/wxgui/inspectors.rb +361 -0
  22. data/lib/weft/wxgui/inspectors/category.rb +165 -0
  23. data/lib/weft/wxgui/inspectors/codereview.rb +275 -0
  24. data/lib/weft/wxgui/inspectors/document.rb +139 -0
  25. data/lib/weft/wxgui/inspectors/imagedocument.rb +56 -0
  26. data/lib/weft/wxgui/inspectors/script.rb +35 -0
  27. data/lib/weft/wxgui/inspectors/search.rb +265 -0
  28. data/lib/weft/wxgui/inspectors/textcontrols.rb +304 -0
  29. data/lib/weft/wxgui/lang.rb +17 -0
  30. data/lib/weft/wxgui/lang/en.rb +45 -0
  31. data/lib/weft/wxgui/mondrian.xpm +44 -0
  32. data/lib/weft/wxgui/search.xpm +25 -0
  33. data/lib/weft/wxgui/sidebar.rb +498 -0
  34. data/lib/weft/wxgui/utilities.rb +148 -0
  35. data/lib/weft/wxgui/weft16.xpm +31 -0
  36. data/lib/weft/wxgui/workarea.rb +249 -0
  37. data/test/001-document.rb +196 -0
  38. data/test/002-category.rb +138 -0
  39. data/test/003-code.rb +370 -0
  40. data/test/004-application.rb +52 -0
  41. data/test/006-filters.rb +139 -0
  42. data/test/009a-backend_sqlite_basic.rb +280 -0
  43. data/test/009b-backend_sqlite_complex.rb +175 -0
  44. data/test/009c_backend_sqlite_bench.rb +81 -0
  45. data/test/010-backend_nudist.rb +5 -0
  46. data/test/all-tests.rb +1 -0
  47. data/test/manual-gui-script.txt +24 -0
  48. data/test/testdata/autocoding-test.txt +15 -0
  49. data/test/testdata/iso-8859-1.txt +5 -0
  50. data/test/testdata/sample_doc.txt +19 -0
  51. data/test/testdata/search_results.txt +1254 -0
  52. data/test/testdata/text1-dos-ascii.txt +2 -0
  53. data/test/testdata/text1-unix-utf8.txt +2 -0
  54. data/weft-qda.rb +28 -0
  55. metadata +96 -0
@@ -0,0 +1,26 @@
1
+ /* XPM */
2
+ static char *category[] = {
3
+ /* columns rows colors chars-per-pixel */
4
+ "16 16 4 1",
5
+ " c black",
6
+ ". c gray60",
7
+ "X c gray100",
8
+ "o c None",
9
+ /* pixels */
10
+ "oooooooooooooooo",
11
+ "oo ooooooooo",
12
+ "o XXXXX oooooooo",
13
+ "o XXXXX oooooooo",
14
+ "o XXXXX oooooooo",
15
+ "oo ooooooooo",
16
+ "oooo.ooooooooooo",
17
+ "oooo.ooooooooooo",
18
+ "oooo.ooo oo",
19
+ "oooo.ooo XXXX oo",
20
+ "oooo.... oo",
21
+ "oooo.ooooooooooo",
22
+ "oooo.ooo oo",
23
+ "oooo.ooo XXXX oo",
24
+ "oooo.... oo",
25
+ "oooooooooooooooo"
26
+ };
@@ -0,0 +1,128 @@
1
+ module QDA::GUI
2
+ class DocumentImportProgressTracker < QDA::Indexer
3
+ PT_STYLE = Wx::PD_APP_MODAL|Wx::PD_AUTO_HIDE
4
+ def initialize(parent, title)
5
+ super()
6
+ @parent = parent
7
+ @doctitle = title
8
+ end
9
+
10
+ def prepare(content)
11
+ @progbar = Wx::ProgressDialog.new('Importing document',
12
+ "Reading document #{@doctitle}",
13
+ content.count($/),
14
+ @parent, PT_STYLE)
15
+ @progress = 0
16
+ end
17
+
18
+ def feed(line)
19
+ if ! @progbar.update(@progress += 1)
20
+ raise "Aborted document import"
21
+ end
22
+ super
23
+ end
24
+
25
+ def terminate()
26
+ @progbar.destroy()
27
+ end
28
+ end
29
+
30
+ class WordIndexSaveProgressTracker < QDA::Indexer
31
+ attr_reader :progbar
32
+ PT_STYLE = Wx::PD_APP_MODAL|Wx::PD_AUTO_HIDE
33
+ def initialize(count, parent, title)
34
+ super()
35
+ @progbar = Wx::ProgressDialog.new( 'Importing document',
36
+ "Saving indexes for #{title}",
37
+ count, parent, PT_STYLE)
38
+ @progress = 0
39
+ end
40
+
41
+ def next()
42
+ if ! @progbar.update(@progress += 1)
43
+ raise "Aborted document import"
44
+ end
45
+ end
46
+
47
+ def terminate()
48
+ @progbar.destroy()
49
+ end
50
+ end
51
+
52
+ class SearchDialog < Wx::Dialog
53
+ def initialize(parent)
54
+ super( parent, -1, 'Search', DEF_POS, Wx::Size.new(500,175) )
55
+
56
+ sizer = Wx::FlexGridSizer.new(2, 5)
57
+
58
+ # search text entry
59
+ sizer.add(Wx::StaticText.new(self, -1, 'Search for'),
60
+ 0, Wx::ALIGN_CENTRE_VERTICAL|Wx::ALIGN_LEFT|Wx::ALL, 4)
61
+ @term = Wx::TextCtrl.new(self, -1, '', DEF_POS, DEF_SIZE,
62
+ Wx::TE_PROCESS_ENTER)
63
+ evt_text_enter(@term.get_id) { | e | on_search(e) }
64
+ sizer.add(@term, 2, Wx::GROW|Wx::ALL|Wx::ADJUST_MINSIZE, 4)
65
+
66
+ # how much context to return
67
+ sizer.add(Wx::StaticText.new(self, -1, 'Expand results by '),
68
+ 0, Wx::ALIGN_CENTRE_VERTICAL|Wx::ALIGN_LEFT|Wx::ALL, 4)
69
+ mini_sizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
70
+
71
+ @expand = Wx::SpinCtrl.new( self, -1, "")
72
+ @expand.set_range(0, 1000)
73
+ @expand.set_value(100)
74
+ mini_sizer.add(@expand, 0, Wx::ALL, 4)
75
+ mini_sizer.add(Wx::StaticText.new(self, -1, 'characters'),
76
+ 0, Wx::ALL, 6)
77
+ sizer.add(mini_sizer, 0)
78
+
79
+ # options
80
+ sizer.add(Wx::StaticText.new(self, -1, ''), 0, Wx::ALIGN_CENTRE, 4)
81
+ @case_sensi = Wx::CheckBox.new(self, -1, "Case sensitive?")
82
+ sizer.add(@case_sensi, 0, Wx::ALL, 4)
83
+
84
+ sizer.add(Wx::StaticText.new(self, -1, ''), 0, Wx::ALIGN_CENTRE, 4)
85
+ @whole_word = Wx::CheckBox.new(self, -1, "Whole words only?")
86
+ sizer.add(@whole_word, 0, Wx::ALL, 4)
87
+
88
+ # buttons
89
+ button = Wx::Button.new(self, -1, 'Search')
90
+ button.evt_button(button.get_id) { | e | on_search(e) }
91
+ sizer.add(button, 0, Wx::ALL, 4)
92
+
93
+ button = Wx::Button.new(self, -1, 'Cancel')
94
+ button.evt_button(button.get_id) { | e | end_modal(Wx::ID_CANCEL) }
95
+ sizer.add(button, 0, Wx::ALL|Wx::ALIGN_RIGHT, 4)
96
+
97
+ self.set_sizer(sizer)
98
+ # sizer.set_size_hints(self)
99
+ sizer.fit(self)
100
+ end
101
+
102
+ def on_search(e)
103
+ if term =~ /^\s*$/
104
+ Wx::MessageDialog.new(nil, Lang::NO_SEARCH_TERM_SPECIFIED,
105
+ Lang::NO_SEARCH_TERM_SPECIFIED,
106
+ Wx::OK|Wx::ICON_ERROR).show_modal()
107
+ return false
108
+ end
109
+ end_modal(Wx::ID_OK)
110
+ end
111
+
112
+ def term
113
+ @term.get_value
114
+ end
115
+
116
+ def case_sensitive
117
+ @case_sensi.is_checked
118
+ end
119
+
120
+ def whole_word
121
+ @whole_word.is_checked
122
+ end
123
+
124
+ def expand
125
+ @expand.get_value().to_i
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,25 @@
1
+ /* XPM */
2
+ static char *document[] = {
3
+ /* columns rows colors chars-per-pixel */
4
+ "16 16 3 1",
5
+ " c black",
6
+ ". c gray100",
7
+ "X c None",
8
+ /* pixels */
9
+ "XXXXXXXXXXXXXXXX",
10
+ "XX XXXXX",
11
+ "XX ........ XXXX",
12
+ "XX ......... XXX",
13
+ "XX . ... XX",
14
+ "XX .......... XX",
15
+ "XX . . XX",
16
+ "XX .......... XX",
17
+ "XX . . XX",
18
+ "XX .......... XX",
19
+ "XX . . XX",
20
+ "XX .......... XX",
21
+ "XX . . XX",
22
+ "XX .......... XX",
23
+ "XX XX",
24
+ "XXXXXXXXXXXXXXXX"
25
+ };
@@ -0,0 +1,52 @@
1
+ module QDA::GUI
2
+ class ErrorHandlerApp < Wx::App
3
+ attr_accessor :err
4
+
5
+ def on_init()
6
+ frame = Wx::Frame.new(nil, -1, 'Text')
7
+
8
+ panel = Wx::Panel.new(frame)
9
+ sizer = Wx::BoxSizer.new(Wx::VERTICAL)
10
+
11
+ @text_box = Wx::TextCtrl.new(panel, -1, @err.to_s,
12
+ Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE,
13
+ Wx::TE_MULTILINE|Wx::TE_RICH|Wx::TE_NOHIDESEL)
14
+ butt_panel = Wx::Panel.new(panel)
15
+ bott_sizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
16
+
17
+ button = Wx::Button.new(butt_panel, -1, 'Save')
18
+ button.evt_button(button.get_id) { | e | on_font(e) }
19
+ bott_sizer.add(button, 1, Wx::ALL, 4)
20
+
21
+ button = Wx::Button.new(butt_panel, -1, 'Send')
22
+ button.evt_button(button.get_id) { | e | on_bold(e) }
23
+ bott_sizer.add(button, 1, Wx::ALL, 4)
24
+
25
+ button = Wx::Button.new(butt_panel, -1, 'Close')
26
+ button.evt_button(button.get_id) { | e | on_colour(e) }
27
+ bott_sizer.add(button, 1, Wx::ALL, 4)
28
+
29
+ butt_panel.set_sizer(bott_sizer)
30
+
31
+ sizer.add(@text_box, 1, Wx::GROW)
32
+ sizer.add(butt_panel, 0, Wx::GROW|Wx::ADJUST_MINSIZE|Wx::ALIGN_BOTTOM)
33
+ panel.set_sizer(sizer)
34
+
35
+
36
+ frame.set_client_size( Wx::Size.new(200,200) )
37
+ frame.show()
38
+ end
39
+
40
+ def on_font(e)
41
+ dialog = Wx::FontDialog.new()
42
+ case dialog.show_modal()
43
+ when Wx::ID_OK
44
+ font = dialog.get_font_data.get_chosen_font()
45
+ @text_box.set_font(font)
46
+ when Wx::ID_CANCEL
47
+ return
48
+ end
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,361 @@
1
+ require 'weft/wxgui/inspectors/textcontrols'
2
+
3
+ module QDA::GUI
4
+ class CategoryDropDown < Wx::ComboBox
5
+ include Subscriber
6
+
7
+ MAXIMUM_DROPDOWN_LENGTH = 7
8
+ attr_accessor :sticky
9
+
10
+ # +locked+ if true will prevent the dropdown from responding to
11
+ # global category focus events.
12
+ def initialize(app, parent, text_box = nil, locked = false)
13
+ super(parent, -1, '', Wx::DEFAULT_POSITION,
14
+ Wx::DEFAULT_SIZE, [])
15
+ @locked = locked
16
+ @client_data = {}
17
+ @text_box = text_box
18
+ @sticky = false
19
+
20
+ @app = app
21
+
22
+ evt_kill_focus() do | e |
23
+ find_and_add_categories()
24
+ e.skip()
25
+ end
26
+
27
+ evt_text_enter(self.get_id) do | e |
28
+ find_and_add_categories()
29
+ end
30
+
31
+ evt_combobox(self.get_id) do | e |
32
+ e.skip()
33
+ on_item_selected(e)
34
+ end
35
+
36
+ subscribe(:focus_category, :category_deleted, :category_changed)
37
+ if $wxapp.current_category
38
+ set_active_category($wxapp.current_category)
39
+ end
40
+ end
41
+
42
+ # is this dropdown responding to global :focus_category events?
43
+ def locked?
44
+ @locked ? true : false
45
+ end
46
+
47
+ # make this dropdown receive global :focus_category events
48
+ def lock
49
+ @locked = true
50
+ end
51
+
52
+ # prevent this dropdown responding to global :focus_category events
53
+ def unlock
54
+ @locked = false
55
+ end
56
+
57
+ # highlight text coded by the category on the way.
58
+ def set_selection(idx)
59
+ super(idx)
60
+ if @text_box && category = current_category
61
+ @text_box.highlight_codingtable(category.codes)
62
+ end
63
+ end
64
+
65
+ # highlight text coded by the newly-selected category
66
+ def on_item_selected(e)
67
+ if @text_box && category = current_category
68
+ @text_box.highlight_codingtable(category.codes)
69
+ end
70
+ end
71
+
72
+ # add the newly-focused category to this dropdown and highlight
73
+ # its text.
74
+ def receive_focus_category(cat)
75
+ set_active_category(cat) unless locked?
76
+ end
77
+
78
+ # if a category is deleted it should be removed from the list
79
+ def receive_category_deleted(cat)
80
+ (0 .. count - 1).each do | i |
81
+ delete(i) if get_client_data(i).dbid == cat.dbid
82
+ end
83
+ end
84
+
85
+ def receive_category_changed(cat)
86
+ (0 .. count - 1).each do | i |
87
+ if get_client_data(i).dbid == cat.dbid
88
+ # TODO set_string not implemented (wxr 0.6.0)
89
+ # set_string(i, cat.name)
90
+ # set_client_data(cat.name, cat)
91
+ prepend(cat) # will automatically delete old
92
+ end
93
+ end
94
+ end
95
+
96
+ def set_active_category(category)
97
+ # clear the first node unless it is sticky because it has been used
98
+ unless @sticky
99
+ delete(0)
100
+ end
101
+ # clear any remaining excess items
102
+ while count > MAXIMUM_DROPDOWN_LENGTH
103
+ delete(count - 1)
104
+ end
105
+
106
+ prepend(category)
107
+ @sticky = false
108
+ set_selection(0)
109
+ # currently disabled until 0.9.6
110
+
111
+ end
112
+
113
+ def prepend(category)
114
+ copy = [ category.name, category ]
115
+ while count > 0
116
+ this_text = get_string(0)
117
+ this_cat = @client_data[this_text]
118
+ unless this_cat.dbid == category.dbid
119
+ copy.push( this_text, @client_data[this_text] )
120
+ end
121
+ delete(0)
122
+ end
123
+
124
+ until copy.empty?
125
+ new_text, new_data = copy.shift, copy.shift
126
+ append(new_text, nil)
127
+ set_client_data(new_text, new_data)
128
+ end
129
+ set_selection(0)
130
+ end
131
+
132
+ # added for compatibility with set_client_data - temporarily
133
+ # removed in WxRuby 0.4.0, should remove when this is fixed
134
+ def append(text, category, *args )
135
+ super(text, nil, *args)
136
+ set_client_data(text, category )
137
+ end
138
+
139
+ # mimicking WxWidgets method, temp disabled in WxRuby
140
+ def set_client_data(text, client_data)
141
+ @client_data[text] = client_data
142
+ end
143
+
144
+ # mimicking ...
145
+ def get_client_data(index)
146
+ text = get_string(index)
147
+ @client_data[text]
148
+ end
149
+
150
+ def find_and_add_categories()
151
+ typed_text = get_value()
152
+ unless find_string( typed_text ) || typed_text.empty?
153
+ matches = @app.app.get_categories_by_path(typed_text)
154
+ if matches.empty?
155
+
156
+ elsif matches.length > 1
157
+
158
+ end
159
+ matches.each { | cat | prepend(cat) unless cat.parent.nil? }
160
+ set_selection( 0 )
161
+ end
162
+ end
163
+
164
+ def on_blur(e)
165
+ find_and_add_categories()
166
+ e.skip()
167
+ end
168
+
169
+ # missing in wxruby, but part of WxWidgets
170
+ # this version differs by returning nil rather than -1 on failure
171
+ def find_string(str)
172
+ ( 0 ... count ).each do | i |
173
+ return i if str == get_string(i)
174
+ end
175
+ return nil
176
+ end
177
+
178
+
179
+ # TODO - some visual cue to indicate that no category matched find-first
180
+ def set_broken(bool)
181
+
182
+ end
183
+
184
+ def set_warning(bool)
185
+
186
+ end
187
+ # returns the Category object associated with the currently
188
+ # selected item in the drop down.
189
+ def current_category
190
+ if curr_sel = get_selection()
191
+ if curr_sel.nil? || curr_sel == -1
192
+ return nil
193
+ end
194
+ return get_client_data( curr_sel )
195
+ end
196
+ end
197
+ end
198
+
199
+ class WorkAreaWindow < Wx::MDIChildFrame
200
+ # the default size for new windows of this type and
201
+ # subclasses. Expressed as a proportion of MDI client area width
202
+ # and MDI client area height.
203
+ W_WINDOW_DEF_SIZE = [ 0.6, 0.8 ]
204
+
205
+ def initialize(workarea, title, last_layout)
206
+ size = pos = nil
207
+ if last_layout
208
+ size = Wx::Size.new( last_layout[:w], last_layout[:h] )
209
+ pos = Wx::Point.new( last_layout[:x], last_layout[:y] )
210
+ else
211
+ proportions = self.class::W_WINDOW_DEF_SIZE
212
+ size = workarea.proportional_size(*proportions)
213
+ pos = Wx::DEFAULT_POSITION
214
+ end
215
+ super(workarea, -1, title, pos, size)
216
+ end
217
+
218
+ # returns a hash serialising the current shape and location of
219
+ # this window, so it can later be unthawed
220
+ def layout()
221
+ curr_size = get_size()
222
+ pos = get_position
223
+ return { :x => pos.x,
224
+ :y => pos.y,
225
+ :w => curr_size.width,
226
+ :h => curr_size.height }
227
+ end
228
+
229
+ def layout=(layout)
230
+ move( Wx::Point.new(layout[:x], layout[:y]) )
231
+ set_client_size( Wx::Size.new(layout[:w], layout[:h]) )
232
+ end
233
+
234
+ # is this the currently focused window within the MDI layout?
235
+ def active?()
236
+ self == parent.active_child
237
+ end
238
+ end
239
+
240
+ # a WorkArea Window with a notebook layout with a coding panel
241
+ # including a text display in the first pane. Documents, Categories
242
+ # and Queries are all displayed using this model
243
+ class InspectorWindow < WorkAreaWindow
244
+ if Wx::RUBY_PLATFORM == 'WXGTK'
245
+ # GTK uses a notebook to fake MDI windows, so if running under
246
+ # WXGTK, place the real notebook tabs on the right instead
247
+ INSPECTOR_NB_STYLE = [ Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE,
248
+ Wx::NB_RIGHT ]
249
+ else
250
+ INSPECTOR_NB_STYLE = []
251
+ end
252
+
253
+ def initialize(workarea, title, last_layout, &text_constructor)
254
+ super(workarea, title, last_layout)
255
+
256
+ @notebook = Wx::Notebook.new(self, -1, *INSPECTOR_NB_STYLE)
257
+ panel_1 = Wx::Panel.new(@notebook, -1)
258
+ sizer_1 = Wx::BoxSizer.new(Wx::VERTICAL)
259
+
260
+ @text_box = text_constructor.call(panel_1)
261
+ sizer_1.add(@text_box, 10, Wx::GROW|Wx::ALL, 4)
262
+
263
+ butt_panel = Wx::Panel.new(panel_1, -1)
264
+ bott_sizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
265
+
266
+ @drop_down = CategoryDropDown.new(@app, butt_panel, @text_box)
267
+ bott_sizer.add(@drop_down, 3, Wx::ALL, 4)
268
+
269
+ button = Wx::Button.new(butt_panel, -1, 'Code')
270
+ button.evt_button(button.get_id) { | e | on_code(e) }
271
+ bott_sizer.add(button, 1, Wx::ALL, 4)
272
+
273
+ button = Wx::Button.new(butt_panel, -1, 'Uncode')
274
+ button.evt_button(button.get_id) { | e | on_uncode(e) }
275
+ bott_sizer.add(button, 1, Wx::ALL, 4)
276
+
277
+ # button = Wx::Button.new(butt_panel, -1, 'Note')
278
+ # button.evt_button(button.get_id) { | e | on_code(e) }
279
+ # bott_sizer.add(button, 1, Wx::ALL, 4, Wx::ALIGN_RIGHT)
280
+
281
+
282
+ butt_panel.sizer = bott_sizer
283
+ sizer_1.add(butt_panel, 0,
284
+ Wx::GROW|Wx::ADJUST_MINSIZE|Wx::ALIGN_BOTTOM)
285
+
286
+ panel_1.set_sizer( sizer_1 )
287
+ @notebook.add_page(panel_1, 'text')
288
+ evt_activate() { | e | on_activate(e) }
289
+ end
290
+
291
+ # (hopefully temporary) method -- when this window is closed,
292
+ # all widgets containsed within it that are subscribers to
293
+ # application events should also be unsubscribed so their notify
294
+ # method isn't later called - which causes a crash in wxruby 0.6.0
295
+ def associated_subscribers()
296
+ [ @drop_down ]
297
+ end
298
+
299
+ # this method should update the code combo box - this is done by
300
+ # the MDI Parent. But - the ActivateEvent class is not currently
301
+ # available in wxruby 0.6.0, so there's no way to distinguish an
302
+ # activate from a deactivate
303
+ def on_activate(e)
304
+ # e.methods.each { | m | p m }
305
+ # if e.get_active
306
+ # p "FOO"
307
+ # end
308
+ end
309
+
310
+ # code from the main text window
311
+ def on_code(e)
312
+ return unless category = get_current_category() # from drop-down
313
+
314
+ Wx::BusyCursor.busy do
315
+ codes = @text_box.selection_to_fragments()
316
+ codes.each { | c | category.code(c.docid, c.offset, c.length) }
317
+
318
+ $wxapp.app.save_category( category )
319
+ @drop_down.sticky = true
320
+ $wxapp.broadcast(:category_changed, category )
321
+ end
322
+ end
323
+
324
+ # uncode from the main text window
325
+ def on_uncode(e)
326
+ return unless category = get_current_category()
327
+ Wx::BusyCursor.busy do
328
+ codes = @text_box.selection_to_fragments()
329
+ codes.each { | c | category.uncode(c.docid, c.offset, c.length) }
330
+ $wxapp.app.save_category( category )
331
+ @drop_down.sticky = true
332
+ $wxapp.broadcast(:category_changed, category )
333
+ end
334
+ end
335
+
336
+ def refresh()
337
+
338
+ end
339
+
340
+ # the current category active in this window
341
+ def get_current_category()
342
+ if curr = @drop_down.current_category
343
+ return curr
344
+ else
345
+ return nil
346
+ end
347
+ end
348
+
349
+ # set the display font for use in this inspector
350
+ def set_display_font(font)
351
+ @text_box.set_font(font)
352
+ end
353
+ end
354
+
355
+ require 'weft/wxgui/inspectors/document.rb'
356
+ require 'weft/wxgui/inspectors/category.rb'
357
+ # require 'weft/wxgui/inspectors/imagedocument.rb'
358
+ require 'weft/wxgui/inspectors/search.rb'
359
+ require 'weft/wxgui/inspectors/script.rb'
360
+ require 'weft/wxgui/inspectors/codereview.rb'
361
+ end