origami 1.2.7 → 2.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -0
- data/README.md +112 -0
- data/bin/config/pdfcop.conf.yml +232 -233
- data/bin/gui/about.rb +27 -37
- data/bin/gui/config.rb +108 -117
- data/bin/gui/file.rb +416 -365
- data/bin/gui/gtkhex.rb +1138 -1153
- data/bin/gui/hexview.rb +55 -57
- data/bin/gui/imgview.rb +48 -51
- data/bin/gui/menu.rb +388 -386
- data/bin/gui/properties.rb +114 -130
- data/bin/gui/signing.rb +571 -617
- data/bin/gui/textview.rb +77 -95
- data/bin/gui/treeview.rb +382 -387
- data/bin/gui/walker.rb +227 -232
- data/bin/gui/xrefs.rb +56 -60
- data/bin/pdf2pdfa +53 -57
- data/bin/pdf2ruby +212 -228
- data/bin/pdfcop +338 -348
- data/bin/pdfdecompress +58 -65
- data/bin/pdfdecrypt +56 -60
- data/bin/pdfencrypt +75 -80
- data/bin/pdfexplode +185 -182
- data/bin/pdfextract +201 -218
- data/bin/pdfmetadata +83 -82
- data/bin/pdfsh +4 -5
- data/bin/pdfwalker +1 -2
- data/bin/shell/.irbrc +45 -82
- data/bin/shell/console.rb +105 -130
- data/bin/shell/hexdump.rb +40 -64
- data/examples/README.md +34 -0
- data/examples/attachments/attachment.rb +38 -0
- data/examples/attachments/nested_document.rb +51 -0
- data/examples/encryption/encryption.rb +28 -0
- data/{samples/actions/triggerevents/trigger.rb → examples/events/events.rb} +13 -16
- data/examples/flash/flash.rb +37 -0
- data/{samples → examples}/flash/helloworld.swf +0 -0
- data/examples/forms/javascript.rb +54 -0
- data/examples/forms/xfa.rb +115 -0
- data/examples/javascript/hello_world.rb +22 -0
- data/examples/javascript/js_emulation.rb +54 -0
- data/examples/loop/goto.rb +32 -0
- data/examples/loop/named.rb +33 -0
- data/examples/signature/signature.rb +65 -0
- data/examples/uri/javascript.rb +56 -0
- data/examples/uri/open-uri.rb +21 -0
- data/examples/uri/submitform.rb +47 -0
- data/lib/origami.rb +29 -42
- data/lib/origami/3d.rb +350 -225
- data/lib/origami/acroform.rb +262 -288
- data/lib/origami/actions.rb +268 -288
- data/lib/origami/annotations.rb +697 -722
- data/lib/origami/array.rb +258 -184
- data/lib/origami/boolean.rb +74 -84
- data/lib/origami/catalog.rb +397 -434
- data/lib/origami/collections.rb +144 -0
- data/lib/origami/destinations.rb +233 -194
- data/lib/origami/dictionary.rb +253 -232
- data/lib/origami/encryption.rb +1274 -1243
- data/lib/origami/export.rb +232 -268
- data/lib/origami/extensions/fdf.rb +307 -220
- data/lib/origami/extensions/ppklite.rb +368 -435
- data/lib/origami/filespec.rb +197 -0
- data/lib/origami/filters.rb +301 -295
- data/lib/origami/filters/ascii.rb +177 -180
- data/lib/origami/filters/ccitt.rb +528 -535
- data/lib/origami/filters/crypt.rb +26 -35
- data/lib/origami/filters/dct.rb +46 -52
- data/lib/origami/filters/flate.rb +95 -94
- data/lib/origami/filters/jbig2.rb +49 -55
- data/lib/origami/filters/jpx.rb +38 -44
- data/lib/origami/filters/lzw.rb +189 -183
- data/lib/origami/filters/predictors.rb +221 -235
- data/lib/origami/filters/runlength.rb +103 -104
- data/lib/origami/font.rb +173 -186
- data/lib/origami/functions.rb +67 -81
- data/lib/origami/graphics.rb +25 -21
- data/lib/origami/graphics/colors.rb +178 -187
- data/lib/origami/graphics/instruction.rb +79 -85
- data/lib/origami/graphics/path.rb +142 -148
- data/lib/origami/graphics/patterns.rb +160 -167
- data/lib/origami/graphics/render.rb +43 -50
- data/lib/origami/graphics/state.rb +138 -153
- data/lib/origami/graphics/text.rb +188 -205
- data/lib/origami/graphics/xobject.rb +819 -815
- data/lib/origami/header.rb +63 -78
- data/lib/origami/javascript.rb +596 -597
- data/lib/origami/linearization.rb +285 -290
- data/lib/origami/metadata.rb +139 -148
- data/lib/origami/name.rb +112 -148
- data/lib/origami/null.rb +53 -62
- data/lib/origami/numeric.rb +162 -175
- data/lib/origami/obfuscation.rb +186 -174
- data/lib/origami/object.rb +593 -573
- data/lib/origami/outline.rb +42 -47
- data/lib/origami/outputintents.rb +73 -82
- data/lib/origami/page.rb +703 -592
- data/lib/origami/parser.rb +238 -290
- data/lib/origami/parsers/fdf.rb +41 -33
- data/lib/origami/parsers/pdf.rb +75 -95
- data/lib/origami/parsers/pdf/lazy.rb +137 -0
- data/lib/origami/parsers/pdf/linear.rb +64 -66
- data/lib/origami/parsers/ppklite.rb +34 -70
- data/lib/origami/pdf.rb +1030 -1005
- data/lib/origami/reference.rb +102 -102
- data/lib/origami/signature.rb +591 -609
- data/lib/origami/stream.rb +668 -551
- data/lib/origami/string.rb +397 -373
- data/lib/origami/template/patterns.rb +56 -0
- data/lib/origami/template/widgets.rb +151 -0
- data/lib/origami/trailer.rb +144 -158
- data/lib/origami/tree.rb +62 -0
- data/lib/origami/version.rb +23 -0
- data/lib/origami/webcapture.rb +88 -79
- data/lib/origami/xfa.rb +2863 -2882
- data/lib/origami/xreftable.rb +472 -384
- data/test/dataset/calc.pdf +85 -0
- data/test/dataset/crypto.pdf +82 -0
- data/test/dataset/empty.pdf +49 -0
- data/test/test_actions.rb +27 -0
- data/test/test_annotations.rb +90 -0
- data/test/test_pages.rb +31 -0
- data/test/test_pdf.rb +16 -0
- data/test/test_pdf_attachment.rb +34 -0
- data/test/test_pdf_create.rb +24 -0
- data/test/test_pdf_encrypt.rb +95 -0
- data/test/test_pdf_parse.rb +96 -0
- data/test/test_pdf_sign.rb +58 -0
- data/test/test_streams.rb +182 -0
- data/test/test_xrefs.rb +67 -0
- metadata +88 -58
- data/README +0 -67
- data/bin/pdf2graph +0 -121
- data/bin/pdfcocoon +0 -104
- data/lib/origami/file.rb +0 -233
- data/samples/README.txt +0 -45
- data/samples/actions/launch/calc.rb +0 -87
- data/samples/actions/launch/winparams.rb +0 -22
- data/samples/actions/loop/loopgoto.rb +0 -24
- data/samples/actions/loop/loopnamed.rb +0 -21
- data/samples/actions/named/named.rb +0 -31
- data/samples/actions/samba/smbrelay.rb +0 -26
- data/samples/actions/webbug/submitform.js +0 -26
- data/samples/actions/webbug/webbug-browser.rb +0 -68
- data/samples/actions/webbug/webbug-js.rb +0 -67
- data/samples/actions/webbug/webbug-reader.rb +0 -90
- data/samples/attachments/attach.rb +0 -40
- data/samples/attachments/attached.txt +0 -1
- data/samples/crypto/crypto.rb +0 -28
- data/samples/digsig/signed.rb +0 -46
- data/samples/exploits/cve-2008-2992-utilprintf.rb +0 -87
- data/samples/exploits/cve-2009-0927-geticon.rb +0 -65
- data/samples/exploits/exploit_customdictopen.rb +0 -55
- data/samples/exploits/getannots.rb +0 -69
- data/samples/flash/flash.rb +0 -31
- data/samples/javascript/attached.txt +0 -1
- data/samples/javascript/js.rb +0 -52
- data/templates/patterns.rb +0 -66
- data/templates/widgets.rb +0 -173
- data/templates/xdp.rb +0 -92
- data/test/ts_pdf.rb +0 -50
data/bin/gui/walker.rb
CHANGED
|
@@ -2,42 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
=begin
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21
|
-
GNU General Public License for more details.
|
|
22
|
-
|
|
23
|
-
You should have received a copy of the GNU General Public License
|
|
24
|
-
along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
|
|
5
|
+
This file is part of PDF Walker, a graphical PDF file browser
|
|
6
|
+
Copyright (C) 2016 Guillaume Delugré.
|
|
7
|
+
|
|
8
|
+
PDF Walker is free software: you can redistribute it and/or modify
|
|
9
|
+
it under the terms of the GNU General Public License as published by
|
|
10
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
(at your option) any later version.
|
|
12
|
+
|
|
13
|
+
PDF Walker is distributed in the hope that it will be useful,
|
|
14
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
GNU General Public License for more details.
|
|
17
|
+
|
|
18
|
+
You should have received a copy of the GNU General Public License
|
|
19
|
+
along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
|
|
25
20
|
|
|
26
21
|
=end
|
|
27
22
|
|
|
28
23
|
begin
|
|
29
|
-
|
|
24
|
+
require 'gtk2'
|
|
30
25
|
rescue LoadError
|
|
31
|
-
|
|
26
|
+
abort('Error: you need to install ruby-gtk2 to run this application')
|
|
32
27
|
end
|
|
33
28
|
include Gtk
|
|
34
29
|
|
|
35
30
|
begin
|
|
36
|
-
|
|
31
|
+
require 'origami'
|
|
37
32
|
rescue LoadError
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
require 'origami'
|
|
33
|
+
$: << File.join(__dir__, '../../lib')
|
|
34
|
+
require 'origami'
|
|
41
35
|
end
|
|
42
36
|
|
|
43
37
|
require 'gui/menu'
|
|
@@ -54,229 +48,230 @@ require 'gui/signing'
|
|
|
54
48
|
|
|
55
49
|
module PDFWalker #:nodoc:all
|
|
56
50
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
attr_reader :filename
|
|
63
|
-
|
|
64
|
-
def self.start(file = nil)
|
|
65
|
-
Gtk.init
|
|
66
|
-
Walker.new(file)
|
|
67
|
-
Gtk.main
|
|
68
|
-
end
|
|
51
|
+
class Walker < Window
|
|
52
|
+
attr_reader :treeview, :hexview, :objectview
|
|
53
|
+
attr_reader :explorer_history
|
|
54
|
+
attr_reader :config
|
|
55
|
+
attr_reader :filename
|
|
69
56
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
@last_search_result = []
|
|
76
|
-
@last_search =
|
|
77
|
-
{
|
|
78
|
-
:expr => "",
|
|
79
|
-
:regexp => false,
|
|
80
|
-
:type => :body
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@explorer_history = Array.new
|
|
84
|
-
|
|
85
|
-
signal_connect('destroy') {
|
|
86
|
-
@config.save
|
|
87
|
-
Gtk.main_quit
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
add_events(Gdk::Event::KEY_RELEASE_MASK)
|
|
91
|
-
signal_connect('key_release_event') { |w, event|
|
|
92
|
-
|
|
93
|
-
if event.keyval == Gdk::Keyval::GDK_F1 then about
|
|
94
|
-
elsif event.keyval == Gdk::Keyval::GDK_Escape && @opened && ! @explorer_history.empty?
|
|
95
|
-
@treeview.goto(@explorer_history.pop)
|
|
57
|
+
def self.start(file = nil)
|
|
58
|
+
Gtk.init
|
|
59
|
+
Walker.new(file)
|
|
60
|
+
Gtk.main
|
|
96
61
|
end
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
create_menus
|
|
101
|
-
create_treeview
|
|
102
|
-
create_hexview
|
|
103
|
-
create_objectview
|
|
104
|
-
create_panels
|
|
105
|
-
create_statusbar
|
|
106
|
-
|
|
107
|
-
@vbox = VBox.new
|
|
108
|
-
@vbox.pack_start(@menu, false, false)
|
|
109
|
-
@vbox.pack_start(@hpaned)
|
|
110
|
-
@vbox.pack_end(@statusbar, false, false)
|
|
111
|
-
|
|
112
|
-
add @vbox
|
|
113
|
-
|
|
114
|
-
set_default_size(self.screen.width * 0.5, self.screen.height * 0.5)
|
|
115
|
-
#maximize
|
|
116
|
-
show_all
|
|
117
|
-
|
|
118
|
-
open(target_file)
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def error(msg)
|
|
122
|
-
|
|
123
|
-
dialog = Gtk::MessageDialog.new(self,
|
|
124
|
-
Gtk::Dialog::DESTROY_WITH_PARENT,
|
|
125
|
-
Gtk::MessageDialog::ERROR,
|
|
126
|
-
Gtk::MessageDialog::BUTTONS_CLOSE,
|
|
127
|
-
msg)
|
|
128
|
-
dialog.run
|
|
129
|
-
dialog.destroy
|
|
130
|
-
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def reload
|
|
134
|
-
@treeview.load(@opened) if @opened
|
|
135
|
-
end
|
|
136
62
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
@
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
end
|
|
187
|
-
@last_search = search
|
|
188
|
-
end
|
|
63
|
+
def initialize(target_file = nil)
|
|
64
|
+
super("PDF Walker")
|
|
65
|
+
|
|
66
|
+
@config = Walker::Config.new
|
|
67
|
+
@opened = nil
|
|
68
|
+
|
|
69
|
+
@last_search_result = []
|
|
70
|
+
@last_search =
|
|
71
|
+
{
|
|
72
|
+
:expr => "",
|
|
73
|
+
:regexp => false,
|
|
74
|
+
:type => :body
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@explorer_history = Array.new
|
|
78
|
+
|
|
79
|
+
signal_connect('destroy') {
|
|
80
|
+
@config.save
|
|
81
|
+
Gtk.main_quit
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
add_events(Gdk::Event::KEY_RELEASE_MASK)
|
|
85
|
+
signal_connect('key_release_event') { |w, event|
|
|
86
|
+
if event.keyval == Gdk::Keyval::GDK_F1 then about
|
|
87
|
+
elsif event.keyval == Gdk::Keyval::GDK_Escape and @opened and not @explorer_history.empty?
|
|
88
|
+
@treeview.goto(@explorer_history.pop)
|
|
89
|
+
end
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
create_menus
|
|
93
|
+
create_treeview
|
|
94
|
+
create_hexview
|
|
95
|
+
create_objectview
|
|
96
|
+
create_panels
|
|
97
|
+
create_statusbar
|
|
98
|
+
|
|
99
|
+
@vbox = VBox.new
|
|
100
|
+
@vbox.pack_start(@menu, false, false)
|
|
101
|
+
@vbox.pack_start(@hpaned)
|
|
102
|
+
@vbox.pack_end(@statusbar, false, false)
|
|
103
|
+
|
|
104
|
+
add @vbox
|
|
105
|
+
|
|
106
|
+
set_default_size(self.screen.width * 0.5, self.screen.height * 0.5)
|
|
107
|
+
#maximize
|
|
108
|
+
show_all
|
|
109
|
+
|
|
110
|
+
open(target_file)
|
|
111
|
+
end
|
|
189
112
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
113
|
+
def error(msg)
|
|
114
|
+
dialog = Gtk::MessageDialog.new(self,
|
|
115
|
+
Gtk::Dialog::DESTROY_WITH_PARENT,
|
|
116
|
+
Gtk::MessageDialog::ERROR,
|
|
117
|
+
Gtk::MessageDialog::BUTTONS_CLOSE,
|
|
118
|
+
msg
|
|
119
|
+
)
|
|
196
120
|
|
|
197
|
-
|
|
121
|
+
dialog.run
|
|
122
|
+
dialog.destroy
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def reload
|
|
126
|
+
@treeview.load(@opened) if @opened
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def search
|
|
130
|
+
dialog = Gtk::Dialog.new("Search...",
|
|
131
|
+
self,
|
|
132
|
+
Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
|
|
133
|
+
[Gtk::Stock::FIND, Gtk::Dialog::RESPONSE_OK],
|
|
134
|
+
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
entry = Gtk::Entry.new
|
|
138
|
+
entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
|
|
139
|
+
entry.text = @last_search[:expr]
|
|
140
|
+
|
|
141
|
+
button_bydata = Gtk::RadioButton.new("In object body")
|
|
142
|
+
button_byname = Gtk::RadioButton.new(button_bydata, "In object name")
|
|
143
|
+
button_regexp = Gtk::CheckButton.new("Regular expression")
|
|
144
|
+
|
|
145
|
+
button_bydata.set_active(true) if @last_search[:type] == :body
|
|
146
|
+
button_byname.set_active(true) if @last_search[:type] == :name
|
|
147
|
+
button_regexp.set_active(@last_search[:regexp])
|
|
148
|
+
|
|
149
|
+
hbox = HBox.new
|
|
150
|
+
hbox.pack_start Gtk::Label.new("Search for expression ")
|
|
151
|
+
hbox.pack_start entry
|
|
152
|
+
|
|
153
|
+
dialog.vbox.pack_start(hbox)
|
|
154
|
+
dialog.vbox.pack_start(button_bydata)
|
|
155
|
+
dialog.vbox.pack_start(button_byname)
|
|
156
|
+
dialog.vbox.pack_end(button_regexp)
|
|
157
|
+
|
|
158
|
+
dialog.signal_connect('response') do |dlg, response|
|
|
159
|
+
if response != Gtk::Dialog::RESPONSE_OK
|
|
160
|
+
dialog.destroy
|
|
161
|
+
next
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
search =
|
|
165
|
+
{
|
|
166
|
+
:expr => entry.text,
|
|
167
|
+
:regexp => button_regexp.active?,
|
|
168
|
+
:type => button_byname.active? ? :name : :body
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if search == @last_search
|
|
172
|
+
@last_search_result.push @last_search_result.shift
|
|
173
|
+
results = @last_search_result
|
|
174
|
+
else
|
|
175
|
+
expr = search[:regexp] ? Regexp.new(search[:expr]) : search[:expr]
|
|
176
|
+
|
|
177
|
+
results =
|
|
178
|
+
if search[:type] == :body
|
|
179
|
+
@opened.grep(expr)
|
|
180
|
+
else
|
|
181
|
+
@opened.ls(expr, follow_references: false)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
@last_search = search
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
if results.empty?
|
|
188
|
+
error("No result found.")
|
|
189
|
+
else
|
|
190
|
+
if results != @last_search_result
|
|
191
|
+
# Reset the previous search highlighting.
|
|
192
|
+
@last_search_result.each do |obj| @treeview.highlight(obj, nil) end
|
|
193
|
+
|
|
194
|
+
# Highlight the new results.
|
|
195
|
+
results.each do |obj| @treeview.highlight(obj, "lightpink") end
|
|
196
|
+
|
|
197
|
+
@last_search_result = results
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
@treeview.goto(results.first, follow_references: false)
|
|
201
|
+
end
|
|
198
202
|
end
|
|
199
203
|
|
|
200
|
-
|
|
201
|
-
end
|
|
202
|
-
else
|
|
203
|
-
dialog.destroy
|
|
204
|
+
dialog.show_all
|
|
204
205
|
end
|
|
205
|
-
end
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
def goto_catalog
|
|
208
|
+
@treeview.goto(@opened.Catalog.reference)
|
|
209
|
+
end
|
|
209
210
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
def goto_docinfo
|
|
212
|
+
@treeview.goto(@opened.document_info.reference) if @opened.document_info?
|
|
213
|
+
end
|
|
213
214
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
self,
|
|
217
|
-
Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
|
|
218
|
-
[Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
|
|
219
|
-
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
|
|
220
|
-
)
|
|
221
|
-
|
|
222
|
-
entry = Gtk::Entry.new
|
|
223
|
-
entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
|
|
224
|
-
|
|
225
|
-
dialog.vbox.pack_start Gtk::Label.new("Object number: ")
|
|
226
|
-
dialog.vbox.pack_start entry
|
|
227
|
-
dialog.show_all
|
|
228
|
-
|
|
229
|
-
no = 0
|
|
230
|
-
dialog.run do |response|
|
|
231
|
-
if response == Gtk::Dialog::RESPONSE_OK
|
|
232
|
-
no = entry.text.to_i
|
|
215
|
+
def goto_metadata
|
|
216
|
+
@treeview.goto(@opened.Catalog.Metadata.reference) if @opened.metadata?
|
|
233
217
|
end
|
|
234
218
|
|
|
235
|
-
|
|
236
|
-
|
|
219
|
+
def goto_object
|
|
220
|
+
dialog = Gtk::Dialog.new("Jump to object...",
|
|
221
|
+
self,
|
|
222
|
+
Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
|
|
223
|
+
[Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
|
|
224
|
+
[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
entry = Gtk::Entry.new
|
|
228
|
+
entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
|
|
237
229
|
|
|
238
|
-
|
|
239
|
-
|
|
230
|
+
dialog.vbox.pack_start Gtk::Label.new("Object number: ")
|
|
231
|
+
dialog.vbox.pack_start entry
|
|
232
|
+
dialog.show_all
|
|
240
233
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
234
|
+
no = 0
|
|
235
|
+
dialog.run do |response|
|
|
236
|
+
no = entry.text.to_i if response == Gtk::Dialog::RESPONSE_OK
|
|
237
|
+
|
|
238
|
+
dialog.destroy
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
return unless no > 0
|
|
242
|
+
|
|
243
|
+
obj = @opened[no]
|
|
244
|
+
if obj.nil?
|
|
245
|
+
error("Object #{no} not found.")
|
|
246
|
+
else
|
|
247
|
+
@treeview.goto(obj)
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
private
|
|
252
|
+
|
|
253
|
+
def create_panels
|
|
254
|
+
@hpaned = HPaned.new
|
|
255
|
+
|
|
256
|
+
@treepanel = ScrolledWindow.new.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
|
|
257
|
+
@treepanel.add @treeview
|
|
258
|
+
|
|
259
|
+
@vpaned = VPaned.new
|
|
260
|
+
@vpaned.pack1(@objectview, true, false)
|
|
261
|
+
@vpaned.pack2(@hexview, true, false)
|
|
262
|
+
|
|
263
|
+
@hpaned.pack1(@treepanel, true, false)
|
|
264
|
+
@hpaned.pack2(@vpaned, true, false)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def create_statusbar
|
|
268
|
+
@statusbar = Statusbar.new
|
|
269
|
+
|
|
270
|
+
@main_context = @statusbar.get_context_id 'Main'
|
|
271
|
+
@statusbar.push(@main_context, 'No file selected')
|
|
245
272
|
end
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
private
|
|
250
|
-
|
|
251
|
-
def create_panels
|
|
252
|
-
|
|
253
|
-
@hpaned = HPaned.new
|
|
254
|
-
|
|
255
|
-
@treepanel = ScrolledWindow.new.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
|
|
256
|
-
@treepanel.add @treeview
|
|
257
|
-
|
|
258
|
-
@vpaned = VPaned.new
|
|
259
|
-
@vpaned.pack1(@objectview, true, false)
|
|
260
|
-
@vpaned.pack2(@hexview, true, false)
|
|
261
|
-
|
|
262
|
-
@hpaned.pack1(@treepanel, true, false)
|
|
263
|
-
@hpaned.pack2(@vpaned, true, false)
|
|
264
|
-
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def create_statusbar
|
|
268
|
-
|
|
269
|
-
@statusbar = Statusbar.new
|
|
270
|
-
|
|
271
|
-
@main_context = @statusbar.get_context_id 'Main'
|
|
272
|
-
@statusbar.push(@main_context, 'No file selected')
|
|
273
|
-
|
|
274
273
|
end
|
|
275
|
-
|
|
276
|
-
end
|
|
277
274
|
|
|
278
275
|
end
|
|
279
276
|
|
|
280
|
-
if __FILE__ == $0
|
|
281
|
-
PDFWalker::Walker.start
|
|
282
|
-
end
|
|
277
|
+
PDFWalker::Walker.start if __FILE__ == $0
|