rabbit 3.0.5 → 4.0.1

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.
Files changed (241) hide show
  1. checksums.yaml +4 -4
  2. data/data/locale/ja/LC_MESSAGES/rabbit.mo +0 -0
  3. data/doc/_config.yml +2 -2
  4. data/doc/en/news.rd +63 -0
  5. data/doc/ja/news.rd +63 -0
  6. data/lib/rabbit/actions.rb +446 -0
  7. data/lib/rabbit/author-configuration.rb +7 -10
  8. data/lib/rabbit/canvas.rb +74 -42
  9. data/lib/rabbit/command/rabbit-slide.rb +11 -13
  10. data/lib/rabbit/command/rabbit-theme.rb +10 -12
  11. data/lib/rabbit/command/rabbit.rb +31 -43
  12. data/lib/rabbit/console.rb +20 -22
  13. data/lib/rabbit/dependency-canvas.rb +2 -2
  14. data/lib/rabbit/element/base.rb +93 -6
  15. data/lib/rabbit/element/block-element.rb +17 -1
  16. data/lib/rabbit/element/block.rb +17 -1
  17. data/lib/rabbit/element/container-element.rb +59 -3
  18. data/lib/rabbit/element/description-list.rb +18 -2
  19. data/lib/rabbit/element/enum-list.rb +18 -2
  20. data/lib/rabbit/element/footnote.rb +18 -2
  21. data/lib/rabbit/element/image-title-slide.rb +17 -1
  22. data/lib/rabbit/element/image.rb +32 -2
  23. data/lib/rabbit/element/index-slide.rb +29 -13
  24. data/lib/rabbit/element/item-list.rb +18 -2
  25. data/lib/rabbit/element/method-list.rb +18 -2
  26. data/lib/rabbit/element/poppler-page.rb +17 -1
  27. data/lib/rabbit/element/poppler-slide.rb +18 -2
  28. data/lib/rabbit/element/poppler-title-slide.rb +18 -2
  29. data/lib/rabbit/element/preformatted.rb +18 -2
  30. data/lib/rabbit/element/slide-element.rb +29 -2
  31. data/lib/rabbit/element/slide.rb +18 -2
  32. data/lib/rabbit/element/syntax-highlighting.rb +17 -1
  33. data/lib/rabbit/element/table.rb +19 -3
  34. data/lib/rabbit/element/tag.rb +18 -2
  35. data/lib/rabbit/element/text-block-element.rb +18 -2
  36. data/lib/rabbit/element/text-container-element.rb +41 -2
  37. data/lib/rabbit/element/text-element.rb +17 -1
  38. data/lib/rabbit/element/text-renderer.rb +17 -1
  39. data/lib/rabbit/element/text.rb +4 -4
  40. data/lib/rabbit/element/title-slide.rb +19 -3
  41. data/lib/rabbit/element/video.rb +157 -56
  42. data/lib/rabbit/element.rb +20 -20
  43. data/lib/rabbit/formatter.rb +18 -1
  44. data/lib/rabbit/frame.rb +101 -93
  45. data/lib/rabbit/front.rb +11 -4
  46. data/lib/rabbit/gem-finder.rb +4 -8
  47. data/lib/rabbit/gem-pusher.rb +4 -4
  48. data/lib/rabbit/gesture/handler.rb +26 -21
  49. data/lib/rabbit/graffiti/config-dialog.rb +18 -2
  50. data/lib/rabbit/graffiti/processor.rb +20 -4
  51. data/lib/rabbit/gtk.rb +48 -14
  52. data/lib/rabbit/html/generator.rb +18 -18
  53. data/{test/helper/fixture.rb → lib/rabbit/icon.rb} +16 -6
  54. data/lib/rabbit/image/base.rb +7 -6
  55. data/lib/rabbit/image/default.rb +17 -1
  56. data/lib/rabbit/image/dia.rb +2 -2
  57. data/lib/rabbit/image/eps.rb +16 -2
  58. data/lib/rabbit/image/gimp.rb +28 -11
  59. data/lib/rabbit/image/mermaid.rb +3 -3
  60. data/lib/rabbit/image/pdf.rb +3 -3
  61. data/lib/rabbit/image/svg.rb +2 -2
  62. data/lib/rabbit/image.rb +8 -8
  63. data/lib/rabbit/info-window.rb +55 -18
  64. data/lib/rabbit/key-handler.rb +381 -0
  65. data/lib/rabbit/keys.rb +31 -2
  66. data/lib/rabbit/logger/base.rb +17 -1
  67. data/lib/rabbit/logger/gui.rb +20 -4
  68. data/lib/rabbit/logger/stderr.rb +16 -2
  69. data/lib/rabbit/logger.rb +4 -4
  70. data/lib/rabbit/menu.rb +200 -220
  71. data/lib/rabbit/parser/base.rb +17 -1
  72. data/lib/rabbit/parser/ext/aafigure.rb +17 -1
  73. data/lib/rabbit/parser/ext/blockdiag.rb +17 -1
  74. data/lib/rabbit/parser/ext/charty.rb +2 -2
  75. data/lib/rabbit/parser/ext/coderay.rb +20 -4
  76. data/lib/rabbit/parser/ext/enscript.rb +31 -15
  77. data/lib/rabbit/parser/ext/entity.rb +17 -1
  78. data/lib/rabbit/parser/ext/image.rb +6 -6
  79. data/lib/rabbit/parser/ext/inline.rb +17 -1
  80. data/lib/rabbit/parser/ext/rouge.rb +7 -4
  81. data/lib/rabbit/parser/ext/tex.rb +18 -2
  82. data/lib/rabbit/parser/ext/video.rb +4 -4
  83. data/lib/rabbit/parser/image.rb +20 -4
  84. data/lib/rabbit/parser/markdown/converter.rb +12 -13
  85. data/lib/rabbit/parser/markdown.rb +18 -2
  86. data/lib/rabbit/parser/pause-support.rb +1 -0
  87. data/lib/rabbit/parser/pdf.rb +3 -3
  88. data/lib/rabbit/parser/rd/ext/base.rb +20 -4
  89. data/lib/rabbit/parser/rd/ext/block-verbatim.rb +24 -28
  90. data/lib/rabbit/parser/rd/ext/character-reference.rb +18 -2
  91. data/lib/rabbit/parser/rd/ext/image.rb +3 -3
  92. data/lib/rabbit/parser/rd/ext/inline-verbatim.rb +6 -6
  93. data/lib/rabbit/parser/rd/ext/refer.rb +18 -2
  94. data/lib/rabbit/parser/rd/ext/video.rb +19 -2
  95. data/lib/rabbit/parser/rd/rd2rabbit-lib.rb +24 -8
  96. data/lib/rabbit/parser/rd/rt/rt2rabbit-lib.rb +18 -2
  97. data/lib/rabbit/parser/rd/visitor.rb +18 -2
  98. data/lib/rabbit/parser/rd.rb +18 -2
  99. data/lib/rabbit/parser/wiki/output.rb +25 -28
  100. data/lib/rabbit/parser/wiki.rb +18 -2
  101. data/lib/rabbit/parser.rb +6 -6
  102. data/lib/rabbit/path-manipulatable.rb +4 -4
  103. data/lib/rabbit/progress.rb +17 -1
  104. data/lib/rabbit/properties.rb +3 -3
  105. data/lib/rabbit/rabbit.rb +15 -7
  106. data/lib/rabbit/readme-parser.rb +4 -6
  107. data/lib/rabbit/renderer/base.rb +44 -36
  108. data/lib/rabbit/renderer/color.rb +18 -2
  109. data/lib/rabbit/renderer/display/base.rb +10 -12
  110. data/lib/rabbit/renderer/display/button-handler.rb +141 -60
  111. data/lib/rabbit/renderer/display/cursor.rb +4 -5
  112. data/lib/rabbit/renderer/display/drawing-area-base.rb +32 -48
  113. data/lib/rabbit/renderer/display/drawing-area-primitive.rb +10 -61
  114. data/lib/rabbit/renderer/display/drawing-area-view-only.rb +19 -8
  115. data/lib/rabbit/renderer/display/drawing-area.rb +19 -15
  116. data/lib/rabbit/renderer/display/gesture.rb +9 -9
  117. data/lib/rabbit/renderer/display/graffiti.rb +22 -13
  118. data/lib/rabbit/renderer/display/info.rb +22 -2
  119. data/lib/rabbit/renderer/display/magnifier.rb +30 -17
  120. data/lib/rabbit/renderer/display/mask.rb +17 -1
  121. data/lib/rabbit/renderer/display/menu.rb +27 -3
  122. data/lib/rabbit/renderer/display/motion-handler.rb +45 -0
  123. data/lib/rabbit/renderer/display/progress.rb +17 -2
  124. data/lib/rabbit/renderer/display/scroll-handler.rb +60 -13
  125. data/lib/rabbit/renderer/display/search.rb +19 -2
  126. data/lib/rabbit/renderer/display/spotlight.rb +39 -25
  127. data/lib/rabbit/renderer/display.rb +16 -36
  128. data/lib/rabbit/renderer/engine/cairo.rb +4 -11
  129. data/lib/rabbit/renderer/engine.rb +17 -1
  130. data/lib/rabbit/renderer/kernel.rb +2 -20
  131. data/lib/rabbit/renderer/offscreen.rb +8 -14
  132. data/lib/rabbit/renderer/print-layout.rb +2 -2
  133. data/lib/rabbit/renderer/printer.rb +9 -16
  134. data/lib/rabbit/renderer/scene-background-widget.rb +95 -0
  135. data/lib/rabbit/renderer/scene-node-widget.rb +63 -0
  136. data/lib/rabbit/renderer/scene.rb +508 -0
  137. data/lib/rabbit/renderer.rb +6 -6
  138. data/lib/rabbit/search-window.rb +18 -2
  139. data/lib/rabbit/searcher.rb +15 -1
  140. data/lib/rabbit/size.rb +9 -1
  141. data/lib/rabbit/slide-configuration.rb +11 -14
  142. data/lib/rabbit/soap/driver.rb +20 -4
  143. data/lib/rabbit/soap/server.rb +17 -1
  144. data/lib/rabbit/source/argf.rb +5 -5
  145. data/lib/rabbit/source/base.rb +5 -6
  146. data/lib/rabbit/source/file.rb +5 -5
  147. data/lib/rabbit/source/memory.rb +20 -4
  148. data/lib/rabbit/source/uri.rb +9 -11
  149. data/lib/rabbit/source-generator/hiki.rb +2 -7
  150. data/lib/rabbit/source-generator/markdown.rb +2 -7
  151. data/lib/rabbit/source-generator/rd.rb +2 -7
  152. data/lib/rabbit/source-generator.rb +4 -4
  153. data/lib/rabbit/source.rb +5 -5
  154. data/lib/rabbit/task/slide.rb +13 -11
  155. data/lib/rabbit/task/theme.rb +8 -11
  156. data/lib/rabbit/task.rb +3 -3
  157. data/lib/rabbit/theme/applier.rb +27 -11
  158. data/lib/rabbit/theme/clear-blue/clear-blue.rb +1 -1
  159. data/lib/rabbit/theme/color-circle/color-circle.rb +18 -1
  160. data/lib/rabbit/theme/cozmixng/cozmixng.rb +1 -1
  161. data/lib/rabbit/theme/default/default.rb +1 -0
  162. data/lib/rabbit/theme/default-icon/default-icon.rb +1 -1
  163. data/lib/rabbit/theme/default-item-mark-setup/default-item-mark-setup.rb +17 -1
  164. data/lib/rabbit/theme/default-preformatted/default-preformatted.rb +9 -1
  165. data/lib/rabbit/theme/enishi-green/enishi-green.rb +1 -1
  166. data/lib/rabbit/theme/entry.rb +10 -12
  167. data/lib/rabbit/theme/icon/icon.rb +3 -8
  168. data/lib/rabbit/theme/image-slide-number/image-slide-number.rb +5 -5
  169. data/lib/rabbit/theme/image-timer/image-timer.rb +3 -3
  170. data/lib/rabbit/theme/lightning-simple/lightning-simple.rb +1 -0
  171. data/lib/rabbit/theme/lightning-talk/lightning-talk.rb +1 -0
  172. data/lib/rabbit/theme/manager.rb +19 -9
  173. data/lib/rabbit/theme/rabbit-icon/rabbit-icon.rb +1 -1
  174. data/lib/rabbit/theme/ranguba/ranguba.rb +1 -1
  175. data/lib/rabbit/theme/red-frame/red-frame.rb +6 -2
  176. data/lib/rabbit/theme/ruby-gnome2/ruby-gnome2.rb +1 -0
  177. data/lib/rabbit/theme/ruby-gnome2-icon/ruby-gnome2-icon.rb +1 -1
  178. data/lib/rabbit/theme/searcher.rb +23 -7
  179. data/lib/rabbit/theme/slide-number/slide-number.rb +1 -1
  180. data/lib/rabbit/theme/slide-show/slide-show.rb +1 -1
  181. data/lib/rabbit/theme/table/table.rb +2 -2
  182. data/lib/rabbit/theme/video/property.rb +3 -0
  183. data/lib/rabbit/theme/video/video.rb +5 -0
  184. data/lib/rabbit/theme-configuration.rb +9 -11
  185. data/lib/rabbit/utils.rb +12 -94
  186. data/lib/rabbit/version.rb +1 -1
  187. data/lib/rabbit/xmlrpc/client.rb +17 -1
  188. data/lib/rabbit/xmlrpc/server.rb +17 -1
  189. data/po/en/rabbit.edit.po +324 -316
  190. data/po/en/rabbit.po +61 -55
  191. data/po/fr/rabbit.edit.po +324 -316
  192. data/po/fr/rabbit.po +61 -55
  193. data/po/ja/rabbit.edit.po +345 -370
  194. data/po/ja/rabbit.po +83 -80
  195. data/rabbit.gemspec +4 -2
  196. data/sample/block-quote.rab +13 -0
  197. data/sample/description-list.rab +17 -0
  198. data/sample/mermaid.rab +16 -0
  199. data/sample/rabbit-en.hiki +0 -1
  200. data/sample/rabbit-en.md +0 -1
  201. data/sample/rabbit-en.rd +0 -1
  202. data/sample/rabbit.hiki +0 -1
  203. data/sample/rabbit.md +0 -1
  204. data/sample/rabbit.rd +0 -1
  205. data/sample/video.rab +17 -0
  206. metadata +33 -65
  207. data/lib/rabbit/action/basic.rb +0 -304
  208. data/lib/rabbit/action/radio.rb +0 -78
  209. data/lib/rabbit/action/toggle.rb +0 -82
  210. data/lib/rabbit/action.rb +0 -140
  211. data/lib/rabbit/renderer/display/gl.rb +0 -98
  212. data/lib/rabbit/renderer/display/key-handler.rb +0 -321
  213. data/lib/rabbit/renderer/gl.rb +0 -95
  214. data/lib/rabbit/renderer/screen.rb +0 -286
  215. data/lib/rabbit/renderer/widget/drawing-area.rb +0 -93
  216. data/lib/rabbit/stock.rb +0 -31
  217. data/lib/rabbit/trackball.rb +0 -228
  218. data/lib/rabbit/video-window.rb +0 -123
  219. data/test/command/test-rabbit.rb +0 -101
  220. data/test/helper/parser.rb +0 -48
  221. data/test/helper.rb +0 -24
  222. data/test/image/test-dia.rb +0 -54
  223. data/test/image/test-eps.rb +0 -41
  224. data/test/parser/test-markdown.rb +0 -360
  225. data/test/parser/test-rd.rb +0 -43
  226. data/test/parser/test-wiki.rb +0 -71
  227. data/test/run-test.rb +0 -27
  228. data/test/source-generator/test-hiki.rb +0 -68
  229. data/test/source-generator/test-markdown.rb +0 -67
  230. data/test/source-generator/test-rd.rb +0 -69
  231. data/test/test-applier.rb +0 -73
  232. data/test/test-author-configuration.rb +0 -37
  233. data/test/test-canvas.rb +0 -70
  234. data/test/test-color.rb +0 -51
  235. data/test/test-element.rb +0 -103
  236. data/test/test-readme-parser.rb +0 -160
  237. data/test/test-size.rb +0 -155
  238. data/test/test-slide-configuration.rb +0 -74
  239. data/test/test-source.rb +0 -122
  240. data/test/test-theme-configuration.rb +0 -47
  241. data/test/test-utils.rb +0 -64
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2004-2017 Kouhei Sutou <kou@cozmixng.org>
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
2
  #
3
3
  # This program is free software; you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
16
16
 
17
17
  require "rsvg2"
18
18
 
19
- require "rabbit/image/base"
19
+ require_relative "base"
20
20
 
21
21
  unless Object.const_defined?(:Rsvg)
22
22
  Rsvg = RSVG
data/lib/rabbit/image.rb CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2004-2020 Sutou Kouhei <kou@cozmixng.org>
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
2
  #
3
3
  # This program is free software; you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -17,13 +17,13 @@
17
17
  require "forwardable"
18
18
  require "tempfile"
19
19
 
20
- require "rabbit/image/default"
21
- require "rabbit/image/dia"
22
- require "rabbit/image/eps"
23
- require "rabbit/image/gimp"
24
- require "rabbit/image/mermaid"
25
- require "rabbit/image/pdf"
26
- require "rabbit/image/svg"
20
+ require_relative "image/default"
21
+ require_relative "image/dia"
22
+ require_relative "image/eps"
23
+ require_relative "image/gimp"
24
+ require_relative "image/mermaid"
25
+ require_relative "image/pdf"
26
+ require_relative "image/svg"
27
27
 
28
28
  module Rabbit
29
29
  module ImageManipulable
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2006-2023 Sutou Kouhei <kou@cozmixng.org>
1
+ # Copyright (C) 2006-2025 Sutou Kouhei <kou@cozmixng.org>
2
2
  #
3
3
  # This program is free software; you can redistribute it and/or modify
4
4
  # it under the terms of the GNU General Public License as published by
@@ -14,21 +14,20 @@
14
14
  # with this program; if not, write to the Free Software Foundation, Inc.,
15
15
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
16
 
17
- require 'rabbit/gtk'
18
- require 'rabbit/dependency-canvas'
19
- require 'rabbit/renderer/display/drawing-area-view-only'
20
- require 'rabbit/renderer/display/hook-handler'
21
- require 'rabbit/renderer/display/key-handler'
22
- require 'rabbit/renderer/display/button-handler'
23
- require 'rabbit/renderer/display/scroll-handler'
24
- require 'rabbit/renderer/display/menu'
17
+ require_relative "gtk"
18
+ require_relative "dependency-canvas"
19
+ require_relative "rabbit"
20
+ require_relative "renderer/display/drawing-area-view-only"
21
+ require_relative "renderer/display/hook-handler"
22
+ require_relative "renderer/display/button-handler"
23
+ require_relative "renderer/display/scroll-handler"
24
+ require_relative "renderer/display/menu"
25
25
 
26
26
  module Rabbit
27
27
  class InfoWindow
28
28
  include GetText
29
29
 
30
30
  include Renderer::Display::HookHandler
31
- include Renderer::Display::KeyHandler
32
31
  include Renderer::Display::ButtonHandler
33
32
  include Renderer::Display::ScrollHandler
34
33
  include Renderer::Display::Menu
@@ -39,7 +38,6 @@ module Rabbit
39
38
  @timer_id = nil
40
39
  @note_area = nil
41
40
  init_hook_handler
42
- init_key_handler
43
41
  init_button_handler
44
42
  init_scroll_handler
45
43
  end
@@ -55,13 +53,21 @@ module Rabbit
55
53
  def hide
56
54
  return unless showing?
57
55
  detach_menu(@window)
58
- detach_key(@window)
59
56
  each do |canvas|
60
57
  canvas.detach
61
58
  end
59
+ if @window_notify_id
60
+ @window.signal_handler_disconnect(@window_notify_id)
61
+ end
62
+ if @window_configure_event_id
63
+ @window.signal_handler_disconnect(@window_configure_event_id)
64
+ end
62
65
  @window.signal_handler_disconnect(@window_destroy_id)
63
66
  @window.destroy
64
- @window = @window_destroy_id = nil
67
+ @window = nil
68
+ @window_notify_id = nil
69
+ @window_configure_event_id = nil
70
+ @window_destroy_id = nil
65
71
  @canvas_widgets = @grid = nil
66
72
  GLib::Source.remove(@timer_id) if @timer_id
67
73
  @timer_id = nil
@@ -106,12 +112,44 @@ module Rabbit
106
112
  end
107
113
 
108
114
  def make_canvas
109
- DependencyCanvas.new(@canvas, @canvas.logger,
110
- Renderer::Display::DrawingAreaViewOnly)
115
+ DependencyCanvas.new(@canvas, Renderer::Display::DrawingAreaViewOnly)
111
116
  end
112
117
 
113
118
  def init_window(width, height)
114
119
  @window = Gtk::Window.new
120
+ @window_notify_id = nil
121
+ @window_configure_event_id = nil
122
+ update_size = lambda do |new_width, new_height|
123
+ if on_note_mode?
124
+ @current_canvas.renderer.update_size(new_width / 2.0,
125
+ new_height / 2.0)
126
+ @previous_canvas.renderer.update_size(new_width / 4.0,
127
+ new_height / 2.0)
128
+ @next_canvas.renderer.update_size(new_width / 4.0,
129
+ new_height / 2.0)
130
+ else
131
+ @current_canvas.renderer.update_size(new_width / 2.0,
132
+ new_height * (2.0 / 3.0))
133
+ @previous_canvas.renderer.update_size(new_width / 4.0,
134
+ new_height / 3.0)
135
+ @next_canvas.renderer.update_size(new_width / 4.0,
136
+ new_height / 3.0)
137
+ end
138
+ end
139
+ if @window.class.signals.include?("configure-event")
140
+ @window_configure_event_id = @window.signal_connect(:configure_event) do |_, event|
141
+ update_size.call(event.width, event.height)
142
+ false
143
+ end
144
+ else
145
+ @window_notify_id = @window.signal_connect(:notify) do |_, param|
146
+ case param.name
147
+ when "default-width", "default-height"
148
+ update_size.call(@window.default_width,
149
+ @window.default_height)
150
+ end
151
+ end
152
+ end
115
153
  @window_destroy_id = @window.signal_connect("destroy") do
116
154
  @canvas.activate("ToggleInfoWindow")
117
155
  Gdk::Event::PROPAGATE
@@ -124,7 +162,6 @@ module Rabbit
124
162
  init_widgets
125
163
  end
126
164
  init_menu
127
- attach_key(@window)
128
165
  attach_menu(@window)
129
166
  event_mask = Gdk::EventMask::BUTTON_PRESS_MASK
130
167
  event_mask |= Gdk::EventMask::BUTTON_RELEASE_MASK
@@ -340,7 +377,7 @@ module Rabbit
340
377
 
341
378
  def update_source
342
379
  each do |canvas|
343
- source = Source::Memory.new("UTF-8", @canvas.logger)
380
+ source = Source::Memory.new("UTF-8")
344
381
  @canvas.source_force_modified(true) do |original_source|
345
382
  source.source = original_source.read
346
383
  source.base = original_source.base
@@ -363,7 +400,7 @@ module Rabbit
363
400
  @current_canvas.move_to_if_can(base_index)
364
401
  @current_canvas.current_slide.drawing_index =
365
402
  @canvas.current_slide.drawing_index
366
- @next_canvas.move_to_if_can([base_index + 1, @canvas.slide_size - 1].min)
403
+ @next_canvas.move_to_if_can([base_index + 1, @canvas.n_slides - 1].min)
367
404
  end
368
405
 
369
406
  def toggle_index_mode
@@ -0,0 +1,381 @@
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ require_relative "gtk"
18
+ require_relative "keys"
19
+
20
+ module Rabbit
21
+ class KeyHandler
22
+ def initialize(canvas, window)
23
+ @canvas = canvas
24
+ @window = window
25
+ init
26
+ end
27
+
28
+ if Gtk.const_defined?(:ShortcutController)
29
+ def connect_key(keyval, modifier, flags, &block)
30
+ trigger = Gtk::KeyvalTrigger.new(keyval, modifier)
31
+ action = Gio::SimpleAction.new
32
+ action.signal_connect do
33
+ block.call
34
+ end
35
+ shortcut = Gtk::Shortcut.new(trigger, action)
36
+ @user_shortcuts.append(shortcut)
37
+ end
38
+
39
+ def disconnect_key(keyval, modifier)
40
+ @user_shortcuts.each_with_index do |shortcut, i |
41
+ if shortcut.keyval == keyval and shortcut.modifier == modifier
42
+ @user_shortcuts.remove(i)
43
+ break
44
+ end
45
+ end
46
+ end
47
+
48
+ def pre_terminal
49
+ @window.remove_controller(@user_shortcut_controller)
50
+ @window.remove_controller(@shortcut_controller)
51
+ end
52
+
53
+ def post_terminal
54
+ @window.add_controller(@shortcut_controller)
55
+ @window.add_controller(@user_shortcut_controller)
56
+ end
57
+
58
+ def clear
59
+ super
60
+ clear_user_shortcuts
61
+ end
62
+
63
+ def detach
64
+ @window.insert_action_group("rabbit", nil)
65
+ @window.remove_controller(@user_shortcut_controller)
66
+ @window.remove_controller(@toggle_terminal_controller)
67
+ @window.remove_controller(@shortcut_controller)
68
+ end
69
+
70
+ private
71
+ def init
72
+ @user_shortcuts = Gio::ListStore.new(Gtk::Shortcut)
73
+ @user_shortcut_controller =
74
+ Gtk::ShortcutController.new(@user_shortcuts)
75
+ init_shortcuts
76
+ init_toggle_terminal_shortcuts
77
+ attach
78
+ end
79
+
80
+ def clear_user_shortcuts
81
+ @user_shortcuts.remove_all
82
+ end
83
+
84
+ def attach
85
+ @window.insert_action_group("rabbit", @canvas.actions.group)
86
+ @window.add_controller(@shortcut_controller)
87
+ @window.add_controller(@toggle_terminal_shortcut_controller)
88
+ @window.add_controller(@user_shortcut_controller)
89
+ end
90
+
91
+ def init_shortcuts
92
+ @shortcuts = Gio::ListStore.new(Gtk::Shortcut)
93
+ @shortcut_controller = Gtk::ShortcutController.new(@shortcuts)
94
+ init_keys
95
+ end
96
+
97
+ def init_toggle_terminal_shortcuts
98
+ @toggle_terminal_shortcuts = Gio::ListStore.new(Gtk::Shortcut)
99
+ @toggle_terminal_shortcut_controller =
100
+ Gtk::ShortcutController.new(@toggle_terminal_shortcuts)
101
+ keys = Keys::ShiftControlAlt::TOGGLE_TERMINAL_KEYS
102
+ modifiers = Gdk::ModifierType::SHIFT_MASK |
103
+ Gdk::ModifierType::CONTROL_MASK |
104
+ Gdk::ModifierType::ALT_MASK
105
+ set_keys("ToggleTerminal",
106
+ nil,
107
+ keys,
108
+ modifiers,
109
+ @toggle_terminal_shortcuts)
110
+ end
111
+
112
+ def set_keys(action_name,
113
+ action_arguments,
114
+ keys,
115
+ modifiers,
116
+ shortcuts=@shortcuts)
117
+ keys.each do |key|
118
+ trigger = Gtk::KeyvalTrigger.new(key, modifiers)
119
+ action = Gtk::NamedAction.new("rabbit.#{action_name}")
120
+ shortcut = Gtk::Shortcut.new(trigger, action)
121
+ shortcut.arguments = action_arguments
122
+ shortcuts.append(shortcut)
123
+ end
124
+ end
125
+ else
126
+ def connect_key(keyval, modifier, flags, &block)
127
+ @user_accel_group.connect(keyval, modifier, flags, &block)
128
+ end
129
+
130
+ def disconnect_key(keyval, modifier)
131
+ @user_accel_group.disconnect_key(keyval, modifier)
132
+ end
133
+
134
+ def pre_terminal
135
+ @window.remove_accel_group(@accel_group)
136
+ end
137
+
138
+ def post_terminal
139
+ @window.add_accel_group(@accel_group)
140
+ end
141
+
142
+ def detach
143
+ @window.signal_handler_disconnect(@key_press_event_id)
144
+ @key_press_event_id = nil
145
+ @window.remove_accel_group(@accel_group)
146
+ @window.remove_accel_group(@toggle_terminal_accel_group)
147
+ end
148
+
149
+ def clear
150
+ @window.remove_accel_group(@user_accel_group) if @user_accel_group
151
+ clear_user_accel_group
152
+ @window.add_accel_group(@user_accel_group)
153
+ end
154
+
155
+ private
156
+ def init
157
+ @user_accel_group = nil
158
+ init_accel_group
159
+ init_toggle_terminal_accel_group
160
+ attach
161
+ end
162
+
163
+ def clear_user_accel_group
164
+ @user_accel_group = Gtk::AccelGroup.new
165
+ end
166
+
167
+ def attach
168
+ @window.add_accel_group(@accel_group)
169
+ @window.add_accel_group(@toggle_terminal_accel_group)
170
+ set_key_press_event
171
+ end
172
+
173
+ def init_accel_group
174
+ @accel_group = Gtk::AccelGroup.new
175
+ init_keys
176
+ end
177
+
178
+ def init_toggle_terminal_accel_group
179
+ @toggle_terminal_accel_group = Gtk::AccelGroup.new
180
+ mod = Gdk::ModifierType::SHIFT_MASK |
181
+ Gdk::ModifierType::CONTROL_MASK |
182
+ Gdk::ModifierType::ALT_MASK
183
+ keys = Keys::ShiftControlAlt::TOGGLE_TERMINAL_KEYS
184
+ set_keys("ToggleTerminal",
185
+ nil,
186
+ keys,
187
+ mod,
188
+ nil,
189
+ @toggle_terminal_accel_group)
190
+ end
191
+
192
+ def set_keys(action_name,
193
+ action_arguments,
194
+ keys,
195
+ mod,
196
+ flags=nil,
197
+ accel_group=@accel_group)
198
+ flags ||= Gtk::AccelFlags::VISIBLE
199
+ keys.each do |val|
200
+ accel_group.connect(val, mod, flags) do |group, obj, val, modifier|
201
+ if action_arguments
202
+ @canvas.activate(action_name, action_arguments)
203
+ else
204
+ @canvas.activate(action_name)
205
+ end
206
+ end
207
+ end
208
+ end
209
+
210
+ def set_key_press_event
211
+ # We can't use Gtk::AccelGroup with unmodified direction
212
+ # keys. See gtk_accelerator_valid() for details.
213
+ prev_keys = [
214
+ Gdk::Keyval::KEY_Up,
215
+ Gdk::Keyval::KEY_Left,
216
+ Gdk::Keyval::KEY_KP_Up,
217
+ Gdk::Keyval::KEY_KP_Left,
218
+ ]
219
+ next_keys = [
220
+ Gdk::Keyval::KEY_Right,
221
+ Gdk::Keyval::KEY_Down,
222
+ Gdk::Keyval::KEY_KP_Right,
223
+ Gdk::Keyval::KEY_KP_Down,
224
+ ]
225
+ @key_press_event_id = @window.signal_connect("key_press_event") do |_widget, event|
226
+ handled = true
227
+ modifier = event.state
228
+ case event.keyval
229
+ when *prev_keys
230
+ if have_slide_number_related_mask?(modifier)
231
+ index = calc_slide_number(0, modifier)
232
+ @canvas.activate("JumpToRelativeSlide",
233
+ GLib::Variant.new(-index, "i"))
234
+ else
235
+ @canvas.activate("PreviousSlide")
236
+ end
237
+ when *next_keys
238
+ if have_slide_number_related_mask?(modifier)
239
+ index = calc_slide_number(0, modifier)
240
+ @canvas.activate("JumpToRelativeSlide",
241
+ GLib::Variant.new(index, "i"))
242
+ else
243
+ @canvas.activate("NextSlide")
244
+ end
245
+ else
246
+ handled = false
247
+ end
248
+ handled
249
+ end
250
+ end
251
+ end
252
+
253
+ def init_keys
254
+ init_move_slide_keys
255
+ init_no_prefix_keys
256
+ init_shift_keys
257
+ init_control_keys
258
+ init_alt_keys
259
+ end
260
+
261
+ def have_slide_number_related_mask?(modifier)
262
+ modifier.control_mask? or
263
+ modifier.alt_mask?
264
+ end
265
+
266
+ def calc_slide_number(val, modifier)
267
+ val += 10 if modifier.control_mask?
268
+ val += 20 if modifier.alt_mask?
269
+ val
270
+ end
271
+
272
+ def init_move_slide_keys
273
+ no_mod = Gdk::ModifierType.new
274
+ mods = Utils.power_set([
275
+ Gdk::ModifierType::CONTROL_MASK,
276
+ Gdk::ModifierType::ALT_MASK,
277
+ ])
278
+ mods.each do |mod|
279
+ mod = mod.inject(no_mod) do |result, item|
280
+ result | item
281
+ end
282
+ (0..9).each do |i|
283
+ key = Gdk::Keyval.const_get("KEY_#{i}")
284
+ index = calc_slide_number(i, mod)
285
+ set_keys("JumpToSlide", GLib::Variant.new(index, "i"), [key], mod)
286
+ end
287
+ (0..9).each do |i|
288
+ key = Gdk::Keyval.const_get("KEY_KP_#{i}")
289
+ index = calc_slide_number(i, mod)
290
+ set_keys("JumpToSlide", GLib::Variant.new(index, "i"), [key], mod)
291
+ end
292
+ if mod == no_mod
293
+ set_keys("NextSlide",
294
+ nil,
295
+ Keys::MOVE_TO_NEXT_SLIDE_KEYS,
296
+ mod)
297
+ set_keys("PreviousSlide",
298
+ nil,
299
+ Keys::MOVE_TO_PREVIOUS_SLIDE_KEYS,
300
+ mod)
301
+ else
302
+ set_keys("JumpToRelativeSlide",
303
+ GLib::Variant.new(calc_slide_number(0, mod), "i"),
304
+ Keys::MOVE_TO_NEXT_SLIDE_KEYS,
305
+ mod)
306
+ set_keys("JumpToRelativeSlide",
307
+ GLib::Variant.new(-calc_slide_number(0, mod), "i"),
308
+ Keys::MOVE_TO_PREVIOUS_SLIDE_KEYS,
309
+ mod)
310
+ end
311
+ end
312
+ end
313
+
314
+ def init_no_prefix_keys
315
+ mod = Gdk::ModifierType.new
316
+ [
317
+ ["Quit", Keys::QUIT_KEYS],
318
+ ["Next", Keys::MOVE_TO_NEXT_KEYS],
319
+ ["Previous", Keys::MOVE_TO_PREVIOUS_KEYS],
320
+ ["FirstSlide", Keys::MOVE_TO_FIRST_KEYS],
321
+ ["LastSlide", Keys::MOVE_TO_LAST_KEYS],
322
+ ["ToggleFullscreen", Keys::TOGGLE_FULLSCREEN_KEYS],
323
+ ["ReloadTheme", Keys::RELOAD_THEME_KEYS],
324
+ ["SaveAsImage", Keys::SAVE_AS_IMAGE_KEYS],
325
+ ["Iconify", Keys::ICONIFY_KEYS],
326
+ ["ToggleIndexMode", Keys::TOGGLE_INDEX_MODE_KEYS],
327
+ ["CacheAllSlides", Keys::CACHE_ALL_SLIDES_KEYS],
328
+ ["SearchSlideForward", Keys::SEARCH_SLIDE_FORWARD_KEYS],
329
+ ["SearchSlideBackward", Keys::SEARCH_SLIDE_BACKWARD_KEYS],
330
+ ["SearchSlideForwardNext", Keys::SEARCH_SLIDE_FORWARD_NEXT_KEYS],
331
+ ].each do |action_name, keys|
332
+ set_keys(action_name, nil, keys, mod)
333
+ end
334
+ end
335
+
336
+ def init_shift_keys
337
+ mod = Gdk::ModifierType::SHIFT_MASK
338
+ [
339
+ ["ToggleWhiteout", Keys::Shift::WHITE_OUT_KEYS],
340
+ ["ToggleBlackout", Keys::Shift::BLACK_OUT_KEYS],
341
+ ["ExpandHole", Keys::Shift::EXPAND_HOLE_KEYS],
342
+ ["NarrowHole", Keys::Shift::NARROW_HOLE_KEYS],
343
+ ["ToggleGraffitiMode", Keys::Shift::TOGGLE_GRAFFITI_MODE_KEYS],
344
+ ["SearchSlideBackwardNext",
345
+ Keys::Shift::SEARCH_SLIDE_BACKWARD_NEXT_KEYS],
346
+ ["ToggleInfoWindow", Keys::Shift::TOGGLE_INFO_WINDOW_KEYS],
347
+ ].each do |action_name, keys|
348
+ set_keys(action_name, nil, keys, mod)
349
+ end
350
+ end
351
+
352
+ def init_control_keys
353
+ mod = Gdk::ModifierType::CONTROL_MASK
354
+ [
355
+ ["ClearGraffiti", Keys::Control::CLEAR_GRAFFITI_KEYS],
356
+ ["UndoGraffiti", Keys::Control::UNDO_GRAFFITI_KEYS],
357
+ ["ClearSlide", Keys::Control::CLEAR_SLIDE_KEYS],
358
+ ["Print", Keys::Control::PRINT_KEYS],
359
+ ["SearchSlideForward", Keys::Control::SEARCH_SLIDE_FORWARD_KEYS],
360
+ ["SearchSlideBackward", Keys::Control::SEARCH_SLIDE_BACKWARD_KEYS],
361
+ ["SearchSlideForwardNext",
362
+ Keys::Control::SEARCH_SLIDE_FORWARD_NEXT_KEYS],
363
+ ["SearchSlideBackwardNext",
364
+ Keys::Control::SEARCH_SLIDE_BACKWARD_NEXT_KEYS],
365
+ ["StopSlideSearch", Keys::Control::STOP_SLIDE_SEARCH_KEYS],
366
+ ].each do |action_name, keys|
367
+ set_keys(action_name, nil, keys, mod)
368
+ end
369
+ end
370
+
371
+ def init_alt_keys
372
+ mod = Gdk::ModifierType::ALT_MASK
373
+ [
374
+ ["ResetAdjustment", Keys::Alt::RESET_ADJUSTMENT_KEYS],
375
+ ["ResetTimer", Keys::Alt::RESET_TIMER_KEYS],
376
+ ].each do |action_name, keys|
377
+ set_keys(action_name, nil, keys, mod)
378
+ end
379
+ end
380
+ end
381
+ end
data/lib/rabbit/keys.rb CHANGED
@@ -1,5 +1,20 @@
1
- require "rabbit/gtk"
2
- require "rabbit/utils"
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ require_relative "gtk"
3
18
 
4
19
  module Rabbit
5
20
  module Keys
@@ -27,6 +42,13 @@ module Rabbit
27
42
  Gdk::Keyval::KEY_KP_Tab,
28
43
  ]
29
44
 
45
+ MOVE_TO_NEXT_SLIDE_KEYS = [
46
+ Gdk::Keyval::KEY_Right,
47
+ Gdk::Keyval::KEY_Down,
48
+ Gdk::Keyval::KEY_KP_Right,
49
+ Gdk::Keyval::KEY_KP_Down,
50
+ ]
51
+
30
52
  MOVE_TO_PREVIOUS_KEYS = [
31
53
  Gdk::Keyval::KEY_p,
32
54
  Gdk::Keyval::KEY_b,
@@ -43,6 +65,13 @@ module Rabbit
43
65
  Gdk::Keyval::KEY_KP_Delete,
44
66
  ]
45
67
 
68
+ MOVE_TO_PREVIOUS_SLIDE_KEYS = [
69
+ Gdk::Keyval::KEY_Left,
70
+ Gdk::Keyval::KEY_Up,
71
+ Gdk::Keyval::KEY_KP_Left,
72
+ Gdk::Keyval::KEY_KP_Up,
73
+ ]
74
+
46
75
  MOVE_TO_FIRST_KEYS = [
47
76
  Gdk::Keyval::KEY_a,
48
77
  Gdk::Keyval::KEY_Home,
@@ -1,4 +1,20 @@
1
- require "rabbit/gettext"
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ require_relative "../gettext"
2
18
 
3
19
  module Rabbit
4
20
  module Logger
@@ -1,7 +1,23 @@
1
- require "rabbit/gtk"
2
-
3
- require "rabbit/keys"
4
- require "rabbit/logger/base"
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+
17
+ require_relative "../gtk"
18
+
19
+ require_relative "../keys"
20
+ require_relative "base"
5
21
 
6
22
  module Rabbit
7
23
  module Logger
@@ -1,6 +1,20 @@
1
- require "glib2"
1
+ # Copyright (C) 2004-2025 Sutou Kouhei <kou@cozmixng.org>
2
+ #
3
+ # This program is free software; you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation; either version 2 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License along
14
+ # with this program; if not, write to the Free Software Foundation, Inc.,
15
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2
16
 
3
- require "rabbit/logger/base"
17
+ require_relative "base"
4
18
 
5
19
  module Rabbit
6
20
  module Logger