Usability improvements
Keyboard shortcuts Title reporting Context menu for comic/pdf view
This commit is contained in:
9
TODO
9
TODO
@@ -1,4 +1,7 @@
|
|||||||
TODO
|
TODO
|
||||||
|
General:
|
||||||
|
Application icon
|
||||||
|
.desktop file
|
||||||
Options:
|
Options:
|
||||||
✓ Automatic library management
|
✓ Automatic library management
|
||||||
✓ Recursive file addition
|
✓ Recursive file addition
|
||||||
@@ -51,8 +54,9 @@ TODO
|
|||||||
✓ Cache next and previous images
|
✓ Cache next and previous images
|
||||||
✓ Set context menu for definitions and the like
|
✓ Set context menu for definitions and the like
|
||||||
✓ Paragraph indentation
|
✓ Paragraph indentation
|
||||||
|
✓ Comic view keyboard shortcuts
|
||||||
|
Comic view context menu
|
||||||
Search document using QTextCursor?
|
Search document using QTextCursor?
|
||||||
Comic view keyboard shortcuts
|
|
||||||
Filetypes:
|
Filetypes:
|
||||||
✓ pdf support
|
✓ pdf support
|
||||||
Parse TOC
|
Parse TOC
|
||||||
@@ -90,9 +94,6 @@ TODO
|
|||||||
Comic view modes
|
Comic view modes
|
||||||
Continuous paging
|
Continuous paging
|
||||||
Double pages
|
Double pages
|
||||||
Leave comic images on disk in case tab isn't closed and files are remembered
|
|
||||||
Give the comic view a 'Save image as...' option
|
|
||||||
Ignore a / the / numbers for sorting purposes
|
Ignore a / the / numbers for sorting purposes
|
||||||
? Add only one file type if multiple are present
|
? Add only one file type if multiple are present
|
||||||
? Plugin system for parsers
|
|
||||||
? Create emblem per filetype
|
? Create emblem per filetype
|
||||||
|
@@ -105,7 +105,8 @@ class EPUB:
|
|||||||
#______________________________________________________
|
#______________________________________________________
|
||||||
|
|
||||||
def generate_book_metadata(self, contents_path):
|
def generate_book_metadata(self, contents_path):
|
||||||
self.book['title'] = 'Unknown'
|
self.book['title'] = os.path.splitext(
|
||||||
|
os.path.basename(self.filename))[0]
|
||||||
self.book['author'] = 'Unknown'
|
self.book['author'] = 'Unknown'
|
||||||
self.book['isbn'] = None
|
self.book['isbn'] = None
|
||||||
self.book['tags'] = None
|
self.book['tags'] = None
|
||||||
@@ -281,9 +282,11 @@ class EPUB:
|
|||||||
with open(cover_path, 'wb') as cover_temp:
|
with open(cover_path, 'wb') as cover_temp:
|
||||||
cover_temp.write(self.book['cover'])
|
cover_temp.write(self.book['cover'])
|
||||||
|
|
||||||
self.book['book_list'][0] = (
|
try:
|
||||||
'Cover', f'<center><img src="{cover_path}" alt="Cover"></center>')
|
self.book['book_list'][0] = (
|
||||||
|
'Cover', f'<center><img src="{cover_path}" alt="Cover"></center>')
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
|
||||||
def get_split_content(chapter_data, split_by):
|
def get_split_content(chapter_data, split_by):
|
||||||
split_anchors = [i[0] for i in split_by]
|
split_anchors = [i[0] for i in split_by]
|
||||||
|
@@ -74,7 +74,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
# Widget declarations
|
# Widget declarations
|
||||||
self.libraryFilterMenu = QtWidgets.QMenu()
|
self.libraryFilterMenu = QtWidgets.QMenu()
|
||||||
self.statusMessage = QtWidgets.QLabel()
|
self.statusMessage = QtWidgets.QLabel()
|
||||||
self.toolbarToggle = QtWidgets.QToolButton()
|
self.distractionFreeToggle = QtWidgets.QToolButton()
|
||||||
self.reloadLibrary = QtWidgets.QToolButton()
|
self.reloadLibrary = QtWidgets.QToolButton()
|
||||||
|
|
||||||
# Create the database in case it doesn't exist
|
# Create the database in case it doesn't exist
|
||||||
@@ -100,13 +100,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.statusBar.addWidget(self.sorterProgress)
|
self.statusBar.addWidget(self.sorterProgress)
|
||||||
self.sorterProgress.setVisible(False)
|
self.sorterProgress.setVisible(False)
|
||||||
|
|
||||||
# Statusbar - Toolbar Visibility
|
# Statusbar + Toolbar Visibility
|
||||||
self.toolbarToggle.setIcon(self.QImageFactory.get_image('visibility'))
|
self.distractionFreeToggle.setIcon(self.QImageFactory.get_image('visibility'))
|
||||||
self.toolbarToggle.setObjectName('toolbarToggle')
|
self.distractionFreeToggle.setObjectName('distractionFreeToggle')
|
||||||
self.toolbarToggle.setToolTip('Toggle toolbar')
|
self.distractionFreeToggle.setToolTip('Toggle distraction free mode (Ctrl + D)')
|
||||||
self.toolbarToggle.setAutoRaise(True)
|
self.distractionFreeToggle.setAutoRaise(True)
|
||||||
self.toolbarToggle.clicked.connect(self.toggle_toolbars)
|
self.distractionFreeToggle.clicked.connect(self.toggle_distraction_free)
|
||||||
self.statusBar.addPermanentWidget(self.toolbarToggle)
|
self.statusBar.addPermanentWidget(self.distractionFreeToggle)
|
||||||
|
|
||||||
# Application wide temporary directory
|
# Application wide temporary directory
|
||||||
self.temp_dir = QtCore.QTemporaryDir()
|
self.temp_dir = QtCore.QTemporaryDir()
|
||||||
@@ -121,7 +121,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
|
|
||||||
# Toolbar display
|
# Toolbar display
|
||||||
# Maybe make this a persistent option
|
# Maybe make this a persistent option
|
||||||
self.settings['show_toolbars'] = True
|
self.settings['show_bars'] = True
|
||||||
|
|
||||||
# Library toolbar
|
# Library toolbar
|
||||||
self.libraryToolBar.addButton.triggered.connect(self.add_books)
|
self.libraryToolBar.addButton.triggered.connect(self.add_books)
|
||||||
@@ -254,14 +254,22 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.tableView.customContextMenuRequested.connect(self.generate_library_context_menu)
|
self.tableView.customContextMenuRequested.connect(self.generate_library_context_menu)
|
||||||
|
|
||||||
# Keyboard shortcuts
|
# Keyboard shortcuts
|
||||||
self.ksCloseTab = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+W'), self)
|
self.ksDistractionFree = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+D'), self)
|
||||||
self.ksCloseTab.setContext(QtCore.Qt.ApplicationShortcut)
|
self.ksDistractionFree.setContext(QtCore.Qt.ApplicationShortcut)
|
||||||
self.ksCloseTab.activated.connect(self.tab_close)
|
self.ksDistractionFree.activated.connect(self.toggle_distraction_free)
|
||||||
|
|
||||||
|
self.ksOpenFile = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+O'), self)
|
||||||
|
self.ksOpenFile.setContext(QtCore.Qt.ApplicationShortcut)
|
||||||
|
self.ksOpenFile.activated.connect(self.add_books)
|
||||||
|
|
||||||
self.ksExitAll = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+Q'), self)
|
self.ksExitAll = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+Q'), self)
|
||||||
self.ksExitAll.setContext(QtCore.Qt.ApplicationShortcut)
|
self.ksExitAll.setContext(QtCore.Qt.ApplicationShortcut)
|
||||||
self.ksExitAll.activated.connect(self.closeEvent)
|
self.ksExitAll.activated.connect(self.closeEvent)
|
||||||
|
|
||||||
|
self.ksCloseTab = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+W'), self)
|
||||||
|
self.ksCloseTab.setContext(QtCore.Qt.ApplicationShortcut)
|
||||||
|
self.ksCloseTab.activated.connect(self.tab_close)
|
||||||
|
|
||||||
self.listView.setFocus()
|
self.listView.setFocus()
|
||||||
self.open_books_at_startup()
|
self.open_books_at_startup()
|
||||||
|
|
||||||
@@ -402,9 +410,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
if self.tabWidget.currentIndex() != 0:
|
if self.tabWidget.currentIndex() != 0:
|
||||||
self.tabWidget.widget(self.tabWidget.currentIndex()).add_bookmark()
|
self.tabWidget.widget(self.tabWidget.currentIndex()).add_bookmark()
|
||||||
|
|
||||||
def test_function(self):
|
|
||||||
print('Caesar si viveret, ad remum dareris')
|
|
||||||
|
|
||||||
def resizeEvent(self, event=None):
|
def resizeEvent(self, event=None):
|
||||||
if event:
|
if event:
|
||||||
# This implies a vertical resize event only
|
# This implies a vertical resize event only
|
||||||
@@ -447,7 +452,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
# from the libary in case of a database refresh
|
# from the libary in case of a database refresh
|
||||||
|
|
||||||
opened_files = QtWidgets.QFileDialog.getOpenFileNames(
|
opened_files = QtWidgets.QFileDialog.getOpenFileNames(
|
||||||
self, 'Open file', self.settings['last_open_path'],
|
self, 'Add books to database', self.settings['last_open_path'],
|
||||||
f'eBooks ({self.available_parsers})')
|
f'eBooks ({self.available_parsers})')
|
||||||
|
|
||||||
if not opened_files[0]:
|
if not opened_files[0]:
|
||||||
@@ -570,7 +575,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
|
|
||||||
self.resizeEvent()
|
self.resizeEvent()
|
||||||
self.start_culling_timer()
|
self.start_culling_timer()
|
||||||
if self.settings['show_toolbars']:
|
if self.settings['show_bars']:
|
||||||
self.bookToolBar.hide()
|
self.bookToolBar.hide()
|
||||||
self.libraryToolBar.show()
|
self.libraryToolBar.show()
|
||||||
|
|
||||||
@@ -581,7 +586,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
str(self.lib_ref.item_proxy_model.rowCount()) + ' Books')
|
str(self.lib_ref.item_proxy_model.rowCount()) + ' Books')
|
||||||
else:
|
else:
|
||||||
|
|
||||||
if self.settings['show_toolbars']:
|
if self.settings['show_bars']:
|
||||||
self.bookToolBar.show()
|
self.bookToolBar.show()
|
||||||
self.libraryToolBar.hide()
|
self.libraryToolBar.hide()
|
||||||
|
|
||||||
@@ -869,15 +874,19 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
profile_index, current_profile, QtCore.Qt.UserRole)
|
profile_index, current_profile, QtCore.Qt.UserRole)
|
||||||
self.format_contentView()
|
self.format_contentView()
|
||||||
|
|
||||||
def modify_comic_view(self):
|
def modify_comic_view(self, key_pressed=None):
|
||||||
signal_sender = self.sender().objectName()
|
if key_pressed:
|
||||||
|
signal_sender = None
|
||||||
|
else:
|
||||||
|
signal_sender = self.sender().objectName()
|
||||||
|
|
||||||
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
|
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
|
||||||
|
|
||||||
self.bookToolBar.fitWidth.setChecked(False)
|
self.bookToolBar.fitWidth.setChecked(False)
|
||||||
self.bookToolBar.bestFit.setChecked(False)
|
self.bookToolBar.bestFit.setChecked(False)
|
||||||
self.bookToolBar.originalSize.setChecked(False)
|
self.bookToolBar.originalSize.setChecked(False)
|
||||||
|
|
||||||
if signal_sender == 'zoomOut':
|
if signal_sender == 'zoomOut' or key_pressed == QtCore.Qt.Key_Minus:
|
||||||
self.comic_profile['zoom_mode'] = 'manualZoom'
|
self.comic_profile['zoom_mode'] = 'manualZoom'
|
||||||
self.comic_profile['padding'] += 50
|
self.comic_profile['padding'] += 50
|
||||||
|
|
||||||
@@ -885,7 +894,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
if self.comic_profile['padding'] * 2 > current_tab.contentView.viewport().width():
|
if self.comic_profile['padding'] * 2 > current_tab.contentView.viewport().width():
|
||||||
self.comic_profile['padding'] -= 50
|
self.comic_profile['padding'] -= 50
|
||||||
|
|
||||||
if signal_sender == 'zoomIn':
|
if signal_sender == 'zoomIn' or key_pressed in (QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal):
|
||||||
self.comic_profile['zoom_mode'] = 'manualZoom'
|
self.comic_profile['zoom_mode'] = 'manualZoom'
|
||||||
self.comic_profile['padding'] -= 50
|
self.comic_profile['padding'] -= 50
|
||||||
|
|
||||||
@@ -893,18 +902,18 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
if self.comic_profile['padding'] < 0:
|
if self.comic_profile['padding'] < 0:
|
||||||
self.comic_profile['padding'] = 0
|
self.comic_profile['padding'] = 0
|
||||||
|
|
||||||
if signal_sender == 'fitWidth':
|
if signal_sender == 'fitWidth' or key_pressed == QtCore.Qt.Key_W:
|
||||||
self.comic_profile['zoom_mode'] = 'fitWidth'
|
self.comic_profile['zoom_mode'] = 'fitWidth'
|
||||||
self.comic_profile['padding'] = 0
|
self.comic_profile['padding'] = 0
|
||||||
self.bookToolBar.fitWidth.setChecked(True)
|
self.bookToolBar.fitWidth.setChecked(True)
|
||||||
|
|
||||||
# Padding in the following cases is decided by
|
# Padding in the following cases is decided by
|
||||||
# the image pixmap loaded by the widget
|
# the image pixmap loaded by the widget
|
||||||
if signal_sender == 'bestFit':
|
if signal_sender == 'bestFit' or key_pressed == QtCore.Qt.Key_B:
|
||||||
self.comic_profile['zoom_mode'] = 'bestFit'
|
self.comic_profile['zoom_mode'] = 'bestFit'
|
||||||
self.bookToolBar.bestFit.setChecked(True)
|
self.bookToolBar.bestFit.setChecked(True)
|
||||||
|
|
||||||
if signal_sender == 'originalSize':
|
if signal_sender == 'originalSize' or key_pressed == QtCore.Qt.Key_O:
|
||||||
self.comic_profile['zoom_mode'] = 'originalSize'
|
self.comic_profile['zoom_mode'] = 'originalSize'
|
||||||
self.bookToolBar.originalSize.setChecked(True)
|
self.bookToolBar.originalSize.setChecked(True)
|
||||||
|
|
||||||
@@ -914,7 +923,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
# TODO
|
# TODO
|
||||||
# See what happens if a font isn't installed
|
# See what happens if a font isn't installed
|
||||||
|
|
||||||
current_tab = self.tabWidget.widget(self.tabWidget.currentIndex())
|
current_tab = self.tabWidget.widget(
|
||||||
|
self.tabWidget.currentIndex())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
current_metadata = current_tab.metadata
|
current_metadata = current_tab.metadata
|
||||||
@@ -1144,8 +1154,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
|
|
||||||
self.lib_ref.update_proxymodels()
|
self.lib_ref.update_proxymodels()
|
||||||
|
|
||||||
def toggle_toolbars(self):
|
def toggle_distraction_free(self):
|
||||||
self.settings['show_toolbars'] = not self.settings['show_toolbars']
|
self.settings['show_bars'] = not self.settings['show_bars']
|
||||||
|
|
||||||
|
self.statusBar.setVisible(
|
||||||
|
not self.statusBar.isVisible())
|
||||||
|
self.tabWidget.tabBar().setVisible(
|
||||||
|
not self.tabWidget.tabBar().isVisible())
|
||||||
|
|
||||||
current_tab = self.tabWidget.currentIndex()
|
current_tab = self.tabWidget.currentIndex()
|
||||||
if current_tab == 0:
|
if current_tab == 0:
|
||||||
|
@@ -143,8 +143,6 @@ class Tab(QtWidgets.QWidget):
|
|||||||
self.horzLayout.addWidget(self.contentView)
|
self.horzLayout.addWidget(self.contentView)
|
||||||
self.horzLayout.addWidget(self.dockWidget)
|
self.horzLayout.addWidget(self.dockWidget)
|
||||||
title = self.metadata['title']
|
title = self.metadata['title']
|
||||||
if self.are_we_doing_images_only:
|
|
||||||
title = os.path.basename(title)
|
|
||||||
self.parent.addTab(self, title)
|
self.parent.addTab(self, title)
|
||||||
|
|
||||||
# Hide mouse cursor timer
|
# Hide mouse cursor timer
|
||||||
@@ -293,6 +291,9 @@ class Tab(QtWidgets.QWidget):
|
|||||||
self.contentView.setWindowState(QtCore.Qt.WindowNoState)
|
self.contentView.setWindowState(QtCore.Qt.WindowNoState)
|
||||||
self.contentView.show()
|
self.contentView.show()
|
||||||
|
|
||||||
|
# Hide the view modification buttons in case they're visible
|
||||||
|
self.main_window.bookToolBar.customize_view_off()
|
||||||
|
|
||||||
def change_chapter_tocBox(self):
|
def change_chapter_tocBox(self):
|
||||||
chapter_number = self.main_window.bookToolBar.tocBox.currentIndex()
|
chapter_number = self.main_window.bookToolBar.tocBox.currentIndex()
|
||||||
required_content = self.metadata['content'][chapter_number][1]
|
required_content = self.metadata['content'][chapter_number][1]
|
||||||
@@ -481,8 +482,8 @@ class Tab(QtWidgets.QWidget):
|
|||||||
class PliantQGraphicsView(QtWidgets.QGraphicsView):
|
class PliantQGraphicsView(QtWidgets.QGraphicsView):
|
||||||
def __init__(self, filepath, main_window, parent=None):
|
def __init__(self, filepath, main_window, parent=None):
|
||||||
super(PliantQGraphicsView, self).__init__(parent)
|
super(PliantQGraphicsView, self).__init__(parent)
|
||||||
self.main_window = main_window
|
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
self.main_window = main_window
|
||||||
|
|
||||||
self.qimage = None # Will be needed to resize pdf
|
self.qimage = None # Will be needed to resize pdf
|
||||||
self.image_pixmap = None
|
self.image_pixmap = None
|
||||||
@@ -516,6 +517,10 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView):
|
|||||||
self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
|
self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
|
||||||
self.viewport().setCursor(QtCore.Qt.ArrowCursor)
|
self.viewport().setCursor(QtCore.Qt.ArrowCursor)
|
||||||
|
|
||||||
|
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
|
||||||
|
self.customContextMenuRequested.connect(
|
||||||
|
self.generate_graphicsview_context_menu)
|
||||||
|
|
||||||
def loadImage(self, current_page):
|
def loadImage(self, current_page):
|
||||||
# TODO
|
# TODO
|
||||||
# For double page view: 1 before, 1 after
|
# For double page view: 1 before, 1 after
|
||||||
@@ -625,28 +630,98 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView):
|
|||||||
self.common_functions.wheelEvent(event, True)
|
self.common_functions.wheelEvent(event, True)
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
# This function is sufficiently different to warrant
|
vertical = self.verticalScrollBar().value()
|
||||||
# exclusion from the common functions class
|
maximum = self.verticalScrollBar().maximum()
|
||||||
|
|
||||||
# TODO
|
def scroller(increment, move_forward=True):
|
||||||
# Not working correctly
|
if move_forward:
|
||||||
# Add other keys: Up and Down
|
if vertical == maximum:
|
||||||
|
self.common_functions.change_chapter(1, True)
|
||||||
if event.key() == 32: # Spacebar press
|
else:
|
||||||
vertical = self.verticalScrollBar().value()
|
next_val = vertical + increment
|
||||||
maximum = self.verticalScrollBar().maximum()
|
if next_val >= .95 * maximum:
|
||||||
|
next_val = maximum
|
||||||
if vertical == maximum:
|
self.verticalScrollBar().setValue(next_val)
|
||||||
self.common_functions.change_chapter(1, True)
|
|
||||||
else:
|
else:
|
||||||
# Increment by following value
|
if vertical == 0:
|
||||||
scroll_increment = int((maximum - 0) / 2)
|
self.common_functions.change_chapter(-1, False)
|
||||||
self.verticalScrollBar().setValue(vertical + scroll_increment)
|
else:
|
||||||
|
next_val = vertical - increment
|
||||||
|
if next_val <= .05 * maximum:
|
||||||
|
next_val = 0
|
||||||
|
self.verticalScrollBar().setValue(next_val)
|
||||||
|
|
||||||
|
small_increment = maximum // 5
|
||||||
|
big_increment = maximum // 3
|
||||||
|
|
||||||
|
if event.key() == QtCore.Qt.Key_Up:
|
||||||
|
scroller(small_increment, False)
|
||||||
|
if event.key() == QtCore.Qt.Key_Down:
|
||||||
|
scroller(small_increment)
|
||||||
|
if event.key() == QtCore.Qt.Key_Space:
|
||||||
|
scroller(big_increment)
|
||||||
|
|
||||||
|
view_modification_keys = (
|
||||||
|
QtCore.Qt.Key_Plus, QtCore.Qt.Key_Minus, QtCore.Qt.Key_Equal,
|
||||||
|
QtCore.Qt.Key_B, QtCore.Qt.Key_W, QtCore.Qt.Key_O)
|
||||||
|
if event.key() in view_modification_keys:
|
||||||
|
self.main_window.modify_comic_view(event.key())
|
||||||
|
|
||||||
def mouseMoveEvent(self, *args):
|
def mouseMoveEvent(self, *args):
|
||||||
self.viewport().setCursor(QtCore.Qt.ArrowCursor)
|
self.viewport().setCursor(QtCore.Qt.ArrowCursor)
|
||||||
self.parent.mouse_hide_timer.start(3000)
|
self.parent.mouse_hide_timer.start(3000)
|
||||||
|
|
||||||
|
def generate_graphicsview_context_menu(self, position):
|
||||||
|
contextMenu = QtWidgets.QMenu()
|
||||||
|
viewSubMenu = contextMenu.addMenu('View')
|
||||||
|
|
||||||
|
saveAction = contextMenu.addAction(
|
||||||
|
self.main_window.QImageFactory.get_image('filesaveas'),
|
||||||
|
'Save page as...')
|
||||||
|
|
||||||
|
zoominAction = viewSubMenu.addAction(
|
||||||
|
self.main_window.QImageFactory.get_image('zoom-in'),
|
||||||
|
'Zoom in (+)')
|
||||||
|
|
||||||
|
zoomoutAction = viewSubMenu.addAction(
|
||||||
|
self.main_window.QImageFactory.get_image('zoom-out'),
|
||||||
|
'Zoom out (-)')
|
||||||
|
|
||||||
|
fitWidthAction = viewSubMenu.addAction(
|
||||||
|
self.main_window.QImageFactory.get_image('zoom-fit-width'),
|
||||||
|
'Fit width (W)')
|
||||||
|
|
||||||
|
bestFitAction = viewSubMenu.addAction(
|
||||||
|
self.main_window.QImageFactory.get_image('zoom-fit-best'),
|
||||||
|
'Best fit (B)')
|
||||||
|
|
||||||
|
originalSizeAction = viewSubMenu.addAction(
|
||||||
|
self.main_window.QImageFactory.get_image('zoom-original'),
|
||||||
|
'Original size (O)')
|
||||||
|
|
||||||
|
toggleAction = contextMenu.addAction(
|
||||||
|
self.main_window.QImageFactory.get_image('visibility'),
|
||||||
|
'Toggle distraction free mode')
|
||||||
|
|
||||||
|
action = contextMenu.exec_(self.sender().mapToGlobal(position))
|
||||||
|
|
||||||
|
if action == saveAction:
|
||||||
|
# TODO
|
||||||
|
# Save this page as an image
|
||||||
|
pass
|
||||||
|
if action == toggleAction:
|
||||||
|
self.main_window.toggle_distraction_free()
|
||||||
|
|
||||||
|
view_action_dict = {
|
||||||
|
zoominAction: QtCore.Qt.Key_Plus,
|
||||||
|
zoomoutAction: QtCore.Qt.Key_Minus,
|
||||||
|
fitWidthAction: QtCore.Qt.Key_W,
|
||||||
|
bestFitAction: QtCore.Qt.Key_B,
|
||||||
|
originalSizeAction: QtCore.Qt.Key_O}
|
||||||
|
|
||||||
|
if action in view_action_dict:
|
||||||
|
self.main_window.modify_comic_view(view_action_dict[action])
|
||||||
|
|
||||||
def closeEvent(self, *args):
|
def closeEvent(self, *args):
|
||||||
# In case the program is closed when a contentView is fullscreened
|
# In case the program is closed when a contentView is fullscreened
|
||||||
self.main_window.closeEvent()
|
self.main_window.closeEvent()
|
||||||
@@ -727,12 +802,18 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
|||||||
self.main_window.QImageFactory.get_image('search'),
|
self.main_window.QImageFactory.get_image('search'),
|
||||||
'Search')
|
'Search')
|
||||||
|
|
||||||
|
toggleAction = context_menu.addAction(
|
||||||
|
self.main_window.QImageFactory.get_image('visibility'),
|
||||||
|
'Toggle distraction free mode')
|
||||||
|
|
||||||
action = context_menu.exec_(self.sender().mapToGlobal(position))
|
action = context_menu.exec_(self.sender().mapToGlobal(position))
|
||||||
|
|
||||||
if action == defineAction:
|
if action == defineAction:
|
||||||
self.main_window.definitionDialog.find_definition(selected_word)
|
self.main_window.definitionDialog.find_definition(selected_word)
|
||||||
if action == searchAction:
|
if action == searchAction:
|
||||||
self.main_window.bookToolBar.searchBar.setFocus()
|
self.main_window.bookToolBar.searchBar.setFocus()
|
||||||
|
if action == toggleAction:
|
||||||
|
self.main_window.toggle_distraction_free()
|
||||||
|
|
||||||
def closeEvent(self, *args):
|
def closeEvent(self, *args):
|
||||||
self.main_window.closeEvent()
|
self.main_window.closeEvent()
|
||||||
|
@@ -49,7 +49,8 @@ class ParseCOMIC:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def get_title(self):
|
def get_title(self):
|
||||||
return self.book_extension[0]
|
title = os.path.basename(self.book_extension[0]).strip(' ')
|
||||||
|
return title
|
||||||
|
|
||||||
def get_author(self):
|
def get_author(self):
|
||||||
return None
|
return None
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import io
|
import io
|
||||||
|
import os
|
||||||
from PyQt5 import QtCore
|
from PyQt5 import QtCore
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ class ParsePDF:
|
|||||||
title = self.metadata.find('title').text
|
title = self.metadata.find('title').text
|
||||||
return title.replace('\n', '')
|
return title.replace('\n', '')
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return 'Unknown'
|
return os.path.splitext(os.path.basename(self.filename))[0]
|
||||||
|
|
||||||
def get_author(self):
|
def get_author(self):
|
||||||
try:
|
try:
|
||||||
|
8
resources/raw/DarkIcons/filesaveas.svg
Normal file
8
resources/raw/DarkIcons/filesaveas.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<defs>
|
||||||
|
<style id="current-color-scheme" type="text/css">
|
||||||
|
.ColorScheme-Text { color:#5c616c; } .ColorScheme-Highlight { color:#5294e2; }
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<path style="fill:currentColor" class="ColorScheme-Text" d="M 5.9980469 1.0195312 L 5.9980469 7.0195312 L 3.6582031 7.0195312 L 7.9902344 13.324219 L 12.371094 7.0195312 L 9.9980469 7.0195312 L 9.9980469 1.0488281 L 5.9980469 1.0195312 z M 1 14.03125 L 1 16 L 15.005859 16 L 15 14.03125 L 1 14.03125 z" transform="translate(4 4)"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 586 B |
8
resources/raw/DarkIcons/search.svg
Normal file
8
resources/raw/DarkIcons/search.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22">
|
||||||
|
<defs>
|
||||||
|
<style id="current-color-scheme" type="text/css">
|
||||||
|
.ColorScheme-Text { color:#5c616c; } .ColorScheme-Highlight { color:#5294e2; }
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<path style="fill:currentColor" class="ColorScheme-Text" d="M 6.4902344 0.99609375 C 3.4613344 0.99609375 0.99023438 3.4706937 0.99023438 6.4960938 C 0.99023438 9.5214938 3.4613344 11.996094 6.4902344 11.996094 C 7.6422344 11.996094 8.7279444 11.638254 9.6152344 11.027344 L 13.302734 14.714844 A 1.0055 1.0055 0 1 0 14.708984 13.277344 L 11.021484 9.5898438 C 11.632274 8.7038438 12.021484 7.6459938 12.021484 6.4960938 C 12.021484 3.4706937 9.5190344 0.99609375 6.4902344 0.99609375 z M 6.4902344 2.9960938 C 8.4376344 2.9960938 9.9902344 4.5508938 9.9902344 6.4960938 C 9.9902344 8.4411937 8.4376344 9.9960938 6.4902344 9.9960938 C 4.5428344 9.9960938 2.9902344 8.4411937 2.9902344 6.4960938 C 2.9902344 4.5508938 4.5428344 2.9960938 6.4902344 2.9960938 z" transform="translate(3 3)"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
8
resources/raw/LightIcons/filesaveas.svg
Normal file
8
resources/raw/LightIcons/filesaveas.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<defs>
|
||||||
|
<style id="current-color-scheme" type="text/css">
|
||||||
|
.ColorScheme-Text { color:#d3dae3; } .ColorScheme-Highlight { color:#5294e2; }
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<path style="fill:currentColor" class="ColorScheme-Text" d="M 5.9980469 1.0195312 L 5.9980469 7.0195312 L 3.6582031 7.0195312 L 7.9902344 13.324219 L 12.371094 7.0195312 L 9.9980469 7.0195312 L 9.9980469 1.0488281 L 5.9980469 1.0195312 z M 1 14.03125 L 1 16 L 15.005859 16 L 15 14.03125 L 1 14.03125 z" transform="translate(4 4)"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 586 B |
8
resources/raw/LightIcons/search.svg
Normal file
8
resources/raw/LightIcons/search.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22">
|
||||||
|
<defs>
|
||||||
|
<style id="current-color-scheme" type="text/css">
|
||||||
|
.ColorScheme-Text { color:#d3dae3; } .ColorScheme-Highlight { color:#5294e2; }
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
<path style="fill:currentColor" class="ColorScheme-Text" d="M 6.4902344 0.99609375 C 3.4613344 0.99609375 0.99023438 3.4706937 0.99023438 6.4960938 C 0.99023438 9.5214938 3.4613344 11.996094 6.4902344 11.996094 C 7.6422344 11.996094 8.7279444 11.638254 9.6152344 11.027344 L 13.302734 14.714844 A 1.0055 1.0055 0 1 0 14.708984 13.277344 L 11.021484 9.5898438 C 11.632274 8.7038438 12.021484 7.6459938 12.021484 6.4960938 C 12.021484 3.4706937 9.5190344 0.99609375 6.4902344 0.99609375 z M 6.4902344 2.9960938 C 8.4376344 2.9960938 9.9902344 4.5508938 9.9902344 6.4960938 C 9.9902344 8.4411937 8.4376344 9.9960938 6.4902344 9.9960938 C 4.5428344 9.9960938 2.9902344 8.4411937 2.9902344 6.4960938 C 2.9902344 4.5508938 4.5428344 2.9960938 6.4902344 2.9960938 z" transform="translate(3 3)"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
@@ -1,5 +1,9 @@
|
|||||||
<RCC>
|
<RCC>
|
||||||
<qresource prefix="images">
|
<qresource prefix="images">
|
||||||
|
<file>DarkIcons/filesaveas.svg</file>
|
||||||
|
<file>LightIcons/filesaveas.svg</file>
|
||||||
|
<file>DarkIcons/search.svg</file>
|
||||||
|
<file>LightIcons/search.svg</file>
|
||||||
<file>xmark.svg</file>
|
<file>xmark.svg</file>
|
||||||
<file>DarkIcons/add.svg</file>
|
<file>DarkIcons/add.svg</file>
|
||||||
<file>DarkIcons/bookmark-new.svg</file>
|
<file>DarkIcons/bookmark-new.svg</file>
|
||||||
|
File diff suppressed because it is too large
Load Diff
2
setup.py
2
setup.py
@@ -6,7 +6,7 @@ HERE = path.abspath(path.dirname(__file__))
|
|||||||
|
|
||||||
MAJOR_VERSION = '0'
|
MAJOR_VERSION = '0'
|
||||||
MINOR_VERSION = '2'
|
MINOR_VERSION = '2'
|
||||||
MICRO_VERSION = '0'
|
MICRO_VERSION = '1'
|
||||||
VERSION = "{}.{}.{}".format(MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION)
|
VERSION = "{}.{}.{}".format(MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION)
|
||||||
|
|
||||||
# Get the long description from the README file
|
# Get the long description from the README file
|
||||||
|
Reference in New Issue
Block a user