Class: Alexandria::UI::ImportDialog

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

Constant Summary collapse

FILTERS =
Alexandria::ImportFilter.all

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, #log

Constructor Details

#initialize(parent) ⇒ ImportDialog

Returns a new instance of ImportDialog.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/alexandria/ui/import_dialog.rb', line 22

def initialize(parent)
  title = _("Import a Library")
  @dialog = Gtk::FileChooserDialog.new title: title, parent: parent, action: :open
  log.debug { "ImportDialog opened" }
  @destroyed = false
  @running = false
  dialog.add_button(Gtk::Stock::HELP, Gtk::ResponseType::HELP)
  dialog.add_button(Gtk::Stock::CANCEL, Gtk::ResponseType::CANCEL)
  import_button = dialog.add_button(_("_Import"),
                                    Gtk::ResponseType::ACCEPT)
  import_button.sensitive = false

  dialog.signal_connect("destroy") do
    if @running
      @destroyed = true
    else
      dialog.destroy
    end
  end

  @filters = {}
  FILTERS.each do |filter|
    filefilter = make_filefilter filter
    dialog.add_filter(filefilter)
    log.debug { "Added ImportFilter #{filefilter} -- #{filefilter.name}" }
    @filters[filefilter] = filter
  end

  dialog.signal_connect("selection_changed") do
    import_button.sensitive = dialog.filename && File.file?(dialog.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 = dialog.child.children.last
  dialog.child.set_child_packing(buttonbox, pack_type: :start)
  dialog.child.reorder_child(buttonbox, 1)

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

Instance Attribute Details

#dialogObject (readonly)

Returns the value of attribute dialog.



20
21
22
# File 'lib/alexandria/ui/import_dialog.rb', line 20

def dialog
  @dialog
end

Instance Method Details

#acquireObject



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
# File 'lib/alexandria/ui/import_dialog.rb', line 66

def acquire
  on_progress = proc do |fraction|
    @pbar.show unless @pbar.visible?
    @pbar.fraction = fraction
  end

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

  exec_queue = ExecutionQueue.new

  while !@destroyed &&
      ((response = dialog.run) != Gtk::ResponseType::CANCEL) &&
      response != Gtk::ResponseType::DELETE_EVENT

    if response == Gtk::ResponseType::HELP
      Alexandria::UI.display_help(self, "import-library")
      next
    end
    file = File.basename(dialog.filename, ".*")
    base = GLib.locale_to_utf8(file)
    new_library_name = Library.generate_new_name(
      LibraryCollection.instance.all_libraries,
      base)

    filter = @filters[dialog.filter]
    log.debug { "Going forward with filter: #{filter.name}" }
    dialog.sensitive = false

    filter.on_iterate do |n, total|
      unless @destroyed
        fraction = n * 1.0 / total
        log.debug { "#{inspect} fraction: #{fraction}" }
        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)
      log.debug { "#{inspect} cancel state: #{not_cancelled}" }
    end

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

    while thread.alive? && !@destroyed
      @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
        log.debug { "Raising ErrorDialog because not_cancelled is #{not_cancelled}" }
        ErrorDialog.new(dialog,
                        _("Couldn't import the library"),
                        _("The format of the file you " \
                          "provided is unknown.  Please " \
                          "retry with another file.")).display
      end
      @pbar.hide
      self.sensitive = true
    end
  end

  dialog.destroy unless @destroyed
end