origami 1.2.7 → 2.0.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.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/README.md +112 -0
  4. data/bin/config/pdfcop.conf.yml +232 -233
  5. data/bin/gui/about.rb +27 -37
  6. data/bin/gui/config.rb +108 -117
  7. data/bin/gui/file.rb +416 -365
  8. data/bin/gui/gtkhex.rb +1138 -1153
  9. data/bin/gui/hexview.rb +55 -57
  10. data/bin/gui/imgview.rb +48 -51
  11. data/bin/gui/menu.rb +388 -386
  12. data/bin/gui/properties.rb +114 -130
  13. data/bin/gui/signing.rb +571 -617
  14. data/bin/gui/textview.rb +77 -95
  15. data/bin/gui/treeview.rb +382 -387
  16. data/bin/gui/walker.rb +227 -232
  17. data/bin/gui/xrefs.rb +56 -60
  18. data/bin/pdf2pdfa +53 -57
  19. data/bin/pdf2ruby +212 -228
  20. data/bin/pdfcop +338 -348
  21. data/bin/pdfdecompress +58 -65
  22. data/bin/pdfdecrypt +56 -60
  23. data/bin/pdfencrypt +75 -80
  24. data/bin/pdfexplode +185 -182
  25. data/bin/pdfextract +201 -218
  26. data/bin/pdfmetadata +83 -82
  27. data/bin/pdfsh +4 -5
  28. data/bin/pdfwalker +1 -2
  29. data/bin/shell/.irbrc +45 -82
  30. data/bin/shell/console.rb +105 -130
  31. data/bin/shell/hexdump.rb +40 -64
  32. data/examples/README.md +34 -0
  33. data/examples/attachments/attachment.rb +38 -0
  34. data/examples/attachments/nested_document.rb +51 -0
  35. data/examples/encryption/encryption.rb +28 -0
  36. data/{samples/actions/triggerevents/trigger.rb → examples/events/events.rb} +13 -16
  37. data/examples/flash/flash.rb +37 -0
  38. data/{samples → examples}/flash/helloworld.swf +0 -0
  39. data/examples/forms/javascript.rb +54 -0
  40. data/examples/forms/xfa.rb +115 -0
  41. data/examples/javascript/hello_world.rb +22 -0
  42. data/examples/javascript/js_emulation.rb +54 -0
  43. data/examples/loop/goto.rb +32 -0
  44. data/examples/loop/named.rb +33 -0
  45. data/examples/signature/signature.rb +65 -0
  46. data/examples/uri/javascript.rb +56 -0
  47. data/examples/uri/open-uri.rb +21 -0
  48. data/examples/uri/submitform.rb +47 -0
  49. data/lib/origami.rb +29 -42
  50. data/lib/origami/3d.rb +350 -225
  51. data/lib/origami/acroform.rb +262 -288
  52. data/lib/origami/actions.rb +268 -288
  53. data/lib/origami/annotations.rb +697 -722
  54. data/lib/origami/array.rb +258 -184
  55. data/lib/origami/boolean.rb +74 -84
  56. data/lib/origami/catalog.rb +397 -434
  57. data/lib/origami/collections.rb +144 -0
  58. data/lib/origami/destinations.rb +233 -194
  59. data/lib/origami/dictionary.rb +253 -232
  60. data/lib/origami/encryption.rb +1274 -1243
  61. data/lib/origami/export.rb +232 -268
  62. data/lib/origami/extensions/fdf.rb +307 -220
  63. data/lib/origami/extensions/ppklite.rb +368 -435
  64. data/lib/origami/filespec.rb +197 -0
  65. data/lib/origami/filters.rb +301 -295
  66. data/lib/origami/filters/ascii.rb +177 -180
  67. data/lib/origami/filters/ccitt.rb +528 -535
  68. data/lib/origami/filters/crypt.rb +26 -35
  69. data/lib/origami/filters/dct.rb +46 -52
  70. data/lib/origami/filters/flate.rb +95 -94
  71. data/lib/origami/filters/jbig2.rb +49 -55
  72. data/lib/origami/filters/jpx.rb +38 -44
  73. data/lib/origami/filters/lzw.rb +189 -183
  74. data/lib/origami/filters/predictors.rb +221 -235
  75. data/lib/origami/filters/runlength.rb +103 -104
  76. data/lib/origami/font.rb +173 -186
  77. data/lib/origami/functions.rb +67 -81
  78. data/lib/origami/graphics.rb +25 -21
  79. data/lib/origami/graphics/colors.rb +178 -187
  80. data/lib/origami/graphics/instruction.rb +79 -85
  81. data/lib/origami/graphics/path.rb +142 -148
  82. data/lib/origami/graphics/patterns.rb +160 -167
  83. data/lib/origami/graphics/render.rb +43 -50
  84. data/lib/origami/graphics/state.rb +138 -153
  85. data/lib/origami/graphics/text.rb +188 -205
  86. data/lib/origami/graphics/xobject.rb +819 -815
  87. data/lib/origami/header.rb +63 -78
  88. data/lib/origami/javascript.rb +596 -597
  89. data/lib/origami/linearization.rb +285 -290
  90. data/lib/origami/metadata.rb +139 -148
  91. data/lib/origami/name.rb +112 -148
  92. data/lib/origami/null.rb +53 -62
  93. data/lib/origami/numeric.rb +162 -175
  94. data/lib/origami/obfuscation.rb +186 -174
  95. data/lib/origami/object.rb +593 -573
  96. data/lib/origami/outline.rb +42 -47
  97. data/lib/origami/outputintents.rb +73 -82
  98. data/lib/origami/page.rb +703 -592
  99. data/lib/origami/parser.rb +238 -290
  100. data/lib/origami/parsers/fdf.rb +41 -33
  101. data/lib/origami/parsers/pdf.rb +75 -95
  102. data/lib/origami/parsers/pdf/lazy.rb +137 -0
  103. data/lib/origami/parsers/pdf/linear.rb +64 -66
  104. data/lib/origami/parsers/ppklite.rb +34 -70
  105. data/lib/origami/pdf.rb +1030 -1005
  106. data/lib/origami/reference.rb +102 -102
  107. data/lib/origami/signature.rb +591 -609
  108. data/lib/origami/stream.rb +668 -551
  109. data/lib/origami/string.rb +397 -373
  110. data/lib/origami/template/patterns.rb +56 -0
  111. data/lib/origami/template/widgets.rb +151 -0
  112. data/lib/origami/trailer.rb +144 -158
  113. data/lib/origami/tree.rb +62 -0
  114. data/lib/origami/version.rb +23 -0
  115. data/lib/origami/webcapture.rb +88 -79
  116. data/lib/origami/xfa.rb +2863 -2882
  117. data/lib/origami/xreftable.rb +472 -384
  118. data/test/dataset/calc.pdf +85 -0
  119. data/test/dataset/crypto.pdf +82 -0
  120. data/test/dataset/empty.pdf +49 -0
  121. data/test/test_actions.rb +27 -0
  122. data/test/test_annotations.rb +90 -0
  123. data/test/test_pages.rb +31 -0
  124. data/test/test_pdf.rb +16 -0
  125. data/test/test_pdf_attachment.rb +34 -0
  126. data/test/test_pdf_create.rb +24 -0
  127. data/test/test_pdf_encrypt.rb +95 -0
  128. data/test/test_pdf_parse.rb +96 -0
  129. data/test/test_pdf_sign.rb +58 -0
  130. data/test/test_streams.rb +182 -0
  131. data/test/test_xrefs.rb +67 -0
  132. metadata +88 -58
  133. data/README +0 -67
  134. data/bin/pdf2graph +0 -121
  135. data/bin/pdfcocoon +0 -104
  136. data/lib/origami/file.rb +0 -233
  137. data/samples/README.txt +0 -45
  138. data/samples/actions/launch/calc.rb +0 -87
  139. data/samples/actions/launch/winparams.rb +0 -22
  140. data/samples/actions/loop/loopgoto.rb +0 -24
  141. data/samples/actions/loop/loopnamed.rb +0 -21
  142. data/samples/actions/named/named.rb +0 -31
  143. data/samples/actions/samba/smbrelay.rb +0 -26
  144. data/samples/actions/webbug/submitform.js +0 -26
  145. data/samples/actions/webbug/webbug-browser.rb +0 -68
  146. data/samples/actions/webbug/webbug-js.rb +0 -67
  147. data/samples/actions/webbug/webbug-reader.rb +0 -90
  148. data/samples/attachments/attach.rb +0 -40
  149. data/samples/attachments/attached.txt +0 -1
  150. data/samples/crypto/crypto.rb +0 -28
  151. data/samples/digsig/signed.rb +0 -46
  152. data/samples/exploits/cve-2008-2992-utilprintf.rb +0 -87
  153. data/samples/exploits/cve-2009-0927-geticon.rb +0 -65
  154. data/samples/exploits/exploit_customdictopen.rb +0 -55
  155. data/samples/exploits/getannots.rb +0 -69
  156. data/samples/flash/flash.rb +0 -31
  157. data/samples/javascript/attached.txt +0 -1
  158. data/samples/javascript/js.rb +0 -52
  159. data/templates/patterns.rb +0 -66
  160. data/templates/widgets.rb +0 -173
  161. data/templates/xdp.rb +0 -92
  162. data/test/ts_pdf.rb +0 -50
@@ -1,25 +1,20 @@
1
1
  =begin
2
2
 
3
- = File
4
- hexview.rb
5
-
6
- = Info
7
- This file is part of PDF Walker, a graphical PDF file browser
8
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
9
- All right reserved.
10
-
11
- PDF Walker is free software: you can redistribute it and/or modify
12
- it under the terms of the GNU General Public License as published by
13
- the Free Software Foundation, either version 3 of the License, or
14
- (at your option) any later version.
15
-
16
- PDF Walker is distributed in the hope that it will be useful,
17
- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- GNU General Public License for more details.
20
-
21
- You should have received a copy of the GNU General Public License
22
- along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
3
+ This file is part of PDF Walker, a graphical PDF file browser
4
+ Copyright (C) 2016 Guillaume Delugré.
5
+
6
+ PDF Walker is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ PDF Walker is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
23
18
 
24
19
  =end
25
20
 
@@ -27,56 +22,59 @@ require 'gui/gtkhex'
27
22
 
28
23
  module PDFWalker
29
24
 
30
- class Walker < Window
25
+ class Walker < Window
26
+ private
31
27
 
32
- private
28
+ def create_hexview
29
+ @hexview = DumpView.new(self)
30
+ end
33
31
 
34
- def create_hexview
35
- @hexview = DumpView.new(self)
36
- end
32
+ class DumpView < ScrolledWindow
37
33
 
38
- class DumpView < ScrolledWindow
39
-
40
- def initialize(parent)
41
- @parent = parent
42
- super()
34
+ def initialize(parent)
35
+ @parent = parent
36
+ super()
43
37
 
44
- set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
38
+ set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
45
39
 
46
- @current_obj = nil
47
-
48
- @view = HexEditor.new
49
- @view.show_offsets(true)
40
+ @current_obj = nil
50
41
 
51
- add_with_viewport @view
52
- end
42
+ @view = HexEditor.new
43
+ @view.show_offsets(true)
53
44
 
54
- def clear
55
- @view.set_data ''
56
- end
45
+ add_with_viewport @view
46
+ end
57
47
 
58
- def load(object)
59
- return if @current_obj.equal?(object)
48
+ def clear
49
+ @view.set_data ''
50
+ end
60
51
 
61
- begin
62
- self.clear
52
+ def load(object)
53
+ return if @current_obj.equal?(object)
63
54
 
64
- case object
65
- when Origami::Stream
66
- @view.set_data(object.data)
67
- when Origami::String
68
- @view.set_data(object.value)
69
- end
55
+ begin
56
+ self.clear
70
57
 
71
- @current_obj = object
58
+ case object
59
+ when Origami::Stream
60
+ begin
61
+ @view.set_data(object.data)
62
+ rescue Origami::Filter::Error
63
+ @view.set_data($!.input_data) if $!.input_data
72
64
 
73
- rescue Exception => e
74
- @parent.error("An error occured while loading this object.\n#{e} (#{e.class})")
75
- end
76
- end
65
+ @parent.error("#{$!.class}: #{$!.message}") unless object.filters == [ :DCTDecode ]
66
+ end
77
67
 
78
- end
68
+ when Origami::String
69
+ @view.set_data(object.value)
70
+ end
79
71
 
80
- end
72
+ @current_obj = object
81
73
 
74
+ rescue
75
+ @parent.error("An error occured while loading this object.\n#{$!} (#{$!.class})")
76
+ end
77
+ end
78
+ end
79
+ end
82
80
  end
@@ -1,72 +1,69 @@
1
1
  =begin
2
2
 
3
- = File
4
- imgview.rb
5
-
6
- = Info
7
- This file is part of PDF Walker, a graphical PDF file browser
8
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
9
- All right reserved.
10
-
11
- PDF Walker is free software: you can redistribute it and/or modify
12
- it under the terms of the GNU General Public License as published by
13
- the Free Software Foundation, either version 3 of the License, or
14
- (at your option) any later version.
15
-
16
- PDF Walker is distributed in the hope that it will be useful,
17
- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- GNU General Public License for more details.
20
-
21
- You should have received a copy of the GNU General Public License
22
- along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
3
+ This file is part of PDF Walker, a graphical PDF file browser
4
+ Copyright (C) 2016 Guillaume Delugré.
5
+
6
+ PDF Walker is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ PDF Walker is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
23
18
 
24
19
  =end
25
20
 
26
21
  module PDFWalker
27
22
 
28
- class ImgViewer < Window
29
- attr_reader :image
23
+ class ImgViewer < Window
24
+ attr_reader :image
30
25
 
31
- def initialize
32
- super()
26
+ def initialize
27
+ super()
33
28
 
34
- set_title "Image view"
35
- set_decorated false
36
- set_resizable false
29
+ set_title "Image view"
30
+ set_decorated false
31
+ set_resizable false
37
32
 
38
- add_events(Gdk::Event::KEY_RELEASE_MASK)
39
- signal_connect('key_release_event') { |w, event|
40
- destroy if event.keyval == Gdk::Keyval::GDK_Escape
41
- }
42
- end
33
+ add_events(Gdk::Event::KEY_RELEASE_MASK)
34
+ signal_connect('key_release_event') { |w, event|
35
+ destroy if event.keyval == Gdk::Keyval::GDK_Escape
36
+ }
37
+ end
43
38
 
44
- def show_raw_img(data, w, h, bpc, bpr)
45
- set_default_size w,h
39
+ def show_raw_img(data, w, h, bpc, bpr)
40
+ set_default_size w,h
46
41
 
47
- pixbuf = Gdk::Pixbuf.new data,
48
- Gdk::Pixbuf::ColorSpace::RGB, false, bpc,
49
- w, h,
50
- bpr
42
+ pixbuf = GdkPixbuf::Pixbuf.new data: data,
43
+ colorspace: GdkPixbuf::Colorspace::RGB,
44
+ has_alpha: false,
45
+ bits_per_sample: bpc,
46
+ width: w, height: h,
47
+ row_stride: bpr
51
48
 
52
- @image = Gtk::Image.new(pixbuf)
53
- add @image
49
+ @image = Gtk::Image.new(pixbuf)
50
+ add @image
54
51
 
55
- show_all
56
- end
52
+ show_all
53
+ end
57
54
 
58
- def show_compressed_img(data)
59
- loader = Gdk::PixbufLoader.new
60
- loader.last_write data
55
+ def show_compressed_img(data)
56
+ loader = Gdk::PixbufLoader.new
57
+ loader.last_write data
61
58
 
62
- pixbuf = loader.pixbuf
63
- set_default_size pixbuf.width, pixbuf.height
59
+ pixbuf = loader.pixbuf
60
+ set_default_size pixbuf.width, pixbuf.height
64
61
 
65
- @image = Gtk::Image.new(pixbuf)
66
- add @image
62
+ @image = Gtk::Image.new(pixbuf)
63
+ add @image
67
64
 
68
- show_all
65
+ show_all
66
+ end
69
67
  end
70
- end
71
68
 
72
69
  end
@@ -1,400 +1,402 @@
1
1
  =begin
2
2
 
3
- = File
4
- menu.rb
5
-
6
- = Info
7
- This file is part of PDF Walker, a graphical PDF file browser
8
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
9
- All right reserved.
10
-
11
- PDF Walker is free software: you can redistribute it and/or modify
12
- it under the terms of the GNU General Public License as published by
13
- the Free Software Foundation, either version 3 of the License, or
14
- (at your option) any later version.
15
-
16
- PDF Walker is distributed in the hope that it will be useful,
17
- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- GNU General Public License for more details.
20
-
21
- You should have received a copy of the GNU General Public License
22
- along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
3
+ This file is part of PDF Walker, a graphical PDF file browser
4
+ Copyright (C) 2016 Guillaume Delugré.
5
+
6
+ PDF Walker is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ PDF Walker is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
23
18
 
24
19
  =end
25
20
 
26
21
  module PDFWalker
27
22
 
28
- module Popable
29
-
30
- @@menus = Hash.new([])
31
- @@menus[:"PDF File"] =
32
- [
33
- {
34
- :Name => Stock::SAVE_AS,
35
- :Sensitive => true,
36
- :Callback => lambda { |widget, viewer, path|
37
- viewer.parent.save
38
- }
39
- },
40
- {
41
- :Name => "Serialize",
42
- :Sensitive => true,
43
- :Callback => lambda { |widget, viewer, path|
44
- viewer.parent.serialize
45
- }
46
- },
47
- {
48
- :Name => :"---"
49
- },
50
- {
51
- :Name => Stock::PROPERTIES,
52
- :Sensitive => true,
53
- :Callback => lambda { |widget, viewer, path|
54
- viewer.parent.display_file_properties
55
- }
56
- },
57
- {
58
- :Name => :"---"
59
- },
60
- {
61
- :Name => Stock::CLOSE,
62
- :Sensitive => true,
63
- :Callback => lambda { |widget, viewer, path|
64
- viewer.parent.close
65
- }
66
- }
67
- ]
68
-
69
- @@menus[:Reference] =
70
- [
71
- {
72
- :Name => Stock::JUMP_TO,
73
- :Sensitive => true,
74
- :Callback => lambda { |widget, viewer, path|
75
- viewer.row_activated(path, viewer.get_column(viewer.class::TEXTCOL))
76
- }
77
- }
78
- ]
79
-
80
- @@menus[:Revision] =
81
- [
82
- {
83
- :Name => "Save to this revision",
84
- :Sensitive => true,
85
- :Callback => lambda { |widget, viewer, path|
86
- revstr = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::TEXTCOL)
87
- revstr.slice!(0, "Revision ".size)
88
-
89
- revnum = revstr.to_i
90
-
91
- dialog = Gtk::FileChooserDialog.new("Save PDF File",
92
- viewer.parent,
93
- Gtk::FileChooser::ACTION_SAVE,
94
- nil,
95
- [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
96
- [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
97
- )
98
-
99
- dialog.filter = FileFilter.new.add_pattern("*.pdf")
100
-
101
- if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
102
- viewer.parent.opened.save_upto(revnum, dialog.filename)
103
- end
104
-
105
- dialog.destroy
106
- }
107
- }
108
- ]
109
-
110
- @@menus[:Stream] =
111
- [
112
- {
113
- :Name => "Dump encoded stream",
114
- :Sensitive => true,
115
- :Callback => lambda { |widget, viewer, path|
116
- stream = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
117
-
118
- viewer.parent.save_data("Save stream to file", stream.rawdata)
119
- }
120
- },
121
- {
122
- :Name => "Dump decoded stream",
123
- :Sensitive => true,
124
- :Callback => lambda { |widget, viewer, path|
125
- stream = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
126
-
127
- viewer.parent.save_data("Save stream to file", stream.data)
128
- }
129
- }
130
- ]
131
-
132
- @@menus[:String] =
133
- [
134
- {
135
- :Name => "Dump string",
136
- :Sensitive => true,
137
- :Callback => lambda { |widget, viewer, path|
138
- string = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
139
-
140
- viewer.parent.save_data("Save string to file", string.value)
141
- }
142
- }
143
- ]
144
-
145
- @@menus[:Image] = @@menus[:Stream] +
146
- [
147
- {
148
- :Name => :"---"
149
- },
150
- {
151
- :Name => "View image",
152
- :Sensitive => true,
153
- :Callback => lambda { |widget, viewer, path|
154
- stm = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
155
- w,h = stm.Width, stm.Height
156
- colors =
157
- case stm.ColorSpace
158
- when :DeviceGray.to_o then 1
159
- when :DeviceRGB.to_o then 3
160
- when :DeviceCMYK.to_o then 4
161
- else
162
- 1
163
- end
164
- bpc = stm.BitsPerComponent || 8
165
- bpr = (w * colors * bpc + 7) >> 3
166
- data = stm.data
167
-
168
- begin
169
- imgview = ImgViewer.new
170
- if stm.Filter == :DCTDecode or (stm.Filter.is_a?(Array) and stm.Filter[0] == :DCTDecode)
171
- imgview.show_compressed_img data
172
- else
173
- imgview.show_raw_img data, w, h, bpc, bpr
23
+ module Popable
24
+
25
+ @@menus = Hash.new([])
26
+ @@menus[:"PDF File"] =
27
+ [
28
+ {
29
+ Name: Stock::SAVE_AS,
30
+ Sensitive: true,
31
+ Callback: lambda { |widget, viewer, path|
32
+ viewer.parent.save
33
+ }
34
+ },
35
+ {
36
+ Name: "Serialize",
37
+ Sensitive: true,
38
+ Callback: lambda { |widget, viewer, path|
39
+ viewer.parent.serialize
40
+ }
41
+ },
42
+ {
43
+ Name: :"---"
44
+ },
45
+ {
46
+ Name: Stock::PROPERTIES,
47
+ Sensitive: true,
48
+ Callback: lambda { |widget, viewer, path|
49
+ viewer.parent.display_file_properties
50
+ }
51
+ },
52
+ {
53
+ Name: :"---"
54
+ },
55
+ {
56
+ Name: Stock::CLOSE,
57
+ Sensitive: true,
58
+ Callback: lambda { |widget, viewer, path|
59
+ viewer.parent.close
60
+ }
61
+ }
62
+ ]
63
+
64
+ @@menus[:Reference] =
65
+ [
66
+ {
67
+ Name: Stock::JUMP_TO,
68
+ Sensitive: true,
69
+ Callback: lambda { |widget, viewer, path|
70
+ viewer.row_activated(path, viewer.get_column(viewer.class::TEXTCOL))
71
+ }
72
+ }
73
+ ]
74
+
75
+ @@menus[:Revision] =
76
+ [
77
+ {
78
+ Name: "Save to this revision",
79
+ Sensitive: true,
80
+ Callback: lambda { |widget, viewer, path|
81
+ revstr = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::TEXTCOL)
82
+ revstr.slice!(0, "Revision ".size)
83
+
84
+ revnum = revstr.to_i
85
+
86
+ dialog = Gtk::FileChooserDialog.new("Save PDF File",
87
+ viewer.parent,
88
+ Gtk::FileChooser::ACTION_SAVE,
89
+ nil,
90
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
91
+ [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
92
+ )
93
+
94
+ dialog.filter = FileFilter.new.add_pattern("*.pdf")
95
+
96
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
97
+ viewer.parent.opened.save_upto(revnum, dialog.filename)
98
+ end
99
+
100
+ dialog.destroy
101
+ }
102
+ }
103
+ ]
104
+
105
+ @@menus[:Stream] =
106
+ [
107
+ {
108
+ Name: "Dump encoded stream",
109
+ Sensitive: true,
110
+ Callback: lambda { |widget, viewer, path|
111
+ stream = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
112
+
113
+ viewer.parent.save_data("Save stream to file", stream.encoded_data)
114
+ }
115
+ },
116
+ {
117
+ Name: "Dump decoded stream",
118
+ Sensitive: true,
119
+ Callback: lambda { |widget, viewer, path|
120
+ stream = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
121
+
122
+ viewer.parent.save_data("Save stream to file", stream.data)
123
+ }
124
+ }
125
+ ]
126
+
127
+ @@menus[:String] =
128
+ [
129
+ {
130
+ Name: "Dump string",
131
+ Sensitive: true,
132
+ Callback: lambda { |widget, viewer, path|
133
+ string = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
134
+
135
+ viewer.parent.save_data("Save string to file", string.value)
136
+ }
137
+ }
138
+ ]
139
+
140
+ @@menus[:Image] = @@menus[:Stream] +
141
+ [
142
+ {
143
+ Name: :"---"
144
+ },
145
+ {
146
+ Name: "View image",
147
+ Sensitive: true,
148
+ Callback: lambda { |widget, viewer, path|
149
+ stm = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
150
+ w,h = stm.Width, stm.Height
151
+
152
+ if stm.ColorSpace.nil?
153
+ colors = 1
154
+ else
155
+ colors =
156
+ case stm.ColorSpace.value
157
+ when :DeviceGray then 1
158
+ when :DeviceRGB then 3
159
+ when :DeviceCMYK then 4
160
+ else
161
+ 1
162
+ end
163
+ end
164
+
165
+ bpc = stm.BitsPerComponent || 8
166
+ bpr = (w * colors * bpc + 7) >> 3
167
+ data = stm.data
168
+
169
+ begin
170
+ imgview = ImgViewer.new
171
+ if stm.Filter == :DCTDecode or (stm.Filter.is_a?(Array) and stm.Filter[0] == :DCTDecode)
172
+ imgview.show_compressed_img data
173
+ else
174
+ imgview.show_raw_img data, w, h, bpc, bpr
175
+ end
176
+ rescue
177
+ viewer.parent.error("#{$!.class}: #{$!.message}")
178
+ end
179
+ }
180
+ }
181
+ ]
182
+
183
+ def popup_menu(obj, event, path)
184
+ menu = Menu.new
185
+
186
+ type =
187
+ if obj.is_a?(Origami::Object)
188
+ if obj.is_a?(Origami::Graphics::ImageXObject)
189
+ :Image
190
+ else
191
+ obj.native_type.to_s.split("::").last.to_sym
192
+ end
193
+ else
194
+ case obj
195
+ when Origami::PDF
196
+ :"PDF File"
197
+ when Origami::PDF::Revision, Origami::FDF::Revision, Origami::PPKLite::Revision
198
+ :Revision
199
+ when ::Array
200
+ :Body
201
+ when Origami::PDF::Header, Origami::FDF::Header, Origami::PPKLite::Header
202
+ :Header
203
+ when Origami::Trailer
204
+ :Trailer
205
+ when Origami::XRef::Section
206
+ :XRefSection
207
+ when Origami::XRef::Subsection
208
+ :XRefSubsection
209
+ when Origami::XRef, Origami::XRefToCompressedObj
210
+ :XRef
211
+ else
212
+ :Unknown
213
+ end
214
+ end
215
+
216
+ title = obj.is_a?(Origami::Object) ? "Object : " : ""
217
+ title << type.to_s
218
+ menu.append(MenuItem.new(title).set_sensitive(false).modify_text(Gtk::STATE_INSENSITIVE, Gdk::Color.new(255,0,255)))
219
+
220
+ if obj.is_a?(Origami::Object)
221
+ if obj.indirect?
222
+ menu.append(MenuItem.new("Number : #{obj.no}; Generation : #{obj.generation}").set_sensitive(false))
223
+ menu.append(MenuItem.new("File offset : #{obj.file_offset}").set_sensitive(false))
224
+
225
+ getxrefs = MenuItem.new("Search references to this object").set_sensitive(true)
226
+ getxrefs.signal_connect("activate") do
227
+ ref = self.model.get_value(self.model.get_iter(path), self.class::OBJCOL)
228
+ self.parent.show_xrefs(ref)
229
+ end
230
+
231
+ menu.append(getxrefs)
232
+ elsif not obj.parent.nil?
233
+ gotoparent = MenuItem.new("Goto Parent Object").set_sensitive(true)
234
+ gotoparent.signal_connect("activate") do
235
+ dest = self.model.get_value(self.model.get_iter(path), self.class::OBJCOL).parent
236
+ self.goto(dest)
237
+ end
238
+
239
+ menu.append(gotoparent)
240
+ end
174
241
  end
175
- rescue Exception => e
176
- viewer.parent.error("#{e.class}: #{e.message}")
177
- end
178
- }
179
- }
180
- ]
181
-
182
- def popup_menu(obj, event, path)
183
-
184
- menu = Menu.new
185
-
186
- type = if obj.is_a?(Origami::Object)
187
- if obj.is_a?(Graphics::ImageXObject)
188
- :Image
189
- else
190
- obj.native_type.to_s.split("::").last.to_sym
191
- end
192
- else case obj
193
- when Origami::PDF
194
- :"PDF File"
195
- when Origami::PDF::Revision, Origami::Adobe::PPKLite::Revision
196
- :Revision
197
- when ::Array
198
- :Body
199
- when Origami::PDF::Header, Origami::Adobe::PPKLite::Header
200
- :Header
201
- when Origami::Trailer
202
- :Trailer
203
- when Origami::XRef::Section
204
- :XRefSection
205
- when Origami::XRef::Subsection
206
- :XRefSubsection
207
- when Origami::XRef, Origami::XRefToCompressedObj
208
- :XRef
209
- else
210
- :Unknown
242
+
243
+ items = @@menus[type]
244
+ menu.append(SeparatorMenuItem.new) if not items.empty?
245
+
246
+ items.each { |item|
247
+ if item[:Name] == :"---"
248
+ entry = SeparatorMenuItem.new
249
+ else
250
+ if item[:Name].is_a?(String)
251
+ entry = MenuItem.new(item[:Name])
252
+ else
253
+ entry = ImageMenuItem.new(item[:Name])
254
+ end
255
+
256
+ entry.set_sensitive(item[:Sensitive])
257
+ entry.signal_connect("activate", self, path, &item[:Callback])
258
+ end
259
+
260
+ menu.append(entry)
261
+ }
262
+
263
+ menu.show_all
264
+ menu.popup(nil, nil, event.button, event.time)
211
265
  end
212
- end
213
-
214
- title = obj.is_a?(Origami::Object) ? "Object : " : ""
215
- title << type.to_s
216
- menu.append(MenuItem.new(title).set_sensitive(false).modify_text(Gtk::STATE_INSENSITIVE, Gdk::Color.new(255,0,255)))
217
-
218
- if obj.is_a?(Origami::Object)
219
- if obj.is_indirect?
220
- menu.append(MenuItem.new("Number : #{obj.no}; Generation : #{obj.generation}").set_sensitive(false))
221
- menu.append(MenuItem.new("File offset : #{obj.file_offset}").set_sensitive(false))
222
- xrefsproc = lambda { |widget,viewer,path|
223
- ref = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
224
- viewer.parent.show_xrefs(ref)
225
- }
226
- getxrefs = MenuItem.new("Search references to this object").set_sensitive(true)
227
- getxrefs.signal_connect("activate", self, path, &xrefsproc)
228
-
229
- menu.append(getxrefs)
230
- elsif not obj.parent.nil?
231
- gotoproc = lambda { |widget,viewer,path|
232
- dest = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL).parent
233
- viewer.goto(dest)
234
- }
235
- gotoparent = MenuItem.new("Goto Parent Object").set_sensitive(true)
236
- gotoparent.signal_connect("activate", self, path, &gotoproc)
237
-
238
- menu.append(gotoparent)
266
+ end
267
+
268
+ class Walker < Window
269
+
270
+ private
271
+
272
+ def create_menus
273
+ AccelMap.add_entry("<PDF Walker>/File/Open", Gdk::Keyval::GDK_O, Gdk::Window::CONTROL_MASK)
274
+ AccelMap.add_entry("<PDF Walker>/File/Refresh", Gdk::Keyval::GDK_R, Gdk::Window::CONTROL_MASK)
275
+ AccelMap.add_entry("<PDF Walker>/File/Close", Gdk::Keyval::GDK_W, Gdk::Window::CONTROL_MASK)
276
+ AccelMap.add_entry("<PDF Walker>/File/Save", Gdk::Keyval::GDK_S, Gdk::Window::CONTROL_MASK)
277
+ AccelMap.add_entry("<PDF Walker>/File/Quit", Gdk::Keyval::GDK_Q, Gdk::Window::CONTROL_MASK)
278
+ AccelMap.add_entry("<PDF Walker>/Document/Search", Gdk::Keyval::GDK_F, Gdk::Window::CONTROL_MASK)
279
+
280
+ @menu = MenuBar.new
281
+
282
+ ####################################################
283
+ file_ag = Gtk::AccelGroup.new
284
+ @file_menu = Menu.new.set_accel_group(file_ag).set_accel_path("<PDF Walker>/File")
285
+ add_accel_group(file_ag)
286
+
287
+ @file_menu_open = ImageMenuItem.new(Stock::OPEN).set_accel_path("<PDF Walker>/File/Open")
288
+ @file_menu_recent = MenuItem.new("Last opened")
289
+ @file_menu_deserialize = MenuItem.new("Deserialize")
290
+ @file_menu_refresh = ImageMenuItem.new(Stock::REFRESH).set_sensitive(false).set_accel_path("<PDF Walker>/File/Refresh")
291
+ @file_menu_close = ImageMenuItem.new(Stock::CLOSE).set_sensitive(false).set_accel_path("<PDF Walker>/File/Close")
292
+ @file_menu_saveas = ImageMenuItem.new(Stock::SAVE_AS).set_sensitive(false)
293
+ @file_menu_serialize = MenuItem.new("Serialize").set_sensitive(false)
294
+ @file_menu_exit = ImageMenuItem.new(Stock::QUIT).set_accel_path("<PDF Walker>/File/Quit")
295
+
296
+ @export_menu = Menu.new
297
+ @export_pdf_menu = MenuItem.new("As PDF").set_accel_path("<PDF Walker>/File/Save")
298
+ @export_graph_menu = MenuItem.new("As GraphViz dot file")
299
+ @export_graphml_menu = MenuItem.new("As GraphML file")
300
+
301
+ @export_pdf_menu.signal_connect('activate') do save end
302
+ @export_graph_menu.signal_connect('activate') do save_dot end
303
+ @export_graphml_menu.signal_connect('activate') do save_graphml end
304
+
305
+ @export_menu.append(@export_pdf_menu)
306
+ @export_menu.append(@export_graph_menu)
307
+ @export_menu.append(@export_graphml_menu)
308
+
309
+ @file_menu_saveas.set_submenu(@export_menu)
310
+
311
+ @file_menu_open.signal_connect('activate') do open end
312
+ @file_menu_deserialize.signal_connect('activate') do deserialize end
313
+ @file_menu_refresh.signal_connect('activate') do open(@filename) end
314
+ @file_menu_close.signal_connect('activate') do close end
315
+ @file_menu_serialize.signal_connect('activate') do serialize end
316
+ @file_menu_exit.signal_connect('activate') do self.destroy end
317
+
318
+ update_recent_menu
319
+
320
+ @file_menu.append(@file_menu_open)
321
+ @file_menu.append(@file_menu_recent)
322
+ @file_menu.append(@file_menu_deserialize)
323
+ @file_menu.append(@file_menu_refresh)
324
+ @file_menu.append(@file_menu_close)
325
+ @file_menu.append(@file_menu_saveas)
326
+ @file_menu.append(@file_menu_serialize)
327
+ @file_menu.append(@file_menu_exit)
328
+
329
+ @menu.append(MenuItem.new('_File').set_submenu(@file_menu))
330
+ ####################################################
331
+
332
+ doc_ag = Gtk::AccelGroup.new
333
+ @document_menu = Menu.new.set_accel_group(doc_ag)
334
+ add_accel_group(doc_ag)
335
+
336
+ @document_menu_search = ImageMenuItem.new(Stock::FIND).set_sensitive(false).set_accel_path("<PDF Walker>/Document/Search")
337
+ @document_menu_gotocatalog = MenuItem.new("Jump to Catalog").set_sensitive(false)
338
+ @document_menu_gotodocinfo = MenuItem.new("Jump to Document Info").set_sensitive(false)
339
+ @document_menu_gotometadata = MenuItem.new("Jump to Metadata").set_sensitive(false)
340
+ @document_menu_gotorev = MenuItem.new("Jump to Revision...").set_sensitive(false)
341
+ @document_menu_gotopage = MenuItem.new("Jump to Page...").set_sensitive(false)
342
+ @document_menu_gotofield = MenuItem.new("Jump to Field...").set_sensitive(false)
343
+ @document_menu_gotoobj = MenuItem.new("Jump to Object...").set_sensitive(false)
344
+ @document_menu_properties = ImageMenuItem.new(Stock::PROPERTIES).set_sensitive(false)
345
+ @document_menu_sign = MenuItem.new("Sign the document").set_sensitive(false)
346
+ @document_menu_ur = MenuItem.new("Enable Usage Rights").set_sensitive(false)
347
+
348
+ @document_menu_search.signal_connect('activate') do search end
349
+ @document_menu_gotocatalog.signal_connect('activate') do goto_catalog end
350
+ @document_menu_gotodocinfo.signal_connect('activate') do goto_docinfo end
351
+ @document_menu_gotometadata.signal_connect('activate') do goto_metadata end
352
+ @document_menu_gotoobj.signal_connect('activate') do goto_object end
353
+ @document_menu_properties.signal_connect('activate') do display_file_properties end
354
+ @document_menu_sign.signal_connect('activate') do display_signing_wizard end
355
+ @document_menu_ur.signal_connect('activate') do display_usage_rights_wizard end
356
+
357
+ @document_menu.append(@document_menu_search)
358
+ @document_menu.append(MenuItem.new)
359
+ @document_menu.append(@document_menu_gotocatalog)
360
+ @document_menu.append(@document_menu_gotodocinfo)
361
+ @document_menu.append(@document_menu_gotometadata)
362
+ @document_menu.append(@document_menu_gotorev)
363
+ @document_menu.append(@document_menu_gotopage)
364
+ @document_menu.append(@document_menu_gotofield)
365
+ @document_menu.append(@document_menu_gotoobj)
366
+ @document_menu.append(MenuItem.new)
367
+ @document_menu.append(@document_menu_sign)
368
+ @document_menu.append(@document_menu_ur)
369
+ @document_menu.append(@document_menu_properties)
370
+
371
+ @menu.append(MenuItem.new('_Document').set_submenu(@document_menu))
372
+ ####################################################
373
+ @help_menu = Menu.new
374
+ @help_menu_profile = CheckMenuItem.new("Profiling (Debug purposes only)").set_active(@config.profile?)
375
+ @help_menu_profile.signal_connect('toggled') do @config.set_profiling(@help_menu_profile.active?) end
376
+
377
+ @help_menu_about = ImageMenuItem.new(Stock::ABOUT)
378
+
379
+ @help_menu_about.signal_connect('activate') do about end
380
+
381
+ @help_menu.append(@help_menu_profile)
382
+ @help_menu.append(@help_menu_about)
383
+
384
+ @menu.append(MenuItem.new('_Help').set_submenu(@help_menu))
385
+ ####################################################
239
386
  end
240
- end
241
-
242
- items = @@menus[type]
243
- menu.append(SeparatorMenuItem.new) if not items.empty?
244
-
245
- items.each { |item|
246
-
247
- if item[:Name] == :"---"
248
- entry = SeparatorMenuItem.new
249
- else
250
- if item[:Name].is_a?(String)
251
- entry = MenuItem.new(item[:Name])
252
- else entry = ImageMenuItem.new(item[:Name])
253
- end
254
-
255
- entry.set_sensitive(item[:Sensitive])
256
- entry.signal_connect("activate", self, path, &item[:Callback])
387
+
388
+ def update_recent_menu
389
+ @recent_menu = Menu.new
390
+ @config.recent_files.each { |file|
391
+ menu = MenuItem.new(file)
392
+ menu.signal_connect('activate') do open(file) end
393
+
394
+ @recent_menu.append(menu)
395
+ }
396
+
397
+ @file_menu_recent.set_submenu(@recent_menu)
398
+ @file_menu_recent.show_all
257
399
  end
258
-
259
- menu.append(entry)
260
- }
261
-
262
- menu.show_all
263
- menu.popup(nil, nil, event.button, event.time)
264
-
265
- end
266
-
267
- end
268
-
269
- class Walker < Window
270
-
271
- private
272
-
273
- def create_menus
274
-
275
- AccelMap.add_entry("<PDF Walker>/File/Open", Gdk::Keyval::GDK_O, Gdk::Window::CONTROL_MASK)
276
- AccelMap.add_entry("<PDF Walker>/File/Refresh", Gdk::Keyval::GDK_R, Gdk::Window::CONTROL_MASK)
277
- AccelMap.add_entry("<PDF Walker>/File/Close", Gdk::Keyval::GDK_W, Gdk::Window::CONTROL_MASK)
278
- AccelMap.add_entry("<PDF Walker>/File/Save", Gdk::Keyval::GDK_S, Gdk::Window::CONTROL_MASK)
279
- AccelMap.add_entry("<PDF Walker>/File/Quit", Gdk::Keyval::GDK_Q, Gdk::Window::CONTROL_MASK)
280
- AccelMap.add_entry("<PDF Walker>/Document/Search", Gdk::Keyval::GDK_F, Gdk::Window::CONTROL_MASK)
281
-
282
- @menu = MenuBar.new
283
-
284
- ####################################################
285
- file_ag = Gtk::AccelGroup.new
286
- @file_menu = Menu.new.set_accel_group(file_ag).set_accel_path("<PDF Walker>/File")
287
- add_accel_group(file_ag)
288
-
289
- @file_menu_open = ImageMenuItem.new(Stock::OPEN).set_accel_path("<PDF Walker>/File/Open")
290
- @file_menu_recent = MenuItem.new("Last opened")
291
- @file_menu_deserialize = MenuItem.new("Deserialize")
292
- @file_menu_refresh = ImageMenuItem.new(Stock::REFRESH).set_sensitive(false).set_accel_path("<PDF Walker>/File/Refresh")
293
- @file_menu_close = ImageMenuItem.new(Stock::CLOSE).set_sensitive(false).set_accel_path("<PDF Walker>/File/Close")
294
- @file_menu_saveas = ImageMenuItem.new(Stock::SAVE_AS).set_sensitive(false)
295
- @file_menu_serialize = MenuItem.new("Serialize").set_sensitive(false)
296
- @file_menu_exit = ImageMenuItem.new(Stock::QUIT).set_accel_path("<PDF Walker>/File/Quit")
297
-
298
- @export_menu = Menu.new
299
- @export_pdf_menu = MenuItem.new("As reassembled PDF").set_accel_path("<PDF Walker>/File/Save")
300
- @export_graph_menu = MenuItem.new("As GraphViz dot file")
301
- @export_graphml_menu = MenuItem.new("As GraphML file")
302
-
303
- @export_pdf_menu.signal_connect('activate') do save end
304
- @export_graph_menu.signal_connect('activate') do save_dot end
305
- @export_graphml_menu.signal_connect('activate') do save_graphml end
306
-
307
- @export_menu.append(@export_pdf_menu)
308
- @export_menu.append(@export_graph_menu)
309
- @export_menu.append(@export_graphml_menu)
310
-
311
- @file_menu_saveas.set_submenu(@export_menu)
312
-
313
- @file_menu_open.signal_connect('activate') do open end
314
- @file_menu_deserialize.signal_connect('activate') do deserialize end
315
- @file_menu_refresh.signal_connect('activate') do open(@filename) end
316
- @file_menu_close.signal_connect('activate') do close end
317
- @file_menu_serialize.signal_connect('activate') do serialize end
318
- @file_menu_exit.signal_connect('activate') do self.destroy end
319
-
320
- update_recent_menu
321
-
322
- @file_menu.append(@file_menu_open)
323
- @file_menu.append(@file_menu_recent)
324
- @file_menu.append(@file_menu_deserialize)
325
- @file_menu.append(@file_menu_refresh)
326
- @file_menu.append(@file_menu_close)
327
- @file_menu.append(@file_menu_saveas)
328
- @file_menu.append(@file_menu_serialize)
329
- @file_menu.append(@file_menu_exit)
330
-
331
- @menu.append(MenuItem.new('_File').set_submenu(@file_menu))
332
- ####################################################
333
-
334
- doc_ag = Gtk::AccelGroup.new
335
- @document_menu = Menu.new.set_accel_group(doc_ag)
336
- add_accel_group(doc_ag)
337
-
338
- @document_menu_search = ImageMenuItem.new(Stock::FIND).set_sensitive(false).set_accel_path("<PDF Walker>/Document/Search")
339
- @document_menu_gotocatalog = MenuItem.new("Jump To Catalog").set_sensitive(false)
340
- @document_menu_gotorev = MenuItem.new("Jump To Revision...").set_sensitive(false)
341
- @document_menu_gotopage = MenuItem.new("Jump To Page...").set_sensitive(false)
342
- @document_menu_gotoobj = MenuItem.new("Jump To Object...").set_sensitive(false)
343
- @document_menu_properties = ImageMenuItem.new(Stock::PROPERTIES).set_sensitive(false)
344
- @document_menu_sign = MenuItem.new("Sign the document").set_sensitive(false)
345
- @document_menu_ur = MenuItem.new("Enable Usage Rights").set_sensitive(false)
346
-
347
- @document_menu_search.signal_connect('activate') do search end
348
- @document_menu_gotocatalog.signal_connect('activate') do goto_catalog end
349
- @document_menu_gotoobj.signal_connect('activate') do goto_object end
350
- @document_menu_properties.signal_connect('activate') do display_file_properties end
351
- @document_menu_sign.signal_connect('activate') do display_signing_wizard end
352
- @document_menu_ur.signal_connect('activate') do display_usage_rights_wizard end
353
-
354
- @document_menu.append(@document_menu_search)
355
- @document_menu.append(MenuItem.new)
356
- @document_menu.append(@document_menu_gotocatalog)
357
- @document_menu.append(@document_menu_gotorev)
358
- @document_menu.append(@document_menu_gotopage)
359
- @document_menu.append(@document_menu_gotoobj)
360
- @document_menu.append(MenuItem.new)
361
- @document_menu.append(@document_menu_sign)
362
- @document_menu.append(@document_menu_ur)
363
- @document_menu.append(@document_menu_properties)
364
-
365
- @menu.append(MenuItem.new('_Document').set_submenu(@document_menu))
366
- ####################################################
367
- @help_menu = Menu.new
368
- @help_menu_profile = CheckMenuItem.new("Profiling (Debug purposes only)").set_active(@config.profile?)
369
- @help_menu_profile.signal_connect('toggled') do @config.set_profiling(@help_menu_profile.active?) end
370
-
371
- @help_menu_about = ImageMenuItem.new(Stock::ABOUT)
372
-
373
- @help_menu_about.signal_connect('activate') do about end
374
-
375
- @help_menu.append(@help_menu_profile)
376
- @help_menu.append(@help_menu_about)
377
-
378
- @menu.append(MenuItem.new('_Help').set_submenu(@help_menu))
379
- ####################################################
380
-
381
- end
382
-
383
- def update_recent_menu
384
-
385
- @recent_menu = Menu.new
386
- @config.recent_files.each { |file|
387
-
388
- menu = MenuItem.new(file)
389
- menu.signal_connect('activate') do open(file) end
390
-
391
- @recent_menu.append(menu)
392
- }
393
-
394
- @file_menu_recent.set_submenu(@recent_menu)
395
- @file_menu_recent.show_all
396
400
  end
397
-
398
- end
399
401
 
400
402
  end