1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, Gio, GLib
import pathlib
import os
import subprocess
import logging
import src.utils as utils
logger = logging.getLogger(__name__)
class BookEntries(Gtk.Box):
def __init__(self, window):
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL, spacing=10)
self._window = window
self._books = {} # Dict {path: name}
header = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
header.append(get_label('Books'))
add_button = Gtk.Button(label='+')
add_button.connect('clicked', lambda _: self._open_dialog())
header.append(add_button)
self.append(header)
self._entries = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
self.append(self._entries)
self._setup_filedialog()
def get_books(self):
return self._books
def _setup_filedialog(self):
self._filedialog = Gtk.FileDialog.new()
self._filedialog.set_title('Select a book')
f = Gtk.FileFilter()
f.set_name('Book files')
f.add_mime_type('application/epub+zip')
f.add_mime_type('application/vnd.amazon.ebook')
f.add_mime_type('application/x-mobipocket-ebook')
filters = Gio.ListStore.new(Gtk.FileFilter)
filters.append(f)
self._filedialog.set_filters(filters)
self._filedialog.set_default_filter(f)
def _open_dialog(self):
self._filedialog.open(self._window, None, self._open_dialog_callback)
def _open_dialog_callback(self, dialog, result):
try:
file = dialog.open_finish(result)
if file is not None:
# https://github.com/GNOME/glib/blob/main/gio/glocalfile.c
path = pathlib.Path(file.get_path())
self.add_book(path)
except GLib.Error as error:
logger.error(f'Error opening file: %s', error.message)
def add_book(self, path):
name = os.path.splitext(os.path.basename(path))[0]
self._books[path] = name
line = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
entry = Gtk.Entry()
entry.set_text(name)
entry.set_hexpand(True)
entry.connect('changed', self._update_book, path)
line.append(entry)
line.append(open_book_button(path))
remove_button = Gtk.Button(label='-')
remove_button.connect('clicked', lambda _: self._remove_book(line, path))
line.append(remove_button)
self._entries.append(line)
def _update_book(self, entry, path):
self._books[path] = entry.get_text()
def _remove_book(self, line, path):
del self._books[path]
self._entries.remove(line)
def get_label(text):
label = Gtk.Label()
label.set_text(text)
return label
def open_book_button(path):
open_button = Gtk.Button(label='Ouvrir')
open_button.connect('clicked', lambda _: open_book(path))
return open_button
def open_book(path):
subprocess.run(['xdg-open', path])
|