Implement search UI

Discovered severe inadequacies. Some of them were in the program.
This commit is contained in:
BasioMeusPuga
2019-01-08 05:47:50 +05:30
parent f9eec130dd
commit 026fff3d7a
20 changed files with 6383 additions and 5576 deletions

View File

@@ -171,9 +171,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.libraryToolBar.tableViewButton.trigger()
# Book toolbar
self.bookToolBar.annotationButton.triggered.connect(self.toggle_side_dock)
self.bookToolBar.annotationButton.triggered.connect(
lambda: self.tabWidget.currentWidget().toggle_side_dock(0))
self.bookToolBar.addBookmarkButton.triggered.connect(self.add_bookmark)
self.bookToolBar.bookmarkButton.triggered.connect(self.toggle_side_dock)
self.bookToolBar.bookmarkButton.triggered.connect(
lambda: self.tabWidget.currentWidget().toggle_side_dock(1))
self.bookToolBar.searchButton.triggered.connect(
lambda: self.tabWidget.currentWidget().toggle_side_dock(2))
self.bookToolBar.distractionFreeButton.triggered.connect(self.toggle_distraction_free)
self.bookToolBar.fullscreenButton.triggered.connect(self.set_fullscreen)
@@ -189,7 +193,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.bookToolBar.profileBox.currentIndexChanged.connect(
self.profile_functions.format_contentView)
self.bookToolBar.profileBox.setCurrentIndex(self.current_profile_index)
self.bookToolBar.searchBar.textChanged.connect(self.search_book)
self.bookToolBar.fontBox.currentFontChanged.connect(self.modify_font)
self.bookToolBar.fontSizeBox.currentIndexChanged.connect(self.modify_font)
@@ -219,9 +222,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
self.bookToolBar.tocBox.currentIndexChanged.connect(self.set_toc_position)
self.addToolBar(self.bookToolBar)
# Get the stylesheet of the default QLineEdit
self.lineEditStyleSheet = self.bookToolBar.searchBar.styleSheet()
# Make the correct toolbar visible
self.current_tab = self.tabWidget.currentIndex()
self.tab_switch()
@@ -701,16 +701,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
def set_fullscreen(self):
self.tabWidget.currentWidget().go_fullscreen()
def toggle_side_dock(self):
# Tab indices are fixed
# 0 = Annotations
# 1 = Bookmarks
sender = self.sender()
if sender == self.bookToolBar.annotationButton:
self.tabWidget.currentWidget().toggle_side_dock(0)
if sender == self.bookToolBar.bookmarkButton:
self.tabWidget.currentWidget().toggle_side_dock(1)
def library_doubleclick(self, index):
sender = self.sender().objectName()
@@ -774,6 +764,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
and not self.tabWidget.currentWidget().are_we_doing_images_only):
return
self.tabWidget.currentWidget().sideDock.setVisible(True)
self.tabWidget.currentWidget().sideDockTabWidget.setCurrentIndex(2)
contentView = self.tabWidget.currentWidget().contentView
text_cursor = contentView.textCursor()
@@ -787,10 +780,10 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
text_cursor.clearSelection()
contentView.setTextCursor(text_cursor)
if not something_found:
self.bookToolBar.searchBar.setStyleSheet("QLineEdit {color: red;}")
else:
self.bookToolBar.searchBar.setStyleSheet(self.lineEditStyleSheet)
# if not something_found:
# self.bookToolBar.searchBar.setStyleSheet("QLineEdit {color: red;}")
# else:
# self.bookToolBar.searchBar.setStyleSheet(self.lineEditStyleSheet)
def generate_library_context_menu(self, position):
index = self.sender().indexAt(position)

View File

@@ -371,6 +371,8 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView):
self.main_window.closeEvent()
def toggle_annotation_mode(self):
# The graphics view doesn't currently have annotation functionality
# Don't delete this because it's still called
pass
@@ -554,6 +556,10 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
searchYoutubeAction = searchSubMenu.addAction(
QtGui.QIcon(':/images/Youtube.png'),
'Youtube')
else:
searchAction = contextMenu.addAction(
self.main_window.QImageFactory.get_image('search'),
self._translate('PliantQTextBrowser', 'Search'))
if annotation_is_present:
annotationsubMenu = contextMenu.addMenu('Annotation')
@@ -582,6 +588,11 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
self.main_window.QImageFactory.get_image('visibility'),
distraction_free_prompt)
add_bookmark_string = self._translate('PliantQTextBrowser', 'Add Bookmark')
addBookMarkAction = contextMenu.addAction(
self.main_window.QImageFactory.get_image('bookmark-new'),
add_bookmark_string)
if not self.main_window.settings['show_bars'] or self.parent.is_fullscreen:
bookmarksToggleAction = contextMenu.addAction(
self.main_window.QImageFactory.get_image('bookmarks'),
@@ -591,12 +602,17 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
action = contextMenu.exec_(self.sender().mapToGlobal(position))
if action == addBookMarkAction:
self.parent.add_bookmark(cursor_at_mouse.position())
if action == defineAction:
self.main_window.definitionDialog.find_definition(selection)
if action == searchAction:
self.main_window.bookToolBar.searchBar.setText(selection)
self.main_window.bookToolBar.searchBar.setFocus()
if selection and selection != '':
self.parent.searchLineEdit.setText(selection)
self.parent.toggle_side_dock(2, True)
if action == searchGoogleAction:
webbrowser.open_new_tab(
f'https://www.google.com/search?q={selection}')

View File

@@ -81,7 +81,7 @@ class DefinitionsUI(QtWidgets.QDialog, definitions.Ui_Dialog):
if response.getcode() == 200:
return_json = json.loads(response.read())
return return_json
except urllib.error.HTTPError:
except (urllib.error.HTTPError, urllib.error.URLError):
return None
def find_definition(self, word):

View File

@@ -149,6 +149,7 @@ class Library:
item.setToolTip(tooltip_string)
# Just keep the following order. It's way too much trouble otherwise
# User roles have to be correlated to sorting order below
item.setData(title, QtCore.Qt.UserRole)
item.setData(author, QtCore.Qt.UserRole + 1)
item.setData(year, QtCore.Qt.UserRole + 2)

View File

@@ -1,5 +1,5 @@
# This file is a part of Lector, a Qt based ebook reader
# Copyright (C) 2017-18 BasioMeusPuga
# Copyright (C) 2017-19 BasioMeusPuga
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@@ -1,5 +1,5 @@
# This file is a part of Lector, a Qt based ebook reader
# Copyright (C) 2017-2018 BasioMeusPuga
# Copyright (C) 2017-2019 BasioMeusPuga
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@@ -1,5 +1,5 @@
# This file is a part of Lector, a Qt based ebook reader
# Copyright (C) 2017-2018 BasioMeusPuga
# Copyright (C) 2017-2019 BasioMeusPuga
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@@ -1,5 +1,5 @@
# This file is a part of Lector, a Qt based ebook reader
# Copyright (C) 2017-2018 BasioMeusPuga
# Copyright (C) 2017-2019 BasioMeusPuga
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@@ -1,5 +1,5 @@
# This file is a part of Lector, a Qt based ebook reader
# Copyright (C) 2017-2018 BasioMeusPuga
# Copyright (C) 2017-2019 BasioMeusPuga
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@@ -1,5 +1,5 @@
# This file is a part of Lector, a Qt based ebook reader
# Copyright (C) 2017-2018 BasioMeusPuga
# Copyright (C) 2017-2019 BasioMeusPuga
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -67,7 +67,7 @@ class EPUB:
def get_file_path(self, filename, is_content_file=False):
# Use this to get the location of the content.opf file
# And maybe some other file that has a more well formatted
# idea of the TOC
# We're going to all this trouble because there really is
# no going forward without a toc
if is_content_file:

View File

@@ -1,5 +1,5 @@
# This file is a part of Lector, a Qt based ebook reader
# Copyright (C) 2017-2018 BasioMeusPuga
# Copyright (C) 2017-2019 BasioMeusPuga
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
version="1.1"
id="svg4"
sodipodi:docname="search-case.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1480"
inkscape:window-height="750"
id="namedview6"
showgrid="false"
inkscape:zoom="14.75"
inkscape:cx="-6.5084746"
inkscape:cy="8"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg4" />
<path
style="fill:#5c616c;fill-opacity:1"
d="M 4.7890625,2 1,13 h 1.90625 l 0.6796875,-2 h 3.8300781 l 0.6875,2 H 10 L 6.2109375,2 Z M 5.4980469,5.4375 6.6835938,9 H 4.3144531 Z M 11.5,8 v 1 h 3 C 14.715,9 15,9.305 15,9.5 V 10 h -2.5 c -0.46,0 -0.87,0.189375 -1.125,0.484375 C 11.12,10.774375 11,11.14 11,11.5 c 0,0.36 0.135625,0.725625 0.390625,1.015625 C 11.645625,12.805625 12.045,13 12.5,13 H 16 V 9.5 C 16,8.685 15.34,8 14.5,8 Z m 1,3 H 15 v 1 H 12.5 C 12.3,12 12.215625,11.944375 12.140625,11.859375 12.065625,11.774375 12,11.64 12,11.5 12,11.36 12.05,11.225625 12.125,11.140625 12.2,11.060625 12.29,11 12.5,11 Z"
id="path2" />
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
version="1.1"
id="svg4"
sodipodi:docname="search-word.svg"
inkscape:version="0.92.2 2405546, 2018-03-11">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1043"
id="namedview6"
showgrid="false"
inkscape:zoom="45.254834"
inkscape:cx="6.5123537"
inkscape:cy="6.8917559"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<path
style="fill:#5c616c;fill-opacity:1"
d="M 3,3 C 1.02036,3 -9.9999927e-7,4.1718311 0,6.6074219 V 8.5 A 1.5,1.5 0 0 0 1.5,10 1.5,1.5 0 0 0 3,8.5 1.5,1.5 0 0 0 1.5097656,7 l -0.00781,-0.4023438 c 0,-0.948207 0.1116447,-1.5979182 0.3378907,-1.9511718 C 2.0660618,4.29323 2.453243,4.0371834 3,4 Z M 7,3 C 5.02036,3 3.999999,4.1718311 4,6.6074219 V 8.5 A 1.5,1.5 0 0 0 5.5,10 1.5,1.5 0 0 0 7,8.5 1.5,1.5 0 0 0 5.5097656,7 l -0.00781,-0.4023438 c 0,-0.948207 0.1116447,-1.5979182 0.3378907,-1.9511718 C 6.0660608,4.29323 6.453243,4.0371834 7,4 Z M 9.5,5 A 1.5,1.5 0 0 0 8,6.5 1.5,1.5 0 0 0 9.490234,8 l 0.00781,0.4023438 c 0,0.948207 -0.111645,1.5979182 -0.337891,1.9511722 C 8.9339389,10.70677 8.5467573,10.962817 8,11 v 1 c 1.97964,0 3.000001,-1.171831 3,-3.6074219 V 6.5 A 1.5,1.5 0 0 0 9.5,5 Z m 4,0 A 1.5,1.5 0 0 0 12,6.5 1.5,1.5 0 0 0 13.490234,8 l 0.0078,0.4023438 c 0,0.948207 -0.111645,1.5979182 -0.337891,1.9511722 C 12.933938,10.70677 12.546757,10.962817 12,11 v 1 c 1.97964,0 3.000001,-1.171831 3,-3.6074219 V 6.5 A 1.5,1.5 0 0 0 13.5,5 Z"
id="path2" />
<path
style="fill:#5c616c;stroke:none;stroke-width:0.06779661;fill-opacity:1"
d="M 8.040678,11.489133 V 11.01394 l 0.2542373,-0.0411 C 8.6241141,10.91962 9.0049959,10.657098 9.1919904,10.354534 9.3774432,10.054466 9.5267422,9.2371719 9.5298381,8.5050867 9.5321781,7.9511596 9.5305475,7.9457647 9.3605343,7.9457647 8.6870054,7.9457647 8.0454876,7.2386514 8.0421669,6.4925935 8.0367069,5.2649491 9.4833138,4.5924333 10.437555,5.379 c 0.470567,0.3878808 0.518377,0.5947737 0.518377,2.2432227 0,0.9924588 -0.03143,1.6284257 -0.09756,1.9740504 -0.267079,1.3958959 -1.1175811,2.2244799 -2.3939662,2.3322709 l -0.4237288,0.03579 z"
id="path4524"
inkscape:connector-curvature="0" />
<path
style="fill:#5c616c;stroke:none;stroke-width:0.00390625;fill-opacity:1"
d="m 9.7117131,11.513295 c 0.00204,-0.0018 0.023926,-0.01759 0.048633,-0.03507 0.1798996,-0.127248 0.3444879,-0.28336 0.4858319,-0.460812 0.252616,-0.317149 0.444866,-0.723077 0.559095,-1.1805105 0.06615,-0.2648918 0.09348,-0.4533196 0.116987,-0.8066406 C 10.94809,8.6420545 10.9575,8.1721993 10.95441,7.4247931 10.952,6.840388 10.947836,6.672371 10.92997,6.438465 10.924141,6.3621478 10.9106,6.2310896 10.906461,6.2109259 l -0.0022,-0.010742 h 0.0313 c 0.0366,0 0.0324,-0.00607 0.0433,0.0625 0.01847,0.1161553 0.01782,0.070812 0.01782,1.25 0,1.1705155 -1.65e-4,1.1838055 -0.01779,1.4296875 -0.05607,0.7822203 -0.232739,1.4031726 -0.538111,1.8913516 -0.157745,0.252177 -0.36026,0.471333 -0.5979529,0.647089 l -0.048386,0.03578 h -0.043215 c -0.023798,0 -0.041548,-0.0015 -0.039504,-0.0033 z"
id="path4526"
inkscape:connector-curvature="0" />
<path
style="fill:#5c616c;stroke:none;stroke-width:0.00390625;fill-opacity:1"
d="m 8.0037065,11.500359 v -0.499846 l 0.038086,-0.0025 c 0.052532,-0.0035 0.1567951,-0.0193 0.2234149,-0.03389 C 8.640889,10.881833 8.9448125,10.678717 9.1476483,10.374368 9.3523256,10.067256 9.4641833,9.5521406 9.492672,8.7855008 L 9.497502,8.655618 H 9.512387 9.527272 L 9.524992,8.705423 C 9.5049185,9.1437939 9.4502274,9.5471986 9.3653315,9.8830268 9.3036893,10.126869 9.2445481,10.277176 9.1635619,10.395823 9.0101537,10.620571 8.748788,10.822299 8.4830209,10.92108 c -0.078653,0.02923 -0.1439508,0.04431 -0.30158,0.06961 l -0.140625,0.02258 -9.922e-4,0.475456 c -9.556e-4,0.457983 -7.301e-4,0.475456 0.00614,0.475456 0.012211,0 0.421374,-0.03493 0.483138,-0.04125 0.3949367,-0.04038 0.7679272,-0.159625 1.078125,-0.344663 0.023633,-0.0141 0.0556,-0.03409 0.071038,-0.04442 l 0.028069,-0.01879 0.04029,0.003 0.04029,0.003 -0.046244,0.03035 c -0.2869093,0.188322 -0.6383031,0.321037 -1.0300398,0.389028 -0.189836,0.03295 -0.3718111,0.04969 -0.6219586,0.0572 l -0.084961,0.0026 z"
id="path4528"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 4.7890625,2 1,13 h 1.90625 l 0.6796875,-2 h 3.8300781 l 0.6875,2 H 10 L 6.2109375,2 Z M 5.4980469,5.4375 6.6835938,9 H 4.3144531 Z M 11.5,8 v 1 h 3 C 14.715,9 15,9.305 15,9.5 V 10 h -2.5 c -0.46,0 -0.87,0.189375 -1.125,0.484375 C 11.12,10.774375 11,11.14 11,11.5 c 0,0.36 0.135625,0.725625 0.390625,1.015625 C 11.645625,12.805625 12.045,13 12.5,13 H 16 V 9.5 C 16,8.685 15.34,8 14.5,8 Z m 1,3 H 15 v 1 H 12.5 C 12.3,12 12.215625,11.944375 12.140625,11.859375 12.065625,11.774375 12,11.64 12,11.5 12,11.36 12.05,11.225625 12.125,11.140625 12.2,11.060625 12.29,11 12.5,11 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 693 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" version="1.1">
<path style="fill:#dfdfdf" d="M 3,3 C 1.02036,3 -9.9999927e-7,4.1718311 0,6.6074219 V 8.5 A 1.5,1.5 0 0 0 1.5,10 1.5,1.5 0 0 0 3,8.5 1.5,1.5 0 0 0 1.5097656,7 l -0.00781,-0.4023438 c 0,-0.948207 0.1116447,-1.5979182 0.3378907,-1.9511718 C 2.0660618,4.29323 2.453243,4.0371834 3,4 Z M 7,3 C 5.02036,3 3.999999,4.1718311 4,6.6074219 V 8.5 A 1.5,1.5 0 0 0 5.5,10 1.5,1.5 0 0 0 7,8.5 1.5,1.5 0 0 0 5.5097656,7 l -0.00781,-0.4023438 c 0,-0.948207 0.1116447,-1.5979182 0.3378907,-1.9511718 C 6.0660608,4.29323 6.453243,4.0371834 7,4 Z M 9.5,5 A 1.5,1.5 0 0 0 8,6.5 1.5,1.5 0 0 0 9.490234,8 l 0.00781,0.4023438 c 0,0.948207 -0.111645,1.5979182 -0.337891,1.9511722 C 8.9339389,10.70677 8.5467573,10.962817 8,11 v 1 c 1.97964,0 3.000001,-1.171831 3,-3.6074219 V 6.5 A 1.5,1.5 0 0 0 9.5,5 Z m 4,0 A 1.5,1.5 0 0 0 12,6.5 1.5,1.5 0 0 0 13.490234,8 l 0.0078,0.4023438 c 0,0.948207 -0.111645,1.5979182 -0.337891,1.9511722 C 12.933938,10.70677 12.546757,10.962817 12,11 v 1 c 1.97964,0 3.000001,-1.171831 3,-3.6074219 V 6.5 A 1.5,1.5 0 0 0 13.5,5 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,5 +1,9 @@
<RCC>
<qresource prefix="images">
<file>DarkIcons/search-word.svg</file>
<file>DarkIcons/search-case.svg</file>
<file>LightIcons/search-word.svg</file>
<file>LightIcons/search-case.svg</file>
<file>DarkIcons/page-single.svg</file>
<file>DarkIcons/page-double.svg</file>
<file>LightIcons/page-single.svg</file>

File diff suppressed because it is too large Load Diff

View File

@@ -27,9 +27,6 @@ class BookToolBar(QtWidgets.QToolBar):
spacer.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy = QtWidgets.QSizePolicy(
QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self.setMovable(False)
self.setIconSize(QtCore.QSize(22, 22))
self.setFloatable(False)
@@ -45,7 +42,7 @@ class BookToolBar(QtWidgets.QToolBar):
self)
self.annotationButton = QtWidgets.QAction(
image_factory.get_image('annotate'),
self._translate('BookToolBar', 'Annotations'),
self._translate('BookToolBar', 'Annotations (Ctrl + N)'),
self)
self.addBookmarkButton = QtWidgets.QAction(
image_factory.get_image('bookmark-new'),
@@ -55,13 +52,17 @@ class BookToolBar(QtWidgets.QToolBar):
image_factory.get_image('bookmarks'),
self._translate('BookToolBar', 'Bookmarks (Ctrl + B)'),
self)
self.searchButton = QtWidgets.QAction(
image_factory.get_image('search'),
self._translate('BookToolBar', 'Search (Ctrl + F)'),
self)
self.distractionFreeButton = QtWidgets.QAction(
image_factory.get_image('visibility'),
self._translate('Main_BookToolBarUI', 'Toggle distraction free mode (Ctrl + D)'),
self)
self.fullscreenButton = QtWidgets.QAction(
image_factory.get_image('view-fullscreen'),
self._translate('BookToolBar', 'Fullscreen (F11)'),
self._translate('BookToolBar', 'Fullscreen (F)'),
self)
self.resetProfile = QtWidgets.QAction(
image_factory.get_image('reload'),
@@ -72,12 +73,14 @@ class BookToolBar(QtWidgets.QToolBar):
self.addAction(self.fontButton)
self.fontButton.setCheckable(True)
self.fontButton.triggered.connect(self.toggle_font_settings)
self.addSeparator()
self.bookSeparator1 = self.addSeparator()
self.addAction(self.searchButton)
self.bookSeparator2 = self.addSeparator()
self.addAction(self.annotationButton)
self.addSeparator()
self.bookSeparator3 = self.addSeparator()
self.addAction(self.addBookmarkButton)
self.addAction(self.bookmarkButton)
self.addSeparator()
self.bookSeparator4 = self.addSeparator()
self.addAction(self.distractionFreeButton)
self.addAction(self.fullscreenButton)
@@ -175,7 +178,7 @@ class BookToolBar(QtWidgets.QToolBar):
self.fontSeparator4 = self.addSeparator()
self.addAction(self.paddingUp)
self.addAction(self.paddingDown)
self.fontSeparator4 = self.addSeparator()
self.fontSeparator5 = self.addSeparator()
self.addAction(self.alignLeft)
self.addAction(self.alignRight)
self.addAction(self.alignCenter)
@@ -199,6 +202,7 @@ class BookToolBar(QtWidgets.QToolBar):
self.fontSeparator2,
self.fontSeparator3,
self.fontSeparator4,
self.fontSeparator5,
self.resetProfile]
for i in self.fontActions:
@@ -287,14 +291,6 @@ class BookToolBar(QtWidgets.QToolBar):
for i in self.comicActions:
i.setVisible(False)
# Other booktoolbar widgets
self.searchBar = FixedLineEdit(self)
self.searchBar.setPlaceholderText(
self._translate('BookToolBar', 'Search...'))
self.searchBar.setSizePolicy(sizePolicy)
self.searchBar.setContentsMargins(10, 0, 0, 0)
self.searchBar.setObjectName('searchBar')
# Sorter
self.tocBox = FixedComboBox(self)
self.tocBox.setObjectName('sortingBox')
@@ -304,10 +300,8 @@ class BookToolBar(QtWidgets.QToolBar):
# All of these will be put after the spacer
# This means that the buttons in the left side of
# the toolbar have to split up and added here
self.boxSpacer = self.addWidget(spacer)
self.addWidget(spacer)
self.tocBoxAction = self.addWidget(self.tocBox)
self.searchBarAction = self.addWidget(self.searchBar)
self.bookActions = [
self.annotationButton,
@@ -316,7 +310,9 @@ class BookToolBar(QtWidgets.QToolBar):
self.distractionFreeButton,
self.fullscreenButton,
self.tocBoxAction,
self.searchBarAction]
self.bookSeparator2,
self.bookSeparator3,
self.bookSeparator4]
for i in self.bookActions:
i.setVisible(True)
@@ -368,10 +364,6 @@ class LibraryToolBar(QtWidgets.QToolBar):
super(LibraryToolBar, self).__init__(parent)
self._translate = QtCore.QCoreApplication.translate
spacer = QtWidgets.QWidget()
spacer.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.setMovable(False)
self.setIconSize(QtCore.QSize(22, 22))
self.setFloatable(False)
@@ -418,8 +410,6 @@ class LibraryToolBar(QtWidgets.QToolBar):
self.libraryFilterButton = QtWidgets.QToolButton(self)
self.libraryFilterButton.setIcon(image_factory.get_image('view-readermode'))
self.libraryFilterButton.setText(
self._translate('LibraryToolBar', 'Filter library'))
self.libraryFilterButton.setToolTip(
self._translate('LibraryToolBar', 'Filter library'))
@@ -451,7 +441,7 @@ class LibraryToolBar(QtWidgets.QToolBar):
self.searchBar.setPlaceholderText(
self._translate('LibraryToolBar', 'Search for Title, Author, Tags...'))
self.searchBar.setSizePolicy(sizePolicy)
self.searchBar.setContentsMargins(10, 0, 0, 0)
self.searchBar.setContentsMargins(0, 0, 10, 0)
self.searchBar.setObjectName('searchBar')
# Sorter
@@ -472,10 +462,15 @@ class LibraryToolBar(QtWidgets.QToolBar):
self.sortingBox.setMinimumContentsLength(10)
self.sortingBox.setToolTip(self._translate('LibraryToolBar', 'Sort by'))
# Spacer
spacer = QtWidgets.QWidget()
spacer.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# Add widgets
self.addWidget(spacer)
self.sortingBoxAction = self.addWidget(self.sortingBox)
self.addWidget(self.searchBar)
self.sortingBoxAction = self.addWidget(self.sortingBox)
# Sublassing these widgets out prevents them from resizing

View File

@@ -129,11 +129,10 @@ class Tab(QtWidgets.QWidget):
self.sideDock.setWidget(self.sideDockTabWidget)
# Annotation list view and model
self.annotationListView = QtWidgets.QListView(self.sideDock)
self.annotationListView.setResizeMode(QtWidgets.QListWidget.Adjust)
self.annotationListView.setMaximumWidth(350)
self.annotationListView.doubleClicked.connect(self.contentView.toggle_annotation_mode)
self.annotationListView = QtWidgets.QListView(self.sideDockTabWidget)
# self.annotationListView.setResizeMode(QtWidgets.QListWidget.Adjust)
self.annotationListView.setEditTriggers(QtWidgets.QListView.NoEditTriggers)
self.annotationListView.doubleClicked.connect(self.contentView.toggle_annotation_mode)
annotations_string = self._translate('Tab', 'Annotations')
self.sideDockTabWidget.addTab(self.annotationListView, annotations_string)
@@ -141,9 +140,8 @@ class Tab(QtWidgets.QWidget):
self.generate_annotation_model()
# Bookmark tree view and model
self.bookmarkTreeView = QtWidgets.QTreeView(self.sideDock)
self.bookmarkTreeView = QtWidgets.QTreeView(self.sideDockTabWidget)
self.bookmarkTreeView.setHeaderHidden(True)
self.bookmarkTreeView.setMaximumWidth(350)
self.bookmarkTreeView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.bookmarkTreeView.customContextMenuRequested.connect(
self.generate_bookmark_context_menu)
@@ -155,6 +153,56 @@ class Tab(QtWidgets.QWidget):
self.bookmarkProxyModel = BookmarkProxyModel(self)
self.generate_bookmark_model()
# Search view and model
self.searchLineEdit = QtWidgets.QLineEdit(self.sideDockTabWidget)
self.searchLineEdit.setFocusPolicy(QtCore.Qt.StrongFocus)
search_string = self._translate('Tab', 'Search')
self.searchLineEdit.setPlaceholderText(search_string)
search_book_string = self._translate('Tab', 'Search entire book')
self.searchBookButton = QtWidgets.QToolButton(self.sideDockTabWidget)
self.searchBookButton.setIcon(
self.main_window.QImageFactory.get_image('view-readermode'))
self.searchBookButton.setToolTip(search_book_string)
self.searchBookButton.setCheckable(True)
self.searchBookButton.setAutoRaise(True)
case_sensitive_string = self._translate('Tab', 'Match case')
self.caseSensitiveSearchButton = QtWidgets.QToolButton(self.sideDockTabWidget)
self.caseSensitiveSearchButton.setIcon(
self.main_window.QImageFactory.get_image('search-case'))
self.caseSensitiveSearchButton.setToolTip(case_sensitive_string)
self.caseSensitiveSearchButton.setCheckable(True)
self.caseSensitiveSearchButton.setAutoRaise(True)
match_word_string = self._translate('Tab', 'Match word')
self.matchWholeWordButton = QtWidgets.QToolButton(self.sideDockTabWidget)
self.matchWholeWordButton.setIcon(
self.main_window.QImageFactory.get_image('search-word'))
self.matchWholeWordButton.setToolTip(match_word_string)
self.matchWholeWordButton.setCheckable(True)
self.matchWholeWordButton.setAutoRaise(True)
self.searchOptionsLayout = QtWidgets.QHBoxLayout()
self.searchOptionsLayout.setContentsMargins(0, 3, 0, 0)
self.searchOptionsLayout.addWidget(self.searchLineEdit)
self.searchOptionsLayout.addWidget(self.searchBookButton)
self.searchOptionsLayout.addWidget(self.caseSensitiveSearchButton)
self.searchOptionsLayout.addWidget(self.matchWholeWordButton)
self.searchResultsListView = QtWidgets.QListView(self.sideDockTabWidget)
self.searchResultsListView.setEditTriggers(QtWidgets.QListView.NoEditTriggers)
self.searchResultsListView.doubleClicked.connect(self.go_to_search_result)
self.searchTabLayout = QtWidgets.QVBoxLayout(self.sideDockTabWidget)
self.searchTabLayout.addLayout(self.searchOptionsLayout)
self.searchTabLayout.addWidget(self.searchResultsListView)
self.searchTabLayout.setContentsMargins(0, 0, 0, 0)
self.searchTabWidget = QtWidgets.QWidget(self.sideDockTabWidget)
self.searchTabWidget.setLayout(self.searchTabLayout)
self.sideDockTabWidget.addTab(self.searchTabWidget, search_string)
# Create the annotation notes dock
self.annotationNoteDock = PliantDockWidget(self.main_window, True, self.contentView)
self.annotationNoteDock.setWindowTitle(self._translate('Tab', 'Note'))
@@ -177,6 +225,7 @@ class Tab(QtWidgets.QWidget):
self.sideDock.setWindowOpacity(.95)
self.annotationNoteDock.setFloating(True)
self.annotationNoteDock.setWindowOpacity(.95)
self.sideDock.hide()
title = self.metadata['title']
if self.main_window.settings['attenuate_titles'] and len(title) > 30:
@@ -200,17 +249,18 @@ class Tab(QtWidgets.QWidget):
self.contentView.setFocus()
def toggle_side_dock(self, tab_required=1):
def toggle_side_dock(self, tab_required, override_hide=False):
if (self.sideDock.isVisible()
and self.sideDockTabWidget.currentIndex() == tab_required):
and self.sideDockTabWidget.currentIndex() == tab_required
and not override_hide):
self.sideDock.hide()
elif not self.sideDock.isVisible():
self.sideDock.show()
if tab_required == 2:
self.sideDock.activateWindow()
self.searchLineEdit.setFocus()
if tab_required == 0:
self.sideDockTabWidget.setCurrentIndex(0)
else: # Takes care of the action menu as well
self.sideDockTabWidget.setCurrentIndex(1)
self.sideDockTabWidget.setCurrentIndex(tab_required)
def update_last_accessed_time(self):
self.metadata['last_accessed'] = QtCore.QDateTime().currentDateTime()
@@ -283,28 +333,36 @@ class Tab(QtWidgets.QWidget):
'cursor_position': 0}
def generate_keyboard_shortcuts(self):
self.ksNextChapter = QtWidgets.QShortcut(
ksNextChapter = QtWidgets.QShortcut(
QtGui.QKeySequence('Right'), self.contentView)
self.ksNextChapter.setObjectName('nextChapter')
self.ksNextChapter.activated.connect(self.sneaky_change)
ksNextChapter.setObjectName('nextChapter')
ksNextChapter.activated.connect(self.sneaky_change)
self.ksPrevChapter = QtWidgets.QShortcut(
ksPrevChapter = QtWidgets.QShortcut(
QtGui.QKeySequence('Left'), self.contentView)
self.ksPrevChapter.setObjectName('prevChapter')
self.ksPrevChapter.activated.connect(self.sneaky_change)
ksPrevChapter.setObjectName('prevChapter')
ksPrevChapter.activated.connect(self.sneaky_change)
self.ksGoFullscreen = QtWidgets.QShortcut(
QtGui.QKeySequence('F11'), self.contentView)
self.ksGoFullscreen.activated.connect(self.go_fullscreen)
ksGoFullscreen = QtWidgets.QShortcut(
QtGui.QKeySequence('F'), self.contentView)
ksGoFullscreen.activated.connect(self.go_fullscreen)
self.ksExitFullscreen = QtWidgets.QShortcut(
ksExitFullscreen = QtWidgets.QShortcut(
QtGui.QKeySequence('Escape'), self.contentView)
self.ksExitFullscreen.setContext(QtCore.Qt.ApplicationShortcut)
self.ksExitFullscreen.activated.connect(self.exit_fullscreen)
ksExitFullscreen.setContext(QtCore.Qt.ApplicationShortcut)
ksExitFullscreen.activated.connect(self.exit_fullscreen)
self.ksToggleBookMarks = QtWidgets.QShortcut(
ksToggleAnnotations = QtWidgets.QShortcut(
QtGui.QKeySequence('Ctrl+N'), self.contentView)
ksToggleAnnotations.activated.connect(lambda: self.toggle_side_dock(0))
ksToggleBookmarks = QtWidgets.QShortcut(
QtGui.QKeySequence('Ctrl+B'), self.contentView)
self.ksToggleBookMarks.activated.connect(self.toggle_side_dock)
ksToggleBookmarks.activated.connect(lambda: self.toggle_side_dock(1))
ksToggleSearch = QtWidgets.QShortcut(
QtGui.QKeySequence('Ctrl+F'), self.contentView)
ksToggleSearch.activated.connect(lambda: self.toggle_side_dock(2))
def go_fullscreen(self):
# To allow toggles to function
@@ -453,7 +511,7 @@ class Tab(QtWidgets.QWidget):
self.annotationListView.setModel(self.annotationModel)
def add_bookmark(self):
def add_bookmark(self, position=None):
identifier = uuid.uuid4().hex[:10]
description = self._translate('Tab', 'New bookmark')
@@ -462,6 +520,8 @@ class Tab(QtWidgets.QWidget):
cursor_position = 0
else:
chapter, cursor_position = self.contentView.record_position(True)
if position: # Should be the case when called from the context menu
cursor_position = position
self.metadata['bookmarks'][identifier] = {
'chapter': chapter,
@@ -469,6 +529,7 @@ class Tab(QtWidgets.QWidget):
'description': description}
self.sideDock.setVisible(True)
self.sideDockTabWidget.setCurrentIndex(1)
self.add_bookmark_to_model(
description, chapter, cursor_position, identifier, True)
@@ -564,15 +625,17 @@ class Tab(QtWidgets.QWidget):
self.bookmarkTreeView.setModel(self.bookmarkProxyModel)
def update_bookmark_proxy_model(self):
pass
# TODO
# This isn't being called currently
# See if there's any rationale for keeping it / removing it
self.bookmarkProxyModel.invalidateFilter()
self.bookmarkProxyModel.setFilterParams(
self.main_window.bookToolBar.searchBar.text())
self.bookmarkProxyModel.setFilterFixedString(
self.main_window.bookToolBar.searchBar.text())
# self.bookmarkProxyModel.invalidateFilter()
# self.bookmarkProxyModel.setFilterParams(
# self.main_window.bookToolBar.searchBar.text())
# self.bookmarkProxyModel.setFilterFixedString(
# self.main_window.bookToolBar.searchBar.text())
def generate_bookmark_context_menu(self, position):
index = self.bookmarkTreeView.indexAt(position)
@@ -610,6 +673,9 @@ class Tab(QtWidgets.QWidget):
if child_rows == 1:
self.bookmarkModel.removeRow(parent_index.row())
def go_to_search_result(self, event):
print(event)
def hide_mouse(self):
self.contentView.viewport().setCursor(QtCore.Qt.BlankCursor)
@@ -635,20 +701,19 @@ class PliantDockWidget(QtWidgets.QDockWidget):
self.current_annotation = None
def showEvent(self, event=None):
viewport_height = self.contentView.viewport().size().height()
viewport_topRight = self.contentView.mapToGlobal(
self.contentView.viewport().rect().topRight())
desktop_size = QtWidgets.QDesktopWidget().screenGeometry()
dock_y = viewport_topRight.y()
dock_height = viewport_height * .999
dock_height = self.contentView.viewport().size().height()
if self.notes_only:
dock_width = dock_height = desktop_size.width() // 5.5
dock_x = QtGui.QCursor.pos().x()
dock_y = QtGui.QCursor.pos().y()
else:
dock_width = desktop_size.width() // 5.5
dock_width = desktop_size.width() // 5
dock_x = viewport_topRight.x() - dock_width + 1
self.main_window.active_docks.append(self)