origami 1.2.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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