jota 0.8.1 → 0.9.0dev2

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/gui.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # $Id: gui.rb 53 2009-09-24 14:22:04Z dz $
4
-
5
- # if you use vim and don't like folds type zR
3
+ # $Id: gui.rb 271 2010-07-29 18:56:41Z dz $
6
4
 
7
5
 
8
6
  # rdoc: see http://en.wikibooks.org/wiki/Ruby_Programming/RubyDoc
@@ -27,6 +25,7 @@
27
25
  # @top_window:: main window, only a shortcut
28
26
  # @clip_widget:: textwidget for the clip data, only a shortcut
29
27
  # is not accessible
28
+ # @next_autosave:: Time when next autosave should be done
30
29
 
31
30
  # === See Also
32
31
  # http://ruby-gnome2.sourceforge.jp/hiki.cgi?GladeXML
@@ -43,43 +42,43 @@ include GetText
43
42
 
44
43
  attr :glade
45
44
 
45
+ def Gui.gtk_version
46
+ return "GTK+ %d.%d.%d" % [Gtk::MAJOR_VERSION, Gtk::MINOR_VERSION, Gtk::MICRO_VERSION]
47
+ # TODO http://ruby-gnome2.sourceforge.jp/hiki.cgi?Gtk#MICRO_VERSION
48
+ end
49
+
46
50
  def initialize
47
- #{{{1
48
51
  @data = nil
49
52
  @glade = nil
50
53
  @top_widget = nil
51
54
  @clip_widget = nil
52
- end #}}}1
55
+ @next_autosave = Time.now
56
+ end
53
57
 
54
58
  def open(filename)
55
- #{{{1
56
59
  begin
57
60
  @data = ClipArray.open(filename)
58
61
  rescue AppError, SystemCallError => msg
59
62
  error_msgbox(msg)
60
- return
63
+ return nil
61
64
  end
62
65
  set_autosave
63
- end #}}}1
66
+ return @data
67
+ end
64
68
 
65
69
  def close
66
- #{{{1
67
70
  widget_to_clip(@clip_widget,@data)
68
71
 
69
72
  if @data
70
73
  @data.close
71
74
  end
72
- end #}}}1
75
+ end
73
76
 
74
- def goto_regexp(regexp)
75
- #{{{1
76
- if @data then
77
- @data.goto_regexp(regexp)
78
- end
79
- end #}}}1
77
+ def clip_array
78
+ return @data
79
+ end
80
80
 
81
81
  def create_gui
82
- #{{{1
83
82
  glade_file = File.dirname(__FILE__)+"/jota.glade"
84
83
  domain = nil
85
84
  localedir = nil
@@ -104,14 +103,38 @@ def create_gui
104
103
 
105
104
  clip_to_widget(@clip_widget,@data)
106
105
 
106
+ # Accelerators
107
+ @accel_group = Gtk::AccelGroup.new
108
+ @top_window.add_accel_group(@accel_group)
109
+ @glade["main_menu"].accel_group=(@accel_group)
110
+
111
+ @glade["menu_new"].add_accelerator('activate', @accel_group,
112
+ Gdk::Keyval::GDK_N, Gdk::Window::CONTROL_MASK, Gtk::ACCEL_VISIBLE)
113
+ @glade["menu_open"].add_accelerator('activate', @accel_group,
114
+ Gdk::Keyval::GDK_O, Gdk::Window::CONTROL_MASK, Gtk::ACCEL_VISIBLE)
115
+ @glade["menu_save"].add_accelerator('activate', @accel_group,
116
+ Gdk::Keyval::GDK_S, Gdk::Window::CONTROL_MASK, Gtk::ACCEL_VISIBLE)
117
+ @glade["menu_close"].add_accelerator('activate', @accel_group,
118
+ Gdk::Keyval::GDK_W, Gdk::Window::CONTROL_MASK, Gtk::ACCEL_VISIBLE)
119
+ @glade["menu_quit"].add_accelerator('activate', @accel_group,
120
+ Gdk::Keyval::GDK_Q, Gdk::Window::CONTROL_MASK, Gtk::ACCEL_VISIBLE)
121
+
107
122
  # Show
108
123
  print_debug " showing widgets"
109
124
  @top_window.show
110
- set_buttons
125
+ update
111
126
  set_style
112
127
  set_about_dialog
113
128
 
114
- end #}}}1
129
+ # Call 'update' every 2 seconds
130
+ Gtk.timeout_add(2000) do
131
+ update
132
+ autosave
133
+ true
134
+ end
135
+
136
+
137
+ end
115
138
 
116
139
 
117
140
  #
@@ -119,20 +142,17 @@ end #}}}1
119
142
  #
120
143
 
121
144
  def on_top_destroy(widget)
122
- #{{{1
123
145
  quit_app
124
- end #}}}1
146
+ end
125
147
 
126
148
  def on_top_delete(widget, arg0)
127
- #{{{1
128
149
  quit_app
129
150
  return true
130
- end #}}}1
151
+ end
131
152
 
132
153
  def on_dialog_delete(widget, arg0)
133
- #{{{1
134
154
  return true
135
- end #}}}1
155
+ end
136
156
 
137
157
 
138
158
  #
@@ -140,30 +160,27 @@ end #}}}1
140
160
  #
141
161
 
142
162
  def on_main_menu_pressed(widget)
143
- #{{{1
144
163
  # update Go To menu
145
164
  widget_to_clip(@clip_widget,@data)
146
- set_buttons
165
+ update
166
+ set_goto_menu
147
167
 
148
168
  @glade["main_menu"].popup(
149
169
  nil,
150
170
  nil,
151
171
  Gtk.current_event.button,
152
172
  Gtk.current_event_time)
153
- end #}}}1
173
+ end
154
174
 
155
175
  def on_edit_menu_pressed(widget)
156
- #{{{1
157
176
  @glade["edit_text_menu"].popup(
158
177
  nil,
159
178
  nil,
160
179
  Gtk.current_event.button,
161
180
  Gtk.current_event_time)
162
- end #}}}1
181
+ end
163
182
 
164
183
  def on_delete_clicked(widget)
165
- #{{{1
166
-
167
184
  if pref("confirm_delete") then
168
185
  msgbox = Gtk::MessageDialog.new(@top_window,
169
186
  Gtk::Dialog::MODAL,
@@ -188,7 +205,7 @@ def on_delete_clicked(widget)
188
205
  deletefile = expand_filename(pref("deletesave_file"),
189
206
  @data.dirname, @data.filename)
190
207
  begin
191
- @data.current.append_as_mbox(deletefile)
208
+ @data.append(deletefile)
192
209
  rescue SystemCallError => msg
193
210
  error_msgbox(msg)
194
211
  end
@@ -196,32 +213,29 @@ def on_delete_clicked(widget)
196
213
 
197
214
  @data.delete
198
215
  clip_to_widget(@clip_widget,@data)
199
- set_buttons
200
- end #}}}1
216
+ update
217
+ end
201
218
 
202
219
  def on_new_clicked(widget)
203
- #{{{1
204
220
  widget_to_clip(@clip_widget,@data)
205
221
  @data.new
206
222
  clip_to_widget(@clip_widget,@data)
207
- set_buttons
208
- end #}}}1
223
+ update
224
+ end
209
225
 
210
226
  def on_next_clicked(widget)
211
- #{{{1
212
227
  widget_to_clip(@clip_widget,@data)
213
228
  @data.next
214
229
  clip_to_widget(@clip_widget,@data)
215
- set_buttons
216
- end #}}}1
230
+ update
231
+ end
217
232
 
218
233
  def on_prev_clicked(widget)
219
- #{{{1
220
234
  widget_to_clip(@clip_widget,@data)
221
235
  @data.prev
222
236
  clip_to_widget(@clip_widget,@data)
223
- set_buttons
224
- end #}}}1
237
+ update
238
+ end
225
239
 
226
240
 
227
241
 
@@ -231,18 +245,15 @@ end #}}}1
231
245
  #
232
246
 
233
247
  def on_menu_quit_activate(widget)
234
- #{{{1
235
248
  quit_app
236
- end #}}}1
249
+ end
237
250
 
238
251
  def on_menu_save_activate(widget)
239
- #{{{1
240
252
  widget_to_clip(@clip_widget,@data)
241
253
  @data.save
242
- end #}}}1
254
+ end
243
255
 
244
256
  def on_menu_new_activate(widget)
245
- #{{{1
246
257
  filename = get_filename(:ask,:save)
247
258
  return if filename.nil?
248
259
 
@@ -261,13 +272,12 @@ def on_menu_new_activate(widget)
261
272
  @data = ca
262
273
 
263
274
  clip_to_widget(@clip_widget,@data)
264
- set_buttons
275
+ update
265
276
  set_autosave
266
277
  set_style
267
- end #}}}1
278
+ end
268
279
 
269
280
  def on_menu_open_activate(widget)
270
- #{{{1
271
281
  filename = get_filename(:ask,:open)
272
282
  return if filename.nil?
273
283
 
@@ -286,13 +296,12 @@ def on_menu_open_activate(widget)
286
296
  @data = ca
287
297
 
288
298
  clip_to_widget(@clip_widget,@data)
289
- set_buttons
299
+ update
290
300
  set_autosave
291
301
  set_style
292
- end #}}}1
302
+ end
293
303
 
294
304
  def on_menu_close_activate(widget)
295
- #{{{1
296
305
  if @data.nil? then
297
306
  return
298
307
  end
@@ -301,31 +310,26 @@ def on_menu_close_activate(widget)
301
310
  @data.close
302
311
  @data = nil
303
312
  clip_to_widget(@clip_widget,@data)
304
- set_buttons
305
- end #}}}1
313
+ update
314
+ end
306
315
 
307
316
  def on_menu_export_mbox_activate(widget)
308
- #{{{1
309
317
  # TODO
310
- end #}}}1
318
+ end
311
319
 
312
320
  def on_menu_export_yaml_activate(widget)
313
- #{{{1
314
321
  # TODO
315
- end #}}}1
322
+ end
316
323
 
317
324
  def on_menu_import_mbox_activate(widget)
318
- #{{{1
319
325
  # TODO
320
- end #}}}1
326
+ end
321
327
 
322
328
  def on_menu_import_yaml_activate(widget)
323
- #{{{1
324
329
  # TODO
325
- end #}}}1
330
+ end
326
331
 
327
332
  def on_menu_preferences_activate(widget)
328
- #{{{1
329
333
  old_autosave_seconds = pref("autosave_seconds")
330
334
  old_autosave_enable = pref("autosave_enable")
331
335
 
@@ -374,10 +378,9 @@ def on_menu_preferences_activate(widget)
374
378
  dialog.signal_connect("close") do
375
379
  dialog.hide
376
380
  end
377
- end #}}}1
381
+ end
378
382
 
379
383
  def on_menu_about_activate(widget)
380
- #{{{1
381
384
  dialog = @glade["about_dialog"]
382
385
  dialog.show
383
386
  dialog.signal_connect("close") do
@@ -389,7 +392,7 @@ def on_menu_about_activate(widget)
389
392
  dialog.signal_connect("response") do
390
393
  dialog.hide
391
394
  end
392
- end #}}}
395
+ end
393
396
 
394
397
 
395
398
  #
@@ -397,12 +400,11 @@ end #}}}
397
400
  #
398
401
 
399
402
  def on_menu_goto(nr)
400
- #{{{1
401
403
  widget_to_clip(@clip_widget,@data)
402
404
  @data.current_index=nr
403
405
  clip_to_widget(@clip_widget,@data)
404
- set_buttons
405
- end #}}}
406
+ update
407
+ end
406
408
 
407
409
 
408
410
  #
@@ -410,14 +412,13 @@ end #}}}
410
412
  #
411
413
 
412
414
  def on_edit_text_wrap_activate(widget)
413
- #{{{1
414
415
  print_debug "on_edit_text_wrap_activate called"
415
416
  widget_to_clip(@clip_widget,@data)
416
417
  @data.current.wrap = @glade["edit_text_wrap"].active?
417
418
  clip_to_widget(@clip_widget,@data)
418
- set_buttons
419
+ update
419
420
  set_style
420
- end #}}}1
421
+ end
421
422
 
422
423
 
423
424
  #
@@ -425,7 +426,6 @@ end #}}}1
425
426
  #
426
427
 
427
428
  def on_font(widget)
428
- #{{{1
429
429
  dialog = Gtk::FontSelectionDialog.new("Select Font")
430
430
 
431
431
  dialog.font_name = pref("font")
@@ -442,25 +442,22 @@ def on_font(widget)
442
442
  end
443
443
 
444
444
  dialog.show
445
- end #}}}1
445
+ end
446
446
 
447
447
  def on_bgcolor(widget)
448
- #{{{1
449
448
  color_helper :dialog_text => "Select Background Color",
450
449
  :pref_variable => "background"
451
- end #}}}1
450
+ end
452
451
 
453
452
  def on_fgcolor(widget)
454
- #{{{1
455
453
  color_helper :dialog_text => "Select Foreground Color",
456
454
  :pref_variable => "foreground"
457
- end #}}}1
455
+ end
458
456
 
459
457
 
460
458
  private
461
459
 
462
460
  def error_msgbox(message)
463
- #{{{1
464
461
  print_verbose "error message: #{message}"
465
462
 
466
463
  msgbox = Gtk::MessageDialog.new(@top_window,
@@ -478,10 +475,9 @@ def error_msgbox(message)
478
475
  end
479
476
  end
480
477
  msgbox.destroy
481
- end #}}}1
478
+ end
482
479
 
483
480
  def set_goto_menu
484
- # {{{1
485
481
  return if @data.nil?
486
482
 
487
483
  goto_menu = Gtk::Menu.new
@@ -490,7 +486,7 @@ def set_goto_menu
490
486
  if @data[i].title.length > 37 then
491
487
  title = @data[i].title[0..36]+"..."
492
488
  else
493
- title = @data[i].title
489
+ title = @data[i].title!
494
490
  end
495
491
 
496
492
  # Using markup in a MenuItems is not implemented before
@@ -520,11 +516,10 @@ def set_goto_menu
520
516
  goto_menu.append(mi)
521
517
  end
522
518
  @glade["menu_goto"].submenu = goto_menu
523
- end #}}}
519
+ end
524
520
 
525
521
 
526
522
  def color_helper (hash)
527
- #{{{1
528
523
  dialog_text = hash[:dialog_text]
529
524
  pref_variable = hash[:pref_variable]
530
525
 
@@ -548,27 +543,36 @@ def color_helper (hash)
548
543
  end
549
544
 
550
545
  dialog.show
551
- end #}}}1
546
+ end
552
547
 
553
548
 
554
549
  def pref(key)
555
- #{{{1
556
550
  if @data.nil? then
557
551
  return Preferences.defaults[key]
558
552
  else
559
553
  @data.pref[key]
560
554
  end
561
- end #}}}1
555
+ end
562
556
 
563
557
  def set_pref(key,value)
564
- #{{{1
565
558
  if @data
566
559
  @data.pref[key] = value
567
560
  end
568
- end #}}}1
561
+ end
562
+
563
+ def set_title
564
+ if @data then
565
+ @top_window.title = "%s: %s" % [
566
+ Version::PROGRAM_NAME,
567
+ @data.current.title!]
568
+ else
569
+ @top_window.title = "%s %s" % [
570
+ Version::PROGRAM_NAME,
571
+ Version::STRING]
572
+ end
573
+ end
569
574
 
570
575
  def set_buttons
571
- #{{{1
572
576
  #
573
577
  # CAUTION: set_buttons may trigger callback functions "on_*"
574
578
  #
@@ -589,10 +593,6 @@ def set_buttons
589
593
  @glade["menu_goto"].sensitive = false
590
594
  @glade["menu_export"].sensitive = false
591
595
  @glade["menu_import"].sensitive = false
592
-
593
- @top_window.title = "%s %s" % [
594
- Version::PROGRAM_NAME.capitalize,
595
- Version::STRING]
596
596
  else
597
597
  @glade["but_delete"].sensitive = true
598
598
  @glade["but_new"].sensitive = true
@@ -622,18 +622,6 @@ def set_buttons
622
622
  @glade["menu_export"].sensitive = true
623
623
  @glade["menu_import"].sensitive = true
624
624
 
625
- if @data.current.title.strip.empty? then
626
- @top_window.title = "%s %s" % [
627
- Version::PROGRAM_NAME.capitalize,
628
- Version::STRING]
629
- else
630
- @top_window.title = "%s: %s" % [
631
- Version::PROGRAM_NAME.capitalize,
632
- @data.current.title]
633
- end
634
-
635
- set_goto_menu
636
-
637
625
  # Gtk::ToggleButton#active= emits an activate signal
638
626
  # and thus calls on_edit_text_wrap_activate
639
627
  if @data.current.wrap then
@@ -646,10 +634,9 @@ def set_buttons
646
634
  end
647
635
 
648
636
  @top_window.focus = @glade["clip"]
649
- end #}}}1
637
+ end
650
638
 
651
639
  def set_style
652
- #{{{1
653
640
  @clip_widget.modify_text(Gtk::STATE_NORMAL,
654
641
  array_to_color(pref("foreground")))
655
642
  ###@clip_widget.modify_fg(Gtk::STATE_NORMAL,
@@ -658,7 +645,7 @@ def set_style
658
645
  @clip_widget.modify_base(Gtk::STATE_NORMAL,
659
646
  array_to_color(pref("background")))
660
647
  @clip_widget.modify_font(Pango::FontDescription.new(pref("font")))
661
- end #}}}1
648
+ end
662
649
 
663
650
 
664
651
  #
@@ -666,16 +653,14 @@ end #}}}1
666
653
  #
667
654
 
668
655
  def set_style_sample(fg_gdk_color, bg_gdk_color, font)
669
- #{{{1
670
656
  sample = @glade["entry_sample"]
671
657
 
672
658
  sample.modify_text(Gtk::STATE_NORMAL, fg_gdk_color) if fg_gdk_color
673
659
  sample.modify_base(Gtk::STATE_NORMAL, bg_gdk_color) if bg_gdk_color
674
660
  sample.modify_font(Pango::FontDescription.new(font)) if font
675
- end #}}}1
661
+ end
676
662
 
677
663
  def quit_app
678
- #{{{1
679
664
  if pref("confirm_quit") then
680
665
  msgbox = Gtk::MessageDialog.new(@top_window,
681
666
  Gtk::Dialog::MODAL,
@@ -701,10 +686,9 @@ def quit_app
701
686
  end
702
687
 
703
688
  Gtk.main_quit
704
- end #}}}1
689
+ end
705
690
 
706
691
  def set_about_dialog
707
- #{{{1
708
692
  dlg = @glade["about_dialog"]
709
693
  if dlg.respond_to? :program_name then
710
694
  dlg.program_name="#{Version::PROGRAM_NAME}"
@@ -714,17 +698,17 @@ def set_about_dialog
714
698
  #dlg.comments = "}"
715
699
  dlg.version="#{Version::STRING}"
716
700
  dlg.copyright="(C) #{Version::YEARS} #{Version::AUTHOR}"
701
+ dlg.copyright+="\nUsing #{Version.ruby_version} "+
702
+ "and #{Gui.gtk_version} on #{Version.platform}"
717
703
  dlg.website="#{Version::AUTHOR_WEBSITE}"
718
704
  dlg.license="#{Version::LICENSE}"
719
705
  dlg.authors=["#{Version::AUTHOR} <#{Version::AUTHOR_EMAIL}>"]
720
-
721
- end #}}}1
706
+ end
722
707
 
723
708
  def clip_to_widget(textview, clip_array)
724
- #{{{1
725
709
  print_debug "clip_to_widget"
726
710
  if clip_array.nil? then
727
- str = "#{Version::PROGRAM_NAME.capitalize} #{Version::STRING} ready\n\n"+
711
+ str = "#{Version::PROGRAM_NAME} #{Version::STRING} ready\n\n"+
728
712
  "Use Menu->New or Menu->Open\n"
729
713
  textview.buffer.text = str
730
714
  textview.editable = false
@@ -747,12 +731,10 @@ def clip_to_widget(textview, clip_array)
747
731
  textview.editable = true
748
732
  end
749
733
 
750
-
751
734
  @top_window.focus = @glade["clip"]
752
- end #}}}1
735
+ end
753
736
 
754
737
  def widget_to_clip(textview, clip_array)
755
- #{{{1
756
738
  print_debug "widget_to_clip"
757
739
  if clip_array then
758
740
  clip_array.current.text = textview.buffer.text
@@ -764,15 +746,74 @@ def widget_to_clip(textview, clip_array)
764
746
  clip_array.current.wrap = true
765
747
  end
766
748
  end
767
- end #}}}1
749
+ end
768
750
 
769
751
  def set_autosave
770
- #{{{1
771
- if @data and pref("autosave_enable") then
772
- @data.autosave(pref("autosave_seconds"))
752
+ if pref("autosave_enable") then
753
+ @next_autosave = Time.now + pref("autosave_seconds")
773
754
  end
774
- end #}}}1
755
+ end
756
+
757
+ def array_to_color(arr)
758
+ return Gdk::Color.new(arr[0],arr[1],arr[2])
759
+ end
760
+
761
+ def color_to_array(gdk_color)
762
+ return [gdk_color.red, gdk_color.green, gdk_color.blue]
763
+ end
764
+
765
+ def get_filename(filename, mode)
766
+ if filename.class == Symbol and filename == :ask then
767
+ case mode
768
+ when :save
769
+ action = Gtk::FileChooser::ACTION_SAVE
770
+ ok_button = Gtk::Stock::SAVE
771
+ when :open
772
+ action = Gtk::FileChooser::ACTION_OPEN
773
+ ok_button = Gtk::Stock::OPEN
774
+ else
775
+ raise "Wrong mode #{mode} in helper:get_filename"
776
+ end
775
777
 
776
- end # Class
778
+ title = "Select Filename"
777
779
 
778
- # vim: set foldmethod=marker:
780
+ dialog = Gtk::FileChooserDialog.new(
781
+ title,
782
+ nil,
783
+ action,
784
+ nil,
785
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
786
+ [ok_button, Gtk::Dialog::RESPONSE_ACCEPT])
787
+
788
+ case dialog.run
789
+ when Gtk::Dialog::RESPONSE_ACCEPT
790
+ filename = dialog.filename
791
+ else
792
+ filename = nil
793
+ end
794
+ dialog.destroy
795
+ end
796
+
797
+ if filename.nil? then
798
+ return
799
+ end
800
+
801
+ return filename
802
+ end
803
+
804
+ def update
805
+ widget_to_clip(@clip_widget, @data) if @data
806
+ set_buttons
807
+ set_title
808
+ end
809
+
810
+ def autosave
811
+ # do autosave if enabled and due
812
+ if @data and pref("autosave_enable") and Time.now >= @next_autosave then
813
+ print_verbose "autosaving at #{Time.now}"
814
+ @data.save
815
+ set_autosave
816
+ end
817
+ end
818
+
819
+ end # Class