alexandria-book-collection-manager 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.gitignore +4 -1
  4. data/.rubocop.yml +51 -29
  5. data/.rubocop_todo.yml +33 -155
  6. data/.simplecov +5 -2
  7. data/.travis.yml +10 -4
  8. data/CHANGELOG.md +19 -0
  9. data/INSTALL.md +23 -11
  10. data/README.md +36 -35
  11. data/Rakefile +7 -5
  12. data/alexandria-book-collection-manager.gemspec +8 -3
  13. data/doc/dependency_decisions.yml +22 -3
  14. data/lib/alexandria.rb +2 -2
  15. data/lib/alexandria/book_providers.rb +47 -49
  16. data/lib/alexandria/book_providers/adlibris.rb +8 -13
  17. data/lib/alexandria/book_providers/amazon_aws.rb +47 -60
  18. data/lib/alexandria/book_providers/amazon_ecs_util.rb +283 -298
  19. data/lib/alexandria/book_providers/barnes_and_noble.rb +8 -8
  20. data/lib/alexandria/book_providers/douban.rb +2 -2
  21. data/lib/alexandria/book_providers/proxis.rb +12 -11
  22. data/lib/alexandria/book_providers/pseudomarc.rb +60 -70
  23. data/lib/alexandria/book_providers/siciliano.rb +5 -6
  24. data/lib/alexandria/book_providers/thalia.rb +8 -9
  25. data/lib/alexandria/book_providers/worldcat.rb +25 -31
  26. data/lib/alexandria/book_providers/z3950.rb +62 -69
  27. data/lib/alexandria/default_preferences.rb +37 -0
  28. data/lib/alexandria/execution_queue.rb +13 -12
  29. data/lib/alexandria/export_library.rb +4 -8
  30. data/lib/alexandria/import_library.rb +38 -62
  31. data/lib/alexandria/import_library_csv.rb +16 -16
  32. data/lib/alexandria/library_sort_order.rb +3 -1
  33. data/lib/alexandria/library_store.rb +16 -16
  34. data/lib/alexandria/logging.rb +4 -8
  35. data/lib/alexandria/models/book.rb +2 -2
  36. data/lib/alexandria/models/library.rb +18 -14
  37. data/lib/alexandria/net.rb +1 -2
  38. data/lib/alexandria/preferences.rb +27 -31
  39. data/lib/alexandria/scanners.rb +2 -2
  40. data/lib/alexandria/scanners/cue_cat.rb +5 -5
  41. data/lib/alexandria/scanners/keyboard.rb +1 -1
  42. data/lib/alexandria/smart_library.rb +22 -26
  43. data/lib/alexandria/ui.rb +7 -7
  44. data/lib/alexandria/ui/about_dialog.rb +1 -1
  45. data/lib/alexandria/ui/acquire_dialog.rb +9 -10
  46. data/lib/alexandria/ui/alert_dialog.rb +34 -19
  47. data/lib/alexandria/ui/bad_isbns_dialog.rb +13 -9
  48. data/lib/alexandria/ui/barcode_animation.rb +5 -5
  49. data/lib/alexandria/ui/book_properties_dialog.rb +2 -2
  50. data/lib/alexandria/ui/book_properties_dialog_base.rb +23 -17
  51. data/lib/alexandria/ui/callbacks.rb +141 -120
  52. data/lib/alexandria/ui/completion_models.rb +1 -1
  53. data/lib/alexandria/ui/confirm_erase_dialog.rb +1 -1
  54. data/lib/alexandria/ui/conflict_while_copying_dialog.rb +1 -1
  55. data/lib/alexandria/ui/error_dialog.rb +1 -1
  56. data/lib/alexandria/ui/export_dialog.rb +13 -15
  57. data/lib/alexandria/ui/icons.rb +34 -40
  58. data/lib/alexandria/ui/iconview_tooltips.rb +40 -53
  59. data/lib/alexandria/ui/import_dialog.rb +48 -47
  60. data/lib/alexandria/ui/init.rb +3 -2
  61. data/lib/alexandria/ui/keep_bad_isbn_dialog.rb +2 -2
  62. data/lib/alexandria/ui/libraries_combo.rb +10 -9
  63. data/lib/alexandria/ui/listview.rb +5 -6
  64. data/lib/alexandria/ui/main_app.rb +2 -2
  65. data/lib/alexandria/ui/multi_drag_treeview.rb +4 -6
  66. data/lib/alexandria/ui/new_book_dialog.rb +52 -52
  67. data/lib/alexandria/ui/new_provider_dialog.rb +12 -11
  68. data/lib/alexandria/ui/new_smart_library_dialog.rb +39 -27
  69. data/lib/alexandria/ui/preferences_dialog.rb +23 -82
  70. data/lib/alexandria/ui/provider_preferences_base_dialog.rb +9 -5
  71. data/lib/alexandria/ui/provider_preferences_dialog.rb +5 -5
  72. data/lib/alexandria/ui/really_delete_dialog.rb +1 -1
  73. data/lib/alexandria/ui/sidepane_manager.rb +35 -37
  74. data/lib/alexandria/ui/skip_entry_dialog.rb +3 -2
  75. data/lib/alexandria/ui/smart_library_properties_dialog.rb +35 -36
  76. data/lib/alexandria/ui/smart_library_properties_dialog_base.rb +59 -138
  77. data/lib/alexandria/ui/smart_library_rule_box.rb +119 -0
  78. data/lib/alexandria/ui/sound.rb +4 -6
  79. data/lib/alexandria/ui/ui_manager.rb +62 -64
  80. data/lib/alexandria/version.rb +2 -2
  81. data/lib/alexandria/web_themes.rb +15 -15
  82. data/po/cs.po +991 -874
  83. data/po/cy.po +957 -870
  84. data/po/de.po +991 -866
  85. data/po/el.po +987 -863
  86. data/po/es.po +986 -862
  87. data/po/fr.po +988 -868
  88. data/po/ga.po +910 -822
  89. data/po/gl.po +983 -863
  90. data/po/it.po +984 -862
  91. data/po/ja.po +969 -849
  92. data/po/mk.po +983 -859
  93. data/po/nb.po +982 -862
  94. data/po/nl.po +992 -869
  95. data/po/pl.po +1018 -963
  96. data/po/pt.po +983 -852
  97. data/po/pt_BR.po +983 -863
  98. data/po/ru.po +992 -869
  99. data/po/sk.po +986 -864
  100. data/po/sv.po +980 -860
  101. data/po/uk.po +975 -861
  102. data/po/zh_TW.po +974 -854
  103. data/share/alexandria/glade/main_app__builder.glade +6 -21
  104. data/share/gnome/help/alexandria/C/smart-libraries.xml +2 -2
  105. data/share/gnome/help/alexandria/C/working-with-libraries.xml +1 -1
  106. data/share/gnome/help/alexandria/fr/alexandria.xml +1 -1
  107. data/share/gnome/help/alexandria/ja/smart-libraries.xml +1 -1
  108. data/spec/alexandria/book_providers/world_cat_provider_spec.rb +160 -0
  109. data/spec/alexandria/book_providers_spec.rb +73 -129
  110. data/spec/alexandria/console_spec.rb +0 -5
  111. data/spec/alexandria/export_library_spec.rb +27 -38
  112. data/spec/alexandria/library_spec.rb +56 -44
  113. data/spec/alexandria/preferences_spec.rb +29 -3
  114. data/spec/alexandria/scanners/cue_cat_spec.rb +1 -1
  115. data/spec/alexandria/ui/about_dialog_spec.rb +1 -1
  116. data/spec/alexandria/ui/acquire_dialog_spec.rb +1 -1
  117. data/spec/alexandria/ui/alert_dialog_spec.rb +1 -1
  118. data/spec/alexandria/ui/bad_isbns_dialog_spec.rb +1 -1
  119. data/spec/alexandria/ui/book_properties_dialog_spec.rb +1 -1
  120. data/spec/alexandria/ui/confirm_erase_dialog_spec.rb +1 -1
  121. data/spec/alexandria/ui/conflict_while_copying_dialog_spec.rb +1 -1
  122. data/spec/alexandria/ui/error_dialog_spec.rb +1 -1
  123. data/spec/alexandria/ui/export_dialog_spec.rb +1 -1
  124. data/spec/alexandria/ui/icons_spec.rb +26 -0
  125. data/spec/alexandria/ui/iconview_spec.rb +1 -1
  126. data/spec/alexandria/ui/import_dialog_spec.rb +30 -3
  127. data/spec/alexandria/ui/keep_bad_isbn_dialog_spec.rb +1 -1
  128. data/spec/alexandria/ui/main_app_spec.rb +1 -1
  129. data/spec/alexandria/ui/new_book_dialog_manual_spec.rb +1 -1
  130. data/spec/alexandria/ui/new_provider_dialog_spec.rb +19 -3
  131. data/spec/alexandria/ui/new_smart_library_dialog_spec.rb +28 -3
  132. data/spec/alexandria/ui/preferences_dialog_spec.rb +1 -1
  133. data/spec/alexandria/ui/provider_preferences_dialog_spec.rb +23 -8
  134. data/spec/alexandria/ui/really_delete_dialog_spec.rb +1 -1
  135. data/spec/alexandria/ui/sidepane_manager_spec.rb +2 -2
  136. data/spec/alexandria/ui/skip_entry_dialog_spec.rb +1 -1
  137. data/spec/alexandria/ui/smart_library_properties_dialog_spec.rb +21 -7
  138. data/spec/alexandria/ui/ui_manager_spec.rb +39 -2
  139. data/spec/spec_helper.rb +46 -3
  140. data/tasks/spec.rake +3 -5
  141. data/util/rake/fileinstall.rb +12 -11
  142. metadata +82 -10
  143. data/spec/alexandria/ui/ui_utilities_spec.rb +0 -62
  144. data/spec/alexandria/utilities_spec.rb +0 -52
@@ -13,7 +13,7 @@ module Alexandria
13
13
 
14
14
  def on_new(*)
15
15
  name = Library.generate_new_name(@libraries.all_libraries)
16
- library = Library.load(name)
16
+ library = @libraries.library_store.load_library(name)
17
17
  @libraries.add_library(library)
18
18
  append_library(library, true)
19
19
  setup_move_actions
@@ -21,17 +21,17 @@ module Alexandria
21
21
  end
22
22
 
23
23
  def on_new_smart(*)
24
- NewSmartLibraryDialog.new(@main_app).acquire do |smart_library|
25
- smart_library.refilter
26
- @libraries.add_library(smart_library)
27
- append_library(smart_library, true)
28
- smart_library.save
29
- end
24
+ smart_library = NewSmartLibraryDialog.new(@main_app).acquire or return
25
+
26
+ smart_library.refilter
27
+ @libraries.add_library(smart_library)
28
+ append_library(smart_library, true)
29
+ smart_library.save
30
30
  end
31
31
 
32
32
  def on_add_book(*)
33
33
  log.info { "on_add_book" }
34
- NewBookDialog.new(@main_app, selected_library) do |_books, library, is_new|
34
+ dialog = NewBookDialog.new(@main_app, selected_library) do |_books, library, is_new|
35
35
  if is_new
36
36
  append_library(library, true)
37
37
  setup_move_actions
@@ -39,13 +39,15 @@ module Alexandria
39
39
  select_library(library)
40
40
  end
41
41
  end
42
+ dialog.show
42
43
  end
43
44
 
44
45
  def on_add_book_manual(*)
45
46
  library = selected_library
46
- NewBookDialogManual.new(@main_app, library) do |_book|
47
+ dialog = NewBookDialogManual.new(@main_app, library) do |_book|
47
48
  refresh_books
48
49
  end
50
+ dialog.show
49
51
  end
50
52
 
51
53
  def on_import(*)
@@ -53,14 +55,12 @@ module Alexandria
53
55
  unless bad_isbns.empty?
54
56
  log.debug { "bad_isbn" }
55
57
  message = _("The following lines are not valid ISBNs and were not imported:")
56
- bad_isbn_warn = BadIsbnsDialog.new(@main_app, message, bad_isbns)
57
- bad_isbn_warn.signal_connect("response") { bad_isbn_warn.destroy }
58
+ BadIsbnsDialog.new(@main_app, message, bad_isbns).show
58
59
  end
59
60
  unless failed_isbns.nil? || failed_isbns.empty?
60
61
  log.debug { "failed lookup of #{failed_isbns.size} ISBNs" }
61
62
  message = _("Books could not be found for the following ISBNs:")
62
- failed_lookup = BadIsbnsDialog.new(@main_app, message, failed_isbns)
63
- failed_lookup.signal_connect("response") { failed_lookup.destroy }
63
+ BadIsbnsDialog.new(@main_app, message, failed_isbns).show
64
64
  end
65
65
  @libraries.add_library(library)
66
66
  append_library(library, true)
@@ -76,9 +76,9 @@ module Alexandria
76
76
  log.debug { "end window-state-event" }
77
77
  end
78
78
 
79
- def on_toolbar_view_as_changed(cb)
79
+ def on_toolbar_view_as_changed(widget)
80
80
  log.debug { "changed" }
81
- action = case cb.active
81
+ action = case widget.active
82
82
  when 0
83
83
  @actiongroup["AsIcons"]
84
84
  when 1
@@ -100,9 +100,9 @@ module Alexandria
100
100
  @iconview.unfreeze
101
101
  end
102
102
 
103
- def on_criterion_combobox_changed(cb)
103
+ def on_criterion_combobox_changed(widget)
104
104
  log.debug { "changed" }
105
- @filter_books_mode = cb.active
105
+ @filter_books_mode = widget.active
106
106
  @filter_entry.text.strip!
107
107
  @iconview.freeze
108
108
  @filtered_model.refilter
@@ -114,22 +114,25 @@ module Alexandria
114
114
  end
115
115
 
116
116
  def on_acquire(*)
117
- AcquireDialog.new(@main_app,
118
- selected_library) do |_books, library, is_new|
119
- if is_new
120
- append_library(library, true)
121
- setup_move_actions
122
- elsif selected_library != library
123
- select_library(library)
124
- end
125
- end
117
+ dialog =
118
+ AcquireDialog.new(@main_app, selected_library) do |_books, library, is_new|
119
+ if is_new
120
+ append_library(library, true)
121
+ setup_move_actions
122
+ elsif selected_library != library
123
+ select_library(library)
124
+ end
125
+ end
126
+ dialog.show
126
127
  end
127
128
 
128
129
  def on_properties(*)
129
130
  if @library_listview.focus? || selected_books.empty?
130
131
  library = selected_library
131
132
  if library.is_a?(SmartLibrary)
132
- SmartLibraryPropertiesDialog.new(@main_app, library).acquire do
133
+ success = SmartLibraryPropertiesDialog.new(@main_app, library).acquire
134
+
135
+ if success
133
136
  library.refilter
134
137
  refresh_books
135
138
  end
@@ -138,9 +141,10 @@ module Alexandria
138
141
  books = selected_books
139
142
  if books.length == 1
140
143
  book = books.first
141
- BookPropertiesDialog.new(@main_app,
142
- selected_library,
143
- book) # { |modified_book| }
144
+ dialog = BookPropertiesDialog.new(@main_app,
145
+ selected_library,
146
+ book)
147
+ dialog.show
144
148
  end
145
149
  end
146
150
  end
@@ -236,9 +240,10 @@ module Alexandria
236
240
  end
237
241
 
238
242
  def on_preferences(*)
239
- PreferencesDialog.new(@main_app) do
243
+ dialog = PreferencesDialog.new(@main_app) do
240
244
  @listview_manager.setup_listview_columns_visibility
241
245
  end
246
+ dialog.show
242
247
  end
243
248
 
244
249
  def on_submit_bug_report(*)
@@ -276,90 +281,36 @@ module Alexandria
276
281
  end
277
282
 
278
283
  def connect_signals
279
- # rubocop:disable Layout/LineLength
280
- standard_actions = [
281
- ["LibraryMenu", nil, _("_Library")],
282
- ["New", Gtk::Stock::NEW, _("_New Library"), "<control>L", _("Create a new library"), method(:on_new)],
283
- ["NewSmart", nil, _("New _Smart Library..."), "<control><shift>L", _("Create a new smart library"), method(:on_new_smart)],
284
- ["AddBook", Gtk::Stock::ADD, _("_Add Book..."), "<control>N", _("Add a new book from the Internet"), method(:on_add_book)],
285
- ["AddBookManual", nil, _("Add Book _Manually..."), "<control><shift>N", _("Add a new book manually"), method(:on_add_book_manual)],
286
- ["Import", nil, _("_Import..."), "<control>I", _("Import a library"), method(:on_import)],
287
- ["Export", nil, _("_Export..."), "<control><shift>E", _("Export the selected library"), method(:on_export)],
288
- ["Acquire", nil, _("A_cquire from Scanner..."), "<control><shift>S", _("Acquire books from a scanner"), method(:on_acquire)],
289
- ["Properties", Gtk::Stock::PROPERTIES, _("_Properties"), nil, _("Edit the properties of the selected book"), method(:on_properties)],
290
- ["Quit", Gtk::Stock::QUIT, _("_Quit"), "<control>Q", _("Quit the program"), method(:on_quit)],
291
- ["EditMenu", nil, _("_Edit")],
292
- ["Undo", Gtk::Stock::UNDO, _("_Undo"), "<control>Z", _("Undo the last action"), method(:on_undo)],
293
- ["Redo", Gtk::Stock::REDO, _("_Redo"), "<control><shift>Z", _("Redo the undone action"), method(:on_redo)],
294
- ["SelectAll", nil, _("_Select All"), "<control>A", _("Select all visible books"), method(:on_select_all)],
295
- ["DeselectAll", nil, _("Dese_lect All"), "<control><shift>A", _("Deselect everything"), method(:on_deselect_all)],
296
- ["SetRating", nil, _("My _Rating")],
297
- ["SetRating0", nil, _("None"), nil, nil, proc { on_set_rating[0].call }],
298
- ["SetRating1", nil, _("One Star"), nil, nil, proc { on_set_rating[1].call }],
299
- ["SetRating2", nil, _("Two Stars"), nil, nil, proc { on_set_rating[2].call }],
300
- ["SetRating3", nil, _("Three Stars"), nil, nil, proc { on_set_rating[3].call }],
301
- ["SetRating4", nil, _("Four Stars"), nil, nil, proc { on_set_rating[4].call }],
302
- ["SetRating5", nil, _("Five Stars"), nil, nil, proc { on_set_rating[5].call }],
303
- ["Move", nil, _("_Move")],
304
- ["Rename", nil, _("_Rename"), nil, nil, method(:on_rename)],
305
- ["Delete", Gtk::Stock::DELETE, _("_Delete"), "Delete", _("Delete the selected books or library"), method(:on_delete)],
306
- ["Search", Gtk::Stock::FIND, _("_Search"), "<control>F", _("Filter books"), method(:on_search)],
307
- ["ClearSearchResult", Gtk::Stock::CLEAR, _("_Clear Results"), "<control><alt>B", _("Clear the search results"), method(:on_clear_search_results)],
308
- ["Preferences", Gtk::Stock::PREFERENCES, _("_Preferences"), "<control>O", _("Change Alexandria's settings"), method(:on_preferences)],
309
- ["ViewMenu", nil, _("_View")],
310
- ["ArrangeIcons", nil, _("Arran_ge Icons")],
311
- ["OnlineInformation", nil, _("Display Online _Information")],
312
-
313
- ["HelpMenu", nil, _("_Help")],
314
- ["SubmitBugReport", Gtk::Stock::EDIT, _("Submit _Bug Report"), nil, _("Submit a bug report to the developers"), method(:on_submit_bug_report)],
315
- ["Help", Gtk::Stock::HELP, _("Contents"), "F1", _("View Alexandria's manual"), method(:on_help)],
316
- ["About", Gtk::Stock::ABOUT, _("_About"), nil, _("Show information about Alexandria"), method(:on_about)],
317
- ]
318
-
319
- toggle_actions = [
320
- ["Sidepane", nil, _("Side _Pane"), "F9", nil, method(:on_view_sidepane), true],
321
- ["Toolbar", nil, _("_Toolbar"), nil, nil, method(:on_view_toolbar), true],
322
- ["Statusbar", nil, _("_Statusbar"), nil, nil, method(:on_view_statusbar), true],
323
- ["ReversedOrder", nil, _("Re_versed Order"), nil, nil, method(:on_reverse_order), false],
324
- ]
325
-
326
- view_as_actions = [
327
- ["AsIcons", nil, _("View as _Icons"), nil, nil, 0],
328
- ["AsList", nil, _("View as _List"), nil, nil, 1]
329
- ]
330
-
331
- arrange_icons_actions = [
332
- ["ByTitle", nil, _("By _Title"), nil, nil, 0],
333
- ["ByAuthors", nil, _("By _Authors"), nil, nil, 1],
334
- ["ByISBN", nil, _("By _ISBN"), nil, nil, 2],
335
- ["ByPublisher", nil, _("By _Publisher"), nil, nil, 3],
336
- ["ByEdition", nil, _("By _Binding"), nil, nil, 4],
337
- ["ByRating", nil, _("By _Rating"), nil, nil, 5]
338
- ]
339
- # rubocop:enable Layout/LineLength
340
-
341
- providers_actions = BookProviders.map do |provider|
342
- [provider.action_name, Gtk::Stock::JUMP_TO,
343
- _("At _%s") % provider.fullname, nil, nil,
344
- proc { open_web_browser(provider.url(selected_books.first)) }]
345
- end
346
-
347
284
  log.debug { "Adding actions to @actiongroup" }
348
285
 
349
286
  @actiongroup = Gtk::ActionGroup.new("actions")
350
287
 
351
- standard_actions.each do |name, stock_id, label, accelerator, tooltip, callback|
352
- action = Gtk::Action.new(name, label: label, tooltip: tooltip, stock_id: stock_id)
353
- @actiongroup.add_action_with_accel(action, accelerator)
354
- action.signal_connect("activate", &callback) if callback
355
- end
288
+ connect_standard_actions
289
+ connect_providers_actions
290
+ connect_toggle_actions
291
+ connect_view_actions
292
+ connect_arrange_icons_actions
293
+ end
294
+
295
+ private
296
+
297
+ def connect_standard_actions
298
+ connect_actions standard_actions
299
+ end
300
+
301
+ def connect_providers_actions
302
+ connect_actions providers_actions
303
+ end
356
304
 
357
- providers_actions.each do |name, stock_id, label, accelerator, tooltip, callback|
305
+ def connect_actions(actions)
306
+ actions.each do |name, stock_id, label, accelerator, tooltip, callback|
358
307
  action = Gtk::Action.new(name, label: label, tooltip: tooltip, stock_id: stock_id)
359
308
  @actiongroup.add_action_with_accel(action, accelerator)
360
309
  action.signal_connect("activate", &callback) if callback
361
310
  end
311
+ end
362
312
 
313
+ def connect_toggle_actions
363
314
  toggle_actions
364
315
  .each do |name, stock_id, label, accelerator, tooltip, callback, is_active|
365
316
  action = Gtk::ToggleAction.new(name, label: label, tooltip: tooltip,
@@ -368,18 +319,10 @@ module Alexandria
368
319
  @actiongroup.add_action_with_accel(action, accelerator)
369
320
  action.signal_connect("toggled", &callback) if callback
370
321
  end
322
+ end
371
323
 
372
- first_action = nil
373
- view_as_actions.each do |name, stock_id, label, accelerator, tooltip, value|
374
- action = Gtk::RadioAction.new(name, value, label: label, tooltip: tooltip,
375
- stock_id: stock_id)
376
- if first_action
377
- action.join_group first_action
378
- else
379
- first_action = action
380
- end
381
- @actiongroup.add_action_with_accel(action, accelerator)
382
- end
324
+ def connect_view_actions
325
+ first_action = connect_radio_actions view_as_actions
383
326
 
384
327
  first_action.signal_connect "changed" do |_action, current, _user_data|
385
328
  @notebook.page = current.current_value
@@ -388,9 +331,20 @@ module Alexandria
388
331
  @toolbar_view_as.active = current.current_value
389
332
  end
390
333
  end
334
+ end
391
335
 
336
+ def connect_arrange_icons_actions
337
+ first_action = connect_radio_actions arrange_icons_actions
338
+
339
+ first_action.signal_connect "changed" do |_action, current, _user_data|
340
+ @prefs.arrange_icons_mode = current.current_value
341
+ setup_books_iconview_sorting
342
+ end
343
+ end
344
+
345
+ def connect_radio_actions(actions)
392
346
  first_action = nil
393
- arrange_icons_actions.each do |name, stock_id, label, accelerator, tooltip, value|
347
+ actions.each do |name, stock_id, label, accelerator, tooltip, value|
394
348
  action = Gtk::RadioAction.new(name, value, label: label, tooltip: tooltip,
395
349
  stock_id: stock_id)
396
350
  if first_action
@@ -400,12 +354,79 @@ module Alexandria
400
354
  end
401
355
  @actiongroup.add_action_with_accel(action, accelerator)
402
356
  end
357
+ first_action
358
+ end
403
359
 
404
- first_action.signal_connect "changed" do |_action, current, _user_data|
405
- @prefs.arrange_icons_mode = current.current_value
406
- setup_books_iconview_sorting
360
+ def standard_actions
361
+ # rubocop:disable Layout/LineLength
362
+ [["LibraryMenu", nil, _("_Library")],
363
+ ["New", Gtk::Stock::NEW, _("_New Library"), "<control>L", _("Create a new library"), method(:on_new)],
364
+ ["NewSmart", nil, _("New _Smart Library..."), "<control><shift>L", _("Create a new smart library"), method(:on_new_smart)],
365
+ ["AddBook", Gtk::Stock::ADD, _("_Add Book..."), "<control>N", _("Add a new book from the Internet"), method(:on_add_book)],
366
+ ["AddBookManual", nil, _("Add Book _Manually..."), "<control><shift>N", _("Add a new book manually"), method(:on_add_book_manual)],
367
+ ["Import", nil, _("_Import..."), "<control>I", _("Import a library"), method(:on_import)],
368
+ ["Export", nil, _("_Export..."), "<control><shift>E", _("Export the selected library"), method(:on_export)],
369
+ ["Acquire", nil, _("A_cquire from Scanner..."), "<control><shift>S", _("Acquire books from a scanner"), method(:on_acquire)],
370
+ ["Properties", Gtk::Stock::PROPERTIES, _("_Properties"), nil, _("Edit the properties of the selected book"), method(:on_properties)],
371
+ ["Quit", Gtk::Stock::QUIT, _("_Quit"), "<control>Q", _("Quit the program"), method(:on_quit)],
372
+ ["EditMenu", nil, _("_Edit")],
373
+ ["Undo", Gtk::Stock::UNDO, _("_Undo"), "<control>Z", _("Undo the last action"), method(:on_undo)],
374
+ ["Redo", Gtk::Stock::REDO, _("_Redo"), "<control><shift>Z", _("Redo the undone action"), method(:on_redo)],
375
+ ["SelectAll", nil, _("_Select All"), "<control>A", _("Select all visible books"), method(:on_select_all)],
376
+ ["DeselectAll", nil, _("Dese_lect All"), "<control><shift>A", _("Deselect everything"), method(:on_deselect_all)],
377
+ ["SetRating", nil, _("My _Rating")],
378
+ ["SetRating0", nil, _("None"), nil, nil, proc { on_set_rating[0].call }],
379
+ ["SetRating1", nil, _("One Star"), nil, nil, proc { on_set_rating[1].call }],
380
+ ["SetRating2", nil, _("Two Stars"), nil, nil, proc { on_set_rating[2].call }],
381
+ ["SetRating3", nil, _("Three Stars"), nil, nil, proc { on_set_rating[3].call }],
382
+ ["SetRating4", nil, _("Four Stars"), nil, nil, proc { on_set_rating[4].call }],
383
+ ["SetRating5", nil, _("Five Stars"), nil, nil, proc { on_set_rating[5].call }],
384
+ ["Move", nil, _("_Move")],
385
+ ["Rename", nil, _("_Rename"), nil, nil, method(:on_rename)],
386
+ ["Delete", Gtk::Stock::DELETE, _("_Delete"), "Delete", _("Delete the selected books or library"), method(:on_delete)],
387
+ ["Search", Gtk::Stock::FIND, _("_Search"), "<control>F", _("Filter books"), method(:on_search)],
388
+ ["ClearSearchResult", Gtk::Stock::CLEAR, _("_Clear Results"), "<control><alt>B", _("Clear the search results"), method(:on_clear_search_results)],
389
+ ["Preferences", Gtk::Stock::PREFERENCES, _("_Preferences"), "<control>O", _("Change Alexandria's settings"), method(:on_preferences)],
390
+ ["ViewMenu", nil, _("_View")],
391
+ ["ArrangeIcons", nil, _("Arran_ge Icons")],
392
+ ["OnlineInformation", nil, _("Display Online _Information")],
393
+
394
+ ["HelpMenu", nil, _("_Help")],
395
+ ["SubmitBugReport", Gtk::Stock::EDIT, _("Submit _Bug Report"), nil, _("Submit a bug report to the developers"), method(:on_submit_bug_report)],
396
+ ["Help", Gtk::Stock::HELP, _("Contents"), "F1", _("View Alexandria's manual"), method(:on_help)],
397
+ ["About", Gtk::Stock::ABOUT, _("_About"), nil, _("Show information about Alexandria"), method(:on_about)]]
398
+ # rubocop:enable Layout/LineLength
399
+ end
400
+
401
+ def providers_actions
402
+ BookProviders.list.map do |provider|
403
+ [provider.action_name, Gtk::Stock::JUMP_TO,
404
+ _("At _%s") % provider.fullname, nil, nil,
405
+ proc { open_web_browser(provider.url(selected_books.first)) }]
407
406
  end
408
407
  end
408
+
409
+ def toggle_actions
410
+ [["Sidepane", nil, _("Side_pane"), "F9", nil, method(:on_view_sidepane), true],
411
+ ["Toolbar", nil, _("_Toolbar"), nil, nil, method(:on_view_toolbar), true],
412
+ ["Statusbar", nil, _("_Statusbar"), nil, nil, method(:on_view_statusbar), true],
413
+ ["ReversedOrder", nil, _("Re_versed Order"), nil, nil,
414
+ method(:on_reverse_order), false]]
415
+ end
416
+
417
+ def view_as_actions
418
+ [["AsIcons", nil, _("View as _Icons"), nil, nil, 0],
419
+ ["AsList", nil, _("View as _List"), nil, nil, 1]]
420
+ end
421
+
422
+ def arrange_icons_actions
423
+ [["ByTitle", nil, _("By _Title"), nil, nil, 0],
424
+ ["ByAuthors", nil, _("By _Authors"), nil, nil, 1],
425
+ ["ByISBN", nil, _("By _ISBN"), nil, nil, 2],
426
+ ["ByPublisher", nil, _("By _Publisher"), nil, nil, 3],
427
+ ["ByEdition", nil, _("By _Binding"), nil, nil, 4],
428
+ ["ByRating", nil, _("By _Rating"), nil, nil, 5]]
429
+ end
409
430
  end
410
431
  end
411
432
  end
@@ -164,7 +164,7 @@ module Alexandria
164
164
  editions << book.edition
165
165
  borrowers << book.loaned_to
166
166
  # TODO: Ensure #tags is always an array
167
- (book.tags || []).each { |tag| tags << tag }
167
+ tags.concat(book.tags) if book.tags
168
168
  end
169
169
  end
170
170
 
@@ -20,7 +20,7 @@ module Alexandria
20
20
  _("A file named '%s' already exists. Do you want " \
21
21
  "to replace it with the one you are generating?") % filename)
22
22
  # FIXME: Should accept just :cancel
23
- self.default_response = Gtk::ResponseType::CANCEL
23
+ dialog.default_response = Gtk::ResponseType::CANCEL
24
24
  end
25
25
 
26
26
  def erase?
@@ -21,7 +21,7 @@ module Alexandria
21
21
  [_("_Replace"), Gtk::ResponseType::OK]],
22
22
  _("If you replace the existing book, its contents will " \
23
23
  "be overwritten."))
24
- self.default_response = Gtk::ResponseType::CANCEL
24
+ dialog.default_response = Gtk::ResponseType::CANCEL
25
25
  end
26
26
 
27
27
  def replace?
@@ -13,7 +13,7 @@ module Alexandria
13
13
  super(parent, title, Gtk::Stock::DIALOG_ERROR,
14
14
  [[Gtk::Stock::OK, :ok]], message)
15
15
  # FIXME: Should accept just :ok
16
- self.default_response = Gtk::ResponseType::OK
16
+ dialog.default_response = Gtk::ResponseType::OK
17
17
  end
18
18
 
19
19
  def display
@@ -10,7 +10,7 @@ require "alexandria/ui/error_dialog"
10
10
 
11
11
  module Alexandria
12
12
  module UI
13
- class ExportDialog < SimpleDelegator
13
+ class ExportDialog
14
14
  include GetText
15
15
  extend GetText
16
16
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
@@ -19,16 +19,14 @@ module Alexandria
19
19
  THEMES = Alexandria::WebTheme.all
20
20
 
21
21
  def initialize(parent, library, sort_order)
22
- @export_dialog = Gtk::FileChooserDialog.new(title: _("Export '%s'") % library.name,
23
- parent: parent,
24
- action: :save,
25
- buttons: [[Gtk::Stock::HELP, :help],
26
- [Gtk::Stock::CANCEL, :cancel],
27
- [_("_Export"), :accept]])
28
- super(@export_dialog)
29
-
30
- self.current_name = library.name
31
- signal_connect("destroy") { hide }
22
+ @dialog = Gtk::FileChooserDialog.new(title: _("Export '%s'") % library.name,
23
+ parent: parent,
24
+ action: :save,
25
+ buttons: [[Gtk::Stock::HELP, :help],
26
+ [Gtk::Stock::CANCEL, :cancel],
27
+ [_("_Export"), :accept]])
28
+ @dialog.current_name = library.name
29
+ @dialog.signal_connect("destroy") { @dialog.hide }
32
30
 
33
31
  @parent = parent
34
32
  @library = library
@@ -84,7 +82,7 @@ module Alexandria
84
82
  grid.attach theme_label, 0, 1, 1, 1
85
83
  grid.attach @theme_combo, 1, 1, 1, 1
86
84
  grid.attach preview_image, 2, 0, 1, 3
87
- set_extra_widget grid
85
+ @dialog.set_extra_widget grid
88
86
  end
89
87
 
90
88
  def perform
@@ -98,7 +96,7 @@ module Alexandria
98
96
  break if on_export(FORMATS[@types_combo.active],
99
97
  THEMES[@theme_combo.active])
100
98
  rescue StandardError => ex
101
- ErrorDialog.new(@export_dialog, _("Export failed"), ex.message).display
99
+ ErrorDialog.new(@dialog, _("Export failed"), ex.message).display
102
100
  end
103
101
  end
104
102
  end
@@ -112,7 +110,7 @@ module Alexandria
112
110
  if format.ext
113
111
  filename += "." + format.ext if File.extname(filename).empty?
114
112
  if File.exist?(filename)
115
- dialog = ConfirmEraseDialog.new(@export_dialog, filename)
113
+ dialog = ConfirmEraseDialog.new(@dialog, filename)
116
114
  return unless dialog.erase?
117
115
 
118
116
  FileUtils.rm(filename)
@@ -125,7 +123,7 @@ module Alexandria
125
123
  "file. A directory is needed for this " \
126
124
  "operation. Please select a directory and " \
127
125
  "try again.") % filename
128
- ErrorDialog.new(@export_dialog, _("Not a directory"), msg).display
126
+ ErrorDialog.new(@dialog, _("Not a directory"), msg).display
129
127
  return
130
128
  end
131
129
  else