Module: Alexandria::UI::Callbacks

Includes:
Logging
Defined in:
lib/alexandria/ui/callbacks.rb

Instance Method Summary collapse

Methods included from Logging

included, #log

Instance Method Details

#connect_signalsObject



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'lib/alexandria/ui/callbacks.rb', line 278

def connect_signals
  # rubocop:disable Layout/LineLength
  standard_actions = [
    ["LibraryMenu", nil, _("_Library")],
    ["New", Gtk::Stock::NEW, _("_New Library"), "<control>L", _("Create a new library"), method(:on_new)],
    ["NewSmart", nil, _("New _Smart Library..."), "<control><shift>L", _("Create a new smart library"), method(:on_new_smart)],
    ["AddBook", Gtk::Stock::ADD, _("_Add Book..."), "<control>N", _("Add a new book from the Internet"), method(:on_add_book)],
    ["AddBookManual", nil, _("Add Book _Manually..."), "<control><shift>N", _("Add a new book manually"), method(:on_add_book_manual)],
    ["Import", nil, _("_Import..."), "<control>I", _("Import a library"), method(:on_import)],
    ["Export", nil, _("_Export..."), "<control><shift>E", _("Export the selected library"), method(:on_export)],
    ["Acquire", nil, _("A_cquire from Scanner..."), "<control><shift>S", _("Acquire books from a scanner"), method(:on_acquire)],
    ["Properties", Gtk::Stock::PROPERTIES, _("_Properties"), nil, _("Edit the properties of the selected book"), method(:on_properties)],
    ["Quit", Gtk::Stock::QUIT, _("_Quit"), "<control>Q", _("Quit the program"), method(:on_quit)],
    ["EditMenu", nil, _("_Edit")],
    ["Undo", Gtk::Stock::UNDO, _("_Undo"), "<control>Z", _("Undo the last action"), method(:on_undo)],
    ["Redo", Gtk::Stock::REDO, _("_Redo"), "<control><shift>Z", _("Redo the undone action"), method(:on_redo)],
    ["SelectAll", nil, _("_Select All"), "<control>A", _("Select all visible books"), method(:on_select_all)],
    ["DeselectAll", nil, _("Dese_lect All"), "<control><shift>A", _("Deselect everything"), method(:on_deselect_all)],
    ["SetRating", nil, _("My _Rating")],
    ["SetRating0", nil, _("None"), nil, nil, proc { on_set_rating[0].call }],
    ["SetRating1", nil, _("One Star"), nil, nil, proc { on_set_rating[1].call }],
    ["SetRating2", nil, _("Two Stars"), nil, nil, proc { on_set_rating[2].call }],
    ["SetRating3", nil, _("Three Stars"), nil, nil, proc { on_set_rating[3].call }],
    ["SetRating4", nil, _("Four Stars"), nil, nil, proc { on_set_rating[4].call }],
    ["SetRating5", nil, _("Five Stars"), nil, nil, proc { on_set_rating[5].call }],
    ["Move", nil, _("_Move")],
    ["Rename", nil, _("_Rename"), nil, nil, method(:on_rename)],
    ["Delete", Gtk::Stock::DELETE, _("_Delete"), "Delete", _("Delete the selected books or library"), method(:on_delete)],
    ["Search", Gtk::Stock::FIND, _("_Search"), "<control>F", _("Filter books"), method(:on_search)],
    ["ClearSearchResult", Gtk::Stock::CLEAR, _("_Clear Results"), "<control><alt>B", _("Clear the search results"), method(:on_clear_search_results)],
    ["Preferences", Gtk::Stock::PREFERENCES, _("_Preferences"), "<control>O", _("Change Alexandria's settings"), method(:on_preferences)],
    ["ViewMenu", nil, _("_View")],
    ["ArrangeIcons", nil, _("Arran_ge Icons")],
    ["OnlineInformation", nil, _("Display Online _Information")],

    ["HelpMenu", nil, _("_Help")],
    ["SubmitBugReport", Gtk::Stock::EDIT, _("Submit _Bug Report"), nil, _("Submit a bug report to the developers"), method(:on_submit_bug_report)],
    ["Help", Gtk::Stock::HELP, _("Contents"), "F1", _("View Alexandria's manual"), method(:on_help)],
    ["About", Gtk::Stock::ABOUT, _("_About"), nil, _("Show information about Alexandria"), method(:on_about)],
  ]

  toggle_actions = [
    ["Sidepane", nil, _("Side _Pane"), "F9", nil, method(:on_view_sidepane), true],
    ["Toolbar", nil, _("_Toolbar"), nil, nil, method(:on_view_toolbar), true],
    ["Statusbar", nil, _("_Statusbar"), nil, nil, method(:on_view_statusbar), true],
    ["ReversedOrder", nil, _("Re_versed Order"), nil, nil, method(:on_reverse_order), false],
  ]

  view_as_actions = [
    ["AsIcons", nil, _("View as _Icons"), nil, nil, 0],
    ["AsList", nil, _("View as _List"), nil, nil, 1]
  ]

  arrange_icons_actions = [
    ["ByTitle", nil, _("By _Title"), nil, nil, 0],
    ["ByAuthors", nil, _("By _Authors"), nil, nil, 1],
    ["ByISBN", nil, _("By _ISBN"), nil, nil, 2],
    ["ByPublisher", nil, _("By _Publisher"), nil, nil, 3],
    ["ByEdition", nil, _("By _Binding"), nil, nil, 4],
    ["ByRating", nil, _("By _Rating"), nil, nil, 5]
  ]
  # rubocop:enable Layout/LineLength

  providers_actions = BookProviders.map do |provider|
    [provider.action_name, Gtk::Stock::JUMP_TO,
     _("At _%s") % provider.fullname, nil, nil,
     proc { open_web_browser(provider.url(selected_books.first)) }]
  end

  log.debug { "Adding actions to @actiongroup" }

  @actiongroup = Gtk::ActionGroup.new("actions")

  standard_actions.each do |name, stock_id, label, accelerator, tooltip, callback|
    action = Gtk::Action.new(name, label: label, tooltip: tooltip, stock_id: stock_id)
    @actiongroup.add_action_with_accel(action, accelerator)
    action.signal_connect("activate", &callback) if callback
  end

  providers_actions.each do |name, stock_id, label, accelerator, tooltip, callback|
    action = Gtk::Action.new(name, label: label, tooltip: tooltip, stock_id: stock_id)
    @actiongroup.add_action_with_accel(action, accelerator)
    action.signal_connect("activate", &callback) if callback
  end

  toggle_actions
    .each do |name, stock_id, label, accelerator, tooltip, callback, is_active|
    action = Gtk::ToggleAction.new(name, label: label, tooltip: tooltip,
                                   stock_id: stock_id)
    action.set_active is_active
    @actiongroup.add_action_with_accel(action, accelerator)
    action.signal_connect("toggled", &callback) if callback
  end

  first_action = nil
  view_as_actions.each do |name, stock_id, label, accelerator, tooltip, value|
    action = Gtk::RadioAction.new(name, value, label: label, tooltip: tooltip,
                                  stock_id: stock_id)
    if first_action
      action.join_group first_action
    else
      first_action = action
    end
    @actiongroup.add_action_with_accel(action, accelerator)
  end

  first_action.signal_connect "changed" do |_action, current, _user_data|
    @notebook.page = current.current_value
    hid = @toolbar_view_as_signal_hid
    @toolbar_view_as.signal_handler_block(hid) do
      @toolbar_view_as.active = current.current_value
    end
  end

  first_action = nil
  arrange_icons_actions.each do |name, stock_id, label, accelerator, tooltip, value|
    action = Gtk::RadioAction.new(name, value, label: label, tooltip: tooltip,
                                  stock_id: stock_id)
    if first_action
      action.join_group first_action
    else
      first_action = action
    end
    @actiongroup.add_action_with_accel(action, accelerator)
  end

  first_action.signal_connect "changed" do |_action, current, _user_data|
    @prefs.arrange_icons_mode = current.current_value
    setup_books_iconview_sorting
  end
end

#on_aboutObject



252
253
254
# File 'lib/alexandria/ui/callbacks.rb', line 252

def on_about(*)
  AboutDialog.new(@main_app).show
end

#on_acquireObject



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/alexandria/ui/callbacks.rb', line 116

def on_acquire(*)
  AcquireDialog.new(@main_app,
                    selected_library) do |_books, library, is_new|
                      if is_new
                        append_library(library, true)
                        setup_move_actions
                      elsif selected_library != library
                        select_library(library)
                      end
                    end
end

#on_add_bookObject



32
33
34
35
36
37
38
39
40
41
42
# File 'lib/alexandria/ui/callbacks.rb', line 32

def on_add_book(*)
  log.info { "on_add_book" }
  NewBookDialog.new(@main_app, selected_library) do |_books, library, is_new|
    if is_new
      append_library(library, true)
      setup_move_actions
    elsif selected_library != library
      select_library(library)
    end
  end
end

#on_add_book_manualObject



44
45
46
47
48
49
# File 'lib/alexandria/ui/callbacks.rb', line 44

def on_add_book_manual(*)
  library = selected_library
  NewBookDialogManual.new(@main_app, library) do |_book|
    refresh_books
  end
end

#on_clear_search_resultsObject



227
228
229
230
231
232
# File 'lib/alexandria/ui/callbacks.rb', line 227

def on_clear_search_results(*)
  @filter_entry.text = ""
  @iconview.freeze
  @filtered_model.refilter
  @iconview.unfreeze
end

#on_criterion_combobox_changed(cb) ⇒ Object



103
104
105
106
107
108
109
110
# File 'lib/alexandria/ui/callbacks.rb', line 103

def on_criterion_combobox_changed(cb)
  log.debug { "changed" }
  @filter_books_mode = cb.active
  @filter_entry.text.strip!
  @iconview.freeze
  @filtered_model.refilter
  @iconview.unfreeze
end

#on_deleteObject



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/alexandria/ui/callbacks.rb', line 205

def on_delete(*)
  library = selected_library

  books = if selected_books.empty?
            nil
          else
            selected_books
          end
  # books = @library_listview.focus? ? nil : selected_books
  is_smart = library.is_a?(SmartLibrary)
  last_library = (@libraries.all_regular_libraries.length == 1)
  if books.nil? && !is_smart && last_library
    log.warn { "Attempted to delete last library, fix GUI" }
    return
  end
  if library.empty? || ReallyDeleteDialog.new(@main_app,
                                              library,
                                              books).ok?
    undoable_delete(library, books)
  end
end

#on_deselect_allObject



174
175
176
177
178
179
180
181
182
# File 'lib/alexandria/ui/callbacks.rb', line 174

def on_deselect_all(*)
  log.debug { "on_deselect_all" }
  case @notebook.page
  when 0
    @iconview.unselect_all
  when 1
    @listview.selection.unselect_all
  end
end

#on_exportObject



112
113
114
# File 'lib/alexandria/ui/callbacks.rb', line 112

def on_export(*)
  ExportDialog.new(@main_app, selected_library, library_sort_order).perform
end

#on_helpObject



248
249
250
# File 'lib/alexandria/ui/callbacks.rb', line 248

def on_help(*)
  Alexandria::UI.display_help(@main_app)
end

#on_importObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/alexandria/ui/callbacks.rb', line 51

def on_import(*)
  ImportDialog.new(@main_app).acquire do |library, bad_isbns, failed_isbns|
    unless bad_isbns.empty?
      log.debug { "bad_isbn" }
      message = _("The following lines are not valid ISBNs and were not imported:")
      bad_isbn_warn = BadIsbnsDialog.new(@main_app, message, bad_isbns)
      bad_isbn_warn.signal_connect("response") { bad_isbn_warn.destroy }
    end
    unless failed_isbns.nil? || failed_isbns.empty?
      log.debug { "failed lookup of #{failed_isbns.size} ISBNs" }
      message = _("Books could not be found for the following ISBNs:")
      failed_lookup = BadIsbnsDialog.new(@main_app, message, failed_isbns)
      failed_lookup.signal_connect("response") { failed_lookup.destroy }
    end
    @libraries.add_library(library)
    append_library(library, true)
    setup_move_actions
  end
end

#on_newObject



14
15
16
17
18
19
20
21
# File 'lib/alexandria/ui/callbacks.rb', line 14

def on_new(*)
  name = Library.generate_new_name(@libraries.all_libraries)
  library = Library.load(name)
  @libraries.add_library(library)
  append_library(library, true)
  setup_move_actions
  library.add_observer(self)
end

#on_new_smartObject



23
24
25
26
27
28
29
30
# File 'lib/alexandria/ui/callbacks.rb', line 23

def on_new_smart(*)
  NewSmartLibraryDialog.new(@main_app).acquire do |smart_library|
    smart_library.refilter
    @libraries.add_library(smart_library)
    append_library(smart_library, true)
    smart_library.save
  end
end

#on_preferencesObject



238
239
240
241
242
# File 'lib/alexandria/ui/callbacks.rb', line 238

def on_preferences(*)
  PreferencesDialog.new(@main_app) do
    @listview_manager.setup_listview_columns_visibility
  end
end

#on_propertiesObject



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/alexandria/ui/callbacks.rb', line 128

def on_properties(*)
  if @library_listview.focus? || selected_books.empty?
    library = selected_library
    if library.is_a?(SmartLibrary)
      SmartLibraryPropertiesDialog.new(@main_app, library).acquire do
        library.refilter
        refresh_books
      end
    end
  else
    books = selected_books
    if books.length == 1
      book = books.first
      BookPropertiesDialog.new(@main_app,
                               selected_library,
                               book) # { |modified_book| }
    end
  end
end

#on_quitObject



148
149
150
151
152
153
154
# File 'lib/alexandria/ui/callbacks.rb', line 148

def on_quit(*)
  save_preferences
  Gtk.main_quit
  # @libraries.really_save_all_books
  @libraries.really_delete_deleted_libraries
  @libraries.all_regular_libraries.each(&:really_delete_deleted_books)
end

#on_redoObject



160
161
162
# File 'lib/alexandria/ui/callbacks.rb', line 160

def on_redo(*)
  UndoManager.instance.redo!
end

#on_renameObject



198
199
200
201
202
203
# File 'lib/alexandria/ui/callbacks.rb', line 198

def on_rename(*)
  iter = @library_listview.selection.selected
  @library_listview.set_cursor(iter.path,
                               @library_listview.get_column(0),
                               true)
end

#on_reverse_order(action) ⇒ Object



271
272
273
274
275
276
# File 'lib/alexandria/ui/callbacks.rb', line 271

def on_reverse_order(action)
  log.debug { "on_reverse_order" }
  Preferences.instance.reverse_icons = action.active?
  Preferences.instance.save!
  setup_books_iconview_sorting
end

#on_searchObject



234
235
236
# File 'lib/alexandria/ui/callbacks.rb', line 234

def on_search(*)
  @filter_entry.grab_focus
end

#on_select_allObject



164
165
166
167
168
169
170
171
172
# File 'lib/alexandria/ui/callbacks.rb', line 164

def on_select_all(*)
  log.debug { "on_select_all" }
  case @notebook.page
  when 0
    @iconview.select_all
  when 1
    @listview.selection.select_all
  end
end

#on_set_ratingObject



184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/alexandria/ui/callbacks.rb', line 184

def on_set_rating
  Book::VALID_RATINGS.map do |rating|
    proc do
      books = selected_books
      library = selected_library
      books.each do |book|
        log.debug { "set #{book.title} rating to #{rating}" }
        book.rating = rating
        library.save(book)
      end
    end
  end
end

#on_submit_bug_reportObject



244
245
246
# File 'lib/alexandria/ui/callbacks.rb', line 244

def on_submit_bug_report(*)
  open_web_browser(BUGREPORT_URL)
end

#on_toolbar_filter_entry_changed(_entry) ⇒ Object



95
96
97
98
99
100
101
# File 'lib/alexandria/ui/callbacks.rb', line 95

def on_toolbar_filter_entry_changed(_entry)
  log.debug { "changed" }
  @filter_entry.text.strip!
  @iconview.freeze
  @filtered_model.refilter
  @iconview.unfreeze
end

#on_toolbar_view_as_changed(cb) ⇒ Object



79
80
81
82
83
84
85
86
87
88
# File 'lib/alexandria/ui/callbacks.rb', line 79

def on_toolbar_view_as_changed(cb)
  log.debug { "changed" }
  action = case cb.active
           when 0
             @actiongroup["AsIcons"]
           when 1
             @actiongroup["AsList"]
           end
  action.active = true
end

#on_undoObject



156
157
158
# File 'lib/alexandria/ui/callbacks.rb', line 156

def on_undo(*)
  UndoManager.instance.undo!
end

#on_view_sidepane(action) ⇒ Object



256
257
258
259
# File 'lib/alexandria/ui/callbacks.rb', line 256

def on_view_sidepane(action)
  log.debug { "on_view_sidepane" }
  @paned.child1.visible = action.active?
end

#on_view_statusbar(action) ⇒ Object



266
267
268
269
# File 'lib/alexandria/ui/callbacks.rb', line 266

def on_view_statusbar(action)
  log.debug { "on_view_statusbar" }
  @appbar.visible = action.active?
end

#on_view_toolbar(action) ⇒ Object



261
262
263
264
# File 'lib/alexandria/ui/callbacks.rb', line 261

def on_view_toolbar(action)
  log.debug { "on_view_toolbar" }
  @toolbar.visible = action.active?
end

#on_window_destroy(_window) ⇒ Object



90
91
92
93
# File 'lib/alexandria/ui/callbacks.rb', line 90

def on_window_destroy(_window)
  log.debug { "destroy" }
  @actiongroup["Quit"].activate
end

#on_window_state_event(_window, event) ⇒ Object



71
72
73
74
75
76
77
# File 'lib/alexandria/ui/callbacks.rb', line 71

def on_window_state_event(_window, event)
  log.debug { "window-state-event" }
  if event.is_a?(Gdk::EventWindowState)
    @maximized = event.new_window_state == :maximized
  end
  log.debug { "end window-state-event" }
end