alexandria-book-collection-manager 0.7.9 → 0.7.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +5 -1
  3. data/.github/workflows/ruby.yml +36 -22
  4. data/.rubocop.yml +12 -3
  5. data/.rubocop_todo.yml +35 -47
  6. data/.simplecov +2 -2
  7. data/CHANGELOG.md +71 -24
  8. data/Gemfile +0 -6
  9. data/Rakefile +5 -5
  10. data/alexandria-book-collection-manager.gemspec +24 -21
  11. data/bin/rake +28 -0
  12. data/bin/rspec +28 -0
  13. data/doc/dependency_decisions.yml +32 -26
  14. data/{bin → exe}/alexandria +1 -3
  15. data/lib/alexandria/about.rb +1 -0
  16. data/lib/alexandria/book_providers/bl_provider.rb +4 -6
  17. data/lib/alexandria/book_providers/{douban.rb → douban_provider.rb} +1 -1
  18. data/lib/alexandria/book_providers/loc_provider.rb +2 -6
  19. data/lib/alexandria/book_providers/sbn_provider.rb +2 -12
  20. data/lib/alexandria/book_providers/thalia_provider.rb +5 -6
  21. data/lib/alexandria/book_providers/{web.rb → website_based_provider.rb} +20 -1
  22. data/lib/alexandria/book_providers/{worldcat.rb → world_cat_provider.rb} +3 -4
  23. data/lib/alexandria/book_providers/z3950_provider.rb +25 -27
  24. data/lib/alexandria/book_providers.rb +14 -10
  25. data/lib/alexandria/config.rb +2 -2
  26. data/lib/alexandria/console.rb +12 -10
  27. data/lib/alexandria/export_format.rb +3 -2
  28. data/lib/alexandria/export_library.rb +35 -40
  29. data/lib/alexandria/import_library.rb +3 -4
  30. data/lib/alexandria/import_library_csv.rb +2 -2
  31. data/lib/alexandria/library_collection.rb +1 -1
  32. data/lib/alexandria/library_store.rb +20 -15
  33. data/lib/alexandria/logging.rb +22 -21
  34. data/lib/alexandria/models/book.rb +1 -2
  35. data/lib/alexandria/models/library.rb +7 -8
  36. data/lib/alexandria/preferences.rb +7 -19
  37. data/lib/alexandria/{book_providers/pseudomarc.rb → pseudo_marc_parser.rb} +2 -2
  38. data/lib/alexandria/scanners/cue_cat.rb +5 -9
  39. data/lib/alexandria/scanners/{keyboard.rb → keyboard_wedge.rb} +3 -3
  40. data/lib/alexandria/scanners.rb +2 -2
  41. data/lib/alexandria/smart_library.rb +9 -5
  42. data/lib/alexandria/ui/acquire_dialog.rb +42 -45
  43. data/lib/alexandria/ui/alert_dialog.rb +3 -3
  44. data/lib/alexandria/ui/barcode_animation.rb +3 -3
  45. data/lib/alexandria/ui/book_properties_dialog.rb +9 -9
  46. data/lib/alexandria/ui/book_properties_dialog_base.rb +13 -14
  47. data/lib/alexandria/ui/builder_base.rb +1 -1
  48. data/lib/alexandria/ui/callbacks.rb +8 -7
  49. data/lib/alexandria/ui/confirm_erase_dialog.rb +1 -0
  50. data/lib/alexandria/ui/conflict_while_copying_dialog.rb +1 -0
  51. data/lib/alexandria/ui/export_dialog.rb +1 -0
  52. data/lib/alexandria/ui/{iconview.rb → icon_view_manager.rb} +1 -0
  53. data/lib/alexandria/ui/icons.rb +2 -2
  54. data/lib/alexandria/ui/iconview_tooltips.rb +1 -1
  55. data/lib/alexandria/ui/init.rb +10 -4
  56. data/lib/alexandria/ui/keep_bad_isbn_dialog.rb +1 -0
  57. data/lib/alexandria/ui/libraries_combo.rb +1 -0
  58. data/lib/alexandria/ui/listview.rb +2 -0
  59. data/lib/alexandria/ui/main_app.rb +3 -1
  60. data/lib/alexandria/ui/multi_drag_treeview.rb +0 -2
  61. data/lib/alexandria/ui/new_book_dialog.rb +15 -20
  62. data/lib/alexandria/ui/new_book_dialog_manual.rb +7 -7
  63. data/lib/alexandria/ui/new_provider_dialog.rb +1 -0
  64. data/lib/alexandria/ui/new_smart_library_dialog.rb +2 -1
  65. data/lib/alexandria/ui/preferences_dialog.rb +4 -4
  66. data/lib/alexandria/ui/provider_preferences_dialog.rb +1 -0
  67. data/lib/alexandria/ui/really_delete_dialog.rb +1 -0
  68. data/lib/alexandria/ui/sidepane_manager.rb +49 -48
  69. data/lib/alexandria/ui/skip_entry_dialog.rb +1 -0
  70. data/lib/alexandria/ui/smart_library_properties_dialog.rb +1 -0
  71. data/lib/alexandria/ui/smart_library_properties_dialog_base.rb +2 -1
  72. data/lib/alexandria/ui/{sound.rb → sound_effects_player.rb} +3 -0
  73. data/lib/alexandria/ui/ui_manager.rb +194 -143
  74. data/lib/alexandria/ui.rb +1 -0
  75. data/lib/alexandria/version.rb +1 -1
  76. data/lib/alexandria/web_themes.rb +1 -1
  77. data/lib/alexandria.rb +6 -5
  78. data/po/Makefile +1 -1
  79. data/po/it.po +64 -82
  80. data/spec/alexandria/book_providers/bl_provider_spec.rb +11 -2
  81. data/spec/alexandria/book_providers/douban_provider_spec.rb +17 -0
  82. data/spec/alexandria/book_providers/loc_provider_spec.rb +10 -2
  83. data/spec/alexandria/book_providers/sbn_provider_spec.rb +10 -2
  84. data/spec/alexandria/book_providers/thalia_provider_spec.rb +9 -1
  85. data/spec/alexandria/book_providers/world_cat_provider_spec.rb +30 -10
  86. data/spec/alexandria/book_providers/z3950_provider_spec.rb +22 -0
  87. data/spec/alexandria/book_spec.rb +5 -3
  88. data/spec/alexandria/console_spec.rb +1 -1
  89. data/spec/alexandria/export_library_spec.rb +65 -19
  90. data/spec/alexandria/library_collection_spec.rb +24 -0
  91. data/spec/alexandria/library_spec.rb +68 -53
  92. data/spec/alexandria/library_store_spec.rb +33 -1
  93. data/spec/alexandria/preferences_spec.rb +7 -7
  94. data/spec/alexandria/pseudo_marc_parser_spec.rb +71 -0
  95. data/spec/alexandria/scanners/cue_cat_spec.rb +11 -4
  96. data/spec/alexandria/scanners/keyboard_wedge_spec.rb +47 -0
  97. data/spec/alexandria/smart_library_spec.rb +7 -5
  98. data/spec/alexandria/ui/about_dialog_spec.rb +2 -2
  99. data/spec/alexandria/ui/acquire_dialog_spec.rb +8 -3
  100. data/spec/alexandria/ui/alert_dialog_spec.rb +6 -4
  101. data/spec/alexandria/ui/bad_isbns_dialog_spec.rb +2 -2
  102. data/spec/alexandria/ui/book_properties_dialog_spec.rb +5 -5
  103. data/spec/alexandria/ui/confirm_erase_dialog_spec.rb +19 -3
  104. data/spec/alexandria/ui/conflict_while_copying_dialog_spec.rb +2 -2
  105. data/spec/alexandria/ui/error_dialog_spec.rb +14 -3
  106. data/spec/alexandria/ui/export_dialog_spec.rb +6 -6
  107. data/spec/alexandria/ui/{iconview_spec.rb → icon_view_manager_spec.rb} +2 -2
  108. data/spec/alexandria/ui/import_dialog_spec.rb +3 -3
  109. data/spec/alexandria/ui/keep_bad_isbn_dialog_spec.rb +2 -2
  110. data/spec/alexandria/ui/main_app_spec.rb +0 -2
  111. data/spec/alexandria/ui/new_book_dialog_manual_spec.rb +5 -5
  112. data/spec/alexandria/ui/new_book_dialog_spec.rb +7 -4
  113. data/spec/alexandria/ui/new_provider_dialog_spec.rb +3 -3
  114. data/spec/alexandria/ui/new_smart_library_dialog_spec.rb +9 -7
  115. data/spec/alexandria/ui/preferences_dialog_spec.rb +2 -2
  116. data/spec/alexandria/ui/provider_preferences_dialog_spec.rb +22 -7
  117. data/spec/alexandria/ui/really_delete_dialog_spec.rb +2 -2
  118. data/spec/alexandria/ui/sidepane_manager_spec.rb +2 -2
  119. data/spec/alexandria/ui/skip_entry_dialog_spec.rb +19 -3
  120. data/spec/alexandria/ui/smart_library_properties_dialog_spec.rb +2 -2
  121. data/spec/alexandria/ui/ui_manager_spec.rb +7 -5
  122. data/spec/end_to_end/basic_run_spec.rb +2 -1
  123. data/spec/spec_helper.rb +26 -33
  124. data/tasks/setup.rb +1 -1
  125. data/util/rake/fileinstall.rb +12 -13
  126. data/util/rake/gettextgenerate.rb +1 -1
  127. data/util/rake/omfgenerate.rb +1 -1
  128. metadata +97 -64
  129. /data/spec/alexandria/ui/{sound_spec.rb → sound_effects_player_spec.rb} +0 -0
@@ -9,20 +9,18 @@ require "monitor"
9
9
  require "alexandria/image_fetcher"
10
10
 
11
11
  require "alexandria/scanners/cue_cat"
12
- require "alexandria/scanners/keyboard"
12
+ require "alexandria/scanners/keyboard_wedge"
13
13
 
14
14
  require "alexandria/ui/builder_base"
15
15
  require "alexandria/ui/barcode_animation"
16
16
  require "alexandria/ui/error_dialog"
17
- require "alexandria/ui/sound"
17
+ require "alexandria/ui/sound_effects_player"
18
18
 
19
19
  module Alexandria
20
20
  module UI
21
21
  # assists in turning on progress bar when searching
22
22
  # and turning it off when all search threads have completed...
23
- class SearchThreadCounter < Monitor
24
- attr_reader :count
25
-
23
+ class SearchThreadMonitor < Monitor
26
24
  def initialize
27
25
  @count = 0
28
26
  super
@@ -39,6 +37,14 @@ module Alexandria
39
37
  @count -= 1 unless @count.zero?
40
38
  end
41
39
  end
40
+
41
+ def any?
42
+ @count > 0
43
+ end
44
+
45
+ def none?
46
+ @count.zero?
47
+ end
42
48
  end
43
49
 
44
50
  class AcquireDialog < BuilderBase
@@ -46,10 +52,12 @@ module Alexandria
46
52
  include ImageFetcher
47
53
  include Logging
48
54
  extend GetText
55
+
49
56
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
50
57
 
51
- def initialize(parent, selected_library = nil, &block)
58
+ def initialize(parent, ui_manager, selected_library, &block)
52
59
  super("acquire_dialog__builder.glade", widget_names)
60
+ @ui_manager = ui_manager
53
61
  @acquire_dialog.transient_for = @parent = parent
54
62
  @block = block
55
63
 
@@ -64,8 +72,8 @@ module Alexandria
64
72
  init_treeview
65
73
  @book_results = {}
66
74
 
67
- @search_thread_counter = SearchThreadCounter.new
68
- @search_threads_running = @search_thread_counter.new_cond
75
+ @search_thread_monitor = SearchThreadMonitor.new
76
+ @search_threads_running = @search_thread_monitor.new_cond
69
77
  end
70
78
 
71
79
  def show
@@ -79,8 +87,9 @@ module Alexandria
79
87
 
80
88
  def book_in_library(isbn10, library)
81
89
  isbn13 = Library.canonicalise_ean(isbn10)
90
+ isbns = [isbn10, isbn13]
82
91
  match = library.find do |book|
83
- (book.isbn == isbn10 || book.isbn == isbn13)
92
+ isbns.include?(book.isbn)
84
93
  end
85
94
  !match.nil?
86
95
  rescue StandardError
@@ -258,28 +267,11 @@ module Alexandria
258
267
  # begin copy-n-paste from new_book_dialog
259
268
 
260
269
  def notify_start_add_by_isbn
261
- GLib::Idle.add do
262
- main_progress_bar = MainApp.instance.appbar.children.first
263
- main_progress_bar.visible = true
264
- @progress_pulsing = GLib::Timeout.add(100) do
265
- if @destroyed
266
- @progress_pulsing = nil
267
- false
268
- else
269
- main_progress_bar.pulse
270
- true
271
- end
272
- end
273
- false
274
- end
270
+ ui_manager.start_progress_bar_pulsing(self)
275
271
  end
276
272
 
277
273
  def notify_end_add_by_isbn
278
- GLib::Idle.add do
279
- MainApp.instance.appbar.children.first.visible = false
280
- GLib::Source.remove(@progress_pulsing) if @progress_pulsing
281
- false
282
- end
274
+ ui_manager.stop_progress_bar_pulsing
283
275
  end
284
276
 
285
277
  def update(status, provider)
@@ -292,28 +284,34 @@ module Alexandria
292
284
  }
293
285
  message = messages[status] % provider
294
286
  log.debug { "update message : #{message}" }
295
- MainApp.instance.ui_manager.set_status_label(message)
287
+ ui_manager.set_status_label(message)
296
288
  false
297
289
  end
298
290
  end
299
291
 
292
+ def destroyed?
293
+ @acquire_dialog.destroyed?
294
+ end
295
+
300
296
  # end copy-n-paste
301
297
 
298
+ attr_reader :ui_manager
299
+
302
300
  private
303
301
 
304
302
  def start_search
305
- @search_thread_counter.synchronize do
306
- first_search = @search_thread_counter.count.zero?
303
+ @search_thread_monitor.synchronize do
304
+ first_search = @search_thread_monitor.none?
307
305
 
308
- @search_thread_counter.new_search
306
+ @search_thread_monitor.new_search
309
307
 
310
308
  if first_search
311
309
  @progress_bar_thread = Thread.new do
312
310
  notify_start_add_by_isbn
313
311
  Alexandria::BookProviders.instance.add_observer(self)
314
- @search_thread_counter.synchronize do
312
+ @search_thread_monitor.synchronize do
315
313
  @search_threads_running.wait_while do
316
- @search_thread_counter.count > 0
314
+ @search_thread_monitor.any?
317
315
  end
318
316
  end
319
317
  notify_end_add_by_isbn
@@ -324,8 +322,8 @@ module Alexandria
324
322
  end
325
323
 
326
324
  def stop_search
327
- @search_thread_counter.synchronize do
328
- @search_thread_counter.end_search
325
+ @search_thread_monitor.synchronize do
326
+ @search_thread_monitor.end_search
329
327
  @search_threads_running.signal
330
328
  end
331
329
  end
@@ -386,7 +384,7 @@ module Alexandria
386
384
  end
387
385
 
388
386
  def on_destroy
389
- MainApp.instance.ui_manager.set_status_label("")
387
+ ui_manager.set_status_label("")
390
388
  notify_end_add_by_isbn
391
389
  # TODO: possibly make sure all threads have stopped running
392
390
  @animation.destroy
@@ -401,7 +399,7 @@ module Alexandria
401
399
 
402
400
  log.debug { "Using #{@scanner.name} scanner" }
403
401
  message = _("Ready to use %s barcode scanner") % @scanner.name
404
- MainApp.instance.ui_manager.set_status_label(message)
402
+ ui_manager.set_status_label(message)
405
403
 
406
404
  @prev_time = 0
407
405
  @interval = 0
@@ -497,11 +495,6 @@ module Alexandria
497
495
  end
498
496
  end
499
497
 
500
- # @sound_player = SoundEffectsPlayer.new
501
- @sound_players = {}
502
- @sound_players["scanning"] = SoundEffectsPlayer.new
503
- @sound_players["good_scan"] = SoundEffectsPlayer.new
504
- @sound_players["bad_scan"] = SoundEffectsPlayer.new
505
498
  @test_scan = false
506
499
  end
507
500
 
@@ -510,16 +503,20 @@ module Alexandria
510
503
  log.debug { "Effect: #{effect}, playing: #{@prefs.play_scanning_sound}" }
511
504
  return unless @prefs.play_scanning_sound
512
505
 
513
- @sound_players["scanning"].play("scanning")
506
+ sound_player.play("scanning")
514
507
  else
515
508
  log.debug { "Effect: #{effect}, playing: #{@prefs.play_scan_sound}" }
516
509
  return unless @prefs.play_scan_sound
517
510
 
518
511
  # sleep(0.5) # "scanning" effect lasts 0.5 seconds, wait for it to end
519
- @sound_players[effect].play(effect)
512
+ sound_player.play(effect)
520
513
  end
521
514
  end
522
515
 
516
+ def sound_player
517
+ @sound_player ||= SoundEffectsPlayer.new
518
+ end
519
+
523
520
  def developer_test_scan
524
521
  log.info { "Developer test scan" }
525
522
  scans = [".C3nZC3nZC3n2ChnWENz7DxnY.cGen.ENr7C3j3C3f1Dxj3Dq.",
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # See the file README.md for authorship and licensing information.
6
6
 
7
- require "cgi"
7
+ require "cgi/escape"
8
8
 
9
9
  module Alexandria
10
10
  module UI
@@ -34,6 +34,8 @@ module Alexandria
34
34
  @dialog.child.pack_start(hbox)
35
35
  end
36
36
 
37
+ attr_reader :dialog
38
+
37
39
  def show_all
38
40
  dialog.show_all
39
41
  end
@@ -52,8 +54,6 @@ module Alexandria
52
54
 
53
55
  private
54
56
 
55
- attr_reader :dialog
56
-
57
57
  def make_label(markup)
58
58
  label = Gtk::Label.new
59
59
  label.set_alignment(0, 0)
@@ -143,9 +143,9 @@ module Alexandria
143
143
  def scan_animation
144
144
  if @index < @barcode_bars.size
145
145
  @index = 0 if @index < 0
146
- alpha = 7 * (@index + 1)
146
+ alpha = (@index + 1) * 7
147
147
  @barcode_bars.each_with_index do |rect, i|
148
- rect.set_property(:fill_color_rgba, 0xFF000000 + alpha)
148
+ rect.set_property(:fill_color_rgba, alpha + 0xFF000000)
149
149
  break if i >= @index
150
150
  end
151
151
  @index += 1
@@ -166,7 +166,7 @@ module Alexandria
166
166
  def fade_animation
167
167
  @fade_opacity = 255 if @fade_opacity == -1
168
168
  if @fade_opacity >= 0
169
- grey = 0x00000000 + @fade_opacity
169
+ grey = @fade_opacity + 0x00000000
170
170
  @barcode_bars.each { |rect| rect.set_property(:fill_color_rgba, grey) }
171
171
  @fade_opacity -= 5
172
172
  else
@@ -11,6 +11,7 @@ module Alexandria
11
11
  class BookPropertiesDialog < BookPropertiesDialogBase
12
12
  include GetText
13
13
  extend GetText
14
+
14
15
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
15
16
 
16
17
  def initialize(parent, library, book)
@@ -82,17 +83,16 @@ module Alexandria
82
83
  end
83
84
 
84
85
  @checkbutton_own.active = book.own?
85
- if (@checkbutton_redd.active = book.redd?)
86
- @redd_date.sensitive = true
87
- if book.redd_when.nil?
88
- log.debug { "no redd_when" }
89
- else
90
- @redd_date.text = format_date(book.redd_when)
91
- end
92
- # self.redd_when = (book.redd_when or Time.now)
86
+
87
+ @block_calendar_popup = true
88
+ if book.redd?
89
+ @redd_date.text = format_date(book.redd_when) unless book.redd_when.nil?
90
+ @checkbutton_redd.active = true
93
91
  else
94
- @redd_date.sensitive = false
92
+ @checkbutton_redd.active = false
95
93
  end
94
+ @block_calendar_popup = false
95
+
96
96
  @checkbutton_want.active = book.want?
97
97
 
98
98
  @checkbutton_want.inconsistent = true if (@checkbutton_own.active = book.own?)
@@ -15,6 +15,7 @@ module Alexandria
15
15
  include Logging
16
16
  include GetText
17
17
  extend GetText
18
+
18
19
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
19
20
 
20
21
  COVER_MAXWIDTH = 140 # pixels
@@ -55,11 +56,7 @@ module Alexandria
55
56
  @treeview_authors.append_column(col)
56
57
 
57
58
  setup_date_widgets
58
- GLib::Timeout.add(150) do
59
- @setup_finished = true
60
-
61
- false
62
- end
59
+ @block_calendar_popup = false
63
60
  end
64
61
 
65
62
  def show
@@ -151,7 +148,7 @@ module Alexandria
151
148
 
152
149
  def want_toggled; end
153
150
 
154
- @@latest_filechooser_directory = ENV["HOME"]
151
+ @@latest_filechooser_directory = Dir.home
155
152
  def on_change_cover
156
153
  dialog = Gtk::FileChooserDialog.new(title: _("Select a cover image"),
157
154
  parent: @book_properties_dialog,
@@ -177,8 +174,8 @@ module Alexandria
177
174
  FileUtils.cp(dialog.filename, "#{@cover_file}.orig")
178
175
  new_width = cover.width / (cover.height / COVER_ABSOLUTE_MAXHEIGHT.to_f)
179
176
  log.info do
180
- "Scaling large cover image to" \
181
- " #{new_width.to_i} x #{COVER_ABSOLUTE_MAXHEIGHT}"
177
+ "Scaling large cover image to " \
178
+ "#{new_width.to_i} x #{COVER_ABSOLUTE_MAXHEIGHT}"
182
179
  end
183
180
  cover = cover.scale(new_width.to_i, COVER_ABSOLUTE_MAXHEIGHT)
184
181
  cover.save(@cover_file, "jpeg")
@@ -242,13 +239,15 @@ module Alexandria
242
239
  end
243
240
 
244
241
  def redd_toggled
245
- redd_yes = @checkbutton_redd.active?
246
- @redd_date.sensitive = redd_yes
242
+ if @checkbutton_redd.active?
243
+ @redd_date.sensitive = true
247
244
 
248
- return unless redd_yes && @redd_date.text.strip.empty?
245
+ return if @block_calendar_popup
249
246
 
250
- # don't do this when popping up the dialog for the first time
251
- display_calendar_popup(@redd_date) if @setup_finished
247
+ display_calendar_popup(@redd_date) if @redd_date.text.strip.empty?
248
+ else
249
+ @redd_date.sensitive = false
250
+ end
252
251
  end
253
252
 
254
253
  private
@@ -263,7 +262,7 @@ module Alexandria
263
262
  ]
264
263
  raise _("out of range") if rating < 0 || rating > images.length
265
264
 
266
- images[0..rating - 1].each { |x| x.pixbuf = Icons::STAR_SET }
265
+ images[0..(rating - 1)].each { |x| x.pixbuf = Icons::STAR_SET }
267
266
  images[rating..].each { |x| x.pixbuf = Icons::STAR_UNSET }
268
267
  @current_rating = rating
269
268
  end
@@ -17,7 +17,7 @@ module Alexandria
17
17
  method(handler)
18
18
  end
19
19
  widget_names.each do |name|
20
- instance_variable_set("@#{name}".intern, builder[name.to_s])
20
+ instance_variable_set(:"@#{name}", builder[name.to_s])
21
21
  end
22
22
  end
23
23
  end
@@ -31,7 +31,8 @@ module Alexandria
31
31
 
32
32
  def on_add_book(*)
33
33
  log.info { "on_add_book" }
34
- dialog = NewBookDialog.new(@main_app, selected_library) do |_books, library, is_new|
34
+ dialog = NewBookDialog.new(@main_app, self, selected_library) do
35
+ |_books, library, is_new|
35
36
  if is_new
36
37
  append_library(library, true)
37
38
  setup_move_actions
@@ -115,7 +116,7 @@ module Alexandria
115
116
 
116
117
  def on_acquire(*)
117
118
  dialog =
118
- AcquireDialog.new(@main_app, selected_library) do |_books, library, is_new|
119
+ AcquireDialog.new(@main_app, self, selected_library) do |_books, library, is_new|
119
120
  if is_new
120
121
  append_library(library, true)
121
122
  setup_move_actions
@@ -313,11 +314,11 @@ module Alexandria
313
314
  def connect_toggle_actions
314
315
  toggle_actions
315
316
  .each do |name, stock_id, label, accelerator, tooltip, callback, is_active|
316
- action = Gtk::ToggleAction.new(name, label: label, tooltip: tooltip,
317
- stock_id: stock_id)
318
- action.set_active is_active
319
- @actiongroup.add_action_with_accel(action, accelerator)
320
- action.signal_connect("toggled", &callback) if callback
317
+ action = Gtk::ToggleAction.new(name, label: label, tooltip: tooltip,
318
+ stock_id: stock_id)
319
+ action.set_active is_active
320
+ @actiongroup.add_action_with_accel(action, accelerator)
321
+ action.signal_connect("toggled", &callback) if callback
321
322
  end
322
323
  end
323
324
 
@@ -10,6 +10,7 @@ module Alexandria
10
10
  module UI
11
11
  class ConfirmEraseDialog < AlertDialog
12
12
  include GetText
13
+
13
14
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
14
15
 
15
16
  def initialize(parent, filename)
@@ -10,6 +10,7 @@ module Alexandria
10
10
  module UI
11
11
  class ConflictWhileCopyingDialog < AlertDialog
12
12
  include GetText
13
+
13
14
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
14
15
 
15
16
  def initialize(parent, library, book)
@@ -13,6 +13,7 @@ module Alexandria
13
13
  class ExportDialog
14
14
  include GetText
15
15
  extend GetText
16
+
16
17
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
17
18
 
18
19
  FORMATS = Alexandria::ExportFormat.all
@@ -29,6 +29,7 @@ module Alexandria
29
29
  include Logging
30
30
  include GetText
31
31
  include DragAndDropable
32
+
32
33
  def initialize(_iconview, parent)
33
34
  @parent = parent
34
35
  @iconview = @parent.iconview
@@ -35,8 +35,8 @@ module Alexandria
35
35
  return GdkPixbuf::Pixbuf.new(file: filename) if File.exist?(filename)
36
36
  rescue GdkPixbuf::PixbufError
37
37
  log.error do
38
- "Failed to load GdkPixbuf::Pixbuf," \
39
- " please ensure that #{filename} is a valid image file"
38
+ "Failed to load GdkPixbuf::Pixbuf, " \
39
+ "please ensure that #{filename} is a valid image file"
40
40
  end
41
41
  end
42
42
  BOOK_ICON
@@ -12,7 +12,7 @@
12
12
  #
13
13
  # Ported to ruby-gtk2 (and modified for IconView) by Cathal Mc Ginley
14
14
 
15
- require "cgi"
15
+ require "cgi/escape"
16
16
 
17
17
  module Alexandria
18
18
  module UI
@@ -25,22 +25,28 @@ class Gtk::ActionGroup
25
25
  end
26
26
 
27
27
  module Alexandria::UI::FreezeThaw
28
+ def self.included(base)
29
+ base.class_eval do
30
+ attr_accessor :old_model
31
+ end
32
+ end
33
+
28
34
  def frozen?
29
- @old_model && !model
35
+ old_model && !model
30
36
  end
31
37
 
32
38
  def freeze
33
39
  return if frozen?
34
40
 
35
- @old_model = model
41
+ self.old_model = model
36
42
  self.model = nil
37
43
  end
38
44
 
39
45
  def unfreeze
40
46
  return unless frozen?
41
47
 
42
- self.model = @old_model
43
- @old_model = nil
48
+ self.model = old_model
49
+ self.old_model = nil
44
50
  end
45
51
  end
46
52
 
@@ -10,6 +10,7 @@ module Alexandria
10
10
  module UI
11
11
  class KeepBadISBNDialog < AlertDialog
12
12
  include GetText
13
+
13
14
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
14
15
 
15
16
  def initialize(parent, book)
@@ -24,6 +24,7 @@ module Alexandria
24
24
  module ComboBoxOverrides
25
25
  include GetText
26
26
  extend GetText
27
+
27
28
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
28
29
 
29
30
  def populate_with_libraries(libraries, selected_library)
@@ -10,11 +10,13 @@ module Alexandria
10
10
  module UI
11
11
  include Logging
12
12
  include GetText
13
+
13
14
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
14
15
  class ListViewManager
15
16
  include Logging
16
17
  include GetText
17
18
  include DragAndDropable
19
+
18
20
  BOOKS_TARGET_TABLE = [["ALEXANDRIA_BOOKS", :same_app, 0]].freeze
19
21
 
20
22
  def initialize(_listview, parent)
@@ -37,19 +37,21 @@ require "alexandria/ui/dndable"
37
37
  require "alexandria/ui/init"
38
38
  require "alexandria/ui/ui_manager"
39
39
  require "alexandria/ui/listview"
40
- require "alexandria/ui/iconview"
40
+ require "alexandria/ui/icon_view_manager"
41
41
  require "alexandria/ui/sidepane_manager"
42
42
 
43
43
  module Alexandria
44
44
  module UI
45
45
  include Logging
46
46
  include GetText
47
+
47
48
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
48
49
 
49
50
  class MainApp
50
51
  include Logging
51
52
  include GetText
52
53
  include Singleton
54
+
53
55
  attr_accessor :main_app, :libraries, :actiongroup, :appbar, :prefs, :ui_manager
54
56
 
55
57
  def initialize
@@ -79,8 +79,6 @@ module Alexandria
79
79
  def motion_notify_event(event)
80
80
  if drag_check_threshold(@context.x, @context.y, event.x, event.y)
81
81
  stop_drag_check
82
- paths = []
83
- selection.each { |_model, path, _iter| paths << path }
84
82
  @context.drag_context = drag_begin(@context.source_targets,
85
83
  @context.source_actions,
86
84
  @context.pressed_button,
@@ -20,13 +20,15 @@ module Alexandria
20
20
  include ImageFetcher
21
21
  include GetText
22
22
  extend GetText
23
+
23
24
  GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
24
25
  @@last_criterion_was_not_isbn = false
25
26
 
26
- def initialize(parent, selected_library = nil, &block)
27
+ def initialize(parent_window, ui_manager, selected_library, &block)
27
28
  super("new_book_dialog__builder.glade", widget_names)
28
29
  log.info { "New Book Dialog" }
29
- @new_book_dialog.transient_for = @parent = parent
30
+ @new_book_dialog.transient_for = @parent = parent_window
31
+ @ui_manager = ui_manager
30
32
  @block = block
31
33
  @destroyed = false
32
34
  @selected_library = selected_library
@@ -317,7 +319,7 @@ module Alexandria
317
319
  return unless entry.text =~ /^\..*?\..*?\.(.*?)\.$/
318
320
 
319
321
  tmp = Regexp.last_match[1].tr("a-zA-Z0-9+-", " -_")
320
- tmp = ((32 + tmp.length * 3 / 4).to_i.chr << tmp).unpack1("u")
322
+ tmp = ((tmp.length * 3 / 4 + 32).to_i.chr << tmp).unpack1("u")
321
323
  tmp.chomp!("\000")
322
324
  entry.text = tmp.gsub!(/./) { |c| (c[0] ^ 67).chr }
323
325
  entry.text = "Bad scan result" if entry.text.count("^ -~") > 0
@@ -426,7 +428,7 @@ module Alexandria
426
428
  @treeview_results.model.clear
427
429
  @entry_search.grab_focus
428
430
  else
429
- @button_add.sensitive = true #
431
+ @button_add.sensitive = true
430
432
  @entry_isbn.text = "" # blank ISBN field
431
433
  @entry_isbn.grab_focus
432
434
  end
@@ -473,24 +475,11 @@ module Alexandria
473
475
  end
474
476
 
475
477
  def notify_start_add_by_isbn
476
- main_progress_bar = MainApp.instance.appbar.children.first
477
- main_progress_bar.visible = true
478
- @progress_pulsing = GLib::Timeout.add(100) do
479
- if @destroyed
480
- false
481
- else
482
- main_progress_bar.pulse
483
- true
484
- end
485
- end
478
+ ui_manager.start_progress_bar_pulsing(self)
486
479
  end
487
480
 
488
481
  def notify_end_add_by_isbn
489
- MainApp.instance.appbar.children.first.visible = false
490
- return unless @progress_pulsing
491
-
492
- GLib::Source.remove(@progress_pulsing)
493
- @progress_pulsing = nil
482
+ ui_manager.stop_progress_bar_pulsing
494
483
  end
495
484
 
496
485
  def update(status, provider)
@@ -502,7 +491,7 @@ module Alexandria
502
491
  }
503
492
  message = messages[status] % provider
504
493
  log.debug { "update message : #{message}" }
505
- MainApp.instance.ui_manager.set_status_label(message)
494
+ ui_manager.set_status_label(message)
506
495
  end
507
496
 
508
497
  def on_focus
@@ -556,6 +545,12 @@ module Alexandria
556
545
  Alexandria::UI.display_help(@preferences_dialog, "add-book-by-isbn")
557
546
  end
558
547
 
548
+ def destroyed?
549
+ @new_book_dialog.destroyed?
550
+ end
551
+
552
+ attr_reader :ui_manager
553
+
559
554
  private
560
555
 
561
556
  def assert_not_exist(library, isbn)