origami 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/COPYING.LESSER +165 -0
  2. data/README +77 -0
  3. data/VERSION +1 -0
  4. data/bin/config/pdfcop.conf.yml +237 -0
  5. data/bin/gui/about.rb +46 -0
  6. data/bin/gui/config.rb +132 -0
  7. data/bin/gui/file.rb +385 -0
  8. data/bin/gui/hexdump.rb +74 -0
  9. data/bin/gui/hexview.rb +91 -0
  10. data/bin/gui/imgview.rb +72 -0
  11. data/bin/gui/menu.rb +392 -0
  12. data/bin/gui/properties.rb +132 -0
  13. data/bin/gui/signing.rb +635 -0
  14. data/bin/gui/textview.rb +107 -0
  15. data/bin/gui/treeview.rb +409 -0
  16. data/bin/gui/walker.rb +282 -0
  17. data/bin/gui/xrefs.rb +79 -0
  18. data/bin/pdf2graph +121 -0
  19. data/bin/pdf2ruby +353 -0
  20. data/bin/pdfcocoon +104 -0
  21. data/bin/pdfcop +455 -0
  22. data/bin/pdfdecompress +104 -0
  23. data/bin/pdfdecrypt +95 -0
  24. data/bin/pdfencrypt +112 -0
  25. data/bin/pdfextract +221 -0
  26. data/bin/pdfmetadata +123 -0
  27. data/bin/pdfsh +13 -0
  28. data/bin/pdfwalker +7 -0
  29. data/bin/shell/.irbrc +104 -0
  30. data/bin/shell/console.rb +136 -0
  31. data/bin/shell/hexdump.rb +83 -0
  32. data/origami.rb +36 -0
  33. data/origami/3d.rb +239 -0
  34. data/origami/acroform.rb +321 -0
  35. data/origami/actions.rb +299 -0
  36. data/origami/adobe/fdf.rb +259 -0
  37. data/origami/adobe/ppklite.rb +489 -0
  38. data/origami/annotations.rb +775 -0
  39. data/origami/array.rb +187 -0
  40. data/origami/boolean.rb +101 -0
  41. data/origami/catalog.rb +486 -0
  42. data/origami/destinations.rb +213 -0
  43. data/origami/dictionary.rb +188 -0
  44. data/origami/docmdp.rb +96 -0
  45. data/origami/encryption.rb +1293 -0
  46. data/origami/export.rb +283 -0
  47. data/origami/file.rb +222 -0
  48. data/origami/filters.rb +250 -0
  49. data/origami/filters/ascii.rb +189 -0
  50. data/origami/filters/ccitt.rb +515 -0
  51. data/origami/filters/crypt.rb +47 -0
  52. data/origami/filters/dct.rb +61 -0
  53. data/origami/filters/flate.rb +112 -0
  54. data/origami/filters/jbig2.rb +63 -0
  55. data/origami/filters/jpx.rb +53 -0
  56. data/origami/filters/lzw.rb +195 -0
  57. data/origami/filters/predictors.rb +276 -0
  58. data/origami/filters/runlength.rb +117 -0
  59. data/origami/font.rb +209 -0
  60. data/origami/functions.rb +93 -0
  61. data/origami/graphics.rb +33 -0
  62. data/origami/graphics/colors.rb +191 -0
  63. data/origami/graphics/instruction.rb +126 -0
  64. data/origami/graphics/path.rb +154 -0
  65. data/origami/graphics/patterns.rb +180 -0
  66. data/origami/graphics/state.rb +164 -0
  67. data/origami/graphics/text.rb +224 -0
  68. data/origami/graphics/xobject.rb +493 -0
  69. data/origami/header.rb +90 -0
  70. data/origami/linearization.rb +318 -0
  71. data/origami/metadata.rb +114 -0
  72. data/origami/name.rb +170 -0
  73. data/origami/null.rb +75 -0
  74. data/origami/numeric.rb +188 -0
  75. data/origami/obfuscation.rb +233 -0
  76. data/origami/object.rb +527 -0
  77. data/origami/outline.rb +59 -0
  78. data/origami/page.rb +559 -0
  79. data/origami/parser.rb +268 -0
  80. data/origami/parsers/fdf.rb +45 -0
  81. data/origami/parsers/pdf.rb +27 -0
  82. data/origami/parsers/pdf/linear.rb +113 -0
  83. data/origami/parsers/ppklite.rb +86 -0
  84. data/origami/pdf.rb +1144 -0
  85. data/origami/reference.rb +113 -0
  86. data/origami/signature.rb +474 -0
  87. data/origami/stream.rb +575 -0
  88. data/origami/string.rb +416 -0
  89. data/origami/trailer.rb +173 -0
  90. data/origami/webcapture.rb +87 -0
  91. data/origami/xfa.rb +3027 -0
  92. data/origami/xreftable.rb +447 -0
  93. data/templates/patterns.rb +66 -0
  94. data/templates/widgets.rb +173 -0
  95. data/templates/xdp.rb +92 -0
  96. data/tests/dataset/test.dummycrt +28 -0
  97. data/tests/dataset/test.dummykey +27 -0
  98. data/tests/tc_actions.rb +32 -0
  99. data/tests/tc_annotations.rb +85 -0
  100. data/tests/tc_pages.rb +37 -0
  101. data/tests/tc_pdfattach.rb +24 -0
  102. data/tests/tc_pdfencrypt.rb +110 -0
  103. data/tests/tc_pdfnew.rb +32 -0
  104. data/tests/tc_pdfparse.rb +98 -0
  105. data/tests/tc_pdfsig.rb +37 -0
  106. data/tests/tc_streams.rb +129 -0
  107. data/tests/ts_pdf.rb +45 -0
  108. metadata +193 -0
@@ -0,0 +1,46 @@
1
+ =begin
2
+
3
+ = File
4
+ about.rb
5
+
6
+ = Info
7
+ This file is part of Origami, PDF manipulation framework for Ruby
8
+ Copyright (C) 2010 Guillaume Delugr� <guillaume@security-labs.org>
9
+ All right reserved.
10
+
11
+ Origami is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU Lesser 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
+ Origami 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 Lesser General Public License for more details.
20
+
21
+ You should have received a copy of the GNU Lesser General Public License
22
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ =end
25
+
26
+ module PDFWalker
27
+
28
+ class Walker < Window
29
+
30
+ def about
31
+
32
+ AboutDialog.show(self,
33
+ {
34
+ :name => "PDF Walker",
35
+ :program_name => "PDF Walker",
36
+ :version => Origami::VERSION,
37
+ :copyright => "Copyright (C) 2010\nGuillaume Delugre, Sogeti-ESEC R&D <guillaume@security-labs.org>\nAll right reserved.",
38
+ :comments => "A graphical PDF parser front-end",
39
+ :license => File.read("#{File.dirname($0)}/../COPYING.LESSER")
40
+ })
41
+
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,132 @@
1
+ =begin
2
+
3
+ = File
4
+ config.rb
5
+
6
+ = Info
7
+ This file is part of Origami, PDF manipulation framework for Ruby
8
+ Copyright (C) 2010 Guillaume Delugr� <guillaume@security-labs.org>
9
+ All right reserved.
10
+
11
+ Origami is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU Lesser 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
+ Origami 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 Lesser General Public License for more details.
20
+
21
+ You should have received a copy of the GNU Lesser General Public License
22
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ =end
25
+
26
+ require 'yaml'
27
+
28
+ module PDFWalker
29
+
30
+ class Walker < Window
31
+
32
+ class Config
33
+
34
+ DEFAULT_CONFIG_FILE = "#{File.expand_path("~")}/.pdfwalker.conf.yml"
35
+ DEFAULT_CONFIG =
36
+ {
37
+ "Debug" =>
38
+ {
39
+ "Profiling" => false,
40
+ "ProfilingOutputDir" => "prof",
41
+ "Verbosity" => Parser::VERBOSE_INSANE,
42
+ "IgnoreFileHeader" => true
43
+ },
44
+
45
+ "UI" =>
46
+ {
47
+ "LastOpenedDocuments" => []
48
+ }
49
+ }
50
+
51
+ NLOG_RECENT_FILES = 5
52
+
53
+ def initialize(configfile = DEFAULT_CONFIG_FILE)
54
+
55
+ begin
56
+ @conf = YAML.load(File.open(configfile)) or DEFAULT_CONFIG
57
+ rescue Exception
58
+ ensure
59
+ @filename = configfile
60
+ set_missing_values
61
+ end
62
+
63
+ end
64
+
65
+ def last_opened_file(filepath)
66
+ @conf["UI"]['LastOpenedDocuments'].push(filepath).uniq!
67
+ @conf["UI"]['LastOpenedDocuments'].delete_at(0) while @conf["UI"]['LastOpenedDocuments'].size > NLOG_RECENT_FILES
68
+
69
+ save
70
+ end
71
+
72
+ def recent_files(n = NLOG_RECENT_FILES)
73
+ @conf["UI"]['LastOpenedDocuments'].last(n).reverse
74
+ end
75
+
76
+ def set_profiling(bool)
77
+ @conf["Debug"]['Profiling'] = bool
78
+ save
79
+ end
80
+
81
+ def profile?
82
+ @conf["Debug"]['Profiling']
83
+ end
84
+
85
+ def profile_output_dir
86
+ @conf["Debug"]['ProfilingOutputDir']
87
+ end
88
+
89
+ def set_ignore_header(bool)
90
+ @conf["Debug"]['IgnoreFileHeader'] = bool
91
+ save
92
+ end
93
+
94
+ def ignore_header?
95
+ @conf["Debug"]['IgnoreFileHeader']
96
+ end
97
+
98
+ def set_verbosity(level)
99
+
100
+ @conf["Debug"]['Verbosity'] = level
101
+ save
102
+
103
+ end
104
+
105
+ def verbosity
106
+ @conf["Debug"]['Verbosity']
107
+ end
108
+
109
+ def save
110
+ File.open(@filename, "w").write(@conf.to_yaml)
111
+ end
112
+
113
+ private
114
+
115
+ def set_missing_values
116
+
117
+ @conf ||= {}
118
+
119
+ DEFAULT_CONFIG.each_key do |cat|
120
+
121
+ @conf[cat] = {} unless @conf.include?(cat)
122
+
123
+ DEFAULT_CONFIG[cat].each_pair do |key, value|
124
+ @conf[cat][key] = value unless @conf[cat].include?(key)
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ end
131
+
132
+ end
@@ -0,0 +1,385 @@
1
+ =begin
2
+
3
+ = File
4
+ file.rb
5
+
6
+ = Info
7
+ This file is part of Origami, PDF manipulation framework for Ruby
8
+ Copyright (C) 2010 Guillaume Delugr� <guillaume@security-labs.org>
9
+ All right reserved.
10
+
11
+ Origami is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU Lesser 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
+ Origami 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 Lesser General Public License for more details.
20
+
21
+ You should have received a copy of the GNU Lesser General Public License
22
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ =end
25
+
26
+ require 'origami'
27
+ include Origami
28
+
29
+ module PDFWalker
30
+
31
+ class Walker < Window
32
+
33
+ attr_reader :opened
34
+ attr_reader :explore_history
35
+
36
+ def close
37
+
38
+ @opened = nil
39
+ @filename = ''
40
+ @explorer_history.clear
41
+
42
+ @treeview.clear
43
+ @objectview.clear
44
+ @hexview.clear
45
+
46
+ [
47
+ @file_menu_close, @file_menu_saveas, @file_menu_serialize, @file_menu_refresh,
48
+ @document_menu_search,
49
+ @document_menu_gotocatalog, @document_menu_gotopage, @document_menu_gotorev, @document_menu_gotoobj,
50
+ @document_menu_properties, @document_menu_sign, @document_menu_ur
51
+ ].each do |menu|
52
+ menu.sensitive = false
53
+ end
54
+
55
+ @statusbar.pop(@main_context)
56
+
57
+ GC.start
58
+ end
59
+
60
+ def open(filename = nil)
61
+
62
+ dialog = Gtk::FileChooserDialog.new("Open PDF File",
63
+ self,
64
+ FileChooser::ACTION_OPEN,
65
+ nil,
66
+ [Stock::CANCEL, Dialog::RESPONSE_CANCEL],
67
+ [Stock::OPEN, Dialog::RESPONSE_ACCEPT])
68
+
69
+ last_file = @config.recent_files.first
70
+ unless last_file.nil?
71
+ last_folder = last_file[0..last_file.size - File.basename(last_file).size - 1]
72
+ dialog.set_current_folder(last_folder) if File.directory?(last_folder)
73
+ end
74
+
75
+ dialog.filter = FileFilter.new.add_pattern("*.acrodata").add_pattern("*.pdf").add_pattern("*.fdf")
76
+
77
+ if filename or dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
78
+
79
+ create_progressbar
80
+
81
+ filename ||= dialog.filename
82
+ dialog.destroy
83
+
84
+ begin
85
+
86
+ if @help_menu_profile.active?
87
+ require 'ruby-prof'
88
+ RubyProf.start
89
+ end
90
+
91
+ target = parsefile(filename)
92
+
93
+ if @help_menu_profile.active?
94
+ result = RubyProf.stop
95
+ txtprinter = RubyProf::FlatPrinter.new(result)
96
+ htmlprinter = RubyProf::GraphHtmlPrinter.new(result)
97
+ txtprinter.print(File.new("#{@config.profile_output_dir}/#{File.basename(filename)}.log", "w"))
98
+ htmlprinter.print(File.new("#{@config.profile_output_dir}/#{File.basename(filename)}.log.html", "w"))
99
+ end
100
+
101
+ if target
102
+ close if @opened
103
+ @opened = target
104
+ @filename = filename
105
+
106
+ @config.last_opened_file(filename)
107
+ @config.save
108
+ update_recent_menu
109
+
110
+ @last_search_result = []
111
+ @last_search =
112
+ {
113
+ :expr => "",
114
+ :regexp => false,
115
+ :type => :body
116
+ }
117
+
118
+ self.reload
119
+
120
+ [
121
+ @file_menu_close, @file_menu_saveas, @file_menu_serialize, @file_menu_refresh,
122
+ @document_menu_search,
123
+ @document_menu_gotocatalog, @document_menu_gotopage, @document_menu_gotorev, @document_menu_gotoobj,
124
+ @document_menu_properties, @document_menu_sign, @document_menu_ur
125
+ ].each do |menu|
126
+ menu.sensitive = true
127
+ end
128
+
129
+ @explorer_history.clear
130
+
131
+ @statusbar.push(@main_context, "Viewing #{filename}")
132
+
133
+ if @opened.is_a?(PDF)
134
+ pagemenu = Menu.new
135
+ @document_menu_gotopage.remove_submenu
136
+ page_index = 1
137
+ @opened.pages.each do |page|
138
+ pagemenu.append(item = MenuItem.new(page_index.to_s).show)
139
+ item.signal_connect("activate") do @treeview.goto(page) end
140
+ page_index = page_index + 1
141
+ end
142
+ @document_menu_gotopage.set_submenu(pagemenu)
143
+
144
+ revmenu = Menu.new
145
+ @document_menu_gotorev.remove_submenu
146
+ rev_index = 1
147
+ @opened.revisions.each do |rev|
148
+ revmenu.append(item = MenuItem.new(rev_index.to_s).show)
149
+ item.signal_connect("activate") do @treeview.goto(rev) end
150
+ rev_index = rev_index + 1
151
+ end
152
+ @document_menu_gotorev.set_submenu(revmenu)
153
+
154
+ goto_catalog
155
+ end
156
+ end
157
+
158
+ rescue Exception => e
159
+ error("Error while parsing file.\n#{e} (#{e.class})\n" + e.backtrace.join("\n"))
160
+ end
161
+
162
+ close_progressbar
163
+ self.activate_focus
164
+
165
+ else
166
+ dialog.destroy
167
+ end
168
+
169
+ end
170
+
171
+ def deserialize
172
+
173
+ dialog = Gtk::FileChooserDialog.new("Open dump file",
174
+ self,
175
+ FileChooser::ACTION_OPEN,
176
+ nil,
177
+ [Stock::CANCEL, Dialog::RESPONSE_CANCEL],
178
+ [Stock::OPEN, Dialog::RESPONSE_ACCEPT])
179
+
180
+ dialog.current_folder = "#{Dir.pwd}/dumps"
181
+ dialog.filter = FileFilter.new.add_pattern("*.gz")
182
+
183
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
184
+
185
+ if @opened then close end
186
+ filename = dialog.filename
187
+
188
+ begin
189
+
190
+ @opened = PDF.deserialize(filename)
191
+
192
+ self.reload
193
+
194
+ [ @file_menu_close, @file_menu_saveas, @file_menu_serialize, @file_menu_refresh,
195
+ @document_menu_properties, @document_menu_sign, @document_menu_ur ].each do |menu|
196
+ menu.sensitive = true
197
+ end
198
+
199
+ @explorer_history.clear
200
+
201
+ @statusbar.push(@main_context, "Viewing dump of #{filename}")
202
+
203
+ rescue Exception => e
204
+ error("This file cannot be loaded.\n#{e} (#{e.class})")
205
+ end
206
+
207
+ end
208
+
209
+ dialog.destroy
210
+
211
+ end
212
+
213
+ def serialize
214
+
215
+ dialog = Gtk::FileChooserDialog.new("Save dump file",
216
+ self,
217
+ Gtk::FileChooser::ACTION_SAVE,
218
+ nil,
219
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
220
+ [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
221
+ )
222
+
223
+ dialog.do_overwrite_confirmation = true
224
+ dialog.current_folder = "#{Dir.pwd}/dumps"
225
+ dialog.current_name = "#{File.basename(@filename)}.dmp.gz"
226
+ dialog.filter = FileFilter.new.add_pattern("*.gz")
227
+
228
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
229
+ @opened.serialize(dialog.filename)
230
+ end
231
+
232
+ dialog.destroy
233
+ end
234
+
235
+ def save_data(caption, data, filename = "")
236
+
237
+ dialog = Gtk::FileChooserDialog.new(caption,
238
+ self,
239
+ Gtk::FileChooser::ACTION_SAVE,
240
+ nil,
241
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
242
+ [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
243
+ )
244
+
245
+ dialog.do_overwrite_confirmation = true
246
+ dialog.current_name = File.basename(filename)
247
+ dialog.filter = FileFilter.new.add_pattern("*.*")
248
+
249
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
250
+ fd = File.open(dialog.filename, "w").binmode
251
+ fd << data
252
+ fd.close
253
+ end
254
+
255
+ dialog.destroy
256
+ end
257
+
258
+ def save
259
+
260
+ dialog = Gtk::FileChooserDialog.new("Save PDF file",
261
+ self,
262
+ Gtk::FileChooser::ACTION_SAVE,
263
+ nil,
264
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
265
+ [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
266
+ )
267
+
268
+ dialog.filter = FileFilter.new.add_pattern("*.acrodata").add_pattern("*.pdf").add_pattern("*.fdf")
269
+
270
+ folder = @filename[0..@filename.size - File.basename(@filename).size - 1]
271
+ dialog.set_current_folder(folder)
272
+
273
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
274
+ @opened.save(dialog.filename)
275
+ end
276
+
277
+ dialog.destroy
278
+ end
279
+
280
+ def save_dot
281
+
282
+ dialog = Gtk::FileChooserDialog.new("Save dot file",
283
+ self,
284
+ Gtk::FileChooser::ACTION_SAVE,
285
+ nil,
286
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
287
+ [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
288
+ )
289
+
290
+ dialog.filter = FileFilter.new.add_pattern("*.dot")
291
+
292
+ folder = @filename[0..@filename.size - File.basename(@filename).size - 1]
293
+ dialog.set_current_folder(folder)
294
+
295
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
296
+ @opened.export_to_graph(dialog.filename)
297
+ end
298
+
299
+ dialog.destroy
300
+ end
301
+
302
+ def save_graphml
303
+
304
+ dialog = Gtk::FileChooserDialog.new("Save GraphML file",
305
+ self,
306
+ Gtk::FileChooser::ACTION_SAVE,
307
+ nil,
308
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
309
+ [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
310
+ )
311
+
312
+ dialog.filter = FileFilter.new.add_pattern("*.graphml")
313
+
314
+ folder = @filename[0..@filename.size - File.basename(@filename).size - 1]
315
+ dialog.set_current_folder(folder)
316
+
317
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
318
+ @opened.export_to_graphml(dialog.filename)
319
+ end
320
+
321
+ dialog.destroy
322
+ end
323
+
324
+ private
325
+
326
+ def parsefile(filename)
327
+ update_bar = lambda { |obj|
328
+ if @progressbar then @progressbar.pulse end
329
+ while (Gtk.events_pending?) do Gtk.main_iteration end
330
+ }
331
+
332
+ prompt_passwd = lambda {
333
+ passwd = ""
334
+
335
+ dialog = Gtk::Dialog.new(
336
+ "This document is encrypted",
337
+ nil,
338
+ Gtk::Dialog::MODAL,
339
+ [ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK ],
340
+ [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ]
341
+ )
342
+
343
+ dialog.set_default_response(Gtk::Dialog::RESPONSE_OK)
344
+
345
+ label = Gtk::Label.new("Please enter password:")
346
+ entry = Gtk::Entry.new
347
+ entry.signal_connect('activate') {
348
+ dialog.response(Gtk::Dialog::RESPONSE_OK)
349
+ }
350
+
351
+ dialog.vbox.add(label)
352
+ dialog.vbox.add(entry)
353
+ dialog.show_all
354
+
355
+ dialog.run do |response|
356
+ if response == Gtk::Dialog::RESPONSE_OK
357
+ passwd = entry.text
358
+ end
359
+ end
360
+
361
+ dialog.destroy
362
+
363
+ return passwd
364
+ }
365
+
366
+ PDF.read(filename,
367
+ :verbosity => Parser::VERBOSE_INSANE,
368
+ :ignoreerrors => false,
369
+ :callback => update_bar,
370
+ :prompt_password => prompt_passwd
371
+ )
372
+ end
373
+
374
+ def create_progressbar
375
+ @progresswin = Dialog.new("Parsing file...", self, Dialog::MODAL)
376
+ @progresswin.vbox.add(@progressbar = ProgressBar.new.set_pulse_step(0.05))
377
+ @progresswin.show_all
378
+ end
379
+
380
+ def close_progressbar
381
+ @progresswin.close
382
+ end
383
+ end
384
+
385
+ end