jota 0.8.0
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/INSTALL +145 -0
- data/bin/jota +12 -0
- data/bin/jotacli +12 -0
- data/lib/app_error.rb +5 -0
- data/lib/cli.rb +277 -0
- data/lib/clip.rb +137 -0
- data/lib/clip_array.rb +393 -0
- data/lib/gui.rb +792 -0
- data/lib/helper.rb +129 -0
- data/lib/jota.glade +730 -0
- data/lib/jota.rb +176 -0
- data/lib/preferences.rb +83 -0
- data/lib/svn_info.rb +16 -0
- data/lib/version.rb +59 -0
- data/tests/test_all.rb +10 -0
- data/tests/test_clip.rb +172 -0
- data/tests/test_clip_array.rb +177 -0
- data/tests/test_preferences.rb +185 -0
- metadata +81 -0
data/lib/gui.rb
ADDED
@@ -0,0 +1,792 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# $Id: gui.rb 37 2009-02-09 10:06:02Z dz $
|
4
|
+
|
5
|
+
# if you use vim and don't like folds type zR
|
6
|
+
|
7
|
+
|
8
|
+
# rdoc: see http://en.wikibooks.org/wiki/Ruby_Programming/RubyDoc
|
9
|
+
|
10
|
+
# = Class Gui - Realize the GTK+ related functions of Jota
|
11
|
+
|
12
|
+
# == Synopsis
|
13
|
+
|
14
|
+
# == Description
|
15
|
+
|
16
|
+
# == Requires
|
17
|
+
|
18
|
+
# == Interface
|
19
|
+
|
20
|
+
# === Mixins
|
21
|
+
|
22
|
+
# === Class Variables
|
23
|
+
|
24
|
+
# === Instance Variables
|
25
|
+
# @data:: ClipArray object in use or nil
|
26
|
+
# @glade:: glade object, to communicate with the widgets
|
27
|
+
# @top_window:: main window, only a shortcut
|
28
|
+
# @clip_widget:: textwidget for the clip data, only a shortcut
|
29
|
+
# is not accessible
|
30
|
+
|
31
|
+
# === See Also
|
32
|
+
# http://ruby-gnome2.sourceforge.jp/hiki.cgi?GladeXML
|
33
|
+
|
34
|
+
require 'clip'
|
35
|
+
require 'clip_array'
|
36
|
+
require 'helper'
|
37
|
+
require 'preferences'
|
38
|
+
|
39
|
+
class Gui
|
40
|
+
|
41
|
+
require 'libglade2'
|
42
|
+
include GetText
|
43
|
+
|
44
|
+
attr :glade
|
45
|
+
|
46
|
+
def initialize
|
47
|
+
#{{{1
|
48
|
+
@data = nil
|
49
|
+
@glade = nil
|
50
|
+
@top_widget = nil
|
51
|
+
@clip_widget = nil
|
52
|
+
end #}}}1
|
53
|
+
|
54
|
+
def open(filename)
|
55
|
+
#{{{1
|
56
|
+
begin
|
57
|
+
@data = ClipArray.open(filename)
|
58
|
+
rescue AppError, SystemCallError => msg
|
59
|
+
error_msgbox(msg)
|
60
|
+
return
|
61
|
+
end
|
62
|
+
set_autosave
|
63
|
+
end #}}}1
|
64
|
+
|
65
|
+
def close
|
66
|
+
#{{{1
|
67
|
+
widget_to_clip(@clip_widget,@data)
|
68
|
+
|
69
|
+
if @data
|
70
|
+
@data.close
|
71
|
+
end
|
72
|
+
end #}}}1
|
73
|
+
|
74
|
+
def set_current(regexp)
|
75
|
+
#{{{1
|
76
|
+
return if @data.nil?
|
77
|
+
@data.each_index do | i |
|
78
|
+
if @data[i].title.match(regexp) then
|
79
|
+
@data.current_index = i
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end #}}}1
|
84
|
+
|
85
|
+
def create_gui
|
86
|
+
#{{{1
|
87
|
+
glade_file = File.dirname(__FILE__)+"/jota.glade"
|
88
|
+
domain = nil
|
89
|
+
localedir = nil
|
90
|
+
|
91
|
+
print_verbose "creating gui"
|
92
|
+
|
93
|
+
bindtextdomain(domain, localedir, nil, "UTF-8")
|
94
|
+
|
95
|
+
print_verbose "loading glade spec from '#{glade_file}'"
|
96
|
+
@glade = GladeXML.new(glade_file,
|
97
|
+
nil,
|
98
|
+
domain,
|
99
|
+
localedir,
|
100
|
+
GladeXML::FILE) do |handler|
|
101
|
+
method(handler)
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Widgets
|
106
|
+
@top_window = @glade.get_widget("top")
|
107
|
+
@clip_widget = @glade.get_widget("clip")
|
108
|
+
|
109
|
+
# Show
|
110
|
+
@top_window.show
|
111
|
+
set_buttons
|
112
|
+
set_style
|
113
|
+
set_about_dialog
|
114
|
+
|
115
|
+
# Show the first clip
|
116
|
+
clip_to_widget(@clip_widget,@data)
|
117
|
+
end #}}}1
|
118
|
+
|
119
|
+
|
120
|
+
#
|
121
|
+
# System Buttons Callbacks
|
122
|
+
#
|
123
|
+
|
124
|
+
def on_top_destroy(widget)
|
125
|
+
#{{{1
|
126
|
+
quit_app
|
127
|
+
end #}}}1
|
128
|
+
|
129
|
+
def on_top_delete(widget, arg0)
|
130
|
+
#{{{1
|
131
|
+
quit_app
|
132
|
+
return true
|
133
|
+
end #}}}1
|
134
|
+
|
135
|
+
def on_dialog_delete(widget, arg0)
|
136
|
+
#{{{1
|
137
|
+
return true
|
138
|
+
end #}}}1
|
139
|
+
|
140
|
+
|
141
|
+
#
|
142
|
+
# Top Window Buttons Callbacks
|
143
|
+
#
|
144
|
+
|
145
|
+
def on_main_menu_pressed(widget)
|
146
|
+
#{{{1
|
147
|
+
# update Go To menu
|
148
|
+
widget_to_clip(@clip_widget,@data)
|
149
|
+
set_buttons
|
150
|
+
|
151
|
+
@glade["main_menu"].popup(
|
152
|
+
nil,
|
153
|
+
nil,
|
154
|
+
Gtk.current_event.button,
|
155
|
+
Gtk.current_event_time)
|
156
|
+
end #}}}1
|
157
|
+
|
158
|
+
def on_edit_menu_pressed(widget)
|
159
|
+
#{{{1
|
160
|
+
@glade["edit_text_menu"].popup(
|
161
|
+
nil,
|
162
|
+
nil,
|
163
|
+
Gtk.current_event.button,
|
164
|
+
Gtk.current_event_time)
|
165
|
+
end #}}}1
|
166
|
+
|
167
|
+
def on_delete_clicked(widget)
|
168
|
+
#{{{1
|
169
|
+
|
170
|
+
if pref("confirm_delete") then
|
171
|
+
msgbox = Gtk::MessageDialog.new(@top_window,
|
172
|
+
Gtk::Dialog::MODAL,
|
173
|
+
Gtk::MessageDialog::QUESTION,
|
174
|
+
Gtk::MessageDialog::BUTTONS_YES_NO,
|
175
|
+
"Do you really want to delete this clip?");
|
176
|
+
msgbox.title = "Confirm"
|
177
|
+
|
178
|
+
msgbox.run do | response |
|
179
|
+
case response
|
180
|
+
when Gtk::Dialog::RESPONSE_NO
|
181
|
+
msgbox.destroy
|
182
|
+
return
|
183
|
+
end
|
184
|
+
end
|
185
|
+
msgbox.destroy
|
186
|
+
end
|
187
|
+
|
188
|
+
widget_to_clip(@clip_widget,@data)
|
189
|
+
|
190
|
+
if pref("deletesave_enable") and not @data.current.empty? then
|
191
|
+
deletefile = expand_filename(pref("deletesave_file"),
|
192
|
+
@data.dirname, @data.filename)
|
193
|
+
begin
|
194
|
+
@data.current.append_as_mbox(deletefile)
|
195
|
+
rescue SystemCallError => msg
|
196
|
+
error_msgbox(msg)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
@data.delete
|
201
|
+
clip_to_widget(@clip_widget,@data)
|
202
|
+
set_buttons
|
203
|
+
end #}}}1
|
204
|
+
|
205
|
+
def on_new_clicked(widget)
|
206
|
+
#{{{1
|
207
|
+
widget_to_clip(@clip_widget,@data)
|
208
|
+
@data.new
|
209
|
+
clip_to_widget(@clip_widget,@data)
|
210
|
+
set_buttons
|
211
|
+
end #}}}1
|
212
|
+
|
213
|
+
def on_next_clicked(widget)
|
214
|
+
#{{{1
|
215
|
+
widget_to_clip(@clip_widget,@data)
|
216
|
+
@data.next
|
217
|
+
clip_to_widget(@clip_widget,@data)
|
218
|
+
set_buttons
|
219
|
+
end #}}}1
|
220
|
+
|
221
|
+
def on_prev_clicked(widget)
|
222
|
+
#{{{1
|
223
|
+
widget_to_clip(@clip_widget,@data)
|
224
|
+
@data.prev
|
225
|
+
clip_to_widget(@clip_widget,@data)
|
226
|
+
set_buttons
|
227
|
+
end #}}}1
|
228
|
+
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
#
|
233
|
+
# Main Menu Callbacks
|
234
|
+
#
|
235
|
+
|
236
|
+
def on_menu_quit_activate(widget)
|
237
|
+
#{{{1
|
238
|
+
quit_app
|
239
|
+
end #}}}1
|
240
|
+
|
241
|
+
def on_menu_save_activate(widget)
|
242
|
+
#{{{1
|
243
|
+
widget_to_clip(@clip_widget,@data)
|
244
|
+
@data.save
|
245
|
+
end #}}}1
|
246
|
+
|
247
|
+
def on_menu_new_activate(widget)
|
248
|
+
#{{{1
|
249
|
+
filename = get_filename(:ask,:save)
|
250
|
+
return if filename.nil?
|
251
|
+
|
252
|
+
begin
|
253
|
+
ca = ClipArray.create(filename)
|
254
|
+
rescue AppError, SystemCallError => msg
|
255
|
+
error_msgbox(msg)
|
256
|
+
return
|
257
|
+
end
|
258
|
+
|
259
|
+
if @data then
|
260
|
+
widget_to_clip(@clip_widget, @data)
|
261
|
+
@data.close
|
262
|
+
end
|
263
|
+
|
264
|
+
@data = ca
|
265
|
+
|
266
|
+
clip_to_widget(@clip_widget,@data)
|
267
|
+
set_buttons
|
268
|
+
set_autosave
|
269
|
+
set_style
|
270
|
+
end #}}}1
|
271
|
+
|
272
|
+
def on_menu_open_activate(widget)
|
273
|
+
#{{{1
|
274
|
+
filename = get_filename(:ask,:open)
|
275
|
+
return if filename.nil?
|
276
|
+
|
277
|
+
begin
|
278
|
+
ca = ClipArray.open(filename)
|
279
|
+
rescue AppError, SystemCallError => msg
|
280
|
+
error_msgbox(msg)
|
281
|
+
return
|
282
|
+
end
|
283
|
+
|
284
|
+
if @data then
|
285
|
+
widget_to_clip(@clip_widget, @data)
|
286
|
+
@data.close
|
287
|
+
end
|
288
|
+
|
289
|
+
@data = ca
|
290
|
+
|
291
|
+
clip_to_widget(@clip_widget,@data)
|
292
|
+
set_buttons
|
293
|
+
set_autosave
|
294
|
+
set_style
|
295
|
+
end #}}}1
|
296
|
+
|
297
|
+
def on_menu_close_activate(widget)
|
298
|
+
#{{{1
|
299
|
+
if @data.nil? then
|
300
|
+
return
|
301
|
+
end
|
302
|
+
|
303
|
+
widget_to_clip(@clip_widget, @data)
|
304
|
+
@data.close
|
305
|
+
@data = nil
|
306
|
+
clip_to_widget(@clip_widget,@data)
|
307
|
+
set_buttons
|
308
|
+
end #}}}1
|
309
|
+
|
310
|
+
def on_menu_export_mbox_activate(widget)
|
311
|
+
#{{{1
|
312
|
+
# TODO
|
313
|
+
end #}}}1
|
314
|
+
|
315
|
+
def on_menu_export_yaml_activate(widget)
|
316
|
+
#{{{1
|
317
|
+
# TODO
|
318
|
+
end #}}}1
|
319
|
+
|
320
|
+
def on_menu_import_mbox_activate(widget)
|
321
|
+
#{{{1
|
322
|
+
# TODO
|
323
|
+
end #}}}1
|
324
|
+
|
325
|
+
def on_menu_import_yaml_activate(widget)
|
326
|
+
#{{{1
|
327
|
+
# TODO
|
328
|
+
end #}}}1
|
329
|
+
|
330
|
+
def on_menu_preferences_activate(widget)
|
331
|
+
#{{{1
|
332
|
+
old_autosave_seconds = pref("autosave_seconds")
|
333
|
+
old_autosave_enable = pref("autosave_enable")
|
334
|
+
|
335
|
+
dialog = @glade["pref_dialog"]
|
336
|
+
|
337
|
+
# set values into dialog
|
338
|
+
|
339
|
+
set_style_sample(
|
340
|
+
array_to_color(pref("foreground")),
|
341
|
+
array_to_color(pref("background")),
|
342
|
+
pref("font"))
|
343
|
+
@glade["entry_sample"].text = "Sample Text"
|
344
|
+
|
345
|
+
@glade["pref_autosave_enable"].active = pref("autosave_enable")
|
346
|
+
@glade["pref_autosave_minutes"].text =
|
347
|
+
"%d" % (pref("autosave_seconds").to_i/60.0)
|
348
|
+
|
349
|
+
@glade["pref_deletesave_enable"].active = pref("deletesave_enable")
|
350
|
+
@glade["pref_deletesave_file"].text = pref("deletesave_file")
|
351
|
+
@glade["pref_confirm_delete"].active = pref("confirm_delete")
|
352
|
+
@glade["pref_confirm_quit"].active = pref("confirm_quit")
|
353
|
+
|
354
|
+
# execute dialog
|
355
|
+
dialog.show
|
356
|
+
|
357
|
+
dialog.signal_connect("response") do
|
358
|
+
# get values from dialog
|
359
|
+
set_style
|
360
|
+
|
361
|
+
set_pref("autosave_enable", @glade["pref_autosave_enable"].active?)
|
362
|
+
set_pref("autosave_seconds", 60 * @glade["pref_autosave_minutes"].text.to_i)
|
363
|
+
|
364
|
+
set_pref("deletesave_enable", @glade["pref_deletesave_enable"].active?)
|
365
|
+
set_pref("deletesave_file", @glade["pref_deletesave_file"].text)
|
366
|
+
|
367
|
+
set_pref("confirm_delete", @glade["pref_confirm_delete"].active?)
|
368
|
+
set_pref("confirm_quit", @glade["pref_confirm_quit"].active?)
|
369
|
+
|
370
|
+
if pref("autosave_seconds") != old_autosave_seconds or
|
371
|
+
pref("autosave_enable") != old_autosave_enable then
|
372
|
+
set_autosave
|
373
|
+
end
|
374
|
+
dialog.hide
|
375
|
+
end
|
376
|
+
|
377
|
+
dialog.signal_connect("close") do
|
378
|
+
dialog.hide
|
379
|
+
end
|
380
|
+
end #}}}1
|
381
|
+
|
382
|
+
def on_menu_about_activate(widget)
|
383
|
+
#{{{1
|
384
|
+
dialog = @glade["about_dialog"]
|
385
|
+
dialog.show
|
386
|
+
dialog.signal_connect("close") do
|
387
|
+
dialog.hide
|
388
|
+
end
|
389
|
+
dialog.signal_connect("destroy") do # XXX tut's nicht!?
|
390
|
+
dialog.hide
|
391
|
+
end
|
392
|
+
dialog.signal_connect("response") do
|
393
|
+
dialog.hide
|
394
|
+
end
|
395
|
+
end #}}}
|
396
|
+
|
397
|
+
|
398
|
+
#
|
399
|
+
# Goto Menu Callbacks
|
400
|
+
#
|
401
|
+
|
402
|
+
def on_menu_goto(nr)
|
403
|
+
#{{{1
|
404
|
+
widget_to_clip(@clip_widget,@data)
|
405
|
+
@data.current_index=nr
|
406
|
+
clip_to_widget(@clip_widget,@data)
|
407
|
+
set_buttons
|
408
|
+
end #}}}
|
409
|
+
|
410
|
+
|
411
|
+
#
|
412
|
+
# Edit Menu Callbacks
|
413
|
+
#
|
414
|
+
|
415
|
+
def on_edit_text_wrap_activate(widget)
|
416
|
+
#{{{1
|
417
|
+
widget_to_clip(@clip_widget,@data)
|
418
|
+
@data.current.wrap = @glade["edit_text_wrap"].active?
|
419
|
+
clip_to_widget(@clip_widget,@data)
|
420
|
+
set_buttons
|
421
|
+
set_style
|
422
|
+
end #}}}1
|
423
|
+
|
424
|
+
|
425
|
+
#
|
426
|
+
# Preferences Dialog Callbacks
|
427
|
+
#
|
428
|
+
|
429
|
+
def on_font(widget)
|
430
|
+
#{{{1
|
431
|
+
dialog = Gtk::FontSelectionDialog.new("Select Font")
|
432
|
+
|
433
|
+
dialog.font_name = pref("font")
|
434
|
+
|
435
|
+
dialog.ok_button.signal_connect("clicked") do
|
436
|
+
font = dialog.font_name
|
437
|
+
set_pref("font", font)
|
438
|
+
set_style_sample(nil, nil, font)
|
439
|
+
dialog.hide
|
440
|
+
end
|
441
|
+
|
442
|
+
dialog.cancel_button.signal_connect("clicked") do
|
443
|
+
dialog.hide
|
444
|
+
end
|
445
|
+
|
446
|
+
dialog.show
|
447
|
+
end #}}}1
|
448
|
+
|
449
|
+
def on_bgcolor(widget)
|
450
|
+
#{{{1
|
451
|
+
color_helper :dialog_text => "Select Background Color",
|
452
|
+
:pref_variable => "background"
|
453
|
+
end #}}}1
|
454
|
+
|
455
|
+
def on_fgcolor(widget)
|
456
|
+
#{{{1
|
457
|
+
color_helper :dialog_text => "Select Foreground Color",
|
458
|
+
:pref_variable => "foreground"
|
459
|
+
end #}}}1
|
460
|
+
|
461
|
+
|
462
|
+
private
|
463
|
+
|
464
|
+
def error_msgbox(message)
|
465
|
+
#{{{1
|
466
|
+
print_verbose "error message: #{message}"
|
467
|
+
|
468
|
+
msgbox = Gtk::MessageDialog.new(@top_window,
|
469
|
+
Gtk::Dialog::MODAL,
|
470
|
+
Gtk::MessageDialog::ERROR,
|
471
|
+
Gtk::MessageDialog::BUTTONS_OK,
|
472
|
+
message);
|
473
|
+
msgbox.title = "Error"
|
474
|
+
|
475
|
+
msgbox.run do | response |
|
476
|
+
case response
|
477
|
+
when Gtk::Dialog::RESPONSE_OK
|
478
|
+
msgbox.destroy
|
479
|
+
return
|
480
|
+
end
|
481
|
+
end
|
482
|
+
msgbox.destroy
|
483
|
+
end #}}}1
|
484
|
+
|
485
|
+
def set_goto_menu
|
486
|
+
# {{{1
|
487
|
+
return if @data.nil?
|
488
|
+
|
489
|
+
goto_menu = Gtk::Menu.new
|
490
|
+
@data.each_index do | i |
|
491
|
+
if i == @data.current_index then
|
492
|
+
marker = "<"
|
493
|
+
else
|
494
|
+
marker = ""
|
495
|
+
end
|
496
|
+
|
497
|
+
mi = Gtk::MenuItem.new("%2d: %s%s" %
|
498
|
+
[i+1, @data[i].title, marker])
|
499
|
+
mi.signal_connect("activate") do
|
500
|
+
on_menu_goto(i)
|
501
|
+
end
|
502
|
+
mi.show
|
503
|
+
goto_menu.append(mi)
|
504
|
+
end
|
505
|
+
@glade["menu_goto"].submenu = goto_menu
|
506
|
+
end #}}}
|
507
|
+
|
508
|
+
|
509
|
+
def color_helper (hash)
|
510
|
+
#{{{1
|
511
|
+
dialog_text = hash[:dialog_text]
|
512
|
+
pref_variable = hash[:pref_variable]
|
513
|
+
|
514
|
+
dialog = Gtk::ColorSelectionDialog.new(dialog_text)
|
515
|
+
|
516
|
+
dialog.colorsel.current_color = array_to_color(pref(pref_variable))
|
517
|
+
|
518
|
+
dialog.ok_button.signal_connect("clicked") do
|
519
|
+
color = dialog.colorsel.current_color
|
520
|
+
set_pref(pref_variable,color_to_array(color))
|
521
|
+
if pref_variable == "foreground" then
|
522
|
+
set_style_sample(color, nil, nil)
|
523
|
+
else
|
524
|
+
set_style_sample(nil, color, nil)
|
525
|
+
end
|
526
|
+
dialog.hide
|
527
|
+
end
|
528
|
+
|
529
|
+
dialog.cancel_button.signal_connect("clicked") do
|
530
|
+
dialog.hide
|
531
|
+
end
|
532
|
+
|
533
|
+
dialog.show
|
534
|
+
end #}}}1
|
535
|
+
|
536
|
+
|
537
|
+
def pref(key)
|
538
|
+
#{{{1
|
539
|
+
if @data.nil? then
|
540
|
+
return Preferences.defaults[key]
|
541
|
+
else
|
542
|
+
@data.pref[key]
|
543
|
+
end
|
544
|
+
end #}}}1
|
545
|
+
|
546
|
+
def set_pref(key,value)
|
547
|
+
#{{{1
|
548
|
+
if @data
|
549
|
+
@data.pref[key] = value
|
550
|
+
end
|
551
|
+
end #}}}1
|
552
|
+
|
553
|
+
def set_buttons
|
554
|
+
#{{{1
|
555
|
+
if @data.nil? then
|
556
|
+
@glade["but_delete"].sensitive = false
|
557
|
+
@glade["but_new"].sensitive = false
|
558
|
+
@glade["but_prev"].sensitive = false
|
559
|
+
@glade["but_next"].sensitive = false
|
560
|
+
@glade["but_edit"].sensitive = false
|
561
|
+
|
562
|
+
@glade["label_index"].text = ""
|
563
|
+
@glade["status"].text = ""
|
564
|
+
|
565
|
+
@glade["menu_new"].sensitive = true
|
566
|
+
@glade["menu_open"].sensitive = true
|
567
|
+
@glade["menu_close"].sensitive = false
|
568
|
+
@glade["menu_save"].sensitive = false
|
569
|
+
@glade["menu_goto"].sensitive = false
|
570
|
+
@glade["menu_export"].sensitive = false
|
571
|
+
@glade["menu_import"].sensitive = false
|
572
|
+
|
573
|
+
@top_window.title = "%s %s" %
|
574
|
+
[Version::PROGRAM_NAME, Version::STRING]
|
575
|
+
else
|
576
|
+
@glade["but_delete"].sensitive = true
|
577
|
+
@glade["but_new"].sensitive = true
|
578
|
+
@glade["but_next"].sensitive =
|
579
|
+
(@data.current_index != @data.length-1)
|
580
|
+
@glade["but_prev"].sensitive = (@data.current_index != 0)
|
581
|
+
@glade["but_edit"].sensitive = true
|
582
|
+
|
583
|
+
@glade["label_index"].text =
|
584
|
+
"%d of %d" % [@data.current_index+1, @data.length]
|
585
|
+
|
586
|
+
status = ""
|
587
|
+
status << "w" if @data.current.wrap
|
588
|
+
#status << "o" if @clip_widget.overwrite?
|
589
|
+
|
590
|
+
if status == "" then
|
591
|
+
@glade["status"].text = ""
|
592
|
+
else
|
593
|
+
@glade["status"].text = "[#{status}]"
|
594
|
+
end
|
595
|
+
|
596
|
+
@glade["menu_new"].sensitive = true
|
597
|
+
@glade["menu_open"].sensitive = true
|
598
|
+
@glade["menu_close"].sensitive = true
|
599
|
+
@glade["menu_save"].sensitive = true
|
600
|
+
@glade["menu_goto"].sensitive = true
|
601
|
+
@glade["menu_export"].sensitive = true
|
602
|
+
@glade["menu_import"].sensitive = true
|
603
|
+
|
604
|
+
if @data.current.title.strip.empty? then
|
605
|
+
@top_window.title = "%s %s" %
|
606
|
+
[Version::PROGRAM_NAME, Version::STRING]
|
607
|
+
else
|
608
|
+
@top_window.title = "%s" % [@data.current.title]
|
609
|
+
end
|
610
|
+
|
611
|
+
set_goto_menu
|
612
|
+
|
613
|
+
# Gtk::ToggleButton#active= emits an activate signal
|
614
|
+
# and thus calls on_edit_text_wrap_activate
|
615
|
+
if @data.current.wrap then
|
616
|
+
@clip_widget.wrap_mode = Gtk::TextTag::WRAP_WORD
|
617
|
+
@glade["edit_text_wrap"].active = true
|
618
|
+
else
|
619
|
+
@clip_widget.wrap_mode = Gtk::TextTag::WRAP_NONE
|
620
|
+
@glade["edit_text_wrap"].active = false
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
@top_window.focus = @glade["clip"]
|
625
|
+
end #}}}1
|
626
|
+
|
627
|
+
def set_style
|
628
|
+
#{{{1
|
629
|
+
@clip_widget.modify_text(Gtk::STATE_NORMAL,
|
630
|
+
array_to_color(pref("foreground")))
|
631
|
+
###@clip_widget.modify_fg(Gtk::STATE_NORMAL,
|
632
|
+
### Gdk::Color.new(0,0,65535))
|
633
|
+
#array_to_color(pref("foreground")))
|
634
|
+
@clip_widget.modify_base(Gtk::STATE_NORMAL,
|
635
|
+
array_to_color(pref("background")))
|
636
|
+
@clip_widget.modify_font(Pango::FontDescription.new(pref("font")))
|
637
|
+
end #}}}1
|
638
|
+
|
639
|
+
|
640
|
+
#
|
641
|
+
# Helper for Preferences Dialog
|
642
|
+
#
|
643
|
+
|
644
|
+
def set_style_sample(fg_gdk_color, bg_gdk_color, font)
|
645
|
+
#{{{1
|
646
|
+
sample = @glade["entry_sample"]
|
647
|
+
|
648
|
+
sample.modify_text(Gtk::STATE_NORMAL, fg_gdk_color) if fg_gdk_color
|
649
|
+
sample.modify_base(Gtk::STATE_NORMAL, bg_gdk_color) if bg_gdk_color
|
650
|
+
sample.modify_font(Pango::FontDescription.new(font)) if font
|
651
|
+
end #}}}1
|
652
|
+
|
653
|
+
def quit_app
|
654
|
+
#{{{1
|
655
|
+
if pref("confirm_quit") then
|
656
|
+
msgbox = Gtk::MessageDialog.new(@top_window,
|
657
|
+
Gtk::Dialog::MODAL,
|
658
|
+
Gtk::MessageDialog::QUESTION,
|
659
|
+
Gtk::MessageDialog::BUTTONS_YES_NO,
|
660
|
+
"Do you really want to quit?");
|
661
|
+
msgbox.title = "Confirm"
|
662
|
+
|
663
|
+
msgbox.run do | response |
|
664
|
+
case response
|
665
|
+
when Gtk::Dialog::RESPONSE_NO
|
666
|
+
msgbox.destroy
|
667
|
+
return
|
668
|
+
end
|
669
|
+
end
|
670
|
+
msgbox.destroy
|
671
|
+
end
|
672
|
+
|
673
|
+
widget_to_clip(@clip_widget,@data)
|
674
|
+
|
675
|
+
if @data
|
676
|
+
@data.close
|
677
|
+
end
|
678
|
+
|
679
|
+
Gtk.main_quit
|
680
|
+
end #}}}1
|
681
|
+
|
682
|
+
def set_about_dialog
|
683
|
+
#{{{1
|
684
|
+
dlg = @glade["about_dialog"]
|
685
|
+
if dlg.respond_to? :program_name then
|
686
|
+
dlg.program_name="#{Version::PROGRAM_NAME}"
|
687
|
+
else
|
688
|
+
dlg.name="#{Version::PROGRAM_NAME}"
|
689
|
+
end
|
690
|
+
#dlg.comments = "}"
|
691
|
+
dlg.version="#{Version::STRING}"
|
692
|
+
dlg.copyright="(C) #{Version::YEARS} #{Version::AUTHOR}"
|
693
|
+
dlg.website="#{Version::AUTHOR_WEBSITE}"
|
694
|
+
dlg.license="#{Version::LICENSE}"
|
695
|
+
dlg.authors=["#{Version::AUTHOR} <#{Version::AUTHOR_EMAIL}>"]
|
696
|
+
|
697
|
+
end #}}}1
|
698
|
+
|
699
|
+
|
700
|
+
# POSSIBLE CASES FOR CLIP TO/FROM WIDGET CONVERSION
|
701
|
+
# {{{1
|
702
|
+
# textview title data
|
703
|
+
# a) "" 1) "" ""
|
704
|
+
# b) abc 2) abc ""
|
705
|
+
# c) abc\n 2) abc ""
|
706
|
+
# d) abc\n 3) abc def\n
|
707
|
+
# def
|
708
|
+
# e) abc\n 3) abc def\n
|
709
|
+
# def\n
|
710
|
+
# }}}1
|
711
|
+
|
712
|
+
def clip_to_widget(textview, clip_array)
|
713
|
+
#{{{1
|
714
|
+
print_debug "clip_to_widget"
|
715
|
+
if clip_array.nil? then
|
716
|
+
str = "#{Version::PROGRAM_NAME} #{Version::STRING} ready\n\n"+
|
717
|
+
"Use Menu->New or Menu->Open\n"
|
718
|
+
textview.buffer.text = str
|
719
|
+
textview.editable = false
|
720
|
+
else
|
721
|
+
clip = clip_array.current
|
722
|
+
print_debug " title='#{clip.title}'"
|
723
|
+
print_debug " data='#{clip.data}'"
|
724
|
+
if clip.title == "" and clip.data == "" then # map (1)
|
725
|
+
str = "" # to (a)
|
726
|
+
else
|
727
|
+
# map (2) and (3) to (c) and (e) resp.
|
728
|
+
str = "#{clip.title}\n#{clip.data}"
|
729
|
+
print_debug " str='#{str}'"
|
730
|
+
end
|
731
|
+
|
732
|
+
textview.buffer.text = str
|
733
|
+
|
734
|
+
if clip.pos then
|
735
|
+
#mark = textview.buffer.get_insert
|
736
|
+
# isn't implemented in Ruby ... grrrr
|
737
|
+
mark = textview.buffer.get_mark("insert")
|
738
|
+
iter = textview.buffer.get_iter_at_mark(mark)
|
739
|
+
iter.offset = clip.pos
|
740
|
+
textview.buffer.place_cursor(iter)
|
741
|
+
#textview.scroll_to_mark(mark, 0, true, 0.0, 0.5)
|
742
|
+
textview.scroll_to_mark(mark, 0, true, 1.0, 0.5)
|
743
|
+
end
|
744
|
+
|
745
|
+
textview.editable = true
|
746
|
+
end
|
747
|
+
|
748
|
+
|
749
|
+
@top_window.focus = @glade["clip"]
|
750
|
+
end #}}}1
|
751
|
+
|
752
|
+
def widget_to_clip(textview, clip_array)
|
753
|
+
#{{{1
|
754
|
+
print_debug "widget_to_clip"
|
755
|
+
if clip_array then
|
756
|
+
str = textview.buffer.text
|
757
|
+
print_debug " str='#{str}'"
|
758
|
+
|
759
|
+
# map (a),(b) to (c) and (d) to (e)
|
760
|
+
str = str.chomp + "\n"
|
761
|
+
print_debug " str='#{str}'"
|
762
|
+
|
763
|
+
# map (c) to (2) and (e) to (3)
|
764
|
+
arr = str.split("\n",-1) # arr has at least 2 elems
|
765
|
+
# the last elem is empty
|
766
|
+
title = arr[0] # first elem = first line
|
767
|
+
print_debug " title='#{title}'"
|
768
|
+
data = arr[1..-1].join("\n") # second to last elem
|
769
|
+
print_debug " data='#{data}'"
|
770
|
+
|
771
|
+
clip_array.current.title = title
|
772
|
+
clip_array.current.data = data
|
773
|
+
clip_array.current.pos = textview.buffer.cursor_position
|
774
|
+
|
775
|
+
if textview.wrap_mode == Gtk::TextTag::WRAP_NONE then
|
776
|
+
clip_array.current.wrap = false
|
777
|
+
else
|
778
|
+
clip_array.current.wrap = true
|
779
|
+
end
|
780
|
+
end
|
781
|
+
end #}}}1
|
782
|
+
|
783
|
+
def set_autosave
|
784
|
+
#{{{1
|
785
|
+
if @data and pref("autosave_enable") then
|
786
|
+
@data.autosave(pref("autosave_seconds"))
|
787
|
+
end
|
788
|
+
end #}}}1
|
789
|
+
|
790
|
+
end # Class
|
791
|
+
|
792
|
+
# vim600: set foldmethod=marker:
|