origami 1.0.2

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