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
@@ -2,42 +2,36 @@
2
2
 
3
3
  =begin
4
4
 
5
- = File
6
- walker.rb
7
-
8
- = Info
9
- This file is part of PDF Walker, a graphical PDF file browser
10
- Copyright (C) 2010 Guillaume Delugré <guillaume AT security-labs DOT org>
11
- All right reserved.
12
-
13
- PDF Walker is free software: you can redistribute it and/or modify
14
- it under the terms of the GNU General Public License as published by
15
- the Free Software Foundation, either version 3 of the License, or
16
- (at your option) any later version.
17
-
18
- PDF Walker is distributed in the hope that it will be useful,
19
- but WITHOUT ANY WARRANTY; without even the implied warranty of
20
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
- GNU General Public License for more details.
22
-
23
- You should have received a copy of the GNU General Public License
24
- along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
5
+ This file is part of PDF Walker, a graphical PDF file browser
6
+ Copyright (C) 2016 Guillaume Delugré.
7
+
8
+ PDF Walker is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation, either version 3 of the License, or
11
+ (at your option) any later version.
12
+
13
+ PDF Walker is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
25
20
 
26
21
  =end
27
22
 
28
23
  begin
29
- require 'gtk2'
24
+ require 'gtk2'
30
25
  rescue LoadError
31
- abort('Error: you need to install ruby-gtk2 to run this application')
26
+ abort('Error: you need to install ruby-gtk2 to run this application')
32
27
  end
33
28
  include Gtk
34
29
 
35
30
  begin
36
- require 'origami'
31
+ require 'origami'
37
32
  rescue LoadError
38
- ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../lib"
39
- $: << ORIGAMIDIR
40
- require 'origami'
33
+ $: << File.join(__dir__, '../../lib')
34
+ require 'origami'
41
35
  end
42
36
 
43
37
  require 'gui/menu'
@@ -54,229 +48,230 @@ require 'gui/signing'
54
48
 
55
49
  module PDFWalker #:nodoc:all
56
50
 
57
- class Walker < Window
58
-
59
- attr_reader :treeview, :hexview, :objectview
60
- attr_reader :explorer_history
61
- attr_reader :config
62
- attr_reader :filename
63
-
64
- def self.start(file = nil)
65
- Gtk.init
66
- Walker.new(file)
67
- Gtk.main
68
- end
51
+ class Walker < Window
52
+ attr_reader :treeview, :hexview, :objectview
53
+ attr_reader :explorer_history
54
+ attr_reader :config
55
+ attr_reader :filename
69
56
 
70
- def initialize(target_file = nil)
71
- super("PDF Walker")
72
-
73
- @config = Walker::Config.new
74
-
75
- @last_search_result = []
76
- @last_search =
77
- {
78
- :expr => "",
79
- :regexp => false,
80
- :type => :body
81
- }
82
-
83
- @explorer_history = Array.new
84
-
85
- signal_connect('destroy') {
86
- @config.save
87
- Gtk.main_quit
88
- }
89
-
90
- add_events(Gdk::Event::KEY_RELEASE_MASK)
91
- signal_connect('key_release_event') { |w, event|
92
-
93
- if event.keyval == Gdk::Keyval::GDK_F1 then about
94
- elsif event.keyval == Gdk::Keyval::GDK_Escape && @opened && ! @explorer_history.empty?
95
- @treeview.goto(@explorer_history.pop)
57
+ def self.start(file = nil)
58
+ Gtk.init
59
+ Walker.new(file)
60
+ Gtk.main
96
61
  end
97
-
98
- }
99
-
100
- create_menus
101
- create_treeview
102
- create_hexview
103
- create_objectview
104
- create_panels
105
- create_statusbar
106
-
107
- @vbox = VBox.new
108
- @vbox.pack_start(@menu, false, false)
109
- @vbox.pack_start(@hpaned)
110
- @vbox.pack_end(@statusbar, false, false)
111
-
112
- add @vbox
113
-
114
- set_default_size(self.screen.width * 0.5, self.screen.height * 0.5)
115
- #maximize
116
- show_all
117
-
118
- open(target_file)
119
- end
120
-
121
- def error(msg)
122
-
123
- dialog = Gtk::MessageDialog.new(self,
124
- Gtk::Dialog::DESTROY_WITH_PARENT,
125
- Gtk::MessageDialog::ERROR,
126
- Gtk::MessageDialog::BUTTONS_CLOSE,
127
- msg)
128
- dialog.run
129
- dialog.destroy
130
-
131
- end
132
-
133
- def reload
134
- @treeview.load(@opened) if @opened
135
- end
136
62
 
137
- def search
138
- dialog = Gtk::Dialog.new("Search...",
139
- self,
140
- Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
141
- [Gtk::Stock::FIND, Gtk::Dialog::RESPONSE_OK],
142
- [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
143
- )
144
-
145
- entry = Gtk::Entry.new
146
- entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
147
- entry.text = @last_search[:expr]
148
-
149
- button_bydata = Gtk::RadioButton.new("In object body")
150
- button_byname = Gtk::RadioButton.new(button_bydata, "In object name")
151
- button_regexp = Gtk::CheckButton.new("Regular expression")
152
-
153
- button_bydata.set_active(true) if @last_search[:type] == :body
154
- button_byname.set_active(true) if @last_search[:type] == :name
155
- button_regexp.set_active(@last_search[:regexp])
156
-
157
- hbox = HBox.new
158
- hbox.pack_start Gtk::Label.new("Search for expression ")
159
- hbox.pack_start entry
160
-
161
- dialog.vbox.pack_start(hbox)
162
- dialog.vbox.pack_start(button_bydata)
163
- dialog.vbox.pack_start(button_byname)
164
- dialog.vbox.pack_end(button_regexp)
165
-
166
- dialog.signal_connect('response') do |dlg, response|
167
- if response == Gtk::Dialog::RESPONSE_OK
168
- search =
169
- {
170
- :expr => entry.text,
171
- :regexp => button_regexp.active?,
172
- :type => button_byname.active? ? :name : :body
173
- }
174
-
175
- if search == @last_search
176
- @last_search_result.push @last_search_result.shift
177
- results = @last_search_result
178
- else
179
- expr = search[:regexp] ? Regexp.new(search[:expr]) : search[:expr]
180
-
181
- results =
182
- if search[:type] == :body
183
- @opened.grep(expr)
184
- else
185
- @opened.ls(expr)
186
- end
187
- @last_search = search
188
- end
63
+ def initialize(target_file = nil)
64
+ super("PDF Walker")
65
+
66
+ @config = Walker::Config.new
67
+ @opened = nil
68
+
69
+ @last_search_result = []
70
+ @last_search =
71
+ {
72
+ :expr => "",
73
+ :regexp => false,
74
+ :type => :body
75
+ }
76
+
77
+ @explorer_history = Array.new
78
+
79
+ signal_connect('destroy') {
80
+ @config.save
81
+ Gtk.main_quit
82
+ }
83
+
84
+ add_events(Gdk::Event::KEY_RELEASE_MASK)
85
+ signal_connect('key_release_event') { |w, event|
86
+ if event.keyval == Gdk::Keyval::GDK_F1 then about
87
+ elsif event.keyval == Gdk::Keyval::GDK_Escape and @opened and not @explorer_history.empty?
88
+ @treeview.goto(@explorer_history.pop)
89
+ end
90
+ }
91
+
92
+ create_menus
93
+ create_treeview
94
+ create_hexview
95
+ create_objectview
96
+ create_panels
97
+ create_statusbar
98
+
99
+ @vbox = VBox.new
100
+ @vbox.pack_start(@menu, false, false)
101
+ @vbox.pack_start(@hpaned)
102
+ @vbox.pack_end(@statusbar, false, false)
103
+
104
+ add @vbox
105
+
106
+ set_default_size(self.screen.width * 0.5, self.screen.height * 0.5)
107
+ #maximize
108
+ show_all
109
+
110
+ open(target_file)
111
+ end
189
112
 
190
- if results.empty?
191
- error("No result found.")
192
- else
193
- if results != @last_search_result
194
- @last_search_result.each do |obj| @treeview.highlight(obj, nil) end
195
- results.each do |obj| @treeview.highlight(obj, "lightpink") end
113
+ def error(msg)
114
+ dialog = Gtk::MessageDialog.new(self,
115
+ Gtk::Dialog::DESTROY_WITH_PARENT,
116
+ Gtk::MessageDialog::ERROR,
117
+ Gtk::MessageDialog::BUTTONS_CLOSE,
118
+ msg
119
+ )
196
120
 
197
- @last_search_result = results
121
+ dialog.run
122
+ dialog.destroy
123
+ end
124
+
125
+ def reload
126
+ @treeview.load(@opened) if @opened
127
+ end
128
+
129
+ def search
130
+ dialog = Gtk::Dialog.new("Search...",
131
+ self,
132
+ Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
133
+ [Gtk::Stock::FIND, Gtk::Dialog::RESPONSE_OK],
134
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
135
+ )
136
+
137
+ entry = Gtk::Entry.new
138
+ entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
139
+ entry.text = @last_search[:expr]
140
+
141
+ button_bydata = Gtk::RadioButton.new("In object body")
142
+ button_byname = Gtk::RadioButton.new(button_bydata, "In object name")
143
+ button_regexp = Gtk::CheckButton.new("Regular expression")
144
+
145
+ button_bydata.set_active(true) if @last_search[:type] == :body
146
+ button_byname.set_active(true) if @last_search[:type] == :name
147
+ button_regexp.set_active(@last_search[:regexp])
148
+
149
+ hbox = HBox.new
150
+ hbox.pack_start Gtk::Label.new("Search for expression ")
151
+ hbox.pack_start entry
152
+
153
+ dialog.vbox.pack_start(hbox)
154
+ dialog.vbox.pack_start(button_bydata)
155
+ dialog.vbox.pack_start(button_byname)
156
+ dialog.vbox.pack_end(button_regexp)
157
+
158
+ dialog.signal_connect('response') do |dlg, response|
159
+ if response != Gtk::Dialog::RESPONSE_OK
160
+ dialog.destroy
161
+ next
162
+ end
163
+
164
+ search =
165
+ {
166
+ :expr => entry.text,
167
+ :regexp => button_regexp.active?,
168
+ :type => button_byname.active? ? :name : :body
169
+ }
170
+
171
+ if search == @last_search
172
+ @last_search_result.push @last_search_result.shift
173
+ results = @last_search_result
174
+ else
175
+ expr = search[:regexp] ? Regexp.new(search[:expr]) : search[:expr]
176
+
177
+ results =
178
+ if search[:type] == :body
179
+ @opened.grep(expr)
180
+ else
181
+ @opened.ls(expr, follow_references: false)
182
+ end
183
+
184
+ @last_search = search
185
+ end
186
+
187
+ if results.empty?
188
+ error("No result found.")
189
+ else
190
+ if results != @last_search_result
191
+ # Reset the previous search highlighting.
192
+ @last_search_result.each do |obj| @treeview.highlight(obj, nil) end
193
+
194
+ # Highlight the new results.
195
+ results.each do |obj| @treeview.highlight(obj, "lightpink") end
196
+
197
+ @last_search_result = results
198
+ end
199
+
200
+ @treeview.goto(results.first, follow_references: false)
201
+ end
198
202
  end
199
203
 
200
- @treeview.goto(results.first)
201
- end
202
- else
203
- dialog.destroy
204
+ dialog.show_all
204
205
  end
205
- end
206
206
 
207
- dialog.show_all
208
- end
207
+ def goto_catalog
208
+ @treeview.goto(@opened.Catalog.reference)
209
+ end
209
210
 
210
- def goto_catalog
211
- @treeview.goto(@opened.Catalog.reference)
212
- end
211
+ def goto_docinfo
212
+ @treeview.goto(@opened.document_info.reference) if @opened.document_info?
213
+ end
213
214
 
214
- def goto_object
215
- dialog = Gtk::Dialog.new("Jump to object...",
216
- self,
217
- Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
218
- [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
219
- [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
220
- )
221
-
222
- entry = Gtk::Entry.new
223
- entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
224
-
225
- dialog.vbox.pack_start Gtk::Label.new("Object number: ")
226
- dialog.vbox.pack_start entry
227
- dialog.show_all
228
-
229
- no = 0
230
- dialog.run do |response|
231
- if response == Gtk::Dialog::RESPONSE_OK
232
- no = entry.text.to_i
215
+ def goto_metadata
216
+ @treeview.goto(@opened.Catalog.Metadata.reference) if @opened.metadata?
233
217
  end
234
218
 
235
- dialog.destroy
236
- end
219
+ def goto_object
220
+ dialog = Gtk::Dialog.new("Jump to object...",
221
+ self,
222
+ Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
223
+ [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
224
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
225
+ )
226
+
227
+ entry = Gtk::Entry.new
228
+ entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
237
229
 
238
- if no > 0
239
- obj = @opened[no]
230
+ dialog.vbox.pack_start Gtk::Label.new("Object number: ")
231
+ dialog.vbox.pack_start entry
232
+ dialog.show_all
240
233
 
241
- if obj.nil?
242
- error("Object #{no} not found.")
243
- else
244
- @treeview.goto(obj)
234
+ no = 0
235
+ dialog.run do |response|
236
+ no = entry.text.to_i if response == Gtk::Dialog::RESPONSE_OK
237
+
238
+ dialog.destroy
239
+ end
240
+
241
+ return unless no > 0
242
+
243
+ obj = @opened[no]
244
+ if obj.nil?
245
+ error("Object #{no} not found.")
246
+ else
247
+ @treeview.goto(obj)
248
+ end
249
+ end
250
+
251
+ private
252
+
253
+ def create_panels
254
+ @hpaned = HPaned.new
255
+
256
+ @treepanel = ScrolledWindow.new.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
257
+ @treepanel.add @treeview
258
+
259
+ @vpaned = VPaned.new
260
+ @vpaned.pack1(@objectview, true, false)
261
+ @vpaned.pack2(@hexview, true, false)
262
+
263
+ @hpaned.pack1(@treepanel, true, false)
264
+ @hpaned.pack2(@vpaned, true, false)
265
+ end
266
+
267
+ def create_statusbar
268
+ @statusbar = Statusbar.new
269
+
270
+ @main_context = @statusbar.get_context_id 'Main'
271
+ @statusbar.push(@main_context, 'No file selected')
245
272
  end
246
- end
247
- end
248
-
249
- private
250
-
251
- def create_panels
252
-
253
- @hpaned = HPaned.new
254
-
255
- @treepanel = ScrolledWindow.new.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
256
- @treepanel.add @treeview
257
-
258
- @vpaned = VPaned.new
259
- @vpaned.pack1(@objectview, true, false)
260
- @vpaned.pack2(@hexview, true, false)
261
-
262
- @hpaned.pack1(@treepanel, true, false)
263
- @hpaned.pack2(@vpaned, true, false)
264
-
265
- end
266
-
267
- def create_statusbar
268
-
269
- @statusbar = Statusbar.new
270
-
271
- @main_context = @statusbar.get_context_id 'Main'
272
- @statusbar.push(@main_context, 'No file selected')
273
-
274
273
  end
275
-
276
- end
277
274
 
278
275
  end
279
276
 
280
- if __FILE__ == $0
281
- PDFWalker::Walker.start
282
- end
277
+ PDFWalker::Walker.start if __FILE__ == $0