aboutsummaryrefslogtreecommitdiff
path: root/src/book_form.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/book_form.py')
-rw-r--r--src/book_form.py167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/book_form.py b/src/book_form.py
new file mode 100644
index 0000000..af213de
--- /dev/null
+++ b/src/book_form.py
@@ -0,0 +1,167 @@
+import gi
+gi.require_version('Gtk', '4.0')
+from gi.repository import Gtk
+
+import src.utils as utils
+import src.models as models
+from src.ui.entry_list import EntryList
+from src.ui.book_entries import BookEntries
+from src.ui.cover_entry import CoverEntry
+import src.book_store as book_store
+import src.book_files as book_files
+import src.str_format as str_format
+
+class BookForm(Gtk.Window):
+
+ def __init__(self, parent_window, resources, library, conn, init_progress, on_book_saved, book = None):
+ Gtk.Window.__init__(self)
+
+ self._book = book
+ self._library = library
+ self._conn = conn
+ self._on_book_saved = on_book_saved
+
+ title = 'Modifier un livre' if book else 'Ajouter un livre'
+ utils.configure_dialog(self, parent_window, title, height=800)
+
+ scrolled_window = Gtk.ScrolledWindow()
+ self.set_child(scrolled_window)
+
+ box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20)
+ scrolled_window.set_child(box)
+ utils.set_margin(box, 20)
+
+ # Cover and form
+ cover_and_form = Gtk.Box(spacing=20)
+ box.append(cover_and_form)
+ cover_path = f'{library}/{book['id']}/cover.png' if book else None
+ self._cover_entry = CoverEntry(parent_window, resources, cover_path)
+ cover_and_form.append(self._cover_entry)
+ top_form = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=20)
+ cover_and_form.append(top_form)
+
+ # Title and subtitle
+ self._title, self._subtitle = double_entry(top_form, 'Titre')
+ self._title.set_hexpand(True)
+
+ # Year, lang and progress
+ year_lang_progress = Gtk.Box(spacing=10)
+ top_form.append(year_lang_progress)
+ self._year = labeled_entry(year_lang_progress, 'Année')
+ self._lang = dropdown(year_lang_progress, 'Langue', models.langs)
+ self._progress = dropdown(year_lang_progress, 'Progrès', models.all_progress, init_progress)
+
+ # Authors, genres
+ authors_genres = Gtk.Box(spacing=10)
+ box.append(authors_genres)
+ self._authors = EntryList('Auteurs')
+ authors_genres.append(self._authors)
+ self._genres = EntryList('Genres')
+ authors_genres.append(self._genres)
+
+ # Summary
+ summary_box = label_box(box, 'Résumé')
+ self._summary = Gtk.TextView()
+ self._summary.set_wrap_mode(Gtk.WrapMode.WORD)
+ self._summary.set_top_margin(10)
+ self._summary.set_right_margin(10)
+ self._summary.set_bottom_margin(10)
+ self._summary.set_left_margin(10)
+ summary_box.append(self._summary)
+
+ # Books
+ self._book_entries = BookEntries(self)
+ box.append(self._book_entries)
+
+ # Init values
+ if book:
+ book_id = book['id']
+ data = book['data']
+
+ update_entry(self._title, data['title'])
+ if 'subtitle' in data:
+ update_entry(self._subtitle, data['subtitle'])
+ if 'year' in data:
+ update_entry(self._year, str(data['year']))
+ if 'lang' in data:
+ self._lang.set_selected(models.langs.index(data['lang']))
+ for author in data['authors']:
+ self._authors.add_entry(author)
+ for genre in data['genres']:
+ self._genres.add_entry(genre)
+ self._summary.get_buffer().set_text(data['summary'])
+ for path in book_files.get(self._library, book_id):
+ self._book_entries.add_book(path)
+ else:
+ self._authors.add_entry('')
+ self._genres.add_entry('')
+
+ # Button
+ validate = Gtk.Button(label='Modifier' if book else 'Ajouter')
+ validate.connect('clicked', lambda _: self._on_validate())
+ box.append(validate)
+
+ def _on_validate(self):
+ data = {}
+ data['title'] = self._title.get_text()
+ data['subtitle'] = self._subtitle.get_text()
+ match safe_string_to_int(self._year.get_text()):
+ case None: pass
+ case n: data['year'] = n
+ data['lang'] = self._lang.get_selected_item().get_string()
+ data['progress'] = self._progress.get_selected_item().get_string()
+ data['authors'] = non_empty(self._authors.get_entry_texts())
+ data['genres'] = non_empty(self._genres.get_entry_texts())
+ data['summary'] = str_format.cleanup_text(text_view_text(self._summary), data['lang'])
+ cover = self._cover_entry.get_image()
+ books = self._book_entries.get_books()
+
+ book_id = book_store.store(self._library, self._conn, data, cover, books, self._book)
+ if book_id:
+ self.close()
+ self._on_book_saved(book_id, data)
+
+def non_empty(xs):
+ return [x.strip() for x in xs if x.strip()]
+
+def safe_string_to_int(n):
+ try:
+ return int(n)
+ except ValueError:
+ return None
+
+def double_entry(parent, label):
+ box = label_box(parent, label)
+ entry1 = Gtk.Entry()
+ entry2 = Gtk.Entry()
+ box.append(entry1)
+ box.append(entry2)
+ return entry1, entry2
+
+def labeled_entry(parent, label):
+ box = label_box(parent, label)
+ entry = Gtk.Entry()
+ box.append(entry)
+ return entry
+
+def dropdown(parent, label, values, selected = None):
+ box = label_box(parent, label)
+ dropdown = Gtk.DropDown.new_from_strings(values)
+ box.append(dropdown)
+ if selected:
+ dropdown.set_selected(values.index(selected))
+ return dropdown
+
+def label_box(parent, label):
+ box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
+ box.append(utils.label(label))
+ parent.append(box)
+ return box
+
+def text_view_text(text_view):
+ buffer = text_view.get_buffer()
+ start, end = buffer.get_bounds()
+ return buffer.get_text(start, end, False)
+
+def update_entry(entry, text):
+ entry.set_buffer(Gtk.EntryBuffer.new(text, len(text)))