Class: PDFWalker::Walker

Inherits:
Window
  • Object
show all
Defined in:
lib/pdfwalker/file.rb,
lib/pdfwalker/menu.rb,
lib/pdfwalker/about.rb,
lib/pdfwalker/xrefs.rb,
lib/pdfwalker/config.rb,
lib/pdfwalker/walker.rb,
lib/pdfwalker/hexview.rb,
lib/pdfwalker/signing.rb,
lib/pdfwalker/textview.rb,
lib/pdfwalker/treeview.rb,
lib/pdfwalker/properties.rb

Defined Under Namespace

Modules: SignatureDialogs Classes: Config, DumpView, ObjectView, Properties, SignWizard, UsageRightsWizard

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target_file = nil) ⇒ Walker

Returns a new instance of Walker.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/pdfwalker/walker.rb', line 55

def initialize(target_file = nil)
    super("PDF Walker")

    @config = Walker::Config.new
    @opened = nil

    @last_search_result = []
    @last_search =
    {
        :expr => "",
        :regexp => false,
        :type => :body
    }

    @explorer_history = []

    init_interface

    open(target_file)
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



46
47
48
# File 'lib/pdfwalker/walker.rb', line 46

def config
  @config
end

#explore_historyObject (readonly)

Returns the value of attribute explore_history.



27
28
29
# File 'lib/pdfwalker/file.rb', line 27

def explore_history
  @explore_history
end

#explorer_historyObject (readonly)

Returns the value of attribute explorer_history.



45
46
47
# File 'lib/pdfwalker/walker.rb', line 45

def explorer_history
  @explorer_history
end

#filenameObject (readonly)

Returns the value of attribute filename.



47
48
49
# File 'lib/pdfwalker/walker.rb', line 47

def filename
  @filename
end

#hexviewObject (readonly)

Returns the value of attribute hexview.



44
45
46
# File 'lib/pdfwalker/walker.rb', line 44

def hexview
  @hexview
end

#objectviewObject (readonly)

Returns the value of attribute objectview.



44
45
46
# File 'lib/pdfwalker/walker.rb', line 44

def objectview
  @objectview
end

#openedObject (readonly)

Returns the value of attribute opened.



26
27
28
# File 'lib/pdfwalker/file.rb', line 26

def opened
  @opened
end

#treeviewObject (readonly)

Returns the value of attribute treeview.



44
45
46
# File 'lib/pdfwalker/walker.rb', line 44

def treeview
  @treeview
end

Class Method Details

.start(file = nil) ⇒ Object



49
50
51
52
53
# File 'lib/pdfwalker/walker.rb', line 49

def self.start(file = nil)
    Gtk.init
    Walker.new(file)
    Gtk.main
end

Instance Method Details

#aboutObject



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/pdfwalker/about.rb', line 25

def about
    AboutDialog.show(self,
        name: "PDF Walker",
        program_name: "PDF Walker",
        version: "#{PDFWalker::VERSION}",
        copyright: "Copyright © 2017\nGuillaume Delugré",
        comments: "A PDF file explorer, based on Origami",
        license: File.read(File.join(__dir__, "../..", "COPYING")),
        wrap_license: true,
    )
end

#closeObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/pdfwalker/file.rb', line 29

def close
    @opened = nil
    @filename = ''
    @explorer_history.clear

    @treeview.clear
    @objectview.clear
    @hexview.clear

    # disable all menus.
    [
        @file_menu_close, @file_menu_saveas, @file_menu_refresh,
        @document_menu_search,
        @document_menu_gotocatalog, @document_menu_gotodocinfo, ,
        @document_menu_gotopage, @document_menu_gotofield, @document_menu_gotorev, @document_menu_gotoobj,
        @document_menu_properties, @document_menu_sign, @document_menu_ur
    ].each do |menu|
        menu.sensitive = false
    end

    @statusbar.pop(@main_context)

    GC.start
end

#display_file_propertiesObject



27
28
29
# File 'lib/pdfwalker/properties.rb', line 27

def display_file_properties
    Properties.new(self, @opened) if @opened
end

#display_signing_wizardObject



25
26
27
# File 'lib/pdfwalker/signing.rb', line 25

def display_signing_wizard
    SignWizard.new(self, @opened) if @opened
end

#display_usage_rights_wizardObject



29
30
31
# File 'lib/pdfwalker/signing.rb', line 29

def display_usage_rights_wizard
    UsageRightsWizard.new(self, @opened) if @opened
end

#error(msg) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
# File 'lib/pdfwalker/walker.rb', line 76

def error(msg)
    dialog = Gtk::MessageDialog.new(self,
                Gtk::Dialog::DESTROY_WITH_PARENT,
                Gtk::MessageDialog::ERROR,
                Gtk::MessageDialog::BUTTONS_CLOSE,
                msg
             )

    dialog.run
    dialog.destroy
end

#goto_catalogObject



133
134
135
# File 'lib/pdfwalker/walker.rb', line 133

def goto_catalog
    @treeview.goto(@opened.Catalog.reference)
end

#goto_docinfoObject



137
138
139
# File 'lib/pdfwalker/walker.rb', line 137

def goto_docinfo
    @treeview.goto(@opened.document_info.reference) if @opened.document_info?
end

#goto_metadataObject



141
142
143
# File 'lib/pdfwalker/walker.rb', line 141

def 
    @treeview.goto(@opened.Catalog..reference) if @opened.metadata?
end

#goto_objectObject



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
# File 'lib/pdfwalker/walker.rb', line 145

def goto_object
    dialog = Gtk::Dialog.new("Jump to object...",
                self,
                Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
                [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
                [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
    )

    entry = Gtk::Entry.new
    entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }

    dialog.vbox.pack_start Gtk::Label.new("Object number: ")
    dialog.vbox.pack_start entry
    dialog.show_all

    no = 0
    dialog.run do |response|
        no = entry.text.to_i if response == Gtk::Dialog::RESPONSE_OK

        dialog.destroy
    end

    return unless no > 0

    obj = @opened[no]
    if obj.nil?
        error("Object #{no} not found.")
    else
        @treeview.goto(obj)
    end
end

#open(filename = nil) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/pdfwalker/file.rb', line 54

def open(filename = nil)
    dialog = Gtk::FileChooserDialog.new("Open PDF File",
                self,
                FileChooser::ACTION_OPEN,
                nil,
                [Stock::CANCEL, Dialog::RESPONSE_CANCEL],
                [Stock::OPEN, Dialog::RESPONSE_ACCEPT])

    last_file = @config.recent_files.first
    unless last_file.nil?
        last_folder = File.dirname(last_file)
        dialog.set_current_folder(last_folder) if File.directory?(last_folder)
    end

    dialog.filter = FileFilter.new.add_pattern("*.acrodata").add_pattern("*.pdf").add_pattern("*.fdf")

    if filename.nil? and dialog.run != Gtk::Dialog::RESPONSE_ACCEPT
        dialog.destroy
        return
    end

    create_progressbar

    filename ||= dialog.filename
    dialog.destroy

    begin
        document = start_profiling do
            parse_file(filename)
        end

        set_active_document(filename, document)

    rescue
        error("Error while parsing file.\n#{$!} (#{$!.class})\n" + $!.backtrace.join("\n"))
    ensure
        close_progressbar
        self.activate_focus
    end
end

#reloadObject



88
89
90
# File 'lib/pdfwalker/walker.rb', line 88

def reload
    @treeview.load(@opened) if @opened
end

#saveObject



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/pdfwalker/file.rb', line 119

def save
    dialog = Gtk::FileChooserDialog.new("Save PDF file",
                self,
                Gtk::FileChooser::ACTION_SAVE,
                nil,
                [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
                [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
    )

    dialog.filter = FileFilter.new.add_pattern("*.acrodata").add_pattern("*.pdf").add_pattern("*.fdf")

    folder = File.dirname(@filename)
    dialog.set_current_folder(folder)

    if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
        begin
            @opened.save(dialog.filename)
        rescue
            error("#{$!.class}: #{$!.message}\n#{$!.backtrace.join($/)}")
        end
    end

    dialog.destroy
end

#save_data(caption, data, filename = "") ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/pdfwalker/file.rb', line 95

def save_data(caption, data, filename = "")
    dialog = Gtk::FileChooserDialog.new(caption,
                self,
                Gtk::FileChooser::ACTION_SAVE,
                nil,
                [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
                [Gtk::Stock::SAVE, Gtk::Dialog::RESPONSE_ACCEPT]
    )

    dialog.do_overwrite_confirmation = true
    dialog.current_name = File.basename(filename)
    dialog.filter = FileFilter.new.add_pattern("*.*")

    if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
        begin
            File.binwrite(dialog.filename, data)
        rescue
            error("Error: #{$!.message}")
        end
    end

    dialog.destroy
end

#searchObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/pdfwalker/walker.rb', line 92

def search
    dialog = Gtk::Dialog.new("Search...",
                self,
                Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
                [Gtk::Stock::FIND, Gtk::Dialog::RESPONSE_OK],
                [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL]
    )

    entry = Gtk::Entry.new
    entry.signal_connect('activate') { dialog.response(Gtk::Dialog::RESPONSE_OK) }
    entry.text = @last_search[:expr]

    button_bydata = Gtk::RadioButton.new("In object body")
    button_byname = Gtk::RadioButton.new(button_bydata, "In object name")
    button_regexp = Gtk::CheckButton.new("Regular expression")

    button_bydata.set_active(true) if @last_search[:type] == :body
    button_byname.set_active(true) if @last_search[:type] == :name
    button_regexp.set_active(@last_search[:regexp])

    hbox = Gtk::HBox.new
    hbox.pack_start Gtk::Label.new("Search for expression ")
    hbox.pack_start entry

    dialog.vbox.pack_start(hbox)
    dialog.vbox.pack_start(button_bydata)
    dialog.vbox.pack_start(button_byname)
    dialog.vbox.pack_end(button_regexp)

    dialog.signal_connect('response') do |_, response|
        if response != Gtk::Dialog::RESPONSE_OK
            dialog.destroy
            next
        end

        search_document(entry.text, regexp: button_regexp.active?, type: (button_bydata.active? ? 'body' : 'name'))
    end

    dialog.show_all
end

#show_xrefs(target) ⇒ Object



24
25
26
# File 'lib/pdfwalker/xrefs.rb', line 24

def show_xrefs(target)
    XrefsDialog.new(self, target)
end