alexandria-book-collection-manager 0.7.6 → 0.7.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +77 -0
- data/CHANGELOG.md +8 -0
- data/lib/alexandria/export_library.rb +8 -5
- data/lib/alexandria/ui/book_properties_dialog_base.rb +4 -107
- data/lib/alexandria/ui/calendar_popup.rb +58 -0
- data/lib/alexandria/ui/export_dialog.rb +6 -3
- data/lib/alexandria/ui/import_dialog.rb +2 -2
- data/lib/alexandria/ui/smart_library_properties_dialog_base.rb +2 -106
- data/lib/alexandria/ui/smart_library_rule_box.rb +1 -1
- data/lib/alexandria/version.rb +2 -2
- data/po/pl.po +2 -10
- data/spec/alexandria/ui/export_dialog_spec.rb +24 -3
- data/spec/alexandria/ui/import_dialog_spec.rb +5 -0
- data/spec/alexandria/ui/smart_library_properties_dialog_spec.rb +25 -8
- data/spec/end_to_end/basic_run_spec.rb +3 -8
- data/spec/spec_helper.rb +1 -0
- metadata +4 -3
- data/.travis.yml +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88a834cc5346bc0704749533797d91e6ff2a04c372e066fe9f91ca239baa63f1
|
4
|
+
data.tar.gz: 4a68efa9e12431f6ea356325b4bcee4a702a7f1f49710860a399657866c158e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 213ed219cd387370ff664b32b108aff3e6655e07579962f436f013616e02e423ef17afb6ed6bc6f036d2c5de863a9b51f8c5d5de5e8f33b9a51a0dff6522da61
|
7
|
+
data.tar.gz: c6440f573914defb43a7a9f451a4cf5e9091275039137c4dabd02d2290c72e87a17d35f62db08f7669d1a66f51ea53e5ef1b1e170cdd3beea237df1d3a1f5dd4
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and
|
2
|
+
# run tests with Rake
|
3
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
4
|
+
|
5
|
+
name: Ruby
|
6
|
+
|
7
|
+
on:
|
8
|
+
push:
|
9
|
+
branches: [ master ]
|
10
|
+
pull_request:
|
11
|
+
branches: [ master ]
|
12
|
+
|
13
|
+
jobs:
|
14
|
+
test:
|
15
|
+
|
16
|
+
runs-on: ubuntu-latest
|
17
|
+
|
18
|
+
strategy:
|
19
|
+
matrix:
|
20
|
+
ruby: [2.5, 2.6, 2.7]
|
21
|
+
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v2
|
24
|
+
- name: Install non-ruby dependencies
|
25
|
+
run: |
|
26
|
+
# Needed for gtk3 gem
|
27
|
+
sudo apt-get install libgtk-3-dev
|
28
|
+
# Needed for gstreamer gem
|
29
|
+
sudo apt-get install libgstreamer1.0-dev
|
30
|
+
# Needed for GooCanvas::Canvas widget
|
31
|
+
sudo apt-get install libgoocanvas-2.0-dev
|
32
|
+
# Needed for zoom gem
|
33
|
+
sudo apt-get install libyaz-dev
|
34
|
+
# Needed for intltool-merge executable
|
35
|
+
sudo apt-get install intltool
|
36
|
+
# Needed for gconftool-2 executable
|
37
|
+
sudo apt-get install gconf2
|
38
|
+
# Needed to provide A11y dbus service to silence warnings
|
39
|
+
sudo apt-get install at-spi2-core
|
40
|
+
# Needed to set up sound player pipeline
|
41
|
+
sudo apt-get install gstreamer1.0-plugins-good
|
42
|
+
# Needed to play sound
|
43
|
+
sudo apt-get install pulseaudio
|
44
|
+
# Provides xvfb-run
|
45
|
+
sudo apt-get install xvfb
|
46
|
+
|
47
|
+
- name: Set up Ruby
|
48
|
+
uses: ruby/setup-ruby@v1
|
49
|
+
with:
|
50
|
+
ruby-version: ${{ matrix.ruby }}
|
51
|
+
bundler-cache: true
|
52
|
+
- name: Run unit tests
|
53
|
+
run: xvfb-run bundle exec rake spec:unit
|
54
|
+
- name: Run end-to-end tests in a dbus session
|
55
|
+
run: xvfb-run dbus-run-session bundle exec rake spec:end_to_end
|
56
|
+
|
57
|
+
rubocop:
|
58
|
+
|
59
|
+
runs-on: ubuntu-latest
|
60
|
+
|
61
|
+
steps:
|
62
|
+
- uses: actions/checkout@v2
|
63
|
+
- name: Install non-ruby dependencies
|
64
|
+
run: |
|
65
|
+
# Needed for gtk3 gem
|
66
|
+
sudo apt-get install libgtk-3-dev
|
67
|
+
# Needed for gstreamer gem
|
68
|
+
sudo apt-get install libgstreamer1.0-dev
|
69
|
+
# Needed for zoom gem
|
70
|
+
sudo apt-get install libyaz-dev
|
71
|
+
- name: Set up Ruby
|
72
|
+
uses: ruby/setup-ruby@v1
|
73
|
+
with:
|
74
|
+
ruby-version: 2.7
|
75
|
+
bundler-cache: true
|
76
|
+
- name: Run RuboCop
|
77
|
+
run: bundle exec rubocop -P
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.7.7 / 2020-11-15
|
4
|
+
|
5
|
+
* Update Polish translation ([#88] by [Piotr Drąg][piotrdrag])
|
6
|
+
* Fix hiding of progress bar of import dialog
|
7
|
+
* Fix calendar popups in Smart Library and Book Properties dialogs
|
8
|
+
* Fix crashes when activating Export and Import menu items
|
9
|
+
|
3
10
|
## 0.7.6 / 2020-11-01
|
4
11
|
|
5
12
|
* Make more strings translatable with help from rubocop-i18n
|
@@ -100,6 +107,7 @@
|
|
100
107
|
[HappyFacade]: https://github.com/HappyFacade
|
101
108
|
|
102
109
|
<!-- issues and pull requests -->
|
110
|
+
[#88]: https://github.com/mvz/alexandria-book-collection-manager/pull/88
|
103
111
|
[#83]: https://github.com/mvz/alexandria-book-collection-manager/pull/83
|
104
112
|
[#64]: https://github.com/mvz/alexandria-book-collection-manager/pull/64
|
105
113
|
[#51]: https://github.com/mvz/alexandria-book-collection-manager/pull/51
|
@@ -36,16 +36,19 @@ module Alexandria
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def export_as_onix_xml_archive(filename)
|
39
|
-
|
39
|
+
dir = Dir.mktmpdir
|
40
|
+
File.open(File.join(dir, "onix.xml"), "w") do |io|
|
40
41
|
to_onix_document.write(io, 0)
|
41
42
|
end
|
42
|
-
copy_covers(File.join(
|
43
|
-
Dir.chdir(
|
43
|
+
copy_covers(File.join(dir, "images"))
|
44
|
+
Dir.chdir(dir) do
|
44
45
|
output = `tar -cjf \"#{filename}\" onix.xml images 2>&1`
|
45
46
|
raise output unless $CHILD_STATUS.success?
|
46
47
|
end
|
47
|
-
FileUtils.rm_rf(File.join(
|
48
|
-
FileUtils.rm(File.join(
|
48
|
+
FileUtils.rm_rf(File.join(dir, "images"))
|
49
|
+
FileUtils.rm(File.join(dir, "onix.xml"))
|
50
|
+
ensure
|
51
|
+
FileUtils.remove_entry dir
|
49
52
|
end
|
50
53
|
|
51
54
|
def export_as_tellico_xml_archive(filename)
|
@@ -5,11 +5,13 @@
|
|
5
5
|
# See the file README.md for authorship and licensing information.
|
6
6
|
|
7
7
|
require "alexandria/ui/builder_base"
|
8
|
+
require "alexandria/ui/calendar_popup"
|
8
9
|
require "alexandria/ui/error_dialog"
|
9
10
|
|
10
11
|
module Alexandria
|
11
12
|
module UI
|
12
13
|
class BookPropertiesDialogBase < BuilderBase
|
14
|
+
include CalendarPopup
|
13
15
|
include GetText
|
14
16
|
extend GetText
|
15
17
|
GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
@@ -51,7 +53,7 @@ module Alexandria
|
|
51
53
|
editable: 1)
|
52
54
|
@treeview_authors.append_column(col)
|
53
55
|
|
54
|
-
|
56
|
+
setup_date_widgets
|
55
57
|
GLib::Timeout.add(150) do
|
56
58
|
@setup_finished = true
|
57
59
|
|
@@ -63,53 +65,7 @@ module Alexandria
|
|
63
65
|
@book_properties_dialog.show
|
64
66
|
end
|
65
67
|
|
66
|
-
def
|
67
|
-
@popup_displayed = false
|
68
|
-
@calendar_popup = Gtk::Window.new # Gtk::Window::POPUP)
|
69
|
-
# @calendar_popup.modal = true
|
70
|
-
@calendar_popup.decorated = false
|
71
|
-
@calendar_popup.skip_taskbar_hint = true
|
72
|
-
@calendar_popup.skip_pager_hint = true
|
73
|
-
@calendar_popup.events = [:focus_change_mask]
|
74
|
-
|
75
|
-
@calendar_popup.set_transient_for(@book_properties_dialog)
|
76
|
-
@calendar_popup.set_type_hint :dialog
|
77
|
-
@calendar_popup.name = "calendar-popup"
|
78
|
-
@calendar_popup.resizable = false
|
79
|
-
# @calendar_popup.border_width = 4
|
80
|
-
# @calendar_popup.app_paintable = true
|
81
|
-
|
82
|
-
@calendar_popup.signal_connect("focus-out-event") do |_popup, _event|
|
83
|
-
hide_calendar_popup
|
84
|
-
false
|
85
|
-
end
|
86
|
-
|
87
|
-
@calendar = Gtk::Calendar.new
|
88
|
-
@calendar_popup.add(@calendar)
|
89
|
-
|
90
|
-
@calendar.signal_connect("day-selected") do
|
91
|
-
date_arr = @calendar.date
|
92
|
-
year = date_arr[0]
|
93
|
-
month = date_arr[1] # + 1 # gtk : months 0-indexed, Time.gm : 1-index
|
94
|
-
day = date_arr[2]
|
95
|
-
if @calendar_popup_for_entry
|
96
|
-
time = Time.gm(year, month, day)
|
97
|
-
@calendar_popup_for_entry.text = format_date(time)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
@calendar.signal_connect("day-selected-double-click") do
|
102
|
-
date_arr = @calendar.date
|
103
|
-
year = date_arr[0]
|
104
|
-
month = date_arr[1] # + 1 # gtk : months 0-indexed, Time.gm : 1-index
|
105
|
-
day = date_arr[2]
|
106
|
-
if @calendar_popup_for_entry
|
107
|
-
time = Time.gm(year, month, day)
|
108
|
-
@calendar_popup_for_entry.text = format_date(time)
|
109
|
-
end
|
110
|
-
hide_calendar_popup
|
111
|
-
end
|
112
|
-
|
68
|
+
def setup_date_widgets
|
113
69
|
@redd_date.signal_connect("icon-press") do |entry, primary, _icon|
|
114
70
|
case primary.nick
|
115
71
|
when "primary"
|
@@ -130,65 +86,6 @@ module Alexandria
|
|
130
86
|
end
|
131
87
|
end
|
132
88
|
|
133
|
-
def clear_date_entry(entry)
|
134
|
-
entry.text = ""
|
135
|
-
end
|
136
|
-
|
137
|
-
def hide_calendar_popup
|
138
|
-
@calendar_popup_for_entry = nil
|
139
|
-
|
140
|
-
@calendar_popup.hide_all
|
141
|
-
@book_properties_dialog.modal = true
|
142
|
-
|
143
|
-
GLib::Timeout.add(150) do
|
144
|
-
# If we set @popup_displayed=false immediately, then a click
|
145
|
-
# event on the primary icon of the Entry simultaneous with
|
146
|
-
# the focus-out-event of the Calendar causes the Calendar to
|
147
|
-
# pop up again milliseconds after being closed.
|
148
|
-
#
|
149
|
-
# This is never what the user intends.
|
150
|
-
#
|
151
|
-
# So we add a small delay before the primary icon's event
|
152
|
-
# handler is told to pop up the calendar in response to
|
153
|
-
# clicks.
|
154
|
-
|
155
|
-
@popup_displayed = false
|
156
|
-
false
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def display_calendar_popup(entry)
|
161
|
-
if @popup_displayed
|
162
|
-
hide_calendar_popup
|
163
|
-
else
|
164
|
-
@calendar_popup_for_entry = entry
|
165
|
-
unless entry.text.strip.empty?
|
166
|
-
time = parse_date(entry.text)
|
167
|
-
unless time.nil?
|
168
|
-
@calendar.year = time.year
|
169
|
-
@calendar.month = time.month - 1
|
170
|
-
@calendar.day = time.day
|
171
|
-
end
|
172
|
-
end
|
173
|
-
@book_properties_dialog.modal = false
|
174
|
-
@calendar_popup.move(*get_entry_popup_coords(entry))
|
175
|
-
@calendar_popup.show_all
|
176
|
-
@popup_displayed = true
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def get_entry_popup_coords(entry)
|
181
|
-
gdk_win = entry.parent_window
|
182
|
-
x, y = gdk_win.origin
|
183
|
-
alloc = entry.allocation
|
184
|
-
x += alloc.x
|
185
|
-
y += alloc.y
|
186
|
-
y += alloc.height
|
187
|
-
# x = [0, x].max
|
188
|
-
# y = [0, y].max
|
189
|
-
[x, y]
|
190
|
-
end
|
191
|
-
|
192
89
|
def widget_names
|
193
90
|
[:book_properties_dialog, :button_box, :button_cover,
|
194
91
|
:checkbutton_loaned, :checkbutton_own, :checkbutton_redd,
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of Alexandria.
|
4
|
+
#
|
5
|
+
# See the file README.md for authorship and licensing information.
|
6
|
+
|
7
|
+
module Alexandria
|
8
|
+
module UI
|
9
|
+
module CalendarPopup
|
10
|
+
def setup_calendar_widgets
|
11
|
+
@calendar_popup = Gtk::Popover.new
|
12
|
+
@calendar_popup.position = :bottom
|
13
|
+
|
14
|
+
@calendar = Gtk::Calendar.new
|
15
|
+
@calendar.show
|
16
|
+
@calendar_popup.add(@calendar)
|
17
|
+
|
18
|
+
@calendar.signal_connect("day-selected") do
|
19
|
+
assign_selected_date
|
20
|
+
end
|
21
|
+
|
22
|
+
@calendar.signal_connect("day-selected-double-click") do
|
23
|
+
assign_selected_date
|
24
|
+
@calendar_popup.hide
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def assign_selected_date
|
29
|
+
date_arr = @calendar.date
|
30
|
+
year = date_arr[0]
|
31
|
+
month = date_arr[1] # + 1 # gtk : months 0-indexed, Time.gm : 1-index
|
32
|
+
day = date_arr[2]
|
33
|
+
time = Time.gm(year, month, day)
|
34
|
+
@calendar_popup_for_entry.text = format_date(time)
|
35
|
+
end
|
36
|
+
|
37
|
+
def clear_date_entry(entry)
|
38
|
+
entry.text = ""
|
39
|
+
end
|
40
|
+
|
41
|
+
def display_calendar_popup(entry)
|
42
|
+
setup_calendar_widgets unless defined? @calendar_popup
|
43
|
+
|
44
|
+
@calendar_popup_for_entry = entry
|
45
|
+
unless entry.text.strip.empty?
|
46
|
+
time = parse_date(entry.text)
|
47
|
+
unless time.nil?
|
48
|
+
@calendar.year = time.year
|
49
|
+
@calendar.month = time.month - 1
|
50
|
+
@calendar.day = time.day
|
51
|
+
end
|
52
|
+
end
|
53
|
+
@calendar_popup.set_relative_to(entry)
|
54
|
+
@calendar_popup.popup
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -18,6 +18,8 @@ module Alexandria
|
|
18
18
|
FORMATS = Alexandria::ExportFormat.all
|
19
19
|
THEMES = Alexandria::WebTheme.all
|
20
20
|
|
21
|
+
attr_reader :dialog
|
22
|
+
|
21
23
|
def initialize(parent, library, sort_order)
|
22
24
|
@dialog = Gtk::FileChooserDialog.new(title: _("Export '%s'") % library.name,
|
23
25
|
parent: parent,
|
@@ -86,7 +88,7 @@ module Alexandria
|
|
86
88
|
end
|
87
89
|
|
88
90
|
def perform
|
89
|
-
while ((response = run) != Gtk::ResponseType::CANCEL) &&
|
91
|
+
while ((response = dialog.run) != Gtk::ResponseType::CANCEL) &&
|
90
92
|
(response != Gtk::ResponseType::DELETE_EVENT)
|
91
93
|
|
92
94
|
if response == Gtk::ResponseType::HELP
|
@@ -97,16 +99,17 @@ module Alexandria
|
|
97
99
|
THEMES[@theme_combo.active])
|
98
100
|
rescue StandardError => ex
|
99
101
|
ErrorDialog.new(@dialog, _("Export failed"), ex.message).display
|
102
|
+
break
|
100
103
|
end
|
101
104
|
end
|
102
105
|
end
|
103
|
-
destroy
|
106
|
+
dialog.destroy
|
104
107
|
end
|
105
108
|
|
106
109
|
private
|
107
110
|
|
108
111
|
def on_export(format, theme)
|
109
|
-
filename =
|
112
|
+
filename = dialog.filename
|
110
113
|
if format.ext
|
111
114
|
filename += "." + format.ext if File.extname(filename).empty?
|
112
115
|
if File.exist?(filename)
|
@@ -48,7 +48,7 @@ module Alexandria
|
|
48
48
|
end
|
49
49
|
|
50
50
|
dialog.signal_connect("selection_changed") do
|
51
|
-
import_button.sensitive = filename && File.file?(filename)
|
51
|
+
import_button.sensitive = dialog.filename && File.file?(dialog.filename)
|
52
52
|
end
|
53
53
|
|
54
54
|
# before adding the (hidden) progress bar, we must re-set the
|
@@ -136,7 +136,7 @@ module Alexandria
|
|
136
136
|
"provided is unknown. Please " \
|
137
137
|
"retry with another file.")).display
|
138
138
|
end
|
139
|
-
pbar.hide
|
139
|
+
@pbar.hide
|
140
140
|
self.sensitive = true
|
141
141
|
end
|
142
142
|
end
|
@@ -4,12 +4,14 @@
|
|
4
4
|
#
|
5
5
|
# See the file README.md for authorship and licensing information.
|
6
6
|
|
7
|
+
require "alexandria/ui/calendar_popup"
|
7
8
|
require "alexandria/ui/smart_library_rule_box"
|
8
9
|
|
9
10
|
module Alexandria
|
10
11
|
module UI
|
11
12
|
class SmartLibraryPropertiesDialogBase
|
12
13
|
include Logging
|
14
|
+
include CalendarPopup
|
13
15
|
include GetText
|
14
16
|
GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: "UTF-8")
|
15
17
|
|
@@ -49,7 +51,6 @@ module Alexandria
|
|
49
51
|
|
50
52
|
main_box.pack_start(@rules_header_box, expand: false, fill: false)
|
51
53
|
main_box << scrollview
|
52
|
-
setup_calendar_widgets
|
53
54
|
end
|
54
55
|
|
55
56
|
def handle_date_icon_press(widget, primary, _icon)
|
@@ -221,111 +222,6 @@ module Alexandria
|
|
221
222
|
end
|
222
223
|
end
|
223
224
|
|
224
|
-
# COPIED and PASTED from book_properties_dialog_base
|
225
|
-
|
226
|
-
def setup_calendar_widgets
|
227
|
-
@popup_displayed = false
|
228
|
-
@calendar_popup = Gtk::Window.new # Gtk::Window::POPUP)
|
229
|
-
# @calendar_popup.modal = true
|
230
|
-
@calendar_popup.decorated = false
|
231
|
-
@calendar_popup.skip_taskbar_hint = true
|
232
|
-
@calendar_popup.skip_pager_hint = true
|
233
|
-
@calendar_popup.events = [:focus_change_mask]
|
234
|
-
|
235
|
-
@calendar_popup.set_transient_for(@dialog)
|
236
|
-
@calendar_popup.set_type_hint(:dialog)
|
237
|
-
@calendar_popup.name = "calendar-popup"
|
238
|
-
@calendar_popup.resizable = false
|
239
|
-
# @calendar_popup.border_width = 4
|
240
|
-
# @calendar_popup.app_paintable = true
|
241
|
-
|
242
|
-
@calendar_popup.signal_connect("focus-out-event") do |_popup, _event|
|
243
|
-
hide_calendar_popup
|
244
|
-
false
|
245
|
-
end
|
246
|
-
|
247
|
-
@calendar = Gtk::Calendar.new
|
248
|
-
@calendar_popup.add(@calendar)
|
249
|
-
|
250
|
-
@calendar.signal_connect("day-selected") do
|
251
|
-
date_arr = @calendar.date
|
252
|
-
year = date_arr[0]
|
253
|
-
month = date_arr[1] # + 1 # gtk : months 0-indexed, Time.gm : 1-index
|
254
|
-
day = date_arr[2]
|
255
|
-
if @calendar_popup_for_entry
|
256
|
-
time = Time.gm(year, month, day)
|
257
|
-
@calendar_popup_for_entry.text = format_date(time)
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
@calendar.signal_connect("day-selected-double-click") do
|
262
|
-
date_arr = @calendar.date
|
263
|
-
year = date_arr[0]
|
264
|
-
month = date_arr[1] # + 1 # gtk : months 0-indexed, Time.gm : 1-index
|
265
|
-
day = date_arr[2]
|
266
|
-
if @calendar_popup_for_entry
|
267
|
-
time = Time.gm(year, month, day)
|
268
|
-
@calendar_popup_for_entry.text = format_date(time)
|
269
|
-
end
|
270
|
-
hide_calendar_popup
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
def hide_calendar_popup
|
275
|
-
@calendar_popup_for_entry = nil
|
276
|
-
|
277
|
-
@calendar_popup.hide_all
|
278
|
-
self.modal = true
|
279
|
-
|
280
|
-
GLib::Timeout.add(150) do
|
281
|
-
# If we set @popup_displayed=false immediately, then a click
|
282
|
-
# event on the primary icon of the Entry simultaneous with
|
283
|
-
# the focus-out-event of the Calendar causes the Calendar to
|
284
|
-
# pop up again milliseconds after being closed.
|
285
|
-
#
|
286
|
-
# This is never what the user intends.
|
287
|
-
#
|
288
|
-
# So we add a small delay before the primary icon's event
|
289
|
-
# handler is told to pop up the calendar in response to
|
290
|
-
# clicks.
|
291
|
-
|
292
|
-
@popup_displayed = false
|
293
|
-
false
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
def display_calendar_popup(entry)
|
298
|
-
if @popup_displayed
|
299
|
-
hide_calendar_popup
|
300
|
-
else
|
301
|
-
@calendar_popup_for_entry = entry
|
302
|
-
unless entry.text.strip.empty?
|
303
|
-
time = parse_date(entry.text)
|
304
|
-
unless time.nil?
|
305
|
-
@calendar.year = time.year
|
306
|
-
@calendar.month = time.month - 1
|
307
|
-
@calendar.day = time.day
|
308
|
-
end
|
309
|
-
end
|
310
|
-
self.modal = false
|
311
|
-
@calendar_popup.move(*get_entry_popup_coords(entry))
|
312
|
-
@calendar_popup.show_all
|
313
|
-
@popup_displayed = true
|
314
|
-
end
|
315
|
-
end
|
316
|
-
|
317
|
-
def get_entry_popup_coords(entry)
|
318
|
-
gdk_win = entry.parent_window
|
319
|
-
x, y = gdk_win.origin
|
320
|
-
alloc = entry.allocation
|
321
|
-
x += alloc.x
|
322
|
-
y += alloc.y
|
323
|
-
y += alloc.height
|
324
|
-
# x = [0, x].max
|
325
|
-
# y = [0, y].max
|
326
|
-
[x, y]
|
327
|
-
end
|
328
|
-
|
329
225
|
def parse_date(datestring)
|
330
226
|
# '%m/%d/%Y' for USA and Canada ; or '%Y-%m-%d' for most of Asia
|
331
227
|
# http://en.wikipedia.org/wiki/Calendar_date#Middle_endian_forms.2C_starting_with_the_month
|
@@ -27,7 +27,7 @@ module Alexandria
|
|
27
27
|
entry.primary_icon_name = Gtk::Stock::EDIT
|
28
28
|
|
29
29
|
entry.primary_icon_activatable = true
|
30
|
-
entry.signal_connect("icon-press") do |widget, primary,
|
30
|
+
entry.signal_connect("icon-press") do |widget, primary, icon|
|
31
31
|
@parent.handle_date_icon_press(widget, primary, icon)
|
32
32
|
end
|
33
33
|
end
|
data/lib/alexandria/version.rb
CHANGED
data/po/pl.po
CHANGED
@@ -9,7 +9,7 @@ msgstr ""
|
|
9
9
|
"Project-Id-Version: alexandria\n"
|
10
10
|
"Report-Msgid-Bugs-To: \n"
|
11
11
|
"POT-Creation-Date: 2020-09-13 14:52+0200\n"
|
12
|
-
"PO-Revision-Date: 2020-
|
12
|
+
"PO-Revision-Date: 2020-11-01 14:20+0100\n"
|
13
13
|
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
14
14
|
"Language-Team: Polish <pl@li.org>\n"
|
15
15
|
"Language: pl\n"
|
@@ -846,7 +846,6 @@ msgid "Invalid ISBN '%s'"
|
|
846
846
|
msgstr "Nieprawidłowy numer ISBN „%s”"
|
847
847
|
|
848
848
|
#: ../lib/alexandria/ui/keep_bad_isbn_dialog.rb:18
|
849
|
-
#, fuzzy
|
850
849
|
msgid ""
|
851
850
|
"The book titled '%s' has an invalid ISBN, but still exists in the providers "
|
852
851
|
"libraries. Do you want to keep the book but change the ISBN or cancel the "
|
@@ -990,9 +989,8 @@ msgid "Invalid library name '%s'"
|
|
990
989
|
msgstr "Nieprawidłowa nazwa biblioteki „%s”"
|
991
990
|
|
992
991
|
#: ../lib/alexandria/ui/sidepane_manager.rb:55
|
993
|
-
#, fuzzy
|
994
992
|
msgid "The name provided contains the disallowed character <b>%s</b>"
|
995
|
-
msgstr "Podana nazwa zawiera niedozwolony znak <b>%s</b>
|
993
|
+
msgstr "Podana nazwa zawiera niedozwolony znak <b>%s</b>"
|
996
994
|
|
997
995
|
#: ../lib/alexandria/ui/sidepane_manager.rb:58
|
998
996
|
msgid "Invalid library name"
|
@@ -1416,9 +1414,3 @@ msgstr "Menedżer domowej biblioteki"
|
|
1416
1414
|
#: ../alexandria.desktop.in.h:3
|
1417
1415
|
msgid "Manage your book collection"
|
1418
1416
|
msgstr "Zarządzanie domową biblioteką"
|
1419
|
-
|
1420
|
-
#~ msgid "Block is required."
|
1421
|
-
#~ msgstr "Blokada jest wymagana."
|
1422
|
-
|
1423
|
-
#~ msgid "label"
|
1424
|
-
#~ msgstr "etykieta"
|
@@ -7,9 +7,30 @@
|
|
7
7
|
require_relative "../../spec_helper"
|
8
8
|
|
9
9
|
describe Alexandria::UI::ExportDialog do
|
10
|
+
let(:parent) { Gtk::Window.new :toplevel }
|
11
|
+
let(:library) { Alexandria::Library.new "Bar Library" }
|
12
|
+
let(:sort_order) { Alexandria::LibrarySortOrder::Unsorted.new }
|
13
|
+
|
10
14
|
it "works" do
|
11
|
-
parent
|
12
|
-
|
13
|
-
|
15
|
+
described_class.new parent, library, sort_order
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#perform" do
|
19
|
+
let(:export_dialog) { described_class.new parent, library, sort_order }
|
20
|
+
let(:chooser) { export_dialog.dialog }
|
21
|
+
|
22
|
+
it "works when response is cancel" do
|
23
|
+
allow(chooser).to receive(:run).and_return(Gtk::ResponseType::CANCEL)
|
24
|
+
export_dialog.perform
|
25
|
+
end
|
26
|
+
|
27
|
+
it "works when response is OK" do
|
28
|
+
dir = Dir.mktmpdir
|
29
|
+
allow(chooser).to receive(:run).and_return(Gtk::ResponseType::OK)
|
30
|
+
allow(chooser).to receive(:filename).and_return File.join(dir, "export")
|
31
|
+
export_dialog.perform
|
32
|
+
ensure
|
33
|
+
FileUtils.remove_entry dir
|
34
|
+
end
|
14
35
|
end
|
15
36
|
end
|
@@ -13,6 +13,11 @@ describe Alexandria::UI::ImportDialog do
|
|
13
13
|
described_class.new parent
|
14
14
|
end
|
15
15
|
|
16
|
+
it "handles a selection change" do
|
17
|
+
importdialog = described_class.new parent
|
18
|
+
importdialog.dialog.signal_emit "selection_changed"
|
19
|
+
end
|
20
|
+
|
16
21
|
describe "#acquire" do
|
17
22
|
let(:import_dialog) { described_class.new parent }
|
18
23
|
let(:chooser) { import_dialog.dialog }
|
@@ -7,18 +7,15 @@
|
|
7
7
|
require_relative "../../spec_helper"
|
8
8
|
|
9
9
|
describe Alexandria::UI::SmartLibraryPropertiesDialog do
|
10
|
-
let(:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
it "can be instantiated" do
|
10
|
+
let(:properties_dialog) do
|
11
|
+
parent = Gtk::Window.new :toplevel
|
12
|
+
loader = Alexandria::LibraryStore.new(TESTDIR)
|
13
|
+
smart_library = Alexandria::SmartLibrary.new("Foo", [], :all, loader)
|
15
14
|
described_class.new parent, smart_library
|
16
15
|
end
|
16
|
+
let(:gtk_dialog) { properties_dialog.dialog }
|
17
17
|
|
18
18
|
describe "#acquire" do
|
19
|
-
let(:properties_dialog) { described_class.new parent, smart_library }
|
20
|
-
let(:gtk_dialog) { properties_dialog.dialog }
|
21
|
-
|
22
19
|
it "works when response is cancel" do
|
23
20
|
allow(gtk_dialog).to receive(:run).and_return(Gtk::ResponseType::CANCEL)
|
24
21
|
properties_dialog.acquire
|
@@ -29,4 +26,24 @@ describe Alexandria::UI::SmartLibraryPropertiesDialog do
|
|
29
26
|
properties_dialog.acquire
|
30
27
|
end
|
31
28
|
end
|
29
|
+
|
30
|
+
describe "#handle_date_icon_press" do
|
31
|
+
let(:date_entry) do
|
32
|
+
rule_boxes = properties_dialog.handle_add_rule_clicked
|
33
|
+
rule_box = rule_boxes.first
|
34
|
+
rule_box.children[3]
|
35
|
+
end
|
36
|
+
|
37
|
+
before do
|
38
|
+
gtk_dialog.show_all
|
39
|
+
end
|
40
|
+
|
41
|
+
it "pops up the calendar widget" do
|
42
|
+
properties_dialog.handle_date_icon_press(date_entry,
|
43
|
+
Gtk::EntryIconPosition::PRIMARY,
|
44
|
+
nil)
|
45
|
+
popup = properties_dialog.instance_variable_get(:@calendar_popup)
|
46
|
+
expect(popup).to be_visible
|
47
|
+
end
|
48
|
+
end
|
32
49
|
end
|
@@ -19,13 +19,6 @@ describe "The Alexandria application" do
|
|
19
19
|
driver.cleanup
|
20
20
|
end
|
21
21
|
|
22
|
-
it "starts and can be quit with Ctrl-q" do
|
23
|
-
driver.press_ctrl_q
|
24
|
-
|
25
|
-
status = driver.cleanup
|
26
|
-
expect(status.exitstatus).to eq 0
|
27
|
-
end
|
28
|
-
|
29
22
|
it "starts and can be quit with the menu" do
|
30
23
|
frame = driver.frame
|
31
24
|
menu = frame.find_role :menu_item, /Quit/
|
@@ -49,7 +42,9 @@ describe "The Alexandria application" do
|
|
49
42
|
table_cell.do_action idx if name == "activate"
|
50
43
|
end
|
51
44
|
|
52
|
-
driver.
|
45
|
+
frame = driver.frame
|
46
|
+
menu = frame.find_role :menu_item, /Quit/
|
47
|
+
menu.do_action 0
|
53
48
|
|
54
49
|
status = driver.cleanup
|
55
50
|
expect(status.exitstatus).to eq 0
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alexandria-book-collection-manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander McCormmach
|
@@ -28,7 +28,7 @@ authors:
|
|
28
28
|
autorequire:
|
29
29
|
bindir: bin
|
30
30
|
cert_chain: []
|
31
|
-
date: 2020-11-
|
31
|
+
date: 2020-11-15 00:00:00.000000000 Z
|
32
32
|
dependencies:
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: gettext
|
@@ -291,13 +291,13 @@ extensions: []
|
|
291
291
|
extra_rdoc_files: []
|
292
292
|
files:
|
293
293
|
- ".github/dependabot.yml"
|
294
|
+
- ".github/workflows/ruby.yml"
|
294
295
|
- ".gitignore"
|
295
296
|
- ".hound.yml"
|
296
297
|
- ".reek"
|
297
298
|
- ".rubocop.yml"
|
298
299
|
- ".rubocop_todo.yml"
|
299
300
|
- ".simplecov"
|
300
|
-
- ".travis.yml"
|
301
301
|
- ".yardopts"
|
302
302
|
- CHANGELOG.md
|
303
303
|
- COPYING
|
@@ -364,6 +364,7 @@ files:
|
|
364
364
|
- lib/alexandria/ui/book_properties_dialog.rb
|
365
365
|
- lib/alexandria/ui/book_properties_dialog_base.rb
|
366
366
|
- lib/alexandria/ui/builder_base.rb
|
367
|
+
- lib/alexandria/ui/calendar_popup.rb
|
367
368
|
- lib/alexandria/ui/callbacks.rb
|
368
369
|
- lib/alexandria/ui/columns.rb
|
369
370
|
- lib/alexandria/ui/completion_models.rb
|
data/.travis.yml
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
dist: xenial
|
4
|
-
|
5
|
-
services:
|
6
|
-
- xvfb
|
7
|
-
|
8
|
-
before_install:
|
9
|
-
- sudo apt-get update
|
10
|
-
# Needed for gtk3 gem
|
11
|
-
- sudo apt-get install libgtk-3-dev
|
12
|
-
# Needed for gstreamer gem
|
13
|
-
- sudo apt-get install libgstreamer1.0-dev
|
14
|
-
# Needed for GooCanvas::Canvas widget
|
15
|
-
- sudo apt-get install libgoocanvas-2.0-dev
|
16
|
-
# Needed for zoom gem
|
17
|
-
- sudo apt-get install libyaz-dev
|
18
|
-
# Needed for intltool-merge executable
|
19
|
-
- sudo apt-get install intltool
|
20
|
-
# Needed for gconftool-2 executable
|
21
|
-
- sudo apt-get install gconf2
|
22
|
-
# Needed to provide A11y dbus service to silence warnings
|
23
|
-
- sudo apt-get install at-spi2-core
|
24
|
-
# Needed to set up sound player pipeline
|
25
|
-
- sudo apt-get install gstreamer1.0-plugins-good
|
26
|
-
# Needed to play sound
|
27
|
-
- sudo apt-get install pulseaudio
|
28
|
-
|
29
|
-
cache:
|
30
|
-
bundler: true
|
31
|
-
|
32
|
-
script: bundle exec rake
|
33
|
-
|
34
|
-
jobs:
|
35
|
-
include:
|
36
|
-
- rvm: 2.5
|
37
|
-
- rvm: 2.6
|
38
|
-
- rvm: 2.7
|
39
|
-
- rvm: 2.7.1
|
40
|
-
name: "RuboCop"
|
41
|
-
script: bundle exec rubocop
|
42
|
-
|
43
|
-
branches:
|
44
|
-
only:
|
45
|
-
- master
|