diff --git a/TODO b/TODO index cff7690..d5bc4c8 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,9 @@ TODO General: ✓ Internationalization ✓ Application icon - ✓ .desktop file - Flatpak and AppImage support + ✓ .desktop file + ✓ Shift to logging instead of print statements + Flatpak and AppImage support Options: ✓ Automatic library management ✓ Recursive file addition @@ -93,9 +94,13 @@ TODO Last line in QTextBrowser should never be cut off Does image alignment need to be centered? Bookmark name for a page that's not on the TOC or has nothing before + Screen position still keeps jumping when inside a paragraph + Better recursion needed for fb2 toc Secondary: - The cover page needs to be marked separately + Special formatting for each chapter's title + Create covers for books without them + Signal end of chapter with some text Graphical themes Change focus rectangle dimensions Universal Ctrl + Tab @@ -103,7 +108,6 @@ TODO Goodreads API: Ratings, Read, Recommendations Get ISBN using python-isbnlib Use embedded fonts + CSS - Shift to logging instead of print statements txt, doc, chm support Include icons for filetype emblems Comic view modes diff --git a/lector/__main__.py b/lector/__main__.py index 66abd32..e62590e 100755 --- a/lector/__main__.py +++ b/lector/__main__.py @@ -724,7 +724,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): # The set_content method is universal # It's going to do position tracking current_tab = self.tabWidget.currentWidget() - current_tab.set_content(required_position) + current_tab.set_content(required_position, False, True) def library_doubleclick(self, index): sender = self.sender().objectName() diff --git a/lector/contentwidgets.py b/lector/contentwidgets.py index f88e675..36b405c 100644 --- a/lector/contentwidgets.py +++ b/lector/contentwidgets.py @@ -737,7 +737,7 @@ class PliantWidgetsCommonFunctions: return direction current_tab.set_content( - current_position + direction + get_modifier(), True) + current_position + direction + get_modifier(), True, True) # Set page position depending on if the chapter number is increasing or decreasing if direction == 1 or was_button_pressed: @@ -853,7 +853,7 @@ class PliantWidgetsCommonFunctions: def set_toc_position(tocTree): currentIndex = tocTree.currentIndex() required_position = currentIndex.data(QtCore.Qt.UserRole) - self.pw.parent.set_content(required_position, True) + self.pw.parent.set_content(required_position, True, True) # Create the Combobox / Treeview combination tocComboBox = QtWidgets.QComboBox() diff --git a/lector/dockwidgets.py b/lector/dockwidgets.py index 363a9ad..0a91146 100644 --- a/lector/dockwidgets.py +++ b/lector/dockwidgets.py @@ -220,7 +220,7 @@ class Bookmarks: if is_parent: chapter_number = self.parent.bookmarkProxyModel.data( index, QtCore.Qt.UserRole) - self.parentTab.set_content(chapter_number, True) + self.parentTab.set_content(chapter_number, True, True) return chapter = self.parent.bookmarkProxyModel.data( @@ -228,7 +228,7 @@ class Bookmarks: cursor_position = self.parent.bookmarkProxyModel.data( index, QtCore.Qt.UserRole + 1) - self.parentTab.set_content(chapter, True) + self.parentTab.set_content(chapter, True, True) if not self.parentTab.are_we_doing_images_only: self.parentTab.set_cursor_position(cursor_position) @@ -500,7 +500,7 @@ class Search: cursor_position = self.parent.searchResultsModel.data(index, QtCore.Qt.UserRole + 2) search_term = self.parent.searchResultsModel.data(index, QtCore.Qt.UserRole + 4) - self.parentTab.set_content(chapter_number, True) + self.parentTab.set_content(chapter_number, True, True) if not self.parentTab.are_we_doing_images_only: self.parentTab.set_cursor_position( cursor_position, len(search_term)) diff --git a/lector/parsers/fb2.py b/lector/parsers/fb2.py index d35067a..be82af8 100644 --- a/lector/parsers/fb2.py +++ b/lector/parsers/fb2.py @@ -64,8 +64,8 @@ class ParseFB2: toc = [] content = [] for count, i in enumerate(self.book['book_list']): - toc.append((1, i[0], count + 1)) - content.append(i[1]) + toc.append((i[0], i[1], count + 1)) + content.append(i[2]) # Return toc, content, images_only return toc, content, False diff --git a/lector/readers/read_fb2.py b/lector/readers/read_fb2.py index 8d26cb9..1ebcbc2 100644 --- a/lector/readers/read_fb2.py +++ b/lector/readers/read_fb2.py @@ -92,18 +92,50 @@ class FB2: self.book['cover'] = None def parse_chapters(self, temp_dir): - for i in self.xml.find_all('section'): - this_title = '' - for j in i: - if j.name == 'title': - this_title = j.getText(separator=' ') - this_title = this_title.replace('\n', '').strip() - # This comes later because the tag is changed in place - title_xml = j.unwrap() - break + # TODO + # Check what's up with recursion levels + # Why is the TypeError happening in get_title - self.book['book_list'].append( - [this_title, str(title_xml) + str(i)]) + def get_title(element): + this_title = '' + title_xml = '' + try: + for i in element: + if i.name == 'title': + this_title = i.getText(separator=' ') + this_title = this_title.replace('\n', '').strip() + title_xml = str(i.unwrap()) + break + except TypeError: + return None, None + return this_title, title_xml + + def recursor(level, element): + children = element.findChildren('section', recursive=False) + if not children and level != 1: + this_title, title_xml = get_title(element) + self.book['book_list'].append( + [level, this_title, title_xml + str(element)]) + else: + for i in children: + recursor(level + 1, i) + + first_element = self.xml.find('section') # Recursive find + siblings = list(first_element.findNextSiblings('section', recursive=False)) + siblings.insert(0, first_element) + + for this_element in siblings: + this_title, title_xml = get_title(this_element) + # Do not add chapter content in case it has sections + # inside it. This prevents having large Book sections that + # have duplicated content + section_children = this_element.findChildren('section') + chapter_text = str(this_element) + if section_children: + chapter_text = this_title + + self.book['book_list'].append([1, this_title, chapter_text]) + recursor(1, this_element) # Extract all images to the temp_dir for i in self.xml.find_all('binary'): @@ -113,7 +145,7 @@ class FB2: replacement_string = f'

Cover')) + 0, (1, 'Cover', f'
Cover
')) diff --git a/lector/widgets.py b/lector/widgets.py index b7746df..30b013c 100644 --- a/lector/widgets.py +++ b/lector/widgets.py @@ -109,7 +109,7 @@ class Tab(QtWidgets.QWidget): self.hiddenButton.clicked.connect(self.set_cursor_position) # All content must be set through this function - self.set_content(current_chapter, True) + self.set_content(current_chapter, True, False) if not self.are_we_doing_images_only: # Setting this later breaks cursor positioning for search results self.hiddenButton.animateClick(50) @@ -249,7 +249,7 @@ class Tab(QtWidgets.QWidget): # Finally, to make sure the cover image isn't # scrolled halfway through on first open, - if self.main_window.bookToolBar.tocBox.currentIndex() == 0: + if self.metadata['position']['current_chapter'] == 1: self.contentView.verticalScrollBar().setValue(0) def generate_position(self, is_read=False): @@ -266,10 +266,8 @@ class Tab(QtWidgets.QWidget): if not self.are_we_doing_images_only: for i in self.metadata['content']: - chapter_html = i[1] - textDocument = QtGui.QTextDocument(None) - textDocument.setHtml(chapter_html) + textDocument.setHtml(i) block_count = textDocument.blockCount() blocks_per_chapter.append(block_count) @@ -418,7 +416,7 @@ class Tab(QtWidgets.QWidget): self.mouse_hide_timer.start(2000) self.contentView.setFocus() - def set_content(self, required_position, tocBox_readjust=False): + def set_content(self, required_position, tocBox_readjust=False, record_position=False): # All content changes must come through here # This function will decide how to relate # entries in the toc to the actual content @@ -433,7 +431,8 @@ class Tab(QtWidgets.QWidget): # Update the metadata dictionary to save position self.metadata['position']['current_chapter'] = required_position - self.metadata['position']['is_read'] = False + if record_position: + self.contentView.record_position() if self.are_we_doing_images_only: self.contentView.loadImage(required_content)