alexandria-book-collection-manager 0.7.5 → 0.7.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +9 -0
  3. data/.github/workflows/ruby.yml +72 -0
  4. data/.gitignore +4 -1
  5. data/.rubocop.yml +65 -30
  6. data/.rubocop_todo.yml +49 -165
  7. data/.simplecov +5 -2
  8. data/CHANGELOG.md +64 -0
  9. data/ChangeLog.0 +19 -19
  10. data/INSTALL.md +26 -16
  11. data/README.md +31 -35
  12. data/Rakefile +18 -16
  13. data/alexandria-book-collection-manager.gemspec +35 -29
  14. data/doc/FAQ +2 -2
  15. data/doc/dependency_decisions.yml +22 -3
  16. data/lib/alexandria/about.rb +1 -1
  17. data/lib/alexandria/book_providers/bl_provider.rb +88 -0
  18. data/lib/alexandria/book_providers/douban.rb +2 -2
  19. data/lib/alexandria/book_providers/loc_provider.rb +38 -0
  20. data/lib/alexandria/book_providers/pseudomarc.rb +61 -71
  21. data/lib/alexandria/book_providers/sbn_provider.rb +108 -0
  22. data/lib/alexandria/book_providers/{thalia.rb → thalia_provider.rb} +37 -74
  23. data/lib/alexandria/book_providers/web.rb +2 -2
  24. data/lib/alexandria/book_providers/worldcat.rb +34 -38
  25. data/lib/alexandria/book_providers/z3950_provider.rb +199 -0
  26. data/lib/alexandria/book_providers.rb +48 -65
  27. data/lib/alexandria/default_preferences.rb +2 -1
  28. data/lib/alexandria/execution_queue.rb +13 -12
  29. data/lib/alexandria/export_library.rb +21 -22
  30. data/lib/alexandria/image_fetcher.rb +25 -0
  31. data/lib/alexandria/import_library.rb +46 -70
  32. data/lib/alexandria/import_library_csv.rb +16 -16
  33. data/lib/alexandria/library_sort_order.rb +3 -1
  34. data/lib/alexandria/library_store.rb +19 -20
  35. data/lib/alexandria/logging.rb +5 -9
  36. data/lib/alexandria/models/book.rb +15 -2
  37. data/lib/alexandria/models/library.rb +31 -35
  38. data/lib/alexandria/net.rb +1 -2
  39. data/lib/alexandria/preferences.rb +27 -33
  40. data/lib/alexandria/scanners/cue_cat.rb +6 -6
  41. data/lib/alexandria/scanners/keyboard.rb +1 -1
  42. data/lib/alexandria/scanners.rb +2 -2
  43. data/lib/alexandria/smart_library.rb +22 -26
  44. data/lib/alexandria/ui/about_dialog.rb +1 -1
  45. data/lib/alexandria/ui/acquire_dialog.rb +15 -19
  46. data/lib/alexandria/ui/alert_dialog.rb +36 -19
  47. data/lib/alexandria/ui/bad_isbns_dialog.rb +13 -9
  48. data/lib/alexandria/ui/barcode_animation.rb +6 -6
  49. data/lib/alexandria/ui/book_properties_dialog.rb +2 -3
  50. data/lib/alexandria/ui/book_properties_dialog_base.rb +35 -137
  51. data/lib/alexandria/ui/calendar_popup.rb +58 -0
  52. data/lib/alexandria/ui/callbacks.rb +144 -123
  53. data/lib/alexandria/ui/completion_models.rb +2 -6
  54. data/lib/alexandria/ui/confirm_erase_dialog.rb +1 -1
  55. data/lib/alexandria/ui/conflict_while_copying_dialog.rb +2 -2
  56. data/lib/alexandria/ui/error_dialog.rb +1 -1
  57. data/lib/alexandria/ui/export_dialog.rb +19 -18
  58. data/lib/alexandria/ui/icons.rb +34 -40
  59. data/lib/alexandria/ui/iconview_tooltips.rb +40 -53
  60. data/lib/alexandria/ui/import_dialog.rb +49 -48
  61. data/lib/alexandria/ui/init.rb +14 -12
  62. data/lib/alexandria/ui/keep_bad_isbn_dialog.rb +2 -2
  63. data/lib/alexandria/ui/libraries_combo.rb +10 -9
  64. data/lib/alexandria/ui/listview.rb +6 -7
  65. data/lib/alexandria/ui/main_app.rb +2 -2
  66. data/lib/alexandria/ui/multi_drag_treeview.rb +5 -7
  67. data/lib/alexandria/ui/new_book_dialog.rb +63 -65
  68. data/lib/alexandria/ui/new_book_dialog_manual.rb +1 -1
  69. data/lib/alexandria/ui/new_provider_dialog.rb +12 -11
  70. data/lib/alexandria/ui/new_smart_library_dialog.rb +39 -27
  71. data/lib/alexandria/ui/preferences_dialog.rb +25 -84
  72. data/lib/alexandria/ui/provider_preferences_base_dialog.rb +10 -6
  73. data/lib/alexandria/ui/provider_preferences_dialog.rb +5 -5
  74. data/lib/alexandria/ui/really_delete_dialog.rb +2 -2
  75. data/lib/alexandria/ui/sidepane_manager.rb +38 -38
  76. data/lib/alexandria/ui/skip_entry_dialog.rb +3 -2
  77. data/lib/alexandria/ui/smart_library_properties_dialog.rb +35 -36
  78. data/lib/alexandria/ui/smart_library_properties_dialog_base.rb +61 -244
  79. data/lib/alexandria/ui/smart_library_rule_box.rb +119 -0
  80. data/lib/alexandria/ui/sound.rb +4 -6
  81. data/lib/alexandria/ui/ui_manager.rb +80 -83
  82. data/lib/alexandria/ui.rb +7 -7
  83. data/lib/alexandria/version.rb +2 -2
  84. data/lib/alexandria/web_themes.rb +15 -15
  85. data/lib/alexandria.rb +2 -2
  86. data/po/cs.po +947 -865
  87. data/po/cy.po +913 -864
  88. data/po/de.po +961 -865
  89. data/po/el.po +956 -861
  90. data/po/es.po +952 -857
  91. data/po/fr.po +950 -865
  92. data/po/ga.po +866 -819
  93. data/po/gl.po +946 -861
  94. data/po/it.po +945 -858
  95. data/po/ja.po +921 -836
  96. data/po/mk.po +953 -858
  97. data/po/nb.po +932 -847
  98. data/po/nl.po +955 -849
  99. data/po/pl.po +999 -963
  100. data/po/pt.po +946 -850
  101. data/po/pt_BR.po +944 -859
  102. data/po/ru.po +959 -868
  103. data/po/sk.po +950 -863
  104. data/po/sv.po +944 -859
  105. data/po/uk.po +925 -846
  106. data/po/zh_TW.po +926 -841
  107. data/schemas/alexandria.schemas +1 -1
  108. data/share/alexandria/glade/main_app__builder.glade +6 -21
  109. data/share/gnome/help/alexandria/C/adding-books.xml +3 -4
  110. data/share/gnome/help/alexandria/C/introduction.xml +0 -16
  111. data/share/gnome/help/alexandria/C/searching.xml +1 -4
  112. data/share/gnome/help/alexandria/C/settings.xml +0 -30
  113. data/share/gnome/help/alexandria/C/smart-libraries.xml +2 -2
  114. data/share/gnome/help/alexandria/C/working-with-libraries.xml +1 -1
  115. data/share/gnome/help/alexandria/fr/alexandria.xml +5 -160
  116. data/share/gnome/help/alexandria/ja/adding-books.xml +1 -1
  117. data/share/gnome/help/alexandria/ja/introduction.xml +0 -15
  118. data/share/gnome/help/alexandria/ja/searching.xml +3 -7
  119. data/share/gnome/help/alexandria/ja/settings.xml +0 -27
  120. data/share/gnome/help/alexandria/ja/smart-libraries.xml +1 -1
  121. data/spec/alexandria/book_providers/bl_provider_spec.rb +13 -0
  122. data/spec/alexandria/book_providers/loc_provider_spec.rb +17 -0
  123. data/spec/alexandria/book_providers/sbn_provider_spec.rb +13 -0
  124. data/spec/alexandria/book_providers/thalia_provider_spec.rb +119 -0
  125. data/spec/alexandria/book_providers/world_cat_provider_spec.rb +160 -0
  126. data/spec/alexandria/book_providers_spec.rb +0 -154
  127. data/spec/alexandria/console_spec.rb +0 -5
  128. data/spec/alexandria/export_library_spec.rb +27 -38
  129. data/spec/alexandria/library_spec.rb +76 -46
  130. data/spec/alexandria/preferences_spec.rb +29 -3
  131. data/spec/alexandria/scanners/cue_cat_spec.rb +1 -1
  132. data/spec/alexandria/ui/about_dialog_spec.rb +1 -1
  133. data/spec/alexandria/ui/acquire_dialog_spec.rb +1 -1
  134. data/spec/alexandria/ui/alert_dialog_spec.rb +1 -1
  135. data/spec/alexandria/ui/bad_isbns_dialog_spec.rb +1 -1
  136. data/spec/alexandria/ui/book_properties_dialog_spec.rb +47 -5
  137. data/spec/alexandria/ui/confirm_erase_dialog_spec.rb +1 -1
  138. data/spec/alexandria/ui/conflict_while_copying_dialog_spec.rb +1 -1
  139. data/spec/alexandria/ui/error_dialog_spec.rb +1 -1
  140. data/spec/alexandria/ui/export_dialog_spec.rb +25 -4
  141. data/spec/alexandria/ui/icons_spec.rb +26 -0
  142. data/spec/alexandria/ui/iconview_spec.rb +1 -1
  143. data/spec/alexandria/ui/import_dialog_spec.rb +35 -3
  144. data/spec/alexandria/ui/keep_bad_isbn_dialog_spec.rb +1 -1
  145. data/spec/alexandria/ui/main_app_spec.rb +1 -1
  146. data/spec/alexandria/ui/new_book_dialog_manual_spec.rb +39 -3
  147. data/spec/alexandria/ui/new_provider_dialog_spec.rb +19 -3
  148. data/spec/alexandria/ui/new_smart_library_dialog_spec.rb +28 -3
  149. data/spec/alexandria/ui/preferences_dialog_spec.rb +2 -2
  150. data/spec/alexandria/ui/provider_preferences_dialog_spec.rb +23 -8
  151. data/spec/alexandria/ui/really_delete_dialog_spec.rb +1 -1
  152. data/spec/alexandria/ui/sidepane_manager_spec.rb +2 -2
  153. data/spec/alexandria/ui/skip_entry_dialog_spec.rb +1 -1
  154. data/spec/alexandria/ui/smart_library_properties_dialog_spec.rb +37 -6
  155. data/spec/alexandria/ui/ui_manager_spec.rb +116 -2
  156. data/spec/data/libraries/0.6.2/My Library/9780571147168.yaml +2 -0
  157. data/spec/end_to_end/basic_run_spec.rb +3 -8
  158. data/spec/fixtures/cover.jpg +0 -0
  159. data/spec/spec_helper.rb +47 -3
  160. data/tasks/spec.rake +3 -5
  161. data/util/rake/fileinstall.rb +16 -15
  162. data/util/rake/omfgenerate.rb +1 -1
  163. metadata +141 -52
  164. data/.travis.yml +0 -39
  165. data/lib/alexandria/book_providers/adlibris.rb +0 -196
  166. data/lib/alexandria/book_providers/amazon_aws.rb +0 -252
  167. data/lib/alexandria/book_providers/amazon_ecs_util.rb +0 -388
  168. data/lib/alexandria/book_providers/barnes_and_noble.rb +0 -209
  169. data/lib/alexandria/book_providers/proxis.rb +0 -175
  170. data/lib/alexandria/book_providers/siciliano.rb +0 -257
  171. data/lib/alexandria/book_providers/z3950.rb +0 -415
  172. data/spec/alexandria/ui/ui_utilities_spec.rb +0 -62
  173. data/spec/alexandria/utilities_spec.rb +0 -52
@@ -8,6 +8,7 @@ require "gdk_pixbuf2"
8
8
  require "alexandria/ui/builder_base"
9
9
  require "alexandria/ui/error_dialog"
10
10
  require "alexandria/ui/keep_bad_isbn_dialog"
11
+ require "alexandria/image_fetcher"
11
12
 
12
13
  module Alexandria
13
14
  class DuplicateBookException < NameError
@@ -16,6 +17,7 @@ module Alexandria
16
17
  module UI
17
18
  class NewBookDialog < BuilderBase
18
19
  include Logging
20
+ include ImageFetcher
19
21
  include GetText
20
22
  extend GetText
21
23
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
@@ -32,6 +34,10 @@ module Alexandria
32
34
  @progressbar.hide
33
35
  end
34
36
 
37
+ def show
38
+ @new_book_dialog.show
39
+ end
40
+
35
41
  def widget_names
36
42
  [:new_book_dialog, :button_add, :button_cancel, :button_find,
37
43
  :button_help, :combo_libraries, :combo_search, :entry_isbn,
@@ -139,7 +145,7 @@ module Alexandria
139
145
 
140
146
  def on_changed(entry)
141
147
  ok = !entry.text.strip.empty?
142
- decode_cuecat?(@entry_isbn) if entry == @entry_isbn
148
+ decode_cuecat(@entry_isbn) if entry == @entry_isbn
143
149
  (entry == @entry_isbn ? @button_add : @button_find).sensitive = ok
144
150
  end
145
151
 
@@ -159,17 +165,11 @@ module Alexandria
159
165
  begin
160
166
  @results.each_with_index do |result, i|
161
167
  uri = result[1]
162
- if uri
163
- if URI.parse(uri).scheme.nil?
164
- File.open(uri, "r") do |io|
165
- @images[i] = io.read
166
- end
167
- else
168
- @images[i] = URI.parse(uri).read
169
- end
170
- end
168
+ @images[i] = fetch_image(uri) if uri
171
169
  end
172
170
  rescue StandardError => ex
171
+ log.error { "Couldn't download image: #{ex.class} #{ex}" }
172
+ log.error { ex.backtrace.join("\n") }
173
173
  @image_error = ex.message
174
174
  end
175
175
  end
@@ -177,8 +177,13 @@ module Alexandria
177
177
  GLib::Timeout.add(100) do
178
178
  if @image_error
179
179
  image_error_dialog(@image_error).display
180
+ @image_error = nil
180
181
  else
181
182
  @images.each_pair do |key, value|
183
+ @images.delete(key)
184
+
185
+ next unless value
186
+
182
187
  loader = GdkPixbuf::PixbufLoader.new
183
188
  loader.last_write(value)
184
189
  pixbuf = loader.pixbuf
@@ -186,13 +191,11 @@ module Alexandria
186
191
  if pixbuf.width > 1
187
192
  iter = @treeview_results.model.get_iter(key.to_s)
188
193
  unless @treeview_results.model.iter_is_valid?(iter)
189
- raise format("Iter is invalid! %s", iter)
194
+ raise format(_("Iter is invalid! %s"), iter)
190
195
  end
191
196
 
192
197
  iter[2] = pixbuf # I bet you this is it!
193
198
  end
194
-
195
- @images.delete(key)
196
199
  rescue StandardError => ex
197
200
  image_error_dialog(ex.message).display
198
201
  end
@@ -284,15 +287,10 @@ module Alexandria
284
287
  # continue == false if @find_error OR if results are returned
285
288
  # timeout ends if continue is false!
286
289
 
287
- unless continue
288
- unless @find_thread.alive? # This happens after find_thread is done
289
- unless @destroyed
290
- # GLib::Source.remove(progress_pulsing)
291
- # @progressbar.hide
292
- notify_end_add_by_isbn
293
- @button_add.sensitive = false
294
- end
295
- end
290
+ # @find_thread.alive? happens after find_thread is done
291
+ unless continue || @find_thread.alive? || @destroyed
292
+ notify_end_add_by_isbn
293
+ @button_add.sensitive = false
296
294
  end
297
295
 
298
296
  continue # timeout loop condition
@@ -307,7 +305,7 @@ module Alexandria
307
305
  (book.authors == book2.authors)
308
306
  end
309
307
  s += " (#{book.edition}, #{book.publisher})" if similar_books.length > 1
310
- log.info { format("Copying %s into tree view.", book.title) }
308
+ log.info { format(_("Copying %s into tree view."), book.title) }
311
309
  iter = model.append
312
310
  iter[0] = s
313
311
  iter[1] = book.ident
@@ -315,19 +313,19 @@ module Alexandria
315
313
  end
316
314
  end
317
315
 
318
- def decode_cuecat?(entry) # srsly?
319
- if entry.text =~ /^\..*?\..*?\.(.*?)\.$/
320
- tmp = Regexp.last_match[1].tr("a-zA-Z0-9+-", " -_")
321
- tmp = ((32 + tmp.length * 3 / 4).to_i.chr << tmp).unpack1("u")
322
- tmp.chomp!("\000")
323
- entry.text = tmp.gsub!(/./) { |c| (c[0] ^ 67).chr }
324
- entry.text = "Bad scan result" if entry.text.count("^ -~") > 0
325
- end
316
+ def decode_cuecat(entry)
317
+ return unless entry.text =~ /^\..*?\..*?\.(.*?)\.$/
318
+
319
+ tmp = Regexp.last_match[1].tr("a-zA-Z0-9+-", " -_")
320
+ tmp = ((32 + tmp.length * 3 / 4).to_i.chr << tmp).unpack1("u")
321
+ tmp.chomp!("\000")
322
+ entry.text = tmp.gsub!(/./) { |c| (c[0] ^ 67).chr }
323
+ entry.text = "Bad scan result" if entry.text.count("^ -~") > 0
326
324
  end
327
325
 
328
326
  def on_results_button_press_event(_widget, event)
329
327
  # double left click
330
- on_add if (event.event_type == :'2button_press') && (event.button == 1)
328
+ on_add if (event.event_type == :"2button_press") && (event.button == 1)
331
329
  end
332
330
 
333
331
  def add_single_book_by_isbn(library, is_new)
@@ -353,8 +351,7 @@ module Alexandria
353
351
  notify_end_add_by_isbn
354
352
 
355
353
  if book
356
-
357
- puts "adding book #{book} to library"
354
+ log.debug { "adding book #{book} to library" }
358
355
  add_book_to_library(library, book, cover_url)
359
356
  @entry_isbn.text = ""
360
357
 
@@ -384,7 +381,7 @@ module Alexandria
384
381
 
385
382
  isbn = book.isbn
386
383
  if isbn.nil? || isbn.empty?
387
- puts "noisbn"
384
+ log.debug { "noisbn" }
388
385
  book.isbn = book.saved_ident = nil
389
386
  books_to_add << [book, cover]
390
387
  next
@@ -392,7 +389,7 @@ module Alexandria
392
389
 
393
390
  isbn = Library.canonicalise_ean(isbn)
394
391
  unless isbn
395
- puts "invalidisbn #{book.isbn}"
392
+ log.debug { "invalidisbn #{book.isbn}" }
396
393
  next unless KeepBadISBNDialog.new(@new_book_dialog, book).keep?
397
394
 
398
395
  book.isbn = book.saved_ident = nil
@@ -416,7 +413,7 @@ module Alexandria
416
413
  end
417
414
 
418
415
  def post_addition(books, library, is_new_library)
419
- puts "post_addition #{books.size}"
416
+ log.debug { "post_addition #{books.size}" }
420
417
  return if books.empty?
421
418
 
422
419
  # books, a 1d array of Alexandria::Book
@@ -464,7 +461,6 @@ module Alexandria
464
461
  # Do not destroy if there is no addition.
465
462
  # return unless book_was_added
466
463
  rescue StandardError => ex
467
- # FIXME: Message containing <> should be displayed correctly.
468
464
  ErrorDialog.new(@new_book_dialog, _("Couldn't add the book"), ex.message).display
469
465
  end
470
466
  # books_to_add
@@ -491,10 +487,10 @@ module Alexandria
491
487
 
492
488
  def notify_end_add_by_isbn
493
489
  MainApp.instance.appbar.children.first.visible = false
494
- if @progress_pulsing
495
- GLib::Source.remove(@progress_pulsing)
496
- @progress_pulsing = nil
497
- end
490
+ return unless @progress_pulsing
491
+
492
+ GLib::Source.remove(@progress_pulsing)
493
+ @progress_pulsing = nil
498
494
  end
499
495
 
500
496
  def update(status, provider)
@@ -510,25 +506,26 @@ module Alexandria
510
506
  end
511
507
 
512
508
  def on_focus
513
- if @isbn_radiobutton.active? && @entry_isbn.text.strip.empty?
514
- clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD)
515
- if (text = clipboard.wait_for_text)
516
- if Library.valid_isbn?(text) || Library.valid_ean?(text) ||
517
- Library.valid_upc?(text)
518
- GLib::Idle.add do
519
- @entry_isbn.text = text
520
- @entry_isbn.grab_focus
521
- @entry_isbn.select_region(0, -1) # select all...
522
- # @button_add.grab_focus
523
- false
524
- end
525
- log.debug { "Setting ISBN field to #{text}" }
526
- puts text # required, strangely, to prevent GUI strangeness
527
- # above last checked with ruby-gnome2 0.17.1 2009-12-09
528
- # if this puts is commented out, the cursor disappears
529
- # from the @entry_isbn box... weird, ne? - CathalMagus
530
- end
509
+ return unless @isbn_radiobutton.active? && @entry_isbn.text.strip.empty?
510
+
511
+ clipboard = Gtk::Clipboard.get(Gdk::Selection::CLIPBOARD)
512
+ text = clipboard.wait_for_text or return
513
+
514
+ if Library.valid_isbn?(text) || Library.valid_ean?(text) ||
515
+ Library.valid_upc?(text)
516
+ GLib::Idle.add do
517
+ @entry_isbn.text = text
518
+ @entry_isbn.grab_focus
519
+ @entry_isbn.select_region(0, -1) # select all...
520
+ # @button_add.grab_focus
521
+ false
531
522
  end
523
+ log.debug { "Setting ISBN field to #{text}" }
524
+ # FIXME: Get rid of this puts!
525
+ puts text # required, strangely, to prevent GUI strangeness
526
+ # above last checked with ruby-gnome2 0.17.1 2009-12-09
527
+ # if this puts is commented out, the cursor disappears
528
+ # from the @entry_isbn box... weird, ne? - CathalMagus
532
529
  end
533
530
  end
534
531
 
@@ -566,11 +563,12 @@ module Alexandria
566
563
  isbn13 = Library.canonicalise_ean(isbn)
567
564
  return unless isbn13
568
565
 
569
- if (book = library.find { |bk| bk.isbn == isbn13 })
570
- raise DuplicateBookException,
571
- format(_("'%s' already exists in '%s' (titled '%s')."),
572
- isbn, library.name, book.title.sub("&", "&amp;"))
573
- end
566
+ book = library.find { |bk| bk.isbn == isbn13 }
567
+ return unless book
568
+
569
+ raise DuplicateBookException,
570
+ format(_("'%s' already exists in '%s' (titled '%s')."),
571
+ isbn, library.name, book.title.sub("&", "&amp;"))
574
572
  end
575
573
  end
576
574
  end
@@ -93,7 +93,7 @@ module Alexandria
93
93
  @treeview_authors.model.each { |_m, _p, i| authors << i[0] }
94
94
  if authors.empty?
95
95
  raise AddError, _("At least one author must be " \
96
- "provided.")
96
+ "provided.")
97
97
  end
98
98
  book = Book.new(title, authors, isbn, publisher,
99
99
  publishing_year.zero? ? nil : publishing_year,
@@ -17,14 +17,14 @@ module Alexandria
17
17
  parent: parent,
18
18
  flags: :modal,
19
19
  buttons: [[Gtk::Stock::CANCEL, Gtk::ResponseType::CANCEL]])
20
- @add_button = add_button(Gtk::Stock::ADD,
21
- Gtk::ResponseType::ACCEPT)
20
+ @add_button = dialog.add_button(Gtk::Stock::ADD,
21
+ Gtk::ResponseType::ACCEPT)
22
22
 
23
23
  instances = BookProviders.abstract_classes.map(&:new)
24
24
  @selected_instance = nil
25
25
 
26
26
  @table = Gtk::Table.new(2, 2)
27
- child.pack_start(@table)
27
+ dialog.child.pack_start(@table)
28
28
 
29
29
  # Name.
30
30
 
@@ -33,10 +33,10 @@ module Alexandria
33
33
  label_name.xalign = 0
34
34
  @table.attach_defaults(label_name, 0, 1, 0, 1)
35
35
 
36
- entry_name = Gtk::Entry.new
37
- entry_name.mandatory = true
38
- label_name.mnemonic_widget = entry_name
39
- @table.attach_defaults(entry_name, 1, 2, 0, 1)
36
+ @entry_name = Gtk::Entry.new
37
+ @entry_name.mandatory = true
38
+ label_name.mnemonic_widget = @entry_name
39
+ @table.attach_defaults(@entry_name, 1, 2, 0, 1)
40
40
 
41
41
  # Type.
42
42
 
@@ -62,14 +62,15 @@ module Alexandria
62
62
  end
63
63
 
64
64
  def acquire
65
- show_all
66
- if run == Gtk::ResponseType::ACCEPT
67
- @selected_instance.reinitialize(entry_name.text)
65
+ dialog.show_all
66
+ if dialog.run == Gtk::ResponseType::ACCEPT
67
+ @selected_instance.reinitialize(@entry_name.text)
68
68
  sync_variables
69
69
  else
70
70
  @selected_instance = nil
71
71
  end
72
- destroy
72
+ dialog.destroy
73
+ instance
73
74
  end
74
75
 
75
76
  def instance
@@ -13,49 +13,61 @@ module Alexandria
13
13
  def initialize(parent)
14
14
  super(parent)
15
15
 
16
- add_buttons([Gtk::Stock::CANCEL, :cancel],
17
- [Gtk::Stock::NEW, :ok])
16
+ dialog.add_buttons([Gtk::Stock::CANCEL, :cancel],
17
+ [Gtk::Stock::NEW, :ok])
18
18
 
19
- self.title = _("New Smart Library")
19
+ dialog.title = _("New Smart Library")
20
20
  # FIXME: Should accept just :cancel
21
- self.default_response = Gtk::ResponseType::CANCEL
21
+ dialog.default_response = Gtk::ResponseType::CANCEL
22
+ insert_new_rule
22
23
  end
23
24
 
24
25
  def acquire
25
- show_all
26
- insert_new_rule
26
+ dialog.show_all
27
27
 
28
- while ((response = run) != Gtk::ResponseType::CANCEL) &&
28
+ result = nil
29
+ while ((response = dialog.run) != Gtk::ResponseType::CANCEL) &&
29
30
  (response != Gtk::ResponseType::DELETE_EVENT)
30
31
 
31
- if response == Gtk::ResponseType::HELP
32
- Alexandria::UI.display_help(self, "new-smart-library")
33
- elsif response == Gtk::ResponseType::OK
34
- if user_confirms_possible_weirdnesses_before_saving?
35
- rules = smart_library_rules
36
- basename = smart_library_base_name(rules) || _("Smart Library")
37
- name = Library.generate_new_name(
38
- LibraryCollection.instance.all_libraries,
39
- basename)
40
- library = SmartLibrary.new(name,
41
- rules,
42
- predicate_operator_rule)
43
- yield(library)
44
- break
45
- end
32
+ case response
33
+ when Gtk::ResponseType::HELP
34
+ handle_help_response
35
+ when Gtk::ResponseType::OK
36
+ result = handle_ok_response
37
+ break if result
46
38
  end
47
39
  end
48
40
 
49
- destroy
41
+ dialog.destroy
42
+ result
50
43
  end
51
44
 
52
45
  private
53
46
 
47
+ def handle_help_response
48
+ Alexandria::UI.display_help(self, "new-smart-library")
49
+ end
50
+
51
+ def handle_ok_response
52
+ user_confirms_possible_weirdnesses_before_saving? or return
53
+
54
+ rules = smart_library_rules
55
+ basename = smart_library_base_name(rules) || _("Smart Library")
56
+ name = Library.generate_new_name(
57
+ LibraryCollection.instance.all_libraries,
58
+ basename)
59
+ library_store = LibraryCollection.instance.library_store
60
+ SmartLibrary.new(name,
61
+ rules,
62
+ predicate_operator_rule,
63
+ library_store)
64
+ end
65
+
54
66
  def smart_library_base_name(rules)
55
- if rules.length == 1
56
- value = rules.first.value
57
- return value if value.is_a?(String) && !value.strip.empty?
58
- end
67
+ return unless rules.length == 1
68
+
69
+ value = rules.first.value
70
+ value if value.is_a?(String) && !value.strip.empty?
59
71
  end
60
72
  end
61
73
  end
@@ -13,7 +13,7 @@ require "alexandria/ui/new_provider_dialog"
13
13
  module Alexandria
14
14
  module UI
15
15
  class PreferencesDialog < BuilderBase
16
- include Alexandria::Logging
16
+ include Logging
17
17
  include GetText
18
18
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
19
19
 
@@ -37,11 +37,11 @@ module Alexandria
37
37
  }
38
38
  @cols.each_pair do |checkbutton, pref_name|
39
39
  if checkbutton
40
- checkbutton.active = Preferences.instance.send(pref_name)
40
+ checkbutton.active = Preferences.instance.get_variable(pref_name)
41
41
  else
42
42
  log.warn do
43
43
  "no CheckButton for property #{pref_name} " \
44
- "(probably conflicting versions of GUI and lib code)"
44
+ "(probably conflicting versions of GUI and lib code)"
45
45
  end
46
46
  end
47
47
  end
@@ -76,21 +76,17 @@ module Alexandria
76
76
  renderer = Gtk::CellRendererText.new
77
77
  column = Gtk::TreeViewColumn.new("Providers",
78
78
  renderer)
79
- # :text => 0)
80
79
  column.set_cell_data_func(renderer) do |_col, rndr, _mod, iter|
81
80
  rndr.markup = iter[0]
82
- # enabled = iter[2]
83
- # unless enabled
84
- # rndr.foreground = "gray"
85
- # end
86
- # rndr.active = value
87
81
  end
88
82
  @treeview_providers.append_column(column)
89
- @treeview_providers.selection.signal_connect("changed") \
90
- { sensitize_providers }
83
+ @treeview_providers.selection
84
+ .signal_connect("changed") { sensitize_providers }
91
85
 
92
86
  @button_prov_setup.sensitive = false
93
- @button_prov_up.sensitive = @button_prov_down.sensitive = BookProviders.length > 1
87
+
88
+ @button_prov_up.sensitive =
89
+ @button_prov_down.sensitive = BookProviders.list.length > 1
94
90
 
95
91
  @buttonbox_prov.set_child_secondary(@button_prov_add, true)
96
92
  @buttonbox_prov.set_child_secondary(@button_prov_remove, true)
@@ -102,11 +98,14 @@ module Alexandria
102
98
  @checkbutton_prov_advanced.active = true if view_advanced
103
99
  end
104
100
 
105
- setup_enable_disable_popup
106
101
  sensitize_providers
107
102
  setup_barcode_scanner_tab
108
103
  end
109
104
 
105
+ def show
106
+ @preferences_dialog.show
107
+ end
108
+
110
109
  def widget_names
111
110
  [:button_prov_add, :button_prov_down, :button_prov_remove,
112
111
  :button_prov_setup, :button_prov_up, :buttonbox_prov,
@@ -141,63 +140,6 @@ module Alexandria
141
140
  @use_scan_sound.active = Preferences.instance.play_scan_sound
142
141
  end
143
142
 
144
- def setup_enable_disable_popup
145
- # New Enable/Disable pop-up menu...
146
- @enable_disable_providers_menu = Gtk::Menu.new
147
- @enable_item = Gtk::MenuItem.new(label: _("Disable Provider"))
148
- @enable_item.signal_connect("activate") do
149
- prov = selected_provider
150
- prov.toggle_enabled
151
- adjust_selected_provider(prov)
152
- end
153
- @enable_disable_providers_menu.append(@enable_item)
154
- @enable_disable_providers_menu.show_all
155
-
156
- @treeview_providers.signal_connect("button_press_event") do |widget, event|
157
- if event_is_right_click(event)
158
- if (path = widget.get_path_at_pos(event.x, event.y))
159
- widget.grab_focus
160
- obj = widget.selection
161
- path = path.first
162
- unless obj.path_is_selected?(path)
163
- widget.unselect_all
164
- obj.select_path(path)
165
- end
166
- sel = widget.selection.selected
167
- if sel
168
- already_enabled = sel[2]
169
- message = already_enabled ? _("Disable Provider") : _("Enable Provider")
170
- @enable_item.label = message
171
- GLib::Idle.add do
172
- @enable_disable_providers_menu.popup(nil, nil, event.button, event.time)
173
- false
174
- end
175
- end
176
- else
177
- puts "not on a path"
178
- end
179
- end
180
- end
181
-
182
- # Popup the menu on Shift-F10
183
- @treeview_providers.signal_connect("popup_menu") do
184
- selected_prov = @treeview_providers.selection.selected
185
- puts selected_prov.inspect
186
- if selected_prov
187
- GLib::Idle.add do
188
- already_enabled = selected_prov[2]
189
- message = already_enabled ? _("Disable Provider") : _("Enable Provider")
190
- @enable_item.label = message
191
-
192
- @enable_disable_providers_menu.popup(nil, nil, 0, :current_time)
193
- false
194
- end
195
- else
196
- puts "no action"
197
- end
198
- end
199
- end
200
-
201
143
  def event_is_right_click(event)
202
144
  (event.event_type == :button_press) && (event.button == 3)
203
145
  end
@@ -239,11 +181,11 @@ module Alexandria
239
181
  end
240
182
 
241
183
  def on_provider_add
242
- dialog = NewProviderDialog.new(@preferences_dialog).acquire
243
- if dialog.instance
244
- BookProviders.update_priority
245
- reload_providers
246
- end
184
+ provider = NewProviderDialog.new(@preferences_dialog).acquire
185
+ return unless provider
186
+
187
+ BookProviders.instance.update_priority
188
+ reload_providers
247
189
  end
248
190
 
249
191
  def on_scanner_device_type(_combo)
@@ -277,7 +219,7 @@ module Alexandria
277
219
  dialog.show_all
278
220
  if dialog.run == Gtk::ResponseType::OK
279
221
  provider.remove
280
- BookProviders.update_priority
222
+ BookProviders.instance.update_priority
281
223
  reload_providers
282
224
  end
283
225
  dialog.destroy
@@ -286,15 +228,14 @@ module Alexandria
286
228
  def on_column_toggled(checkbutton)
287
229
  raise if @cols[checkbutton].nil?
288
230
 
289
- Preferences.instance.send("#{@cols[checkbutton]}=",
290
- checkbutton.active?)
231
+ Preferences.instance.set_variable(@cols[checkbutton], checkbutton.active?)
291
232
 
292
233
  @changed_block.call
293
234
  end
294
235
 
295
236
  def on_providers_button_press_event(_widget, event)
296
237
  # double left click
297
- on_provider_setup if (event.event_type == :'2button_press') && (event.button == 1)
238
+ on_provider_setup if (event.event_type == :"2button_press") && (event.button == 1)
298
239
  end
299
240
 
300
241
  def on_close
@@ -312,7 +253,7 @@ module Alexandria
312
253
  def reload_providers
313
254
  model = @treeview_providers.model
314
255
  model.clear
315
- BookProviders.each_with_index do |x, index|
256
+ BookProviders.list.each_with_index do |x, index|
316
257
  iter = model.append
317
258
  iter[0] = if x.enabled
318
259
  x.fullname
@@ -327,7 +268,7 @@ module Alexandria
327
268
 
328
269
  def selected_provider
329
270
  iter = @treeview_providers.selection.selected
330
- BookProviders.find { |x| x.name == iter[1] } unless iter.nil?
271
+ BookProviders.list.find { |x| x.name == iter[1] } unless iter.nil?
331
272
  end
332
273
 
333
274
  def adjust_selected_provider(prov)
@@ -350,10 +291,10 @@ module Alexandria
350
291
  @button_prov_setup.sensitive = false
351
292
  @button_prov_remove.sensitive = false
352
293
  else
353
- last_iter = model.get_iter((BookProviders.length - 1).to_s)
294
+ last_iter = model.get_iter((BookProviders.list.length - 1).to_s)
354
295
  @button_prov_up.sensitive = sel_iter != model.iter_first
355
296
  @button_prov_down.sensitive = sel_iter != last_iter
356
- provider = BookProviders.find { |x| x.name == sel_iter[1] }
297
+ provider = BookProviders.list.find { |x| x.name == sel_iter[1] }
357
298
  @button_prov_setup.sensitive = !prefs_empty(provider.prefs)
358
299
  @button_prov_remove.sensitive = provider.abstract?
359
300
  end
@@ -365,7 +306,7 @@ module Alexandria
365
306
  priority << iter[1]
366
307
  end
367
308
  Preferences.instance.providers_priority = priority
368
- BookProviders.update_priority
309
+ BookProviders.instance.update_priority
369
310
  end
370
311
  end
371
312
  end
@@ -6,6 +6,7 @@
6
6
 
7
7
  class Gtk::Entry
8
8
  attr_writer :mandatory
9
+
9
10
  def mandatory?
10
11
  @mandatory
11
12
  end
@@ -13,18 +14,21 @@ end
13
14
 
14
15
  module Alexandria
15
16
  module UI
16
- class ProviderPreferencesBaseDialog < SimpleDelegator
17
+ class ProviderPreferencesBaseDialog
18
+ attr_reader :dialog
19
+
17
20
  def initialize(title:, parent:, flags:, buttons:)
18
- dialog = Gtk::Dialog.new(title: title, parent: parent, flags: flags,
19
- buttons: buttons)
20
- super(dialog)
21
+ @dialog = Gtk::Dialog.new(title: title, parent: parent, flags: flags,
22
+ buttons: buttons)
21
23
 
22
- self.resizable = false
23
- child.border_width = 12
24
+ @dialog.resizable = false
25
+ @dialog.child.border_width = 12
24
26
 
25
27
  @controls = []
26
28
  end
27
29
 
30
+ private
31
+
28
32
  def fill_table(table, provider)
29
33
  i = table.n_rows
30
34
  table.resize(table.n_rows + provider.prefs.length,
@@ -20,15 +20,15 @@ module Alexandria
20
20
 
21
21
  table = Gtk::Table.new(0, 0)
22
22
  fill_table(table, provider)
23
- child.pack_start(table)
23
+ dialog.child.pack_start(table)
24
24
 
25
- signal_connect("destroy") { sync_variables }
25
+ dialog.signal_connect("destroy") { sync_variables }
26
26
  end
27
27
 
28
28
  def acquire
29
- show_all
30
- run
31
- destroy
29
+ dialog.show_all
30
+ dialog.run
31
+ dialog.destroy
32
32
  end
33
33
  end
34
34
  end