alexandria-book-collection-manager 0.6.9 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +34 -30
- data/.rubocop_todo.yml +139 -54
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -0
- data/Rakefile +10 -11
- data/alexandria-book-collection-manager.gemspec +3 -2
- data/bin/alexandria +1 -1
- data/lib/alexandria.rb +3 -6
- data/lib/alexandria/about.rb +9 -9
- data/lib/alexandria/book_providers.rb +12 -12
- data/lib/alexandria/book_providers/adlibris.rb +14 -18
- data/lib/alexandria/book_providers/amazon_aws.rb +17 -31
- data/lib/alexandria/book_providers/amazon_ecs_util.rb +5 -6
- data/lib/alexandria/book_providers/barnes_and_noble.rb +51 -76
- data/lib/alexandria/book_providers/bol_it.rb +12 -12
- data/lib/alexandria/book_providers/deastore.rb +27 -31
- data/lib/alexandria/book_providers/douban.rb +9 -13
- data/lib/alexandria/book_providers/ibs_it.rb +10 -10
- data/lib/alexandria/book_providers/mcu.rb +12 -18
- data/lib/alexandria/book_providers/proxis.rb +14 -22
- data/lib/alexandria/book_providers/pseudomarc.rb +8 -18
- data/lib/alexandria/book_providers/renaud.rb +16 -16
- data/lib/alexandria/book_providers/siciliano.rb +25 -38
- data/lib/alexandria/book_providers/thalia.rb +13 -16
- data/lib/alexandria/book_providers/webster_it.rb +14 -18
- data/lib/alexandria/book_providers/worldcat.rb +21 -25
- data/lib/alexandria/book_providers/z3950.rb +19 -23
- data/lib/alexandria/config.rb +2 -2
- data/lib/alexandria/execution_queue.rb +3 -1
- data/lib/alexandria/export_library.rb +19 -22
- data/lib/alexandria/import_library.rb +14 -18
- data/lib/alexandria/import_library_csv.rb +12 -30
- data/lib/alexandria/models/book.rb +7 -9
- data/lib/alexandria/models/library.rb +44 -44
- data/lib/alexandria/net.rb +1 -1
- data/lib/alexandria/preferences.rb +12 -57
- data/lib/alexandria/scanners.rb +10 -6
- data/lib/alexandria/scanners/cuecat.rb +2 -2
- data/lib/alexandria/smart_library.rb +12 -12
- data/lib/alexandria/ui.rb +5 -2
- data/lib/alexandria/ui/callbacks.rb +106 -65
- data/lib/alexandria/ui/completion_models.rb +55 -51
- data/lib/alexandria/ui/dialogs/about_dialog.rb +1 -1
- data/lib/alexandria/ui/dialogs/acquire_dialog.rb +25 -51
- data/lib/alexandria/ui/dialogs/alert_dialog.rb +13 -11
- data/lib/alexandria/ui/dialogs/bad_isbns_dialog.rb +2 -2
- data/lib/alexandria/ui/dialogs/barcode_animation.rb +39 -23
- data/lib/alexandria/ui/dialogs/book_properties_dialog.rb +16 -21
- data/lib/alexandria/ui/dialogs/book_properties_dialog_base.rb +23 -24
- data/lib/alexandria/ui/dialogs/export_dialog.rb +46 -45
- data/lib/alexandria/ui/dialogs/import_dialog.rb +26 -35
- data/lib/alexandria/ui/dialogs/misc_dialogs.rb +11 -11
- data/lib/alexandria/ui/dialogs/new_book_dialog.rb +47 -59
- data/lib/alexandria/ui/dialogs/new_book_dialog_manual.rb +14 -13
- data/lib/alexandria/ui/dialogs/new_smart_library_dialog.rb +12 -11
- data/lib/alexandria/ui/dialogs/preferences_dialog.rb +37 -43
- data/lib/alexandria/ui/dialogs/smart_library_properties_dialog.rb +9 -8
- data/lib/alexandria/ui/dialogs/smart_library_properties_dialog_base.rb +47 -53
- data/lib/alexandria/ui/dndable.rb +5 -4
- data/lib/alexandria/ui/icons.rb +19 -19
- data/lib/alexandria/ui/iconview.rb +7 -12
- data/lib/alexandria/ui/iconview_tooltips.rb +22 -109
- data/lib/alexandria/ui/init.rb +7 -15
- data/lib/alexandria/ui/libraries_combo.rb +54 -48
- data/lib/alexandria/ui/listview.rb +30 -85
- data/lib/alexandria/ui/multi_drag_treeview.rb +110 -107
- data/lib/alexandria/ui/sidepane.rb +23 -25
- data/lib/alexandria/ui/sound.rb +18 -27
- data/lib/alexandria/ui/ui_manager.rb +126 -204
- data/lib/alexandria/undo_manager.rb +2 -2
- data/lib/alexandria/version.rb +4 -4
- data/spec/alexandria/book_providers_spec.rb +7 -4
- data/spec/alexandria/library_spec.rb +13 -16
- data/spec/alexandria/scanners/cuecat_spec.rb +1 -2
- data/spec/alexandria/ui/dialogs_spec.rb +5 -1
- data/spec/alexandria/ui/main_app_spec.rb +3 -3
- data/{lib/alexandria/utils.rb → spec/alexandria/ui/sound_spec.rb} +6 -11
- data/spec/alexandria/ui/ui_utilities_spec.rb +3 -3
- data/spec/spec_helper.rb +2 -2
- data/util/rake/fileinstall.rb +17 -33
- data/util/rake/gettextgenerate.rb +2 -4
- data/util/rake/omfgenerate.rb +1 -3
- metadata +23 -11
- data/lib/alexandria/ui/gtk_thread_help.rb +0 -89
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (C) 2005-2006 Laurent Sansonetti
|
2
|
-
# Copyright (C) 2011 Matijs van Zuijlen
|
2
|
+
# Copyright (C) 2011, 2016 Matijs van Zuijlen
|
3
3
|
#
|
4
4
|
# Alexandria is free software; you can redistribute it and/or
|
5
5
|
# modify it under the terms of the GNU General Public License as
|
@@ -16,69 +16,73 @@
|
|
16
16
|
# write to the Free Software Foundation, Inc., 51 Franklin Street,
|
17
17
|
# Fifth Floor, Boston, MA 02110-1301 USA.
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def complete_authors
|
25
|
-
complete(Alexandria::UI::CompletionModels::AUTHOR)
|
26
|
-
end
|
19
|
+
module Alexandria
|
20
|
+
module EntryOverrides
|
21
|
+
def complete_titles
|
22
|
+
complete(Alexandria::UI::CompletionModels::TITLE)
|
23
|
+
end
|
27
24
|
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
def complete_authors
|
26
|
+
complete(Alexandria::UI::CompletionModels::AUTHOR)
|
27
|
+
end
|
31
28
|
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
def complete_publishers
|
30
|
+
complete(Alexandria::UI::CompletionModels::PUBLISHER)
|
31
|
+
end
|
35
32
|
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
def complete_editions
|
34
|
+
complete(Alexandria::UI::CompletionModels::EDITION)
|
35
|
+
end
|
39
36
|
|
40
|
-
|
41
|
-
|
42
|
-
# min = self.completion.minimum_key_length
|
43
|
-
min = 2
|
44
|
-
completion.signal_connect('match-selected') do |c, model, iter|
|
45
|
-
cur_text = c.entry.text
|
46
|
-
new_tag = model.get_value(iter, 0)
|
47
|
-
cur_text_split = cur_text.split(',')
|
48
|
-
cur_text_split.delete_at(-1)
|
49
|
-
cur_text_split << new_tag
|
50
|
-
c.entry.text = cur_text_split.join(',')
|
51
|
-
true
|
37
|
+
def complete_borrowers
|
38
|
+
complete(Alexandria::UI::CompletionModels::BORROWER)
|
52
39
|
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
40
|
+
|
41
|
+
def complete_tags
|
42
|
+
complete(Alexandria::UI::CompletionModels::TAG)
|
43
|
+
# min = self.completion.minimum_key_length
|
44
|
+
min = 2
|
45
|
+
completion.signal_connect('match-selected') do |c, model, iter|
|
46
|
+
cur_text = c.entry.text
|
47
|
+
new_tag = model.get_value(iter, 0)
|
48
|
+
cur_text_split = cur_text.split(',')
|
49
|
+
cur_text_split.delete_at(-1)
|
50
|
+
cur_text_split << new_tag
|
51
|
+
c.entry.text = cur_text_split.join(',')
|
52
|
+
true
|
53
|
+
end
|
54
|
+
completion.set_match_func do |_comp, key, iter|
|
55
|
+
cur_tag = key.split(',').last.strip
|
56
|
+
if cur_tag.size >= min
|
57
|
+
begin
|
58
|
+
if iter[0] =~ /^#{cur_tag}/
|
59
|
+
true
|
60
|
+
else
|
61
|
+
false
|
62
|
+
end
|
63
|
+
rescue
|
60
64
|
false
|
61
65
|
end
|
62
|
-
|
66
|
+
else
|
63
67
|
false
|
64
68
|
end
|
65
|
-
else
|
66
|
-
false
|
67
69
|
end
|
68
70
|
end
|
69
|
-
end
|
70
71
|
|
71
|
-
|
72
|
+
private
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
def complete(model_id)
|
75
|
+
completion = Gtk::EntryCompletion.new
|
76
|
+
model = Alexandria::UI::CompletionModels.instance.models[model_id]
|
77
|
+
completion.model = model
|
78
|
+
completion.text_column = 0
|
79
|
+
self.completion = completion
|
80
|
+
end
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
84
|
+
Gtk::Entry.prepend Alexandria::EntryOverrides
|
85
|
+
|
82
86
|
begin
|
83
87
|
require 'revolution'
|
84
88
|
|
@@ -97,14 +101,14 @@ begin
|
|
97
101
|
last = nil if last.empty?
|
98
102
|
end
|
99
103
|
|
100
|
-
first
|
104
|
+
first && last ? first + ' ' + last : first ? first : last
|
101
105
|
end
|
102
106
|
rescue LoadError => e
|
103
107
|
Alexandria.log.debug { 'Could not find optional ruby-revolution; Evolution contacts will not be loaded' }
|
104
|
-
EVOLUTION_CONTACTS = []
|
108
|
+
EVOLUTION_CONTACTS = [].freeze
|
105
109
|
rescue => e
|
106
110
|
Alexandria.log.warn { e.message }
|
107
|
-
EVOLUTION_CONTACTS = []
|
111
|
+
EVOLUTION_CONTACTS = [].freeze
|
108
112
|
end
|
109
113
|
|
110
114
|
module Alexandria
|
@@ -21,7 +21,7 @@ module Alexandria
|
|
21
21
|
include GetText
|
22
22
|
GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
|
23
23
|
|
24
|
-
GPL = <<EOL
|
24
|
+
GPL = <<EOL.freeze
|
25
25
|
Alexandria is free software; you can redistribute it and/or
|
26
26
|
modify it under the terms of the GNU General Public License as
|
27
27
|
published by the Free Software Foundation; either version 2 of the
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Copyright (C) 2004-2006 Laurent Sansonetti
|
2
2
|
# Copyright (C) 2007 Cathal Mc Ginley
|
3
|
-
# Copyright (C) 2011 Matijs van Zuijlen
|
3
|
+
# Copyright (C) 2011, 2016 Matijs van Zuijlen
|
4
4
|
#
|
5
5
|
# Alexandria is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU General Public License as
|
@@ -47,7 +47,7 @@ module Alexandria
|
|
47
47
|
|
48
48
|
def end_search
|
49
49
|
synchronize do
|
50
|
-
@count -= 1 unless
|
50
|
+
@count -= 1 unless @count.zero?
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -136,16 +136,6 @@ module Alexandria
|
|
136
136
|
isbns << isbn
|
137
137
|
end
|
138
138
|
end
|
139
|
-
# remove list items (complex, cf. tutorial...)
|
140
|
-
# http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-treeview-model-remove
|
141
|
-
# row_refs = []
|
142
|
-
# paths = selection.selected_rows
|
143
|
-
# paths.each do |path|
|
144
|
-
# row_refs << Gtk::TreeRowReference.new(model, path)
|
145
|
-
# end
|
146
|
-
# row_refs.each do |ref|
|
147
|
-
# model.remove(model.get_iter(ref.path))
|
148
|
-
# end
|
149
139
|
|
150
140
|
# try it this way... works because of persistent iters
|
151
141
|
row_iters = []
|
@@ -154,13 +144,6 @@ module Alexandria
|
|
154
144
|
isbn = iter[0]
|
155
145
|
if book_in_library(isbn, library)
|
156
146
|
log.debug { "#{isbn} is a duplicate" }
|
157
|
-
# #elsif isbns.include? isbn
|
158
|
-
# this won't work since multiple scans of the same
|
159
|
-
# book have the same isbn (so we can't refrain from removing
|
160
|
-
# one, we'd end up not removing any)
|
161
|
-
## TODO add another column in the iter, like "isbn/01"
|
162
|
-
# that would allow this kind of behaviour...
|
163
|
-
|
164
147
|
elsif !@book_results.key?(isbn) # HAX
|
165
148
|
log.debug { "no book found for #{isbn}, not adding" }
|
166
149
|
|
@@ -197,8 +180,8 @@ module Alexandria
|
|
197
180
|
end
|
198
181
|
end
|
199
182
|
# remove list items
|
200
|
-
if isbn_duplicates.empty?
|
201
|
-
model.clear # TODO unless!!!
|
183
|
+
if isbn_duplicates.empty? && !adding_a_selection
|
184
|
+
model.clear # TODO: unless!!!
|
202
185
|
row_iters.clear
|
203
186
|
else
|
204
187
|
row_iters.each do |iter|
|
@@ -266,7 +249,7 @@ module Alexandria
|
|
266
249
|
barcode_text = @scanner.decode(@scanner_buffer)
|
267
250
|
log.debug { "got barcode text #{barcode_text}" }
|
268
251
|
isbn = Library.canonicalise_isbn(barcode_text)
|
269
|
-
# TODO
|
252
|
+
# TODO: : use an AppFacade
|
270
253
|
# isbn = LookupBook.get_isbn(barcode_text)
|
271
254
|
rescue StandardError => err
|
272
255
|
log.error { "Bad scan: #{@scanner_buffer} #{err}" }
|
@@ -293,11 +276,12 @@ module Alexandria
|
|
293
276
|
# begin copy-n-paste from new_book_dialog
|
294
277
|
|
295
278
|
def notify_start_add_by_isbn
|
296
|
-
|
279
|
+
GLib::Idle.add do
|
297
280
|
main_progress_bar = MainApp.instance.appbar.children.first
|
298
281
|
main_progress_bar.visible = true
|
299
|
-
@progress_pulsing =
|
282
|
+
@progress_pulsing = GLib::Timeout.add(100) do
|
300
283
|
if @destroyed
|
284
|
+
@progress_pulsing = nil
|
301
285
|
false
|
302
286
|
else
|
303
287
|
main_progress_bar.pulse
|
@@ -309,15 +293,15 @@ module Alexandria
|
|
309
293
|
end
|
310
294
|
|
311
295
|
def notify_end_add_by_isbn
|
312
|
-
|
296
|
+
GLib::Idle.add do
|
313
297
|
MainApp.instance.appbar.children.first.visible = false
|
314
|
-
|
298
|
+
GLib::Source.remove(@progress_pulsing) if @progress_pulsing
|
315
299
|
false
|
316
300
|
end
|
317
301
|
end
|
318
302
|
|
319
303
|
def update(status, provider)
|
320
|
-
|
304
|
+
GLib::Idle.add do
|
321
305
|
messages = {
|
322
306
|
searching: _("Searching Provider '%s'..."),
|
323
307
|
error: _("Error while Searching Provider '%s'"),
|
@@ -326,7 +310,6 @@ module Alexandria
|
|
326
310
|
}
|
327
311
|
message = messages[status] % provider
|
328
312
|
log.debug { "update message : #{message}" }
|
329
|
-
# @parent.appbar.status = message
|
330
313
|
MainApp.instance.ui_manager.set_status_label(message)
|
331
314
|
false
|
332
315
|
end
|
@@ -338,7 +321,7 @@ module Alexandria
|
|
338
321
|
|
339
322
|
def start_search
|
340
323
|
@search_thread_counter.synchronize do
|
341
|
-
if @search_thread_counter.count
|
324
|
+
if @search_thread_counter.count.zero?
|
342
325
|
@search_thread_counter.new_search
|
343
326
|
@progress_bar_thread = Thread.new do
|
344
327
|
notify_start_add_by_isbn
|
@@ -373,7 +356,7 @@ module Alexandria
|
|
373
356
|
cover_uri = results[1]
|
374
357
|
@book_results[isbn] = results
|
375
358
|
set_cover_image_async(isbn, cover_uri)
|
376
|
-
|
359
|
+
|
377
360
|
@barcodes_treeview.model.freeze_notify do
|
378
361
|
@barcodes_treeview.model.each do |model, path, iter|
|
379
362
|
if iter[0] == isbn
|
@@ -406,7 +389,7 @@ module Alexandria
|
|
406
389
|
else
|
407
390
|
image_data = URI.parse(cover_uri).read
|
408
391
|
end
|
409
|
-
loader =
|
392
|
+
loader = GdkPixbuf::PixbufLoader.new
|
410
393
|
loader.last_write(image_data)
|
411
394
|
pixbuf = loader.pixbuf
|
412
395
|
else
|
@@ -435,7 +418,7 @@ module Alexandria
|
|
435
418
|
def on_destroy
|
436
419
|
MainApp.instance.ui_manager.set_status_label('')
|
437
420
|
notify_end_add_by_isbn
|
438
|
-
# TODO possibly make sure all threads have stopped running
|
421
|
+
# TODO: possibly make sure all threads have stopped running
|
439
422
|
@animation.destroy
|
440
423
|
end
|
441
424
|
|
@@ -443,7 +426,7 @@ module Alexandria
|
|
443
426
|
@scanner_buffer = ''
|
444
427
|
scanner_name = @prefs.barcode_scanner
|
445
428
|
|
446
|
-
@
|
429
|
+
@scanner = Alexandria::Scanners.find_scanner scanner_name ||
|
447
430
|
Alexandria::Scanners.default_scanner # CueCat is default
|
448
431
|
|
449
432
|
log.debug { "Using #{@scanner.name} scanner" }
|
@@ -515,7 +498,7 @@ module Alexandria
|
|
515
498
|
|
516
499
|
Thread.new(@interval, @scanner_buffer) do |interval, buffer|
|
517
500
|
log.debug { 'Waiting for more scanner input...' }
|
518
|
-
|
501
|
+
GLib::Idle.add do
|
519
502
|
@animation.manual_input
|
520
503
|
false
|
521
504
|
end
|
@@ -523,7 +506,7 @@ module Alexandria
|
|
523
506
|
sleep(time_to_wait)
|
524
507
|
if buffer == @scanner_buffer
|
525
508
|
log.debug { 'Buffer unchanged; scanning complete' }
|
526
|
-
|
509
|
+
GLib::Idle.add do
|
527
510
|
@animation.scanner_input
|
528
511
|
false
|
529
512
|
end
|
@@ -550,24 +533,15 @@ module Alexandria
|
|
550
533
|
end
|
551
534
|
|
552
535
|
def play_sound(effect)
|
553
|
-
# HACK, do some thread waiting, if possible
|
554
|
-
puts "scanning sound : #{@prefs.play_scanning_sound}"
|
555
|
-
puts "scan sound: #{@prefs.play_scan_sound}"
|
556
536
|
if effect == 'scanning'
|
557
|
-
puts effect
|
537
|
+
puts "Effect: #{effect}, playing: #{@prefs.play_scanning_sound}" if $DEBUG
|
558
538
|
return unless @prefs.play_scanning_sound
|
559
|
-
|
560
|
-
@sound_players['scanning'].play('scanning')
|
561
|
-
false
|
562
|
-
end
|
539
|
+
@sound_players['scanning'].play('scanning')
|
563
540
|
else
|
564
|
-
puts effect
|
541
|
+
puts "Effect: #{effect}, playing: #{@prefs.play_scan_sound}" if $DEBUG
|
565
542
|
return unless @prefs.play_scan_sound
|
566
|
-
|
567
|
-
|
568
|
-
@sound_players[effect].play(effect)
|
569
|
-
false
|
570
|
-
end
|
543
|
+
# sleep(0.5) # "scanning" effect lasts 0.5 seconds, wait for it to end
|
544
|
+
@sound_players[effect].play(effect)
|
571
545
|
end
|
572
546
|
end
|
573
547
|
|
@@ -590,9 +564,9 @@ module Alexandria
|
|
590
564
|
end
|
591
565
|
|
592
566
|
def init_treeview
|
593
|
-
liststore = Gtk::ListStore.new(String,
|
567
|
+
liststore = Gtk::ListStore.new(String, GdkPixbuf::Pixbuf, String)
|
594
568
|
|
595
|
-
@barcodes_treeview.selection.mode =
|
569
|
+
@barcodes_treeview.selection.mode = :multiple
|
596
570
|
|
597
571
|
@barcodes_treeview.model = liststore
|
598
572
|
|
@@ -20,23 +20,24 @@ module Alexandria
|
|
20
20
|
module UI
|
21
21
|
class AlertDialog < Gtk::Dialog
|
22
22
|
def initialize(parent, title, stock_icon, buttons, message = nil)
|
23
|
-
super('', parent,
|
23
|
+
super(title: '', parent: parent, flags: :destroy_with_parent, buttons: buttons)
|
24
24
|
|
25
25
|
self.border_width = 6
|
26
26
|
self.resizable = false
|
27
|
-
|
28
|
-
vbox.spacing = 12
|
27
|
+
child.spacing = 12
|
29
28
|
|
30
|
-
hbox = Gtk::
|
29
|
+
hbox = Gtk::Box.new(:horizontal, 12)
|
30
|
+
hbox.homogeneous = false
|
31
31
|
hbox.border_width = 6
|
32
|
-
|
32
|
+
child.pack_start(hbox)
|
33
33
|
|
34
|
-
image = Gtk::Image.new(stock_icon,
|
35
|
-
Gtk::IconSize::DIALOG)
|
34
|
+
image = Gtk::Image.new(stock: stock_icon,
|
35
|
+
size: Gtk::IconSize::DIALOG)
|
36
36
|
image.set_alignment(0.5, 0)
|
37
37
|
hbox.pack_start(image)
|
38
38
|
|
39
|
-
vbox = Gtk::
|
39
|
+
vbox = Gtk::Box.new(:vertical, 6)
|
40
|
+
vbox.homogeneous = false
|
40
41
|
hbox.pack_start(vbox)
|
41
42
|
|
42
43
|
label = Gtk::Label.new
|
@@ -58,9 +59,10 @@ module Alexandria
|
|
58
59
|
class ErrorDialog < AlertDialog
|
59
60
|
def initialize(parent, title, message = nil)
|
60
61
|
super(parent, title, Gtk::Stock::DIALOG_ERROR,
|
61
|
-
[[Gtk::Stock::OK,
|
62
|
-
|
63
|
-
|
62
|
+
[[Gtk::Stock::OK, :ok]], message)
|
63
|
+
# FIXME: Should accept just :ok
|
64
|
+
self.default_response = Gtk::ResponseType::OK
|
65
|
+
show_all && run
|
64
66
|
destroy
|
65
67
|
end
|
66
68
|
end
|
@@ -22,8 +22,8 @@ module Alexandria
|
|
22
22
|
class BadIsbnsDialog < Gtk::MessageDialog
|
23
23
|
def initialize(parent, message = nil, list = nil)
|
24
24
|
message = _("There's a problem") unless message
|
25
|
-
super(parent, Gtk::Dialog::MODAL, Gtk::MessageDialog::WARNING,
|
26
|
-
isbn_container = Gtk::
|
25
|
+
super(parent, Gtk::Dialog::MODAL, Gtk::MessageDialog::WARNING, Gtk::MessageDialog::BUTTONS_CLOSE, message)
|
26
|
+
isbn_container = Gtk::Box.new :horizontal
|
27
27
|
the_vbox = children.first
|
28
28
|
the_vbox.pack_start(isbn_container)
|
29
29
|
the_vbox.reorder_child(isbn_container, 3)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
#--
|
3
3
|
# Copyright (C) 2011 Cathal Mc Ginley
|
4
|
-
# Copyright (C) 2011 Matijs van Zuijlen
|
4
|
+
# Copyright (C) 2011, 2016 Matijs van Zuijlen
|
5
5
|
#
|
6
6
|
# This file is part of Alexandria, a GNOME book collection manager.
|
7
7
|
#
|
@@ -21,7 +21,29 @@
|
|
21
21
|
# Boston, MA 02110-1301 USA.
|
22
22
|
#++
|
23
23
|
|
24
|
-
|
24
|
+
require 'gobject-introspection'
|
25
|
+
|
26
|
+
module GooCanvas
|
27
|
+
class << self
|
28
|
+
def const_missing(name)
|
29
|
+
init
|
30
|
+
if const_defined?(name)
|
31
|
+
const_get(name)
|
32
|
+
else
|
33
|
+
super
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def init
|
38
|
+
class << self
|
39
|
+
remove_method(:init)
|
40
|
+
remove_method(:const_missing)
|
41
|
+
end
|
42
|
+
loader = GObjectIntrospection::Loader.new(self)
|
43
|
+
loader.load('GooCanvas')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
25
47
|
|
26
48
|
module Alexandria
|
27
49
|
module UI
|
@@ -29,7 +51,7 @@ module Alexandria
|
|
29
51
|
attr_reader :canvas
|
30
52
|
|
31
53
|
def initialize
|
32
|
-
@canvas =
|
54
|
+
@canvas = GooCanvas::Canvas.new
|
33
55
|
@canvas.set_size_request(300, 70)
|
34
56
|
@canvas.set_bounds(0, 0, 350, 70)
|
35
57
|
@root = @canvas.root_item
|
@@ -55,7 +77,7 @@ module Alexandria
|
|
55
77
|
end
|
56
78
|
|
57
79
|
def start
|
58
|
-
@timeout =
|
80
|
+
@timeout = GLib::Timeout.add(20) do
|
59
81
|
scan_animation
|
60
82
|
(@index >= 0)
|
61
83
|
end
|
@@ -80,12 +102,12 @@ module Alexandria
|
|
80
102
|
end
|
81
103
|
|
82
104
|
def manual_input
|
83
|
-
# TODO distinguish between scanner and manual input
|
105
|
+
# TODO: distinguish between scanner and manual input
|
84
106
|
# @canvas.set_property(:background_color, "#FFF8C0")
|
85
107
|
end
|
86
108
|
|
87
109
|
def scanner_input
|
88
|
-
# TODO distinguish between scanner and manual input
|
110
|
+
# TODO: distinguish between scanner and manual input
|
89
111
|
# @canvas.set_property(:background_color, "white")
|
90
112
|
end
|
91
113
|
|
@@ -94,7 +116,7 @@ module Alexandria
|
|
94
116
|
def create_ean_barcode_data
|
95
117
|
d = '211113123121112331122131113211111123122211132321112311231111'
|
96
118
|
# ####911113... but that's too much padding on the left...
|
97
|
-
|
119
|
+
until d.empty?
|
98
120
|
space_width = d[0].chr.to_i
|
99
121
|
bar_width = d[1].chr.to_i
|
100
122
|
d = d[2..-1]
|
@@ -105,11 +127,11 @@ module Alexandria
|
|
105
127
|
def draw_barcode_bars
|
106
128
|
@barcode_data.each do |space_width, bar_width|
|
107
129
|
@hpos += space_width
|
108
|
-
rect_item =
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
130
|
+
rect_item = GooCanvas::CanvasRect.new(parent: @root,
|
131
|
+
x: @bar_left_edge + @scale * @hpos, y: @bar_top,
|
132
|
+
width: @scale * bar_width, height: @bar_height,
|
133
|
+
line_width: 0,
|
134
|
+
fill_color: 'white')
|
113
135
|
@hpos += bar_width
|
114
136
|
@barcode_bars << rect_item
|
115
137
|
end
|
@@ -117,22 +139,18 @@ module Alexandria
|
|
117
139
|
|
118
140
|
def scan_animation
|
119
141
|
if @index < @barcode_bars.size
|
120
|
-
if @index < 0
|
121
|
-
@index = 0
|
122
|
-
end
|
142
|
+
@index = 0 if @index < 0
|
123
143
|
alpha = 7 * (@index + 1)
|
124
144
|
@barcode_bars.each_with_index do |rect, i|
|
125
145
|
rect.set_property(:fill_color_rgba, 0xFF000000 + alpha)
|
126
|
-
if i >= @index
|
127
|
-
break
|
128
|
-
end
|
146
|
+
break if i >= @index
|
129
147
|
end
|
130
148
|
@index += 1
|
131
149
|
else
|
132
150
|
@index = -1
|
133
|
-
|
151
|
+
GLib::Timeout.add(5) do
|
134
152
|
@barcode_bars.each { |rect| rect.set_property(:fill_color_rgba, 0x000000C0) }
|
135
|
-
|
153
|
+
GLib::Timeout.add(15) do
|
136
154
|
fade_animation
|
137
155
|
(@fade_opacity != -1)
|
138
156
|
end
|
@@ -143,9 +161,7 @@ module Alexandria
|
|
143
161
|
end
|
144
162
|
|
145
163
|
def fade_animation
|
146
|
-
if @fade_opacity == -1
|
147
|
-
@fade_opacity = 255
|
148
|
-
end
|
164
|
+
@fade_opacity = 255 if @fade_opacity == -1
|
149
165
|
if @fade_opacity >= 0
|
150
166
|
grey = 0x00000000 + @fade_opacity
|
151
167
|
@barcode_bars.each { |rect| rect.set_property(:fill_color_rgba, grey) }
|