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.
- data/COPYING.LESSER +165 -0
- data/README +77 -0
- data/VERSION +1 -0
- data/bin/config/pdfcop.conf.yml +237 -0
- data/bin/gui/about.rb +46 -0
- data/bin/gui/config.rb +132 -0
- data/bin/gui/file.rb +385 -0
- data/bin/gui/hexdump.rb +74 -0
- data/bin/gui/hexview.rb +91 -0
- data/bin/gui/imgview.rb +72 -0
- data/bin/gui/menu.rb +392 -0
- data/bin/gui/properties.rb +132 -0
- data/bin/gui/signing.rb +635 -0
- data/bin/gui/textview.rb +107 -0
- data/bin/gui/treeview.rb +409 -0
- data/bin/gui/walker.rb +282 -0
- data/bin/gui/xrefs.rb +79 -0
- data/bin/pdf2graph +121 -0
- data/bin/pdf2ruby +353 -0
- data/bin/pdfcocoon +104 -0
- data/bin/pdfcop +455 -0
- data/bin/pdfdecompress +104 -0
- data/bin/pdfdecrypt +95 -0
- data/bin/pdfencrypt +112 -0
- data/bin/pdfextract +221 -0
- data/bin/pdfmetadata +123 -0
- data/bin/pdfsh +13 -0
- data/bin/pdfwalker +7 -0
- data/bin/shell/.irbrc +104 -0
- data/bin/shell/console.rb +136 -0
- data/bin/shell/hexdump.rb +83 -0
- data/origami.rb +36 -0
- data/origami/3d.rb +239 -0
- data/origami/acroform.rb +321 -0
- data/origami/actions.rb +299 -0
- data/origami/adobe/fdf.rb +259 -0
- data/origami/adobe/ppklite.rb +489 -0
- data/origami/annotations.rb +775 -0
- data/origami/array.rb +187 -0
- data/origami/boolean.rb +101 -0
- data/origami/catalog.rb +486 -0
- data/origami/destinations.rb +213 -0
- data/origami/dictionary.rb +188 -0
- data/origami/docmdp.rb +96 -0
- data/origami/encryption.rb +1293 -0
- data/origami/export.rb +283 -0
- data/origami/file.rb +222 -0
- data/origami/filters.rb +250 -0
- data/origami/filters/ascii.rb +189 -0
- data/origami/filters/ccitt.rb +515 -0
- data/origami/filters/crypt.rb +47 -0
- data/origami/filters/dct.rb +61 -0
- data/origami/filters/flate.rb +112 -0
- data/origami/filters/jbig2.rb +63 -0
- data/origami/filters/jpx.rb +53 -0
- data/origami/filters/lzw.rb +195 -0
- data/origami/filters/predictors.rb +276 -0
- data/origami/filters/runlength.rb +117 -0
- data/origami/font.rb +209 -0
- data/origami/functions.rb +93 -0
- data/origami/graphics.rb +33 -0
- data/origami/graphics/colors.rb +191 -0
- data/origami/graphics/instruction.rb +126 -0
- data/origami/graphics/path.rb +154 -0
- data/origami/graphics/patterns.rb +180 -0
- data/origami/graphics/state.rb +164 -0
- data/origami/graphics/text.rb +224 -0
- data/origami/graphics/xobject.rb +493 -0
- data/origami/header.rb +90 -0
- data/origami/linearization.rb +318 -0
- data/origami/metadata.rb +114 -0
- data/origami/name.rb +170 -0
- data/origami/null.rb +75 -0
- data/origami/numeric.rb +188 -0
- data/origami/obfuscation.rb +233 -0
- data/origami/object.rb +527 -0
- data/origami/outline.rb +59 -0
- data/origami/page.rb +559 -0
- data/origami/parser.rb +268 -0
- data/origami/parsers/fdf.rb +45 -0
- data/origami/parsers/pdf.rb +27 -0
- data/origami/parsers/pdf/linear.rb +113 -0
- data/origami/parsers/ppklite.rb +86 -0
- data/origami/pdf.rb +1144 -0
- data/origami/reference.rb +113 -0
- data/origami/signature.rb +474 -0
- data/origami/stream.rb +575 -0
- data/origami/string.rb +416 -0
- data/origami/trailer.rb +173 -0
- data/origami/webcapture.rb +87 -0
- data/origami/xfa.rb +3027 -0
- data/origami/xreftable.rb +447 -0
- data/templates/patterns.rb +66 -0
- data/templates/widgets.rb +173 -0
- data/templates/xdp.rb +92 -0
- data/tests/dataset/test.dummycrt +28 -0
- data/tests/dataset/test.dummykey +27 -0
- data/tests/tc_actions.rb +32 -0
- data/tests/tc_annotations.rb +85 -0
- data/tests/tc_pages.rb +37 -0
- data/tests/tc_pdfattach.rb +24 -0
- data/tests/tc_pdfencrypt.rb +110 -0
- data/tests/tc_pdfnew.rb +32 -0
- data/tests/tc_pdfparse.rb +98 -0
- data/tests/tc_pdfsig.rb +37 -0
- data/tests/tc_streams.rb +129 -0
- data/tests/ts_pdf.rb +45 -0
- metadata +193 -0
data/bin/gui/hexdump.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
hexdump.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
|
+
class String #:nodoc:
|
27
|
+
|
28
|
+
def hexdump(bytesperline = 16, upcase = true, offsets = true)
|
29
|
+
|
30
|
+
dump = ""
|
31
|
+
counter = 0
|
32
|
+
|
33
|
+
while counter < length
|
34
|
+
|
35
|
+
offset = sprintf("%010u", counter)
|
36
|
+
|
37
|
+
linelen = (counter < length - bytesperline) ? bytesperline : (length - counter)
|
38
|
+
bytes = ""
|
39
|
+
linelen.times do |i|
|
40
|
+
|
41
|
+
byte = self[counter + i].ord.to_s(16)
|
42
|
+
if byte.size < 2 then byte.insert(0, "0") end
|
43
|
+
bytes << byte
|
44
|
+
bytes << " " unless i == bytesperline - 1
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
ascii = self[counter, linelen].ascii_print
|
49
|
+
|
50
|
+
if upcase
|
51
|
+
offset.upcase!
|
52
|
+
bytes.upcase!
|
53
|
+
end
|
54
|
+
|
55
|
+
dump << "#{offset if offsets} #{bytes.to_s.ljust(bytesperline * 3 - 1)} #{ascii}\n"
|
56
|
+
|
57
|
+
counter += bytesperline
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
dump
|
62
|
+
end
|
63
|
+
|
64
|
+
def ascii_print
|
65
|
+
|
66
|
+
printable = ""
|
67
|
+
self.each_byte do |c|
|
68
|
+
if c >= ' '[0].ord && c <= '~'[0].ord then printable << c else printable << '.' end
|
69
|
+
end
|
70
|
+
|
71
|
+
printable
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
data/bin/gui/hexview.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
hexview.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 'gui/hexdump'
|
27
|
+
|
28
|
+
module PDFWalker
|
29
|
+
|
30
|
+
class Walker < Window
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def create_hexview
|
35
|
+
@hexview = DumpView.new(self)
|
36
|
+
end
|
37
|
+
|
38
|
+
class DumpView < ScrolledWindow
|
39
|
+
|
40
|
+
def initialize(parent)
|
41
|
+
@parent = parent
|
42
|
+
super()
|
43
|
+
|
44
|
+
set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
|
45
|
+
|
46
|
+
@current_obj = nil
|
47
|
+
@valuebuffer = TextBuffer.new
|
48
|
+
@valueview = TextView.new(@valuebuffer).set_editable(false).set_cursor_visible(false).set_left_margin(5).set_right_margin(5)
|
49
|
+
|
50
|
+
@valuebuffer.create_tag( "HexView",
|
51
|
+
:weight => Pango::WEIGHT_BOLD,
|
52
|
+
:foreground => "black",
|
53
|
+
:family => "Courier",
|
54
|
+
:scale => Pango::AttrScale::LARGE
|
55
|
+
)
|
56
|
+
|
57
|
+
add_with_viewport @valueview
|
58
|
+
end
|
59
|
+
|
60
|
+
def clear
|
61
|
+
@valuebuffer.set_text("")
|
62
|
+
end
|
63
|
+
|
64
|
+
def load(object)
|
65
|
+
return if @current_obj.equal?(object)
|
66
|
+
|
67
|
+
begin
|
68
|
+
self.clear
|
69
|
+
|
70
|
+
case object
|
71
|
+
when Origami::Stream
|
72
|
+
@valuebuffer.set_text(object.data.to_s.hexdump)
|
73
|
+
when Origami::HexaString
|
74
|
+
@valuebuffer.set_text(object.value.to_s.hexdump)
|
75
|
+
when Origami::ByteString
|
76
|
+
@valuebuffer.set_text(object.to_utf8)
|
77
|
+
end
|
78
|
+
|
79
|
+
@valuebuffer.apply_tag("HexView", @valuebuffer.start_iter, @valuebuffer.end_iter)
|
80
|
+
@current_obj = object
|
81
|
+
|
82
|
+
rescue Exception => e
|
83
|
+
@parent.error("An error occured while loading this object.\n#{e} (#{e.class})")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
data/bin/gui/imgview.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
imgview.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 ImgViewer < Window
|
29
|
+
attr_reader :image
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
super()
|
33
|
+
|
34
|
+
set_title "Image view"
|
35
|
+
set_decorated false
|
36
|
+
set_resizable false
|
37
|
+
|
38
|
+
add_events(Gdk::Event::KEY_RELEASE_MASK)
|
39
|
+
signal_connect('key_release_event') { |w, event|
|
40
|
+
destroy if event.keyval == Gdk::Keyval::GDK_Escape
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def show_raw_img(data, w, h, bpp, bpr)
|
45
|
+
set_default_size w,h
|
46
|
+
|
47
|
+
pixbuf = Gdk::Pixbuf.new data,
|
48
|
+
Gdk::Pixbuf::ColorSpace::RGB, false, bpp,
|
49
|
+
w, h,
|
50
|
+
bpr
|
51
|
+
|
52
|
+
@image = Gtk::Image.new(pixbuf)
|
53
|
+
add @image
|
54
|
+
|
55
|
+
show_all
|
56
|
+
end
|
57
|
+
|
58
|
+
def show_compressed_img(data)
|
59
|
+
loader = Gdk::PixbufLoader.new
|
60
|
+
loader.last_write data
|
61
|
+
|
62
|
+
pixbuf = loader.pixbuf
|
63
|
+
set_default_size pixbuf.width, pixbuf.height
|
64
|
+
|
65
|
+
@image = Gtk::Image.new(pixbuf)
|
66
|
+
add @image
|
67
|
+
|
68
|
+
show_all
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/bin/gui/menu.rb
ADDED
@@ -0,0 +1,392 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
= File
|
4
|
+
menu.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
|
+
module Popable
|
29
|
+
|
30
|
+
@@menus = Hash.new([])
|
31
|
+
@@menus[:"PDF File"] =
|
32
|
+
[
|
33
|
+
{
|
34
|
+
:Name => Stock::SAVE_AS,
|
35
|
+
:Sensitive => true,
|
36
|
+
:Callback => lambda { |widget, viewer, path|
|
37
|
+
viewer.parent.save
|
38
|
+
}
|
39
|
+
},
|
40
|
+
{
|
41
|
+
:Name => "Serialize",
|
42
|
+
:Sensitive => true,
|
43
|
+
:Callback => lambda { |widget, viewer, path|
|
44
|
+
viewer.parent.serialize
|
45
|
+
}
|
46
|
+
},
|
47
|
+
{
|
48
|
+
:Name => :"---"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
:Name => Stock::PROPERTIES,
|
52
|
+
:Sensitive => true,
|
53
|
+
:Callback => lambda { |widget, viewer, path|
|
54
|
+
viewer.parent.display_file_properties
|
55
|
+
}
|
56
|
+
},
|
57
|
+
{
|
58
|
+
:Name => :"---"
|
59
|
+
},
|
60
|
+
{
|
61
|
+
:Name => Stock::CLOSE,
|
62
|
+
:Sensitive => true,
|
63
|
+
:Callback => lambda { |widget, viewer, path|
|
64
|
+
viewer.parent.close
|
65
|
+
}
|
66
|
+
}
|
67
|
+
]
|
68
|
+
|
69
|
+
@@menus[:Reference] =
|
70
|
+
[
|
71
|
+
{
|
72
|
+
:Name => Stock::JUMP_TO,
|
73
|
+
:Sensitive => true,
|
74
|
+
:Callback => lambda { |widget, viewer, path|
|
75
|
+
viewer.row_activated(path, viewer.get_column(viewer.class::TEXTCOL))
|
76
|
+
}
|
77
|
+
}
|
78
|
+
]
|
79
|
+
|
80
|
+
@@menus[:Revision] =
|
81
|
+
[
|
82
|
+
{
|
83
|
+
:Name => "Save to this revision",
|
84
|
+
:Sensitive => true,
|
85
|
+
:Callback => lambda { |widget, viewer, path|
|
86
|
+
revstr = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::TEXTCOL)
|
87
|
+
revstr.slice!(0, "Revision ".size)
|
88
|
+
|
89
|
+
revnum = revstr.to_i
|
90
|
+
|
91
|
+
dialog = Gtk::FileChooserDialog.new("Save PDF File",
|
92
|
+
viewer.parent,
|
93
|
+
Gtk::FileChooser::ACTION_SAVE,
|
94
|
+
nil,
|
95
|
+
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
|
96
|
+
[Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
|
97
|
+
)
|
98
|
+
|
99
|
+
dialog.filter = FileFilter.new.add_pattern("*.pdf")
|
100
|
+
|
101
|
+
if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
|
102
|
+
viewer.parent.opened.save_upto(revnum, dialog.filename)
|
103
|
+
end
|
104
|
+
|
105
|
+
dialog.destroy
|
106
|
+
}
|
107
|
+
}
|
108
|
+
]
|
109
|
+
|
110
|
+
@@menus[:Stream] =
|
111
|
+
[
|
112
|
+
{
|
113
|
+
:Name => "Dump encoded stream",
|
114
|
+
:Sensitive => true,
|
115
|
+
:Callback => lambda { |widget, viewer, path|
|
116
|
+
stream = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
|
117
|
+
|
118
|
+
viewer.parent.save_data("Save stream to file", stream.rawdata)
|
119
|
+
}
|
120
|
+
},
|
121
|
+
{
|
122
|
+
:Name => "Dump decoded stream",
|
123
|
+
:Sensitive => true,
|
124
|
+
:Callback => lambda { |widget, viewer, path|
|
125
|
+
stream = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
|
126
|
+
|
127
|
+
viewer.parent.save_data("Save stream to file", stream.data)
|
128
|
+
}
|
129
|
+
}
|
130
|
+
]
|
131
|
+
|
132
|
+
@@menus[:String] =
|
133
|
+
[
|
134
|
+
{
|
135
|
+
:Name => "Dump string",
|
136
|
+
:Sensitive => true,
|
137
|
+
:Callback => lambda { |widget, viewer, path|
|
138
|
+
string = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
|
139
|
+
|
140
|
+
viewer.parent.save_data("Save string to file", string.value)
|
141
|
+
}
|
142
|
+
}
|
143
|
+
]
|
144
|
+
|
145
|
+
@@menus[:Image] = @@menus[:Stream] +
|
146
|
+
[
|
147
|
+
{
|
148
|
+
:Name => :"---"
|
149
|
+
},
|
150
|
+
{
|
151
|
+
:Name => "View image",
|
152
|
+
:Sensitive => true,
|
153
|
+
:Callback => lambda { |widget, viewer, path|
|
154
|
+
stm = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
|
155
|
+
w,h = stm[:Width], stm[:Height]
|
156
|
+
bpp = stm[:BitsPerComponent] || 8
|
157
|
+
bpr = (bpp >> 3) * 3 * w
|
158
|
+
data = stm.data
|
159
|
+
|
160
|
+
begin
|
161
|
+
imgview = ImgViewer.new
|
162
|
+
if stm[:Filter] == :DCTDecode or (stm[:Filter].is_a?(Array) and stm[:Filter][0] == :DCTDecode)
|
163
|
+
imgview.show_compressed_img data
|
164
|
+
else
|
165
|
+
imgview.show_raw_img data, w, h, bpp, bpr
|
166
|
+
end
|
167
|
+
rescue Exception => e
|
168
|
+
viewer.parent.error("#{e.class}: #{e.message}")
|
169
|
+
end
|
170
|
+
}
|
171
|
+
}
|
172
|
+
]
|
173
|
+
|
174
|
+
def popup_menu(obj, event, path)
|
175
|
+
|
176
|
+
menu = Menu.new
|
177
|
+
|
178
|
+
type = if obj.is_a?(Origami::Object)
|
179
|
+
if obj.is_a?(Graphics::ImageXObject)
|
180
|
+
:Image
|
181
|
+
else
|
182
|
+
obj.real_type.to_s.split("::").last.to_sym
|
183
|
+
end
|
184
|
+
else case obj
|
185
|
+
when Origami::PDF
|
186
|
+
:"PDF File"
|
187
|
+
when Origami::PDF::Revision, Origami::Adobe::PPKLite::Revision
|
188
|
+
:Revision
|
189
|
+
when ::Array
|
190
|
+
:Body
|
191
|
+
when Origami::PDF::Header, Origami::Adobe::PPKLite::Header
|
192
|
+
:Header
|
193
|
+
when Origami::Trailer
|
194
|
+
:Trailer
|
195
|
+
when Origami::XRef::Section
|
196
|
+
:XRefSection
|
197
|
+
when Origami::XRef::Subsection
|
198
|
+
:XRefSubsection
|
199
|
+
when Origami::XRef, Origami::XRefToCompressedObj
|
200
|
+
:XRef
|
201
|
+
else
|
202
|
+
:Unknown
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
title = obj.is_a?(Origami::Object) ? "Object : " : ""
|
207
|
+
title << type.to_s
|
208
|
+
menu.append(MenuItem.new(title).set_sensitive(false).modify_text(Gtk::STATE_INSENSITIVE, Gdk::Color.new(255,0,255)))
|
209
|
+
|
210
|
+
if obj.is_a?(Origami::Object)
|
211
|
+
if obj.is_indirect?
|
212
|
+
menu.append(MenuItem.new("Number : #{obj.no}; Generation : #{obj.generation}").set_sensitive(false))
|
213
|
+
menu.append(MenuItem.new("File offset : #{obj.file_offset}").set_sensitive(false))
|
214
|
+
xrefsproc = lambda { |widget,viewer,path|
|
215
|
+
ref = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL)
|
216
|
+
viewer.parent.show_xrefs(ref)
|
217
|
+
}
|
218
|
+
getxrefs = MenuItem.new("Search references to this object").set_sensitive(true)
|
219
|
+
getxrefs.signal_connect("activate", self, path, &xrefsproc)
|
220
|
+
|
221
|
+
menu.append(getxrefs)
|
222
|
+
elsif not obj.parent.nil?
|
223
|
+
gotoproc = lambda { |widget,viewer,path|
|
224
|
+
dest = viewer.model.get_value(viewer.model.get_iter(path), viewer.class::OBJCOL).parent
|
225
|
+
viewer.goto(dest)
|
226
|
+
}
|
227
|
+
gotoparent = MenuItem.new("Goto Parent Object").set_sensitive(true)
|
228
|
+
gotoparent.signal_connect("activate", self, path, &gotoproc)
|
229
|
+
|
230
|
+
menu.append(gotoparent)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
items = @@menus[type]
|
235
|
+
menu.append(SeparatorMenuItem.new) if not items.empty?
|
236
|
+
|
237
|
+
items.each { |item|
|
238
|
+
|
239
|
+
if item[:Name] == :"---"
|
240
|
+
entry = SeparatorMenuItem.new
|
241
|
+
else
|
242
|
+
if item[:Name].is_a?(String)
|
243
|
+
entry = MenuItem.new(item[:Name])
|
244
|
+
else entry = ImageMenuItem.new(item[:Name])
|
245
|
+
end
|
246
|
+
|
247
|
+
entry.set_sensitive(item[:Sensitive])
|
248
|
+
entry.signal_connect("activate", self, path, &item[:Callback])
|
249
|
+
end
|
250
|
+
|
251
|
+
menu.append(entry)
|
252
|
+
}
|
253
|
+
|
254
|
+
menu.show_all
|
255
|
+
menu.popup(nil, nil, event.button, event.time)
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
260
|
+
|
261
|
+
class Walker < Window
|
262
|
+
|
263
|
+
private
|
264
|
+
|
265
|
+
def create_menus
|
266
|
+
|
267
|
+
AccelMap.add_entry("<PDF Walker>/File/Open", Gdk::Keyval::GDK_O, Gdk::Window::CONTROL_MASK)
|
268
|
+
AccelMap.add_entry("<PDF Walker>/File/Refresh", Gdk::Keyval::GDK_R, Gdk::Window::CONTROL_MASK)
|
269
|
+
AccelMap.add_entry("<PDF Walker>/File/Close", Gdk::Keyval::GDK_X, Gdk::Window::CONTROL_MASK)
|
270
|
+
AccelMap.add_entry("<PDF Walker>/File/Save", Gdk::Keyval::GDK_S, Gdk::Window::CONTROL_MASK)
|
271
|
+
AccelMap.add_entry("<PDF Walker>/File/Quit", Gdk::Keyval::GDK_Q, Gdk::Window::CONTROL_MASK)
|
272
|
+
AccelMap.add_entry("<PDF Walker>/Document/Search", Gdk::Keyval::GDK_F, Gdk::Window::CONTROL_MASK)
|
273
|
+
|
274
|
+
@menu = MenuBar.new
|
275
|
+
|
276
|
+
####################################################
|
277
|
+
file_ag = Gtk::AccelGroup.new
|
278
|
+
@file_menu = Menu.new.set_accel_group(file_ag).set_accel_path("<PDF Walker>/File")
|
279
|
+
add_accel_group(file_ag)
|
280
|
+
|
281
|
+
@file_menu_open = ImageMenuItem.new(Stock::OPEN).set_accel_path("<PDF Walker>/File/Open")
|
282
|
+
@file_menu_recent = MenuItem.new("Last opened")
|
283
|
+
@file_menu_deserialize = MenuItem.new("Deserialize")
|
284
|
+
@file_menu_refresh = ImageMenuItem.new(Stock::REFRESH).set_sensitive(false).set_accel_path("<PDF Walker>/File/Refresh")
|
285
|
+
@file_menu_close = ImageMenuItem.new(Stock::CLOSE).set_sensitive(false).set_accel_path("<PDF Walker>/File/Close")
|
286
|
+
@file_menu_saveas = ImageMenuItem.new(Stock::SAVE_AS).set_sensitive(false)
|
287
|
+
@file_menu_serialize = MenuItem.new("Serialize").set_sensitive(false)
|
288
|
+
@file_menu_exit = ImageMenuItem.new(Stock::QUIT).set_accel_path("<PDF Walker>/File/Quit")
|
289
|
+
|
290
|
+
@export_menu = Menu.new
|
291
|
+
@export_pdf_menu = MenuItem.new("As reassembled PDF").set_accel_path("<PDF Walker>/File/Save")
|
292
|
+
@export_graph_menu = MenuItem.new("As GraphViz dot file")
|
293
|
+
@export_graphml_menu = MenuItem.new("As GraphML file")
|
294
|
+
|
295
|
+
@export_pdf_menu.signal_connect('activate') do save end
|
296
|
+
@export_graph_menu.signal_connect('activate') do save_dot end
|
297
|
+
@export_graphml_menu.signal_connect('activate') do save_graphml end
|
298
|
+
|
299
|
+
@export_menu.append(@export_pdf_menu)
|
300
|
+
@export_menu.append(@export_graph_menu)
|
301
|
+
@export_menu.append(@export_graphml_menu)
|
302
|
+
|
303
|
+
@file_menu_saveas.set_submenu(@export_menu)
|
304
|
+
|
305
|
+
@file_menu_open.signal_connect('activate') do open end
|
306
|
+
@file_menu_deserialize.signal_connect('activate') do deserialize end
|
307
|
+
@file_menu_refresh.signal_connect('activate') do open(@filename) end
|
308
|
+
@file_menu_close.signal_connect('activate') do close end
|
309
|
+
@file_menu_serialize.signal_connect('activate') do serialize end
|
310
|
+
@file_menu_exit.signal_connect('activate') do self.destroy end
|
311
|
+
|
312
|
+
update_recent_menu
|
313
|
+
|
314
|
+
@file_menu.append(@file_menu_open)
|
315
|
+
@file_menu.append(@file_menu_recent)
|
316
|
+
@file_menu.append(@file_menu_deserialize)
|
317
|
+
@file_menu.append(@file_menu_refresh)
|
318
|
+
@file_menu.append(@file_menu_close)
|
319
|
+
@file_menu.append(@file_menu_saveas)
|
320
|
+
@file_menu.append(@file_menu_serialize)
|
321
|
+
@file_menu.append(@file_menu_exit)
|
322
|
+
|
323
|
+
@menu.append(MenuItem.new('_File').set_submenu(@file_menu))
|
324
|
+
####################################################
|
325
|
+
|
326
|
+
doc_ag = Gtk::AccelGroup.new
|
327
|
+
@document_menu = Menu.new.set_accel_group(doc_ag)
|
328
|
+
add_accel_group(doc_ag)
|
329
|
+
|
330
|
+
@document_menu_search = ImageMenuItem.new(Stock::FIND).set_sensitive(false).set_accel_path("<PDF Walker>/Document/Search")
|
331
|
+
@document_menu_gotocatalog = MenuItem.new("Jump To Catalog").set_sensitive(false)
|
332
|
+
@document_menu_gotorev = MenuItem.new("Jump To Revision...").set_sensitive(false)
|
333
|
+
@document_menu_gotopage = MenuItem.new("Jump To Page...").set_sensitive(false)
|
334
|
+
@document_menu_gotoobj = MenuItem.new("Jump To Object...").set_sensitive(false)
|
335
|
+
@document_menu_properties = ImageMenuItem.new(Stock::PROPERTIES).set_sensitive(false)
|
336
|
+
@document_menu_sign = MenuItem.new("Sign the document").set_sensitive(false)
|
337
|
+
@document_menu_ur = MenuItem.new("Enable Usage Rights").set_sensitive(false)
|
338
|
+
|
339
|
+
@document_menu_search.signal_connect('activate') do search end
|
340
|
+
@document_menu_gotocatalog.signal_connect('activate') do goto_catalog end
|
341
|
+
@document_menu_gotoobj.signal_connect('activate') do goto_object end
|
342
|
+
@document_menu_properties.signal_connect('activate') do display_file_properties end
|
343
|
+
@document_menu_sign.signal_connect('activate') do display_signing_wizard end
|
344
|
+
@document_menu_ur.signal_connect('activate') do display_usage_rights_wizard end
|
345
|
+
|
346
|
+
@document_menu.append(@document_menu_search)
|
347
|
+
@document_menu.append(MenuItem.new)
|
348
|
+
@document_menu.append(@document_menu_gotocatalog)
|
349
|
+
@document_menu.append(@document_menu_gotorev)
|
350
|
+
@document_menu.append(@document_menu_gotopage)
|
351
|
+
@document_menu.append(@document_menu_gotoobj)
|
352
|
+
@document_menu.append(MenuItem.new)
|
353
|
+
@document_menu.append(@document_menu_sign)
|
354
|
+
@document_menu.append(@document_menu_ur)
|
355
|
+
@document_menu.append(@document_menu_properties)
|
356
|
+
|
357
|
+
@menu.append(MenuItem.new('_Document').set_submenu(@document_menu))
|
358
|
+
####################################################
|
359
|
+
@help_menu = Menu.new
|
360
|
+
@help_menu_profile = CheckMenuItem.new("Profiling (Debug purposes only)").set_active(@config.profile?)
|
361
|
+
@help_menu_profile.signal_connect('toggled') do @config.set_profiling(@help_menu_profile.active?) end
|
362
|
+
|
363
|
+
@help_menu_about = ImageMenuItem.new(Stock::ABOUT)
|
364
|
+
|
365
|
+
@help_menu_about.signal_connect('activate') do about end
|
366
|
+
|
367
|
+
@help_menu.append(@help_menu_profile)
|
368
|
+
@help_menu.append(@help_menu_about)
|
369
|
+
|
370
|
+
@menu.append(MenuItem.new('_Help').set_submenu(@help_menu))
|
371
|
+
####################################################
|
372
|
+
|
373
|
+
end
|
374
|
+
|
375
|
+
def update_recent_menu
|
376
|
+
|
377
|
+
@recent_menu = Menu.new
|
378
|
+
@config.recent_files.each { |file|
|
379
|
+
|
380
|
+
menu = MenuItem.new(file)
|
381
|
+
menu.signal_connect('activate') do open(file) end
|
382
|
+
|
383
|
+
@recent_menu.append(menu)
|
384
|
+
}
|
385
|
+
|
386
|
+
@file_menu_recent.set_submenu(@recent_menu)
|
387
|
+
@file_menu_recent.show_all
|
388
|
+
end
|
389
|
+
|
390
|
+
end
|
391
|
+
|
392
|
+
end
|