origami 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/bin/gui/config.rb +2 -1
- data/bin/gui/file.rb +118 -240
- data/bin/gui/gtkhex.rb +5 -5
- data/bin/gui/hexview.rb +20 -16
- data/bin/gui/imgview.rb +1 -1
- data/bin/gui/menu.rb +138 -158
- data/bin/gui/properties.rb +46 -48
- data/bin/gui/signing.rb +183 -214
- data/bin/gui/textview.rb +1 -1
- data/bin/gui/treeview.rb +13 -7
- data/bin/gui/walker.rb +102 -71
- data/bin/gui/xrefs.rb +1 -1
- data/bin/pdf2ruby +3 -3
- data/bin/pdfcop +18 -11
- data/bin/pdfextract +14 -5
- data/bin/pdfmetadata +3 -3
- data/bin/shell/console.rb +8 -8
- data/bin/shell/hexdump.rb +4 -4
- data/examples/attachments/nested_document.rb +1 -1
- data/examples/javascript/hello_world.rb +3 -3
- data/lib/origami.rb +0 -1
- data/lib/origami/acroform.rb +3 -3
- data/lib/origami/array.rb +1 -3
- data/lib/origami/boolean.rb +1 -3
- data/lib/origami/catalog.rb +3 -9
- data/lib/origami/destinations.rb +2 -2
- data/lib/origami/dictionary.rb +15 -29
- data/lib/origami/encryption.rb +334 -692
- data/lib/origami/extensions/fdf.rb +3 -2
- data/lib/origami/extensions/ppklite.rb +5 -9
- data/lib/origami/filespec.rb +2 -2
- data/lib/origami/filters.rb +54 -36
- data/lib/origami/filters/ascii.rb +67 -49
- data/lib/origami/filters/ccitt.rb +4 -236
- data/lib/origami/filters/ccitt/tables.rb +267 -0
- data/lib/origami/filters/crypt.rb +1 -1
- data/lib/origami/filters/dct.rb +0 -1
- data/lib/origami/filters/flate.rb +3 -43
- data/lib/origami/filters/lzw.rb +62 -99
- data/lib/origami/filters/predictors.rb +135 -105
- data/lib/origami/filters/runlength.rb +34 -22
- data/lib/origami/graphics.rb +2 -2
- data/lib/origami/graphics/colors.rb +89 -63
- data/lib/origami/graphics/path.rb +14 -14
- data/lib/origami/graphics/patterns.rb +31 -33
- data/lib/origami/graphics/render.rb +0 -1
- data/lib/origami/graphics/state.rb +9 -9
- data/lib/origami/graphics/text.rb +17 -17
- data/lib/origami/graphics/xobject.rb +102 -92
- data/lib/origami/javascript.rb +91 -68
- data/lib/origami/linearization.rb +22 -20
- data/lib/origami/metadata.rb +1 -1
- data/lib/origami/name.rb +1 -3
- data/lib/origami/null.rb +1 -3
- data/lib/origami/numeric.rb +3 -13
- data/lib/origami/object.rb +100 -72
- data/lib/origami/page.rb +24 -28
- data/lib/origami/parser.rb +34 -51
- data/lib/origami/parsers/fdf.rb +2 -2
- data/lib/origami/parsers/pdf.rb +41 -18
- data/lib/origami/parsers/pdf/lazy.rb +83 -46
- data/lib/origami/parsers/pdf/linear.rb +19 -10
- data/lib/origami/parsers/ppklite.rb +1 -1
- data/lib/origami/pdf.rb +150 -206
- data/lib/origami/reference.rb +4 -6
- data/lib/origami/signature.rb +76 -48
- data/lib/origami/stream.rb +69 -63
- data/lib/origami/string.rb +2 -19
- data/lib/origami/trailer.rb +25 -22
- data/lib/origami/version.rb +1 -1
- data/lib/origami/xfa.rb +6 -4
- data/lib/origami/xreftable.rb +29 -29
- data/test/test_annotations.rb +16 -38
- data/test/test_pdf_attachment.rb +1 -1
- data/test/test_pdf_parse.rb +1 -1
- data/test/test_xrefs.rb +2 -2
- metadata +4 -4
- data/lib/origami/export.rb +0 -247
data/bin/gui/properties.rb
CHANGED
@@ -45,38 +45,38 @@ module PDFWalker
|
|
45
45
|
def initialize(parent, pdf)
|
46
46
|
super("Document properties", parent, Dialog::MODAL, [Stock::CLOSE, Dialog::RESPONSE_NONE])
|
47
47
|
|
48
|
-
|
49
|
-
|
48
|
+
file_frame = create_file_frame(parent)
|
49
|
+
pdf_frame = create_document_frame(pdf)
|
50
|
+
|
51
|
+
vbox.add(file_frame)
|
52
|
+
vbox.add(pdf_frame)
|
53
|
+
|
54
|
+
signal_connect('response') { destroy }
|
55
|
+
|
56
|
+
show_all
|
57
|
+
end
|
50
58
|
|
51
|
-
|
52
|
-
|
53
|
-
|
59
|
+
private
|
60
|
+
|
61
|
+
def create_file_frame(parent)
|
62
|
+
file_frame = Frame.new(" File properties ")
|
63
|
+
stat = File.stat(parent.filename)
|
54
64
|
|
55
65
|
labels =
|
56
66
|
[
|
57
67
|
[ "Filename:", parent.filename ],
|
58
68
|
[ "File size:", "#{File.size(parent.filename)} bytes" ],
|
59
|
-
[ "MD5:",
|
69
|
+
[ "MD5:", Digest::MD5.file(parent.filename).hexdigest ],
|
60
70
|
[ "Read-only:", "#{not stat.writable?}" ],
|
61
|
-
[ "Creation date:",
|
62
|
-
[ "Last modified:",
|
71
|
+
[ "Creation date:", stat.ctime.to_s ],
|
72
|
+
[ "Last modified:", stat.mtime.to_s ]
|
63
73
|
]
|
64
74
|
|
65
|
-
|
66
|
-
|
67
|
-
row = 0
|
68
|
-
labels.each do |name, value|
|
69
|
-
doctable.attach(Label.new(name).set_alignment(1,0), 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
70
|
-
doctable.attach(Label.new(value).set_alignment(0,0), 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
71
|
-
|
72
|
-
row = row.succ
|
73
|
-
end
|
74
|
-
|
75
|
-
docframe.border_width = 5
|
76
|
-
docframe.shadow_type = Gtk::SHADOW_IN
|
77
|
-
docframe.add(doctable)
|
75
|
+
create_table(file_frame, labels)
|
76
|
+
end
|
78
77
|
|
79
|
-
|
78
|
+
def create_document_frame(pdf)
|
79
|
+
pdf_frame = Frame.new(" PDF properties ")
|
80
80
|
|
81
81
|
pdf_version = pdf.header.to_f
|
82
82
|
if pdf_version >= 1.0 and pdf_version <= 1.7
|
@@ -87,40 +87,38 @@ module PDFWalker
|
|
87
87
|
|
88
88
|
labels =
|
89
89
|
[
|
90
|
-
[ "Version:",
|
91
|
-
[ "Number of revisions:",
|
90
|
+
[ "Version:", "#{pdf_version} (Acrobat #{acrobat_version})" ],
|
91
|
+
[ "Number of revisions:", "#{pdf.revisions.size}" ],
|
92
92
|
[ "Number of indirect objects:", "#{pdf.indirect_objects.size}" ],
|
93
|
-
[ "Number of pages:",
|
94
|
-
[ "Linearized:",
|
95
|
-
[ "Encrypted:",
|
96
|
-
[ "Signed:",
|
97
|
-
[ "Has usage rights:",
|
98
|
-
[ "Form:",
|
99
|
-
[ "XFA form:",
|
100
|
-
[ "Document information:", pdf.document_info?
|
101
|
-
[ "Metadata:",
|
93
|
+
[ "Number of pages:", "#{pdf.pages.count}" ],
|
94
|
+
[ "Linearized:", boolean_text(pdf.linearized?) ],
|
95
|
+
[ "Encrypted:", boolean_text(pdf.encrypted?) ],
|
96
|
+
[ "Signed:", boolean_text(pdf.signed?) ],
|
97
|
+
[ "Has usage rights:", boolean_text(pdf.usage_rights?) ],
|
98
|
+
[ "Form:", boolean_text(pdf.form?) ],
|
99
|
+
[ "XFA form:", boolean_text(pdf.xfa_form?) ],
|
100
|
+
[ "Document information:", boolean_text(pdf.document_info?) ],
|
101
|
+
[ "Metadata:", boolean_text(pdf.metadata?) ]
|
102
102
|
]
|
103
103
|
|
104
|
-
|
104
|
+
create_table(pdf_frame, labels)
|
105
|
+
end
|
105
106
|
|
106
|
-
|
107
|
-
labels.
|
108
|
-
pdftable.attach(Label.new(name).set_alignment(1,0), 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 4, 4)
|
109
|
-
pdftable.attach(Label.new(value).set_alignment(0,0), 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
107
|
+
def create_table(frame, labels)
|
108
|
+
table = Table.new(labels.size + 1, 3)
|
110
109
|
|
111
|
-
|
110
|
+
labels.each_with_index do |label, row|
|
111
|
+
table.attach(Label.new(label[0]).set_alignment(1,0), 0, 1, row, row + 1, Gtk::FILL, Gtk::SHRINK, 4, 4)
|
112
|
+
table.attach(Label.new(label[1]).set_alignment(0,0), 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
112
113
|
end
|
113
114
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
vbox.add(docframe)
|
119
|
-
vbox.add(pdfframe)
|
120
|
-
|
121
|
-
signal_connect('response') { destroy }
|
115
|
+
frame.border_width = 5
|
116
|
+
frame.shadow_type = Gtk::SHADOW_IN
|
117
|
+
frame.add(table)
|
118
|
+
end
|
122
119
|
|
123
|
-
|
120
|
+
def boolean_text(value)
|
121
|
+
value ? 'yes' : 'no'
|
124
122
|
end
|
125
123
|
end
|
126
124
|
end
|
data/bin/gui/signing.rb
CHANGED
@@ -34,21 +34,7 @@ module PDFWalker
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def open_private_key_dialog(page)
|
37
|
-
|
38
|
-
@parent,
|
39
|
-
FileChooser::ACTION_OPEN,
|
40
|
-
nil,
|
41
|
-
[Stock::CANCEL, Dialog::RESPONSE_CANCEL],
|
42
|
-
[Stock::OPEN, Dialog::RESPONSE_ACCEPT])
|
43
|
-
|
44
|
-
filter = FileFilter.new
|
45
|
-
filter.add_pattern("*.key")
|
46
|
-
filter.add_pattern("*.pem")
|
47
|
-
filter.add_pattern("*.der")
|
48
|
-
|
49
|
-
dialog.set_filter(filter)
|
50
|
-
|
51
|
-
if dialog.run == Dialog::RESPONSE_ACCEPT
|
37
|
+
file_chooser_dialog('Choose a private RSA key', '*.key', '*.pem', '*.der') do |dialog|
|
52
38
|
begin
|
53
39
|
@pkey = OpenSSL::PKey::RSA.new(File.binread(dialog.filename))
|
54
40
|
|
@@ -64,31 +50,15 @@ module PDFWalker
|
|
64
50
|
@ca = [] # Shall be added to the GUI
|
65
51
|
end
|
66
52
|
end
|
67
|
-
|
68
|
-
dialog.destroy
|
69
53
|
end
|
70
54
|
|
71
55
|
def open_certificate_dialog(page)
|
72
|
-
|
73
|
-
@parent,
|
74
|
-
FileChooser::ACTION_OPEN,
|
75
|
-
nil,
|
76
|
-
[Stock::CANCEL, Dialog::RESPONSE_CANCEL],
|
77
|
-
[Stock::OPEN, Dialog::RESPONSE_ACCEPT])
|
78
|
-
filter = FileFilter.new
|
79
|
-
filter.add_pattern("*.crt")
|
80
|
-
filter.add_pattern("*.cer")
|
81
|
-
filter.add_pattern("*.pem")
|
82
|
-
filter.add_pattern("*.der")
|
83
|
-
|
84
|
-
dialog.set_filter(filter)
|
85
|
-
|
86
|
-
if dialog.run == Dialog::RESPONSE_ACCEPT
|
56
|
+
file_chooser_dialog('Choose a x509 certificate', '*.crt', '*.cer', '*.pem', '*.der') do |dialog|
|
87
57
|
begin
|
88
58
|
@cert = OpenSSL::X509::Certificate.new(File.binread(dialog.filename))
|
89
59
|
|
90
60
|
@certfilename.set_text(dialog.filename)
|
91
|
-
|
61
|
+
set_page_complete(page, true) if @pkey
|
92
62
|
|
93
63
|
rescue
|
94
64
|
@parent.error("Error loading file '#{File.basename(dialog.filename)}'")
|
@@ -100,43 +70,13 @@ module PDFWalker
|
|
100
70
|
@ca = [] # Shall be added to the GUI
|
101
71
|
end
|
102
72
|
end
|
103
|
-
|
104
|
-
dialog.destroy
|
105
73
|
end
|
106
74
|
|
107
75
|
def open_pkcs12_file_dialog(page)
|
108
76
|
|
109
|
-
|
110
|
-
dialog = Dialog.new("Enter passphrase",
|
111
|
-
@parent,
|
112
|
-
Dialog::MODAL,
|
113
|
-
[Stock::OK, Dialog::RESPONSE_OK]
|
114
|
-
)
|
115
|
-
|
116
|
-
pwd_entry = Entry.new.set_visibility(false).show
|
117
|
-
dialog.vbox.pack_start(pwd_entry, true, true, 0)
|
118
|
-
|
119
|
-
pwd = (dialog.run == Dialog::RESPONSE_OK) ? pwd_entry.text : ""
|
120
|
-
|
121
|
-
dialog.destroy
|
122
|
-
return pwd
|
123
|
-
end
|
124
|
-
|
125
|
-
dialog = FileChooserDialog.new("Open PKCS12 container",
|
126
|
-
@parent,
|
127
|
-
FileChooser::ACTION_OPEN,
|
128
|
-
nil,
|
129
|
-
[Stock::CANCEL, Dialog::RESPONSE_CANCEL],
|
130
|
-
[Stock::OPEN, Dialog::RESPONSE_ACCEPT])
|
131
|
-
filter = FileFilter.new
|
132
|
-
filter.add_pattern("*.pfx")
|
133
|
-
filter.add_pattern("*.p12")
|
134
|
-
|
135
|
-
dialog.filter = filter
|
136
|
-
|
137
|
-
if dialog.run == Dialog::RESPONSE_ACCEPT
|
77
|
+
file_chooser_dialog('Open PKCS12 container', '*.pfx', '*.p12') do |dialog|
|
138
78
|
begin
|
139
|
-
p12 = OpenSSL::PKCS12::PKCS12.new(File.binread(dialog.filename),
|
79
|
+
p12 = OpenSSL::PKCS12::PKCS12.new(File.binread(dialog.filename), method(:prompt_passphrase))
|
140
80
|
|
141
81
|
raise TypeError, "PKCS12 does not contain a RSA key" unless p12.key.is_a?(OpenSSL::PKey::RSA)
|
142
82
|
raise TypeError, "PKCS12 does not contain a x509 certificate" unless p12.certificate.is_a?(OpenSSL::X509::Certificate)
|
@@ -153,9 +93,71 @@ module PDFWalker
|
|
153
93
|
@pkey, @cert, @ca = nil, nil, []
|
154
94
|
@p12filename.text = ""
|
155
95
|
set_page_complete(page, false)
|
156
|
-
|
157
96
|
end
|
158
97
|
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def create_keypair_import_page
|
101
|
+
labels =
|
102
|
+
[
|
103
|
+
[ "Private RSA key:", @pkeyfilename = Entry.new, pkeychoosebtn = Button.new(Gtk::Stock::OPEN) ],
|
104
|
+
[ "Public certificate:", @certfilename = Entry.new, certchoosebtn = Button.new(Gtk::Stock::OPEN) ]
|
105
|
+
]
|
106
|
+
|
107
|
+
row = 0
|
108
|
+
table = Table.new(2, 3)
|
109
|
+
labels.each do |lbl, entry, btn|
|
110
|
+
entry.editable = entry.sensitive = false
|
111
|
+
|
112
|
+
table.attach(Label.new(lbl).set_alignment(1,0), 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
113
|
+
table.attach(entry, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
114
|
+
table.attach(btn, 2, 3, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
115
|
+
|
116
|
+
row = row.succ
|
117
|
+
end
|
118
|
+
|
119
|
+
pkeychoosebtn.signal_connect('clicked') { open_private_key_dialog(table) }
|
120
|
+
certchoosebtn.signal_connect('clicked') { open_certificate_dialog(table) }
|
121
|
+
|
122
|
+
append_page(table)
|
123
|
+
set_page_title(table, "Import a public/private key pair")
|
124
|
+
set_page_type(table, Assistant::PAGE_CONTENT)
|
125
|
+
end
|
126
|
+
|
127
|
+
def prompt_passphrase
|
128
|
+
dialog = Dialog.new("Enter passphrase",
|
129
|
+
@parent,
|
130
|
+
Dialog::MODAL,
|
131
|
+
[Stock::OK, Dialog::RESPONSE_OK]
|
132
|
+
)
|
133
|
+
|
134
|
+
pwd_entry = Entry.new.set_visibility(false).show
|
135
|
+
dialog.vbox.pack_start(pwd_entry, true, true, 0)
|
136
|
+
|
137
|
+
pwd = pwd_entry.text if dialog.run == Dialog::RESPONSE_OK
|
138
|
+
|
139
|
+
dialog.destroy
|
140
|
+
pwd.to_s
|
141
|
+
end
|
142
|
+
|
143
|
+
def file_chooser_dialog(title, *patterns)
|
144
|
+
dialog = FileChooserDialog.new(title,
|
145
|
+
@parent,
|
146
|
+
FileChooser::ACTION_OPEN,
|
147
|
+
nil,
|
148
|
+
[Stock::CANCEL, Dialog::RESPONSE_CANCEL],
|
149
|
+
[Stock::OPEN, Dialog::RESPONSE_ACCEPT])
|
150
|
+
|
151
|
+
filter = FileFilter.new
|
152
|
+
patterns.each do |pattern|
|
153
|
+
filter.add_pattern(pattern)
|
154
|
+
end
|
155
|
+
|
156
|
+
dialog.set_filter(filter)
|
157
|
+
|
158
|
+
if dialog.run == Dialog::RESPONSE_ACCEPT
|
159
|
+
yield(dialog)
|
160
|
+
end
|
159
161
|
|
160
162
|
dialog.destroy
|
161
163
|
end
|
@@ -180,33 +182,7 @@ module PDFWalker
|
|
180
182
|
signal_connect('close') { self.destroy }
|
181
183
|
|
182
184
|
signal_connect('apply') {
|
183
|
-
rights =
|
184
|
-
|
185
|
-
rights << Origami::UsageRights::Rights::DOCUMENT_FULLSAVE if @document_fullsave.active?
|
186
|
-
|
187
|
-
rights << Origami::UsageRights::Rights::ANNOTS_CREATE if @annots_create.active?
|
188
|
-
rights << Origami::UsageRights::Rights::ANNOTS_DELETE if @annots_delete.active?
|
189
|
-
rights << Origami::UsageRights::Rights::ANNOTS_MODIFY if @annots_modify.active?
|
190
|
-
rights << Origami::UsageRights::Rights::ANNOTS_COPY if @annots_copy.active?
|
191
|
-
rights << Origami::UsageRights::Rights::ANNOTS_IMPORT if @annots_import.active?
|
192
|
-
rights << Origami::UsageRights::Rights::ANNOTS_EXPORT if @annots_export.active?
|
193
|
-
rights << Origami::UsageRights::Rights::ANNOTS_ONLINE if @annots_online.active?
|
194
|
-
rights << Origami::UsageRights::Rights::ANNOTS_SUMMARYVIEW if @annots_sumview.active?
|
195
|
-
|
196
|
-
rights << Origami::UsageRights::Rights::FORM_FILLIN if @form_fillin.active?
|
197
|
-
rights << Origami::UsageRights::Rights::FORM_IMPORT if @form_import.active?
|
198
|
-
rights << Origami::UsageRights::Rights::FORM_EXPORT if @form_export.active?
|
199
|
-
rights << Origami::UsageRights::Rights::FORM_SUBMITSTANDALONE if @form_submit.active?
|
200
|
-
rights << Origami::UsageRights::Rights::FORM_SPAWNTEMPLATE if @form_spawntemplate.active?
|
201
|
-
rights << Origami::UsageRights::Rights::FORM_BARCODEPLAINTEXT if @form_barcode.active?
|
202
|
-
rights << Origami::UsageRights::Rights::FORM_ONLINE if @form_online.active?
|
203
|
-
|
204
|
-
rights << Origami::UsageRights::Rights::SIGNATURE_MODIFY if @signature_modify.active?
|
205
|
-
|
206
|
-
rights << Origami::UsageRights::Rights::EF_CREATE if @ef_create.active?
|
207
|
-
rights << Origami::UsageRights::Rights::EF_DELETE if @ef_delete.active?
|
208
|
-
rights << Origami::UsageRights::Rights::EF_MODIFY if @ef_modify.active?
|
209
|
-
rights << Origami::UsageRights::Rights::EF_IMPORT if @ef_import.active?
|
185
|
+
rights = selected_usage_rights
|
210
186
|
|
211
187
|
begin
|
212
188
|
pdf.enable_usage_rights(@cert, @pkey, *rights)
|
@@ -230,12 +206,43 @@ module PDFWalker
|
|
230
206
|
|
231
207
|
private
|
232
208
|
|
209
|
+
def selected_usage_rights
|
210
|
+
[
|
211
|
+
[ Origami::UsageRights::Rights::DOCUMENT_FULLSAVE, @document_fullsave ],
|
212
|
+
|
213
|
+
[ Origami::UsageRights::Rights::ANNOTS_CREATE, @annots_create ],
|
214
|
+
[ Origami::UsageRights::Rights::ANNOTS_DELETE, @annots_delete ],
|
215
|
+
[ Origami::UsageRights::Rights::ANNOTS_MODIFY, @annots_modify ],
|
216
|
+
[ Origami::UsageRights::Rights::ANNOTS_COPY, @annots_copy ],
|
217
|
+
[ Origami::UsageRights::Rights::ANNOTS_IMPORT, @annots_import ],
|
218
|
+
[ Origami::UsageRights::Rights::ANNOTS_EXPORT, @annots_export ],
|
219
|
+
[ Origami::UsageRights::Rights::ANNOTS_ONLINE, @annots_online ],
|
220
|
+
[ Origami::UsageRights::Rights::ANNOTS_SUMMARYVIEW, @annots_sumview ],
|
221
|
+
|
222
|
+
[ Origami::UsageRights::Rights::FORM_FILLIN, @form_fillin ],
|
223
|
+
[ Origami::UsageRights::Rights::FORM_IMPORT, @form_import ],
|
224
|
+
[ Origami::UsageRights::Rights::FORM_EXPORT, @form_export ],
|
225
|
+
[ Origami::UsageRights::Rights::FORM_SUBMITSTANDALONE, @form_submit ],
|
226
|
+
[ Origami::UsageRights::Rights::FORM_SPAWNTEMPLATE, @form_spawntemplate ],
|
227
|
+
[ Origami::UsageRights::Rights::FORM_BARCODEPLAINTEXT, @form_barcode ],
|
228
|
+
[ Origami::UsageRights::Rights::FORM_ONLINE, @form_online ],
|
229
|
+
|
230
|
+
[ Origami::UsageRights::Rights::SIGNATURE_MODIFY, @signature_modify ],
|
231
|
+
|
232
|
+
[ Origami::UsageRights::Rights::EF_CREATE, @ef_create ],
|
233
|
+
[ Origami::UsageRights::Rights::EF_DELETE, @ef_delete ],
|
234
|
+
[ Origami::UsageRights::Rights::EF_MODIFY, @ef_modify ],
|
235
|
+
[ Origami::UsageRights::Rights::EF_IMPORT, @ef_import ],
|
236
|
+
].select { |_, button| button.active? }
|
237
|
+
.map { |right, _| right }
|
238
|
+
end
|
239
|
+
|
233
240
|
def create_intro_page
|
234
|
-
intro = <<-INTRO
|
235
|
-
You are about to enable Usage Rights for the current PDF document.
|
236
|
-
To enable these features, you need to have an Adobe public/private key pair in your possession.
|
241
|
+
intro = <<-INTRO.gsub(/^\s+/, '')
|
242
|
+
You are about to enable Usage Rights for the current PDF document.
|
243
|
+
To enable these features, you need to have an Adobe public/private key pair in your possession.
|
237
244
|
|
238
|
-
Make sure you have adobe.crt and adobe.key located in the current directory.
|
245
|
+
Make sure you have adobe.crt and adobe.key located in the current directory.
|
239
246
|
INTRO
|
240
247
|
|
241
248
|
vbox = VBox.new(false, 5)
|
@@ -251,125 +258,115 @@ Make sure you have adobe.crt and adobe.key located in the current directory.
|
|
251
258
|
set_page_complete(vbox, true)
|
252
259
|
end
|
253
260
|
|
254
|
-
def
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
[ "Private RSA key:", @pkeyfilename = Entry.new, pkeychoosebtn = Button.new(Gtk::Stock::OPEN) ],
|
259
|
-
[ "Public certificate:", @certfilename = Entry.new, certchoosebtn = Button.new(Gtk::Stock::OPEN) ]
|
260
|
-
]
|
261
|
-
|
262
|
-
row = 0
|
263
|
-
table = Table.new(2, 3)
|
264
|
-
labels.each do |lbl, entry, btn|
|
265
|
-
entry.editable = entry.sensitive = false
|
261
|
+
def create_rights_frame(name)
|
262
|
+
frame = Frame.new(name)
|
263
|
+
frame.border_width = 5
|
264
|
+
frame.shadow_type = Gtk::SHADOW_IN
|
266
265
|
|
267
|
-
|
268
|
-
table.attach(entry, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
269
|
-
table.attach(btn, 2, 3, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
270
|
-
|
271
|
-
row = row.succ
|
272
|
-
end
|
273
|
-
|
274
|
-
pkeychoosebtn.signal_connect('clicked') { open_private_key_dialog(table) }
|
275
|
-
certchoosebtn.signal_connect('clicked') { open_certificate_dialog(table) }
|
276
|
-
|
277
|
-
append_page(table)
|
278
|
-
set_page_title(table, "Import a public/private key pair")
|
279
|
-
set_page_type(table, Assistant::PAGE_CONTENT)
|
266
|
+
frame
|
280
267
|
end
|
281
268
|
|
282
|
-
def
|
283
|
-
|
269
|
+
def create_document_rights_frame
|
270
|
+
frame = create_rights_frame(" Document ")
|
284
271
|
|
285
|
-
|
286
|
-
docframe.border_width = 5
|
287
|
-
docframe.shadow_type = Gtk::SHADOW_IN
|
272
|
+
@document_fullsave = CheckButton.new("Full Save").set_active(true)
|
288
273
|
|
289
|
-
|
290
|
-
|
291
|
-
|
274
|
+
doc_table = Table.new(1, 2)
|
275
|
+
doc_table.attach(@document_fullsave, 0, 1, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
276
|
+
frame.add(doc_table)
|
277
|
+
end
|
292
278
|
|
293
|
-
|
294
|
-
|
295
|
-
annotsframe.shadow_type = Gtk::SHADOW_IN
|
279
|
+
def create_annotations_rights_frame
|
280
|
+
frame = create_rights_frame(" Annotations ")
|
296
281
|
|
297
|
-
|
282
|
+
annots_table = Table.new(4, 2)
|
298
283
|
annots =
|
299
284
|
[
|
300
|
-
[ @annots_create = CheckButton.new("Create")
|
301
|
-
[ @annots_delete = CheckButton.new("Delete")
|
302
|
-
[ @annots_modify = CheckButton.new("Modify")
|
303
|
-
[ @annots_copy = CheckButton.new("Copy")
|
285
|
+
[ @annots_create = CheckButton.new("Create"), @annots_import = CheckButton.new("Import") ],
|
286
|
+
[ @annots_delete = CheckButton.new("Delete"), @annots_export = CheckButton.new("Export") ],
|
287
|
+
[ @annots_modify = CheckButton.new("Modify"), @annots_online = CheckButton.new("Online") ],
|
288
|
+
[ @annots_copy = CheckButton.new("Copy"), @annots_sumview = CheckButton.new("Summary View") ]
|
304
289
|
]
|
305
290
|
|
306
|
-
|
307
|
-
|
308
|
-
annotstable.attach(col1, 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
309
|
-
annotstable.attach(col2, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
291
|
+
annots.each_with_index do |cols, row|
|
292
|
+
col1, col2 = cols
|
310
293
|
|
311
|
-
|
294
|
+
col1.active = true
|
295
|
+
col2.active = true
|
296
|
+
|
297
|
+
annots_table.attach(col1, 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
298
|
+
annots_table.attach(col2, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
312
299
|
end
|
313
300
|
|
314
|
-
|
301
|
+
frame.add(annots_table)
|
302
|
+
end
|
315
303
|
|
316
|
-
|
317
|
-
|
318
|
-
formframe.shadow_type = Gtk::SHADOW_IN
|
304
|
+
def create_form_rights_frame
|
305
|
+
frame = create_rights_frame(" Forms ")
|
319
306
|
|
320
|
-
|
307
|
+
form_table = Table.new(4, 2)
|
321
308
|
forms =
|
322
309
|
[
|
323
|
-
[ @form_fillin = CheckButton.new("Fill in")
|
324
|
-
[ @form_import = CheckButton.new("Import")
|
325
|
-
[ @form_export = CheckButton.new("Export")
|
326
|
-
[ @form_submit = CheckButton.new("Submit stand-alone")
|
310
|
+
[ @form_fillin = CheckButton.new("Fill in"), @form_spawntemplate = CheckButton.new("Spawn template") ],
|
311
|
+
[ @form_import = CheckButton.new("Import"), @form_barcode = CheckButton.new("Barcode plaintext") ],
|
312
|
+
[ @form_export = CheckButton.new("Export"), @form_online = CheckButton.new("Online") ],
|
313
|
+
[ @form_submit = CheckButton.new("Submit stand-alone"), nil ]
|
327
314
|
]
|
328
315
|
|
329
|
-
|
330
|
-
|
331
|
-
formtable.attach(col1, 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
332
|
-
formtable.attach(col2, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4) unless col2.nil?
|
316
|
+
forms.each_with_index do |cols, row|
|
317
|
+
col1, col2 = cols
|
333
318
|
|
334
|
-
|
319
|
+
col1.active = true
|
320
|
+
col2.active = true unless col2.nil?
|
321
|
+
|
322
|
+
form_table.attach(col1, 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
323
|
+
form_table.attach(col2, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4) unless col2.nil?
|
335
324
|
end
|
336
325
|
|
337
|
-
|
326
|
+
frame.add(form_table)
|
327
|
+
end
|
328
|
+
|
329
|
+
def create_signature_rights_frame
|
330
|
+
frame = create_rights_frame(" Signature ")
|
338
331
|
|
339
|
-
|
340
|
-
signatureframe.border_width = 5
|
341
|
-
signatureframe.shadow_type = Gtk::SHADOW_IN
|
332
|
+
@signature_modify = CheckButton.new("Modify").set_active(true)
|
342
333
|
|
343
|
-
|
344
|
-
|
345
|
-
|
334
|
+
signature_table = Table.new(1, 2)
|
335
|
+
signature_table.attach(@signature_modify, 0, 1, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
336
|
+
frame.add(signature_table)
|
337
|
+
end
|
346
338
|
|
347
|
-
|
348
|
-
|
349
|
-
efframe.shadow_type = Gtk::SHADOW_IN
|
339
|
+
def create_embedded_files_rights_frame
|
340
|
+
frame = create_rights_frame(" Embedded files ")
|
350
341
|
|
351
|
-
|
352
|
-
|
342
|
+
ef_table = Table.new(2,2)
|
343
|
+
ef_buttons =
|
353
344
|
[
|
354
|
-
[ @ef_create = CheckButton.new("Create")
|
355
|
-
[ @ef_delete = CheckButton.new("Delete")
|
345
|
+
[ @ef_create = CheckButton.new("Create"), @ef_modify = CheckButton.new("Modify") ],
|
346
|
+
[ @ef_delete = CheckButton.new("Delete"), @ef_import = CheckButton.new("Import") ]
|
356
347
|
]
|
357
348
|
|
358
|
-
|
359
|
-
|
360
|
-
eftable.attach(col1, 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
361
|
-
eftable.attach(col2, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
349
|
+
ef_buttons.each_with_index do |cols, row|
|
350
|
+
col1, col2 = cols
|
362
351
|
|
363
|
-
|
352
|
+
col1.active = true
|
353
|
+
col2.active = true
|
354
|
+
|
355
|
+
ef_table.attach(col1, 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
356
|
+
ef_table.attach(col2, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
364
357
|
end
|
365
358
|
|
366
|
-
|
359
|
+
frame.add(ef_table)
|
360
|
+
end
|
367
361
|
|
368
|
-
|
369
|
-
vbox.
|
370
|
-
|
371
|
-
vbox.add
|
372
|
-
vbox.add
|
362
|
+
def create_rights_selection_page
|
363
|
+
vbox = VBox.new(false, 5)
|
364
|
+
|
365
|
+
vbox.add create_document_rights_frame
|
366
|
+
vbox.add create_annotations_rights_frame
|
367
|
+
vbox.add create_form_rights_frame
|
368
|
+
vbox.add create_signature_rights_frame
|
369
|
+
vbox.add create_embedded_files_rights_frame
|
373
370
|
|
374
371
|
append_page(vbox)
|
375
372
|
set_page_title(vbox, "Select Usage Rights to enable")
|
@@ -461,11 +458,11 @@ Make sure you have adobe.crt and adobe.key located in the current directory.
|
|
461
458
|
private
|
462
459
|
|
463
460
|
def create_intro_page
|
464
|
-
intro = <<-INTRO
|
465
|
-
You are about to sign the current PDF document.
|
466
|
-
Once the document will be signed, no further modification will be allowed.
|
461
|
+
intro = <<-INTRO.gsub(/^\s+/, '')
|
462
|
+
You are about to sign the current PDF document.
|
463
|
+
Once the document will be signed, no further modification will be allowed.
|
467
464
|
|
468
|
-
The signature process is based on assymetric cryptography, so you will basically need a public/private RSA key pair (between 1024 and 4096 bits).
|
465
|
+
The signature process is based on assymetric cryptography, so you will basically need a public/private RSA key pair (between 1024 and 4096 bits).
|
469
466
|
INTRO
|
470
467
|
|
471
468
|
vbox = VBox.new(false, 5)
|
@@ -515,34 +512,6 @@ The signature process is based on assymetric cryptography, so you will basically
|
|
515
512
|
set_page_type(vbox, Assistant::PAGE_CONTENT)
|
516
513
|
end
|
517
514
|
|
518
|
-
def create_keypair_import_page
|
519
|
-
|
520
|
-
labels =
|
521
|
-
[
|
522
|
-
[ "Private RSA key:", @pkeyfilename = Entry.new, pkeychoosebtn = Button.new(Gtk::Stock::OPEN) ],
|
523
|
-
[ "Public certificate:", @certfilename = Entry.new, certchoosebtn = Button.new(Gtk::Stock::OPEN) ]
|
524
|
-
]
|
525
|
-
|
526
|
-
row = 0
|
527
|
-
table = Table.new(2, 3)
|
528
|
-
labels.each do |lbl, entry, btn|
|
529
|
-
entry.editable = entry.sensitive = false
|
530
|
-
|
531
|
-
table.attach(Label.new(lbl).set_alignment(1,0), 0, 1, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
532
|
-
table.attach(entry, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
533
|
-
table.attach(btn, 2, 3, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 4, 4)
|
534
|
-
|
535
|
-
row = row.succ
|
536
|
-
end
|
537
|
-
|
538
|
-
pkeychoosebtn.signal_connect('clicked') { open_private_key_dialog(table) }
|
539
|
-
certchoosebtn.signal_connect('clicked') { open_certificate_dialog(table) }
|
540
|
-
|
541
|
-
append_page(table)
|
542
|
-
set_page_title(table, "Import a public/private key pair")
|
543
|
-
set_page_type(table, Assistant::PAGE_CONTENT)
|
544
|
-
end
|
545
|
-
|
546
515
|
def create_signature_info_page
|
547
516
|
vbox = VBox.new(false, 5)
|
548
517
|
|