origami 2.0.4 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,308 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- =begin
4
-
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/>.
20
-
21
- =end
22
-
23
- begin
24
- require 'gtk2'
25
- rescue LoadError
26
- abort('Error: you need to install ruby-gtk2 to run this application')
27
- end
28
- include Gtk
29
-
30
- begin
31
- require 'origami'
32
- rescue LoadError
33
- $: << File.join(__dir__, '../../lib')
34
- require 'origami'
35
- end
36
-
37
- require 'gui/menu'
38
- require 'gui/about'
39
- require 'gui/file'
40
- require 'gui/hexview'
41
- require 'gui/treeview'
42
- require 'gui/textview'
43
- require 'gui/imgview'
44
- require 'gui/config'
45
- require 'gui/properties'
46
- require 'gui/xrefs'
47
- require 'gui/signing'
48
-
49
- module PDFWalker #:nodoc:all
50
-
51
- class Walker < Window
52
- attr_reader :treeview, :hexview, :objectview
53
- attr_reader :explorer_history
54
- attr_reader :config
55
- attr_reader :filename
56
-
57
- def self.start(file = nil)
58
- Gtk.init
59
- Walker.new(file)
60
- Gtk.main
61
- end
62
-
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 = []
78
-
79
- init_interface
80
-
81
- open(target_file)
82
- end
83
-
84
- def error(msg)
85
- dialog = Gtk::MessageDialog.new(self,
86
- Gtk::Dialog::DESTROY_WITH_PARENT,
87
- Gtk::MessageDialog::ERROR,
88
- Gtk::MessageDialog::BUTTONS_CLOSE,
89
- msg
90
- )
91
-
92
- dialog.run
93
- dialog.destroy
94
- end
95
-
96
- def reload
97
- @treeview.load(@opened) if @opened
98
- end
99
-
100
- def search
101
- dialog = Gtk::Dialog.new("Search...",
102
- self,
103
- Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
104
- [Gtk::Stock::FIND, Gtk::Dialog::RESPONSE_OK],
105
- [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
106
- )
107
-
108
- entry = Gtk::Entry.new
109
- entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
110
- entry.text = @last_search[:expr]
111
-
112
- button_bydata = Gtk::RadioButton.new("In object body")
113
- button_byname = Gtk::RadioButton.new(button_bydata, "In object name")
114
- button_regexp = Gtk::CheckButton.new("Regular expression")
115
-
116
- button_bydata.set_active(true) if @last_search[:type] == :body
117
- button_byname.set_active(true) if @last_search[:type] == :name
118
- button_regexp.set_active(@last_search[:regexp])
119
-
120
- hbox = HBox.new
121
- hbox.pack_start Gtk::Label.new("Search for expression ")
122
- hbox.pack_start entry
123
-
124
- dialog.vbox.pack_start(hbox)
125
- dialog.vbox.pack_start(button_bydata)
126
- dialog.vbox.pack_start(button_byname)
127
- dialog.vbox.pack_end(button_regexp)
128
-
129
- dialog.signal_connect('response') do |_, response|
130
- if response != Gtk::Dialog::RESPONSE_OK
131
- dialog.destroy
132
- next
133
- end
134
-
135
- search_document(entry.text, regexp: button_regexp.active?, type: (button_bydata.active? ? 'body' : 'name'))
136
- end
137
-
138
- dialog.show_all
139
- end
140
-
141
- def goto_catalog
142
- @treeview.goto(@opened.Catalog.reference)
143
- end
144
-
145
- def goto_docinfo
146
- @treeview.goto(@opened.document_info.reference) if @opened.document_info?
147
- end
148
-
149
- def goto_metadata
150
- @treeview.goto(@opened.Catalog.Metadata.reference) if @opened.metadata?
151
- end
152
-
153
- def goto_object
154
- dialog = Gtk::Dialog.new("Jump to object...",
155
- self,
156
- Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
157
- [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
158
- [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
159
- )
160
-
161
- entry = Gtk::Entry.new
162
- entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
163
-
164
- dialog.vbox.pack_start Gtk::Label.new("Object number: ")
165
- dialog.vbox.pack_start entry
166
- dialog.show_all
167
-
168
- no = 0
169
- dialog.run do |response|
170
- no = entry.text.to_i if response == Gtk::Dialog::RESPONSE_OK
171
-
172
- dialog.destroy
173
- end
174
-
175
- return unless no > 0
176
-
177
- obj = @opened[no]
178
- if obj.nil?
179
- error("Object #{no} not found.")
180
- else
181
- @treeview.goto(obj)
182
- end
183
- end
184
-
185
- private
186
-
187
- def init_interface
188
- signal_connect('destroy') {
189
- @config.save
190
- Gtk.main_quit
191
- }
192
-
193
- add_events(Gdk::Event::KEY_RELEASE_MASK)
194
- signal_connect('key_release_event') { |_w, event|
195
- if event.keyval == Gdk::Keyval::GDK_F1 then about
196
- elsif event.keyval == Gdk::Keyval::GDK_Escape and @opened and not @explorer_history.empty?
197
- @treeview.goto(@explorer_history.pop)
198
- end
199
- }
200
-
201
- create_menus
202
- create_treeview
203
- create_hexview
204
- create_objectview
205
- create_panels
206
- create_statusbar
207
-
208
- @vbox = VBox.new
209
- @vbox.pack_start(@menu, false, false)
210
- @vbox.pack_start(@hpaned)
211
- @vbox.pack_end(@statusbar, false, false)
212
-
213
- add @vbox
214
-
215
- set_default_size(self.screen.width * 0.5, self.screen.height * 0.5)
216
- show_all
217
- end
218
-
219
- def search_document(expr, regexp: false, type: 'body')
220
- search =
221
- {
222
- expr: expr,
223
- regexp: regexp,
224
- type: type,
225
- }
226
-
227
- if search == @last_search
228
- @last_search_result.push @last_search_result.shift
229
- results = @last_search_result
230
- else
231
- expr = Regexp.new(expr) if search[:regexp]
232
-
233
- results =
234
- if search[:type] == 'body'
235
- @opened.grep(expr)
236
- else
237
- @opened.ls(expr, follow_references: false)
238
- end
239
-
240
- @last_search = search
241
- end
242
-
243
- goto_next_search_result(results)
244
- end
245
-
246
- def goto_next_search_result(results)
247
- if results.empty?
248
- error("No result found.")
249
- else
250
- if results != @last_search_result
251
- # Reset the previous search highlighting.
252
- @last_search_result.each do |obj| @treeview.highlight(obj, nil) end
253
-
254
- # Highlight the new results.
255
- results.each do |obj| @treeview.highlight(obj, "lightpink") end
256
-
257
- @last_search_result = results
258
- end
259
-
260
- @treeview.goto(results.first, follow_references: false)
261
- end
262
- end
263
-
264
- def create_panels
265
- @hpaned = HPaned.new
266
-
267
- @treepanel = ScrolledWindow.new.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
268
- @treepanel.add @treeview
269
-
270
- @vpaned = VPaned.new
271
- @vpaned.pack1(@objectview, true, false)
272
- @vpaned.pack2(@hexview, true, false)
273
-
274
- @hpaned.pack1(@treepanel, true, false)
275
- @hpaned.pack2(@vpaned, true, false)
276
- end
277
-
278
- def create_statusbar
279
- @statusbar = Statusbar.new
280
-
281
- @main_context = @statusbar.get_context_id 'Main'
282
- @statusbar.push(@main_context, 'No file selected')
283
- end
284
-
285
- def start_profiling
286
- if @help_menu_profile.active?
287
- require 'ruby-prof'
288
- RubyProf.start
289
- end
290
-
291
- result = yield
292
-
293
- if @help_menu_profile.active?
294
- result = RubyProf.stop
295
- multiprinter = RubyProf::MultiPrinter.new(result)
296
-
297
- Dir.mkdir(@config.profile_output_dir) unless Dir.exist?(@config.profile_output_dir)
298
-
299
- multiprinter.print(path: @config.profile_output_dir, profile: File.basename(filename))
300
- end
301
-
302
- result
303
- end
304
- end
305
-
306
- end
307
-
308
- PDFWalker::Walker.start if __FILE__ == $0
@@ -1,75 +0,0 @@
1
- =begin
2
-
3
- This file is part of PDF Walker, a graphical PDF file browser
4
- Copyright (C) 2016 Guillaume Delugré.
5
-
6
- PDF Walker is free software: you can redistribute it and/or modify
7
- it under the terms of the GNU General Public License as published by
8
- the Free Software Foundation, either version 3 of the License, or
9
- (at your option) any later version.
10
-
11
- PDF Walker is distributed in the hope that it will be useful,
12
- but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- GNU General Public License for more details.
15
-
16
- You should have received a copy of the GNU General Public License
17
- along with PDF Walker. If not, see <http://www.gnu.org/licenses/>.
18
-
19
- =end
20
-
21
- module PDFWalker
22
-
23
- class Walker < Window
24
- def show_xrefs(target)
25
- XrefsDialog.new(self, target)
26
- end
27
- end
28
-
29
- class XrefsDialog < Dialog
30
- OBJCOL = 0
31
- REFCOL = 1
32
- NAMECOL = 2
33
-
34
- def initialize(parent, target)
35
- super("Xrefs to #{target.reference}", parent, Dialog::MODAL, [Stock::CLOSE, Dialog::RESPONSE_NONE])
36
- @parent = parent
37
-
38
- @list = ListStore.new(Object, String, String)
39
- @view = TreeView.new(@list)
40
-
41
- column = Gtk::TreeViewColumn.new("Origin", Gtk::CellRendererText.new, text: REFCOL)
42
- @view.append_column(column)
43
-
44
- column = Gtk::TreeViewColumn.new("Objects", Gtk::CellRendererText.new, text: NAMECOL)
45
- @view.append_column(column)
46
-
47
- target.xrefs.each { |obj|
48
- str = obj.type.to_s
49
- iter = @list.append
50
- @list.set_value(iter, OBJCOL, obj)
51
-
52
- obj = obj.parent until obj.indirect?
53
- @list.set_value(iter, REFCOL, obj.reference.to_s)
54
-
55
- @list.set_value(iter, NAMECOL, str)
56
- }
57
-
58
- @view.signal_connect("row_activated") { |_tree, _path, _column|
59
- if @view.selection.selected
60
- from = @list.get_value(@view.selection.selected, OBJCOL)
61
- @parent.treeview.goto(from)
62
- end
63
- }
64
-
65
- scroll = ScrolledWindow.new.set_policy(POLICY_NEVER, POLICY_AUTOMATIC)
66
- scroll.add(@view)
67
- vbox.add(scroll)
68
-
69
- set_default_size(200, 200)
70
-
71
- signal_connect('response') { destroy }
72
- show_all
73
- end
74
- end
75
- end
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift(__dir__)
4
- require 'gui/walker'
5
-
6
- PDFWalker::Walker.start(ARGV[0])