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
@@ -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