Class: Alexandria::UI::ImportDialog

Inherits:
Gtk::FileChooserDialog
  • Object
show all
Includes:
Logging, GetText
Defined in:
lib/alexandria/ui/dialogs/import_dialog.rb

Constant Summary collapse

FILTERS =
Alexandria::ImportFilter.all

Instance Method Summary collapse

Methods included from Logging

included, #log

Constructor Details

#initialize(parent) ⇒ ImportDialog

Returns a new instance of ImportDialog.



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
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
132
133
134
135
136
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
187
188
189
190
191
192
193
# File 'lib/alexandria/ui/dialogs/import_dialog.rb', line 61

def initialize(parent)
  super()
  puts 'ImportDialog opened.' if $DEBUG
  @destroyed = false
  self.title = _('Import a Library')
  self.action = :open
  self.transient_for = parent
  #            self.deletable = false
  running = false
  add_button(Gtk::Stock::HELP, :help)
  add_button(Gtk::Stock::CANCEL, :cancel)
  import_button = add_button(_('_Import'),
                             :accept)
  import_button.sensitive = false

  signal_connect('destroy') {
    if running
      @destroyed = true

    else
      destroy
    end
    # self.destroy unless running
  }

  filters = {}
  FILTERS.each do |filter|
    filefilter = filter.to_filefilter
    add_filter(filefilter)
    puts "Added ImportFilter #{filefilter} -- #{filefilter.name}" if $DEBUG
    filters[filefilter] = filter
  end

  signal_connect('selection_changed') do
    import_button.sensitive = filename && File.file?(filename)
  end

  # before adding the (hidden) progress bar, we must re-set the
  # packing of the button box (currently packed at the end),
  # because the progressbar will be *after* the button box.
  buttonbox = child.children.last
  child.set_child_packing(buttonbox, pack_type: :start)
  child.reorder_child(buttonbox, 1)

  pbar = Gtk::ProgressBar.new
  pbar.show_text = true
  child.pack_start(pbar, expand: false)

  on_progress = proc do |fraction|
    begin
      pbar.show unless pbar.visible?
      pbar.fraction = fraction
    rescue
      # TODO: check if destroyed instead...
    end
  end

  on_error = proc do |message|
    SkipEntryDialog.new(parent, message).continue?
  end

  exec_queue = ExecutionQueue.new

  while !@destroyed &&
      ((response = run) != :cancel) &&
      (response != :delete_event)

    if response == :help
      Alexandria::UI.display_help(self, 'import-library')
      next
    end
    file = File.basename(filename, '.*')
    base = GLib.locale_to_utf8(file)
    new_library_name = Library.generate_new_name(
      Libraries.instance.all_libraries,
      base)

    filter = filters[self.filter]
    puts "Going forward with filter: #{filter.name}" if $DEBUG
    self.sensitive = false

    filter.on_iterate do |n, total|
      unless @destroyed
        fraction = n * 1.0 / total
        puts "#{inspect} fraction: #{fraction}" if $DEBUG
        exec_queue.call(on_progress, fraction)
      end
    end

    not_cancelled = true
    filter.on_error do |message|
      not_cancelled = exec_queue.sync_call(on_error, message)
      puts "#{inspect} cancel state: #{not_cancelled}" if $DEBUG
    end

    library = nil
    @bad_isbns = nil
    @failed_isbns = nil
    thread = Thread.start do
      begin
        library, @bad_isbns, @failed_isbns = filter.invoke(new_library_name,
                                                           filename)
      rescue => ex
        trace = ex.backtrace.join("\n> ")
        log.error { "Import failed: #{ex.message} #{trace}" }
      end
    end

    while thread.alive? && !@destroyed
      # puts "Thread #{thread} still alive."
      running = true
      exec_queue.iterate
      Gtk.main_iteration_do(false)
    end

    unless @destroyed
      if library
        yield(library, @bad_isbns, @failed_isbns)
        break
      elsif not_cancelled
        puts "Raising ErrorDialog because not_cancelled is #{not_cancelled}" if $DEBUG
        ErrorDialog.new(parent,
                        _("Couldn't import the library"),
                        _('The format of the file you ' \
                          'provided is unknown.  Please ' \
                          'retry with another file.'))
      end
      pbar.hide
      self.sensitive = true
    end
  end
  destroy unless @destroyed
end