diff options
Diffstat (limited to 'src/book_form.py')
| -rw-r--r-- | src/book_form.py | 167 |
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))) |
