Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a62e681223 | ||
|
efe52cd3cb | ||
|
23aff44412 | ||
|
e8e3b81871 | ||
|
03b683e05d | ||
|
5b3759afe6 | ||
|
fc2fcb5361 | ||
|
6ee135a52b | ||
|
55545f62e7 | ||
|
160226c6cd | ||
|
5d3ce17447 | ||
|
03afc6933f | ||
|
c9559daaf6 | ||
|
3c293a39d3 | ||
|
a87cd24c3d | ||
|
8564ede48b | ||
|
e0b20e36dd | ||
|
c2db6c13b0 | ||
|
dbff4cbcca | ||
|
ce9ee4ccb2 | ||
|
ca3d747136 | ||
|
9e5559bbfa | ||
|
9e9d7cca90 | ||
|
05e1655fd9 | ||
|
f9bcc399e8 | ||
|
1cd6ff6b58 | ||
|
79180885b5 |
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
__pycache__/
|
||||
.gitignore
|
||||
.vscode/
|
||||
parsers/__pycache__/
|
||||
books/
|
||||
Examples/
|
@@ -246,13 +246,13 @@ class MobiMLConverter(object):
|
||||
# handle case of end tag with no beginning by injecting empty begin tag
|
||||
taginfo = ('begin', tname, None)
|
||||
htmlstr += self.processtag(taginfo)
|
||||
print " - fixed by injecting empty start tag ", tname
|
||||
print(" - fixed by injecting empty start tag ", tname)
|
||||
self.path.append(tname)
|
||||
elif len(self.path) > 1 and tname == self.path[-2]:
|
||||
# handle case of dangling missing end
|
||||
taginfo = ('end', self.path[-1], None)
|
||||
htmlstr += self.processtag(taginfo)
|
||||
print " - fixed by injecting end tag ", self.path[-1]
|
||||
print(" - fixed by injecting end tag ", self.path[-1])
|
||||
self.path.pop()
|
||||
self.path.pop()
|
||||
|
||||
@@ -504,18 +504,18 @@ def main(argv=sys.argv):
|
||||
infile = argv[1]
|
||||
|
||||
try:
|
||||
print 'Converting Mobi Markup Language to XHTML'
|
||||
print('Converting Mobi Markup Language to XHTML')
|
||||
mlc = MobiMLConverter(infile)
|
||||
print 'Processing ...'
|
||||
print('Processing ...')
|
||||
htmlstr, css, cssname = mlc.processml()
|
||||
outname = infile.rsplit('.',1)[0] + '_converted.html'
|
||||
file(outname, 'wb').write(htmlstr)
|
||||
file(cssname, 'wb').write(css)
|
||||
print 'Completed'
|
||||
print 'XHTML version of book can be found at: ' + outname
|
||||
print('Completed')
|
||||
print('XHTML version of book can be found at: ', outname)
|
||||
|
||||
except ValueError, e:
|
||||
print "Error: %s" % e
|
||||
except ValueError as e:
|
||||
print("Error: %s" % e)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
41
README.md
@@ -2,21 +2,45 @@
|
||||
Qt based ebook reader
|
||||
|
||||
Currently supports:
|
||||
* pdf
|
||||
* epub
|
||||
* mobi
|
||||
* azw / azw3 / azw4
|
||||
* cbr / cbz
|
||||
|
||||
Support for a bunch of other formats is coming. Please see the TODO for additional information.
|
||||
|
||||
## Requirements
|
||||
* Qt5
|
||||
* PyQt5
|
||||
* python-requests
|
||||
* python-beautifulsoup4
|
||||
| Package | Version tested |
|
||||
| --- | --- |
|
||||
| Qt5 | 5.10.1 |
|
||||
| Python | 3.6 |
|
||||
| PyQt5 | 5.10.1 |
|
||||
| python-requests | 2.18.4 |
|
||||
| python-beautifulsoup4 | 4.6.0 |
|
||||
| poppler-qt5 | 0.61.1 |
|
||||
| python-poppler-qt5 | 0.24.2 |
|
||||
|
||||
poppler-qt5 and python-poppler-qt5 are optional.
|
||||
|
||||
## Installation
|
||||
0. Install dependencies
|
||||
### Manual
|
||||
0. Install dependencies - I recommend using your package manager for this.
|
||||
1. Clone repository
|
||||
2. Launch with \_\_main\_\_.py
|
||||
2. Type the following in the root directory:
|
||||
|
||||
$ python setup.py build
|
||||
# python setup.py install
|
||||
3. OR launch with `lector/__main__.py`
|
||||
|
||||
### Available packages
|
||||
* [AUR](https://aur.archlinux.org/packages/lector-git/)
|
||||
|
||||
## Reporting issues
|
||||
When reporting issues:
|
||||
|
||||
* If you're having trouble with a book while the rest of the application / other books work, please link to a copy of the book itself.
|
||||
* If nothing is working, please make sure the requirements mentioned above are all installed, and are at least at the version mentioned.
|
||||
|
||||
## Screenshots
|
||||
|
||||
@@ -43,3 +67,8 @@ Currently supports:
|
||||
|
||||
### In program dictionary
|
||||

|
||||
|
||||
## Attributions
|
||||
* [KindleUnpack](https://github.com/kevinhendricks/KindleUnpack)
|
||||
* [rarfile](https://github.com/markokr/rarfile)
|
||||
* [Papirus icon theme](https://github.com/PapirusDevelopmentTeam/papirus-icon-theme)
|
||||
|
11
TODO
@@ -24,6 +24,7 @@ TODO
|
||||
✓ Context menu: Cache, Read, Edit database, delete, Mark read/unread
|
||||
✓ Information dialog widget
|
||||
✓ Allow editing of database data through the UI + for Bookmarks
|
||||
✓ Include (action) icons with the applications
|
||||
Set focus to newly added file
|
||||
Reading:
|
||||
✓ Drop down for TOC
|
||||
@@ -53,6 +54,8 @@ TODO
|
||||
Search document using QTextCursor?
|
||||
Comic view keyboard shortcuts
|
||||
Filetypes:
|
||||
✓ pdf support
|
||||
Parse TOC
|
||||
✓ epub support
|
||||
✓ Homegrown solution please
|
||||
✓ cbz, cbr support
|
||||
@@ -65,7 +68,8 @@ TODO
|
||||
Bugs:
|
||||
If there are files open and the database is deleted, TypeErrors result
|
||||
Cover culling does not occur if some other tab has initial focus
|
||||
Exiting with Ctrl + Q does not save the cursor position INITIALLY
|
||||
Slider position change might be acting up too
|
||||
Take metadata from the database when opening the file
|
||||
|
||||
Secondary:
|
||||
Annotations
|
||||
@@ -76,7 +80,7 @@ TODO
|
||||
Goodreads API: Ratings, Read, Recommendations
|
||||
Get ISBN using python-isbnlib
|
||||
Pagination
|
||||
Use embedded fonts
|
||||
Use embedded fonts + CSS
|
||||
Scrolling: Smooth / By Line
|
||||
Spacebar should not cut off lines at the top
|
||||
Shift to logging instead of print statements
|
||||
@@ -91,5 +95,4 @@ TODO
|
||||
Ignore a / the / numbers for sorting purposes
|
||||
? Add only one file type if multiple are present
|
||||
? Plugin system for parsers
|
||||
? pdf support
|
||||
? Create emblem per filetype
|
||||
? Create emblem per filetype
|
||||
|
@@ -17,7 +17,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import zipfile
|
||||
from urllib.parse import unquote
|
||||
|
||||
@@ -29,6 +28,7 @@ class EPUB:
|
||||
self.filename = filename
|
||||
self.zip_file = None
|
||||
self.book = {}
|
||||
self.book['split_chapters'] = {}
|
||||
|
||||
def read_epub(self):
|
||||
# This is the function that should error out in
|
||||
@@ -57,7 +57,8 @@ class EPUB:
|
||||
try:
|
||||
this_xml = self.zip_file.read(filename).decode()
|
||||
except KeyError:
|
||||
print(str(filename) + ' not found in zip')
|
||||
short_filename = os.path.basename(self.filename)
|
||||
print(f'{str(filename)} not found in {short_filename}')
|
||||
return
|
||||
|
||||
root = BeautifulSoup(this_xml, parser)
|
||||
@@ -127,7 +128,7 @@ class EPUB:
|
||||
|
||||
try:
|
||||
self.book['year'] = int(self.book['year'][:4])
|
||||
except (TypeError, KeyError, IndexError):
|
||||
except (TypeError, KeyError, IndexError, ValueError):
|
||||
self.book['year'] = 9999
|
||||
|
||||
# Get identifier
|
||||
@@ -170,7 +171,7 @@ class EPUB:
|
||||
self.get_file_path(cover_href))
|
||||
|
||||
if not self.book['cover']:
|
||||
# If no cover is located the conventioanl way,
|
||||
# If no cover is located the conventional way,
|
||||
# we go looking for the largest image in the book
|
||||
biggest_image_size = 0
|
||||
biggest_image = None
|
||||
@@ -215,33 +216,32 @@ class EPUB:
|
||||
for i in navpoints:
|
||||
chapter_title = i.find('text').text
|
||||
chapter_source = i.find('content').get('src')
|
||||
chapter_source = unquote(chapter_source.split('#')[0])
|
||||
self.book['navpoint_dict'][chapter_source] = chapter_title
|
||||
chapter_source_file = unquote(chapter_source.split('#')[0])
|
||||
|
||||
if '#' in chapter_source:
|
||||
try:
|
||||
self.book['split_chapters'][chapter_source_file].append(
|
||||
(chapter_source.split('#')[1], chapter_title))
|
||||
except KeyError:
|
||||
self.book['split_chapters'][chapter_source_file] = []
|
||||
self.book['split_chapters'][chapter_source_file].append(
|
||||
(chapter_source.split('#')[1], chapter_title))
|
||||
|
||||
self.book['navpoint_dict'][chapter_source_file] = chapter_title
|
||||
|
||||
def parse_chapters(self, temp_dir=None, split_large_xml=False):
|
||||
no_title_chapter = 0
|
||||
self.book['book_list'] = []
|
||||
|
||||
for i in self.book['chapters_in_order']:
|
||||
chapter_data = self.read_from_zip(i).decode()
|
||||
|
||||
if not split_large_xml:
|
||||
try:
|
||||
self.book['book_list'].append(
|
||||
(self.book['navpoint_dict'][i], chapter_data))
|
||||
except KeyError:
|
||||
fallback_title = str(no_title_chapter)
|
||||
self.book['book_list'].append(
|
||||
(fallback_title, chapter_data))
|
||||
no_title_chapter += 1
|
||||
if i in self.book['split_chapters'] and not split_large_xml:
|
||||
split_chapters = get_split_content(
|
||||
chapter_data, self.book['split_chapters'][i])
|
||||
self.book['book_list'].extend(split_chapters)
|
||||
|
||||
cover_path = os.path.join(temp_dir, os.path.basename(self.filename)) + '- cover'
|
||||
with open(cover_path, 'wb') as cover_temp:
|
||||
cover_temp.write(self.book['cover'])
|
||||
|
||||
self.book['book_list'][0] = (
|
||||
'Cover', f'<center><img src="{cover_path}" alt="Cover"></center>')
|
||||
|
||||
else:
|
||||
elif split_large_xml:
|
||||
# https://stackoverflow.com/questions/14444732/how-to-split-a-html-page-to-multiple-pages-using-python-and-beautiful-soup
|
||||
markup = BeautifulSoup(chapter_data, 'xml')
|
||||
chapters = []
|
||||
@@ -264,13 +264,54 @@ class EPUB:
|
||||
for this_chapter in chapters:
|
||||
fallback_title = str(no_title_chapter)
|
||||
self.book['book_list'].append(
|
||||
(fallback_title, this_chapter))
|
||||
(fallback_title, this_chapter + ('<br/>' * 8)))
|
||||
no_title_chapter += 1
|
||||
else:
|
||||
try:
|
||||
self.book['book_list'].append(
|
||||
(self.book['navpoint_dict'][i], chapter_data + ('<br/>' * 8)))
|
||||
except KeyError:
|
||||
fallback_title = str(no_title_chapter)
|
||||
self.book['book_list'].append(
|
||||
(fallback_title, chapter_data))
|
||||
no_title_chapter += 1
|
||||
|
||||
def main():
|
||||
book = EPUB(sys.argv[1])
|
||||
book.read_epub()
|
||||
book.parse_chapters()
|
||||
cover_path = os.path.join(temp_dir, os.path.basename(self.filename)) + '- cover'
|
||||
if self.book['cover']:
|
||||
with open(cover_path, 'wb') as cover_temp:
|
||||
cover_temp.write(self.book['cover'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
self.book['book_list'][0] = (
|
||||
'Cover', f'<center><img src="{cover_path}" alt="Cover"></center>')
|
||||
|
||||
|
||||
def get_split_content(chapter_data, split_by):
|
||||
split_anchors = [i[0] for i in split_by]
|
||||
chapter_titles = [i[1] for i in split_by]
|
||||
return_list = []
|
||||
|
||||
xml = BeautifulSoup(chapter_data, 'lxml')
|
||||
xml_string = xml.body.prettify()
|
||||
|
||||
for count, i in enumerate(split_anchors):
|
||||
this_split = xml_string.split(i)
|
||||
current_chapter = this_split[0]
|
||||
|
||||
bs_obj = BeautifulSoup(current_chapter, 'lxml')
|
||||
# Since tags correspond to data following them, the first
|
||||
# chunk will be ignored
|
||||
# As will all empty chapters
|
||||
if bs_obj.text == '\n' or bs_obj.text == '' or count == 0:
|
||||
continue
|
||||
bs_obj_string = str(bs_obj).replace('">', '', 1) + ('<br/>' * 8)
|
||||
|
||||
return_list.append(
|
||||
(chapter_titles[count - 1], bs_obj_string))
|
||||
xml_string = this_split[1]
|
||||
|
||||
bs_obj = BeautifulSoup(xml_string, 'lxml')
|
||||
bs_obj_string = str(bs_obj).replace('">', '', 1) + ('<br/>' * 8)
|
||||
return_list.append(
|
||||
(chapter_titles[-1], bs_obj_string))
|
||||
|
||||
return return_list
|
||||
|
0
lector/__init__.py
Normal file
@@ -19,22 +19,30 @@
|
||||
import os
|
||||
import sys
|
||||
import hashlib
|
||||
import pathlib
|
||||
from PyQt5 import QtWidgets, QtGui, QtCore
|
||||
|
||||
import sorter
|
||||
import database
|
||||
# This allows for the program to be launched from the
|
||||
# dir where it's been copied instead of needing to be
|
||||
# installed
|
||||
install_dir = os.path.realpath(__file__)
|
||||
install_dir = pathlib.Path(install_dir).parents[1]
|
||||
sys.path.append(str(install_dir))
|
||||
|
||||
from lector import database
|
||||
from lector import sorter
|
||||
from lector.toolbars import LibraryToolBar, BookToolBar
|
||||
from lector.widgets import Tab
|
||||
from lector.delegates import LibraryDelegate
|
||||
from lector.threaded import BackGroundTabUpdate, BackGroundBookAddition, BackGroundBookDeletion
|
||||
from lector.library import Library
|
||||
from lector.guifunctions import QImageFactory
|
||||
from lector.settings import Settings
|
||||
from lector.settingsdialog import SettingsUI
|
||||
from lector.metadatadialog import MetadataUI
|
||||
from lector.definitionsdialog import DefinitionsUI
|
||||
|
||||
from resources import mainwindow, resources
|
||||
from toolbars import LibraryToolBar, BookToolBar
|
||||
from widgets import Tab
|
||||
from delegates import LibraryDelegate
|
||||
from threaded import BackGroundTabUpdate, BackGroundBookAddition, BackGroundBookDeletion
|
||||
from library import Library
|
||||
from settings import Settings
|
||||
|
||||
from settingsdialog import SettingsUI
|
||||
from metadatadialog import MetadataUI
|
||||
from definitionsdialog import DefinitionsUI
|
||||
|
||||
|
||||
class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
@@ -52,6 +60,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
self.database_path = None
|
||||
self.active_library_filters = []
|
||||
|
||||
# Initialize application
|
||||
Settings(self).read_settings() # This should populate all variables that need
|
||||
# to be remembered across sessions
|
||||
|
||||
# Initialize icon factory
|
||||
self.QImageFactory = QImageFactory(self)
|
||||
|
||||
# Initialize toolbars
|
||||
self.libraryToolBar = LibraryToolBar(self)
|
||||
self.bookToolBar = BookToolBar(self)
|
||||
@@ -62,10 +77,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
self.toolbarToggle = QtWidgets.QToolButton()
|
||||
self.reloadLibrary = QtWidgets.QToolButton()
|
||||
|
||||
# Initialize application
|
||||
Settings(self).read_settings() # This should populate all variables that need
|
||||
# to be remembered across sessions
|
||||
|
||||
# Create the database in case it doesn't exist
|
||||
database.DatabaseInit(self.database_path)
|
||||
|
||||
@@ -90,22 +101,13 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
self.sorterProgress.setVisible(False)
|
||||
|
||||
# Statusbar - Toolbar Visibility
|
||||
self.toolbarToggle.setIcon(QtGui.QIcon.fromTheme('visibility'))
|
||||
self.toolbarToggle.setIcon(self.QImageFactory.get_image('visibility'))
|
||||
self.toolbarToggle.setObjectName('toolbarToggle')
|
||||
self.toolbarToggle.setToolTip('Toggle toolbar')
|
||||
self.toolbarToggle.setAutoRaise(True)
|
||||
self.toolbarToggle.clicked.connect(self.toggle_toolbars)
|
||||
self.statusBar.addPermanentWidget(self.toolbarToggle)
|
||||
|
||||
# THIS IS TEMPORARY
|
||||
self.guiTest = QtWidgets.QToolButton()
|
||||
self.guiTest.setIcon(QtGui.QIcon.fromTheme('mail-thread-watch'))
|
||||
self.guiTest.setObjectName('guiTest')
|
||||
self.guiTest.setToolTip('Test Function')
|
||||
self.guiTest.setAutoRaise(True)
|
||||
self.guiTest.clicked.connect(self.test_function)
|
||||
self.statusBar.addPermanentWidget(self.guiTest)
|
||||
|
||||
# Application wide temporary directory
|
||||
self.temp_dir = QtCore.QTemporaryDir()
|
||||
|
||||
@@ -194,8 +196,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
print('Available parsers: ' + self.available_parsers)
|
||||
|
||||
# The library refresh button on the Library tab
|
||||
self.reloadLibrary.setIcon(QtGui.QIcon.fromTheme('reload'))
|
||||
self.reloadLibrary.setIcon(self.QImageFactory.get_image('reload'))
|
||||
self.reloadLibrary.setObjectName('reloadLibrary')
|
||||
self.reloadLibrary.setToolTip('Scan library')
|
||||
self.reloadLibrary.setAutoRaise(True)
|
||||
self.reloadLibrary.clicked.connect(self.settingsDialog.start_library_scan)
|
||||
|
||||
@@ -243,7 +246,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
if self.settings['main_window_headers']:
|
||||
for count, i in enumerate(self.settings['main_window_headers']):
|
||||
self.tableView.horizontalHeader().resizeSection(count, int(i))
|
||||
self.tableView.horizontalHeader().resizeSection(4, 1)
|
||||
self.tableView.horizontalHeader().resizeSection(5, 1)
|
||||
self.tableView.horizontalHeader().setStretchLastSection(True)
|
||||
self.tableView.horizontalHeader().sectionClicked.connect(
|
||||
self.lib_ref.table_proxy_model.sort_table_columns)
|
||||
@@ -292,6 +295,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
self.temp_dir.path())
|
||||
|
||||
parsed_books = books.initiate_threads()
|
||||
if not parsed_books:
|
||||
return
|
||||
|
||||
database.DatabaseFunctions(self.database_path).add_to_database(parsed_books)
|
||||
self.lib_ref.generate_model('addition', parsed_books, True)
|
||||
|
||||
@@ -365,6 +371,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
{'Hash': ''},
|
||||
'LIKE')
|
||||
|
||||
if not all_covers_db:
|
||||
return
|
||||
|
||||
all_covers = {
|
||||
i[0]: i[1] for i in all_covers_db}
|
||||
|
||||
@@ -990,19 +999,19 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
||||
context_menu = QtWidgets.QMenu()
|
||||
|
||||
openAction = context_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('view-readermode'), 'Start reading')
|
||||
self.QImageFactory.get_image('view-readermode'), 'Start reading')
|
||||
|
||||
editAction = None
|
||||
if len(selected_indexes) == 1:
|
||||
editAction = context_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('edit-rename'), 'Edit')
|
||||
self.QImageFactory.get_image('edit-rename'), 'Edit')
|
||||
|
||||
deleteAction = context_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('trash-empty'), 'Delete')
|
||||
self.QImageFactory.get_image('trash-empty'), 'Delete')
|
||||
readAction = context_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('vcs-normal'), 'Mark read')
|
||||
QtGui.QIcon(':/images/checkmark.svg'), 'Mark read')
|
||||
unreadAction = context_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('emblem-unavailable'), 'Mark unread')
|
||||
QtGui.QIcon(':/images/xmark.svg'), 'Mark unread')
|
||||
|
||||
action = context_menu.exec_(self.sender().mapToGlobal(position))
|
||||
|
32
lector/guifunctions.py
Normal file
@@ -0,0 +1,32 @@
|
||||
#!usr/bin/env python3
|
||||
|
||||
# This file is a part of Lector, a Qt based ebook reader
|
||||
# Copyright (C) 2018 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from PyQt5 import QtGui
|
||||
from resources import resources
|
||||
|
||||
|
||||
class QImageFactory:
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
|
||||
def get_image(self, image_name):
|
||||
icon_theme = self.parent.settings['icon_theme']
|
||||
icon_path = f':/images/{icon_theme}/{image_name}.svg'
|
||||
|
||||
this_qicon = QtGui.QIcon(icon_path)
|
||||
return this_qicon
|
@@ -21,8 +21,8 @@ import pickle
|
||||
import pathlib
|
||||
from PyQt5 import QtGui, QtCore
|
||||
|
||||
import database
|
||||
from models import TableProxyModel, ItemProxyModel
|
||||
from lector import database
|
||||
from lector.models import TableProxyModel, ItemProxyModel
|
||||
|
||||
|
||||
class Library:
|
@@ -18,10 +18,10 @@
|
||||
|
||||
from PyQt5 import QtWidgets, QtCore, QtGui
|
||||
|
||||
import database
|
||||
from lector import database
|
||||
|
||||
from resources import metadata
|
||||
from widgets import PliantQGraphicsScene
|
||||
from lector.widgets import PliantQGraphicsScene
|
||||
|
||||
|
||||
class MetadataUI(QtWidgets.QDialog, metadata.Ui_Dialog):
|
@@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pickle
|
||||
import pathlib
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
@@ -68,7 +69,7 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
|
||||
def __init__(self, temp_dir, parent=None):
|
||||
super(TableProxyModel, self).__init__(parent)
|
||||
self.header_data = [
|
||||
None, 'Title', 'Author', 'Year', '%', 'Tags']
|
||||
None, 'Title', 'Author', 'Year', 'Last Read', '%', 'Tags']
|
||||
self.temp_dir = temp_dir
|
||||
self.filter_text = None
|
||||
self.active_library_filters = None
|
||||
@@ -77,12 +78,13 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
|
||||
1: QtCore.Qt.UserRole, # Title
|
||||
2: QtCore.Qt.UserRole + 1, # Author
|
||||
3: QtCore.Qt.UserRole + 2, # Year
|
||||
4: QtCore.Qt.UserRole + 7, # Position percentage
|
||||
5: QtCore.Qt.UserRole + 4} # Tags
|
||||
4: QtCore.Qt.UserRole + 12, # Last read
|
||||
5: QtCore.Qt.UserRole + 7, # Position percentage
|
||||
6: QtCore.Qt.UserRole + 4} # Tags
|
||||
self.common_functions = ProxyModelsCommonFunctions(self)
|
||||
|
||||
def columnCount(self, parent):
|
||||
return 6
|
||||
return 7
|
||||
|
||||
def headerData(self, column, orientation, role):
|
||||
if role == QtCore.Qt.DisplayRole:
|
||||
@@ -97,11 +99,12 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
|
||||
source_index = self.mapToSource(index)
|
||||
item = self.sourceModel().item(source_index.row(), 0)
|
||||
|
||||
if role == QtCore.Qt.TextAlignmentRole and index.column() == 3:
|
||||
return QtCore.Qt.AlignHCenter
|
||||
if role == QtCore.Qt.TextAlignmentRole:
|
||||
if index.column() in (3, 4):
|
||||
return QtCore.Qt.AlignHCenter
|
||||
|
||||
if role == QtCore.Qt.DecorationRole:
|
||||
if index.column() == 4:
|
||||
if index.column() == 5:
|
||||
return_pixmap = None
|
||||
|
||||
file_exists = item.data(QtCore.Qt.UserRole + 5)
|
||||
@@ -136,11 +139,20 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
|
||||
return return_pixmap
|
||||
|
||||
elif role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
|
||||
if index.column() in (0, 4): # Cover and Status
|
||||
if index.column() in (0, 5): # Cover and Status
|
||||
return QtCore.QVariant()
|
||||
|
||||
return item.data(self.role_dictionary[index.column()])
|
||||
if index.column() == 4:
|
||||
last_accessed_time = item.data(self.role_dictionary[index.column()])
|
||||
if last_accessed_time:
|
||||
last_accessed = last_accessed_time
|
||||
if not isinstance(last_accessed_time, QtCore.QDateTime):
|
||||
last_accessed = pickle.loads(last_accessed_time)
|
||||
right_now = QtCore.QDateTime().currentDateTime()
|
||||
time_diff = last_accessed.msecsTo(right_now)
|
||||
return self.time_convert(time_diff // 1000)
|
||||
|
||||
return item.data(self.role_dictionary[index.column()])
|
||||
else:
|
||||
return QtCore.QVariant()
|
||||
|
||||
@@ -157,6 +169,20 @@ class TableProxyModel(QtCore.QSortFilterProxyModel):
|
||||
self.sort(0, sorting_order)
|
||||
self.setSortRole(self.role_dictionary[column])
|
||||
|
||||
def time_convert(self, seconds):
|
||||
seconds = int(seconds)
|
||||
m, s = divmod(seconds, 60)
|
||||
h, m = divmod(m, 60)
|
||||
d, h = divmod(h, 24)
|
||||
|
||||
if d > 0:
|
||||
return f'{d}d'
|
||||
if h > 0:
|
||||
return f'{h}h'
|
||||
if m > 0:
|
||||
return f'{m}m'
|
||||
else:
|
||||
return '<1m'
|
||||
|
||||
class ProxyModelsCommonFunctions:
|
||||
def __init__(self, parent_model):
|
@@ -54,6 +54,7 @@ class Settings:
|
||||
self.parent.settings['main_window_headers'] = self.settings.value('tableHeaders', None)
|
||||
self.parent.settings['listview_background'] = self.settings.value(
|
||||
'listViewBackground', QtGui.QColor().fromRgb(76, 76, 76))
|
||||
self.parent.settings['icon_theme'] = self.settings.value('iconTheme', 'DarkIcons')
|
||||
self.settings.endGroup()
|
||||
|
||||
self.settings.beginGroup('runtimeVariables')
|
||||
@@ -113,11 +114,12 @@ class Settings:
|
||||
self.settings.setValue('windowSize', self.parent.size())
|
||||
self.settings.setValue('windowPosition', self.parent.pos())
|
||||
self.settings.setValue('currentView', self.parent.stackedWidget.currentIndex())
|
||||
self.settings.setValue('iconTheme', self.parent.settings['icon_theme'])
|
||||
self.settings.setValue(
|
||||
'listViewBackground', self.parent.settings['listview_background'])
|
||||
|
||||
table_headers = []
|
||||
for i in range(3):
|
||||
for i in range(7):
|
||||
table_headers.append(self.parent.tableView.horizontalHeader().sectionSize(i))
|
||||
self.settings.setValue('tableHeaders', table_headers)
|
||||
self.settings.endGroup()
|
@@ -23,10 +23,11 @@ import os
|
||||
import copy
|
||||
from PyQt5 import QtWidgets, QtCore
|
||||
|
||||
import database
|
||||
from lector import database
|
||||
from lector.models import MostExcellentFileSystemModel
|
||||
from lector.threaded import BackGroundBookSearch, BackGroundBookAddition
|
||||
|
||||
from resources import settingswindow
|
||||
from models import MostExcellentFileSystemModel, FileSystemProxyModel
|
||||
from threaded import BackGroundBookSearch, BackGroundBookAddition
|
||||
|
||||
|
||||
class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
|
||||
@@ -41,7 +42,9 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
|
||||
self.move(self.parent.settings['settings_dialog_position'])
|
||||
|
||||
self.aboutBox.setVisible(False)
|
||||
aboutfile_path = os.path.join('resources', 'about.html')
|
||||
application_root = os.sep.join(
|
||||
os.path.realpath(__file__).rsplit('/')[:-2])
|
||||
aboutfile_path = os.path.join(application_root, 'resources', 'about.html')
|
||||
with open(aboutfile_path) as about_html:
|
||||
self.aboutBox.setHtml(about_html.read())
|
||||
|
||||
@@ -66,6 +69,14 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
|
||||
self.cancelButton.clicked.connect(self.cancel_pressed)
|
||||
self.aboutButton.clicked.connect(self.about_pressed)
|
||||
|
||||
# Radio buttons
|
||||
if self.parent.settings['icon_theme'] == 'DarkIcons':
|
||||
self.darkIconsRadio.setChecked(True)
|
||||
else:
|
||||
self.lightIconsRadio.setChecked(True)
|
||||
self.darkIconsRadio.clicked.connect(self.change_icon_theme)
|
||||
self.lightIconsRadio.clicked.connect(self.change_icon_theme)
|
||||
|
||||
# Check boxes
|
||||
self.autoTags.setChecked(self.parent.settings['auto_tags'])
|
||||
self.coverShadows.setChecked(self.parent.settings['cover_shadows'])
|
||||
@@ -79,6 +90,9 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
|
||||
self.fileRemember.clicked.connect(self.manage_checkboxes)
|
||||
self.performCulling.clicked.connect(self.manage_checkboxes)
|
||||
|
||||
self.comicsRemain.setEnabled(False)
|
||||
self.comicsRemain.setToolTip('Not implemented yet')
|
||||
|
||||
# Generate the filesystem treeView
|
||||
self.generate_tree()
|
||||
|
||||
@@ -243,6 +257,12 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
|
||||
table_headers.append(self.treeView.columnWidth(i))
|
||||
self.parent.settings['settings_dialog_headers'] = table_headers
|
||||
|
||||
def change_icon_theme(self):
|
||||
if self.sender() == self.darkIconsRadio:
|
||||
self.parent.settings['icon_theme'] = 'DarkIcons'
|
||||
else:
|
||||
self.parent.settings['icon_theme'] = 'LightIcons'
|
||||
|
||||
def change_dictionary_language(self, event):
|
||||
language_dict = {
|
||||
0: 'en',
|
@@ -42,22 +42,23 @@ import threading
|
||||
from multiprocessing import Pool, Manager
|
||||
from PyQt5 import QtCore, QtGui
|
||||
|
||||
import database
|
||||
from lector import database
|
||||
|
||||
from parsers.cbz import ParseCBZ
|
||||
from parsers.cbr import ParseCBR
|
||||
from parsers.pdf import ParsePDF
|
||||
from parsers.epub import ParseEPUB
|
||||
from parsers.mobi import ParseMOBI
|
||||
from parsers.comicbooks import ParseCOMIC
|
||||
|
||||
sorter = {
|
||||
'pdf': ParsePDF,
|
||||
'epub': ParseEPUB,
|
||||
'mobi': ParseMOBI,
|
||||
'azw': ParseMOBI,
|
||||
'azw3': ParseMOBI,
|
||||
'azw4': ParseMOBI,
|
||||
'prc': ParseMOBI,
|
||||
'cbz': ParseCBZ,
|
||||
'cbr': ParseCBR,}
|
||||
'cbz': ParseCOMIC,
|
||||
'cbr': ParseCOMIC}
|
||||
|
||||
available_parsers = [i for i in sorter]
|
||||
progressbar = None # This is populated by __main__
|
||||
@@ -149,7 +150,9 @@ class BookSorter:
|
||||
# Do not allow addition in case the file
|
||||
# is already in the database and it remains at its original path
|
||||
if self.mode == 'addition' and file_md5 in self.hashes_and_paths:
|
||||
if self.hashes_and_paths[file_md5] == filename:
|
||||
if (self.hashes_and_paths[file_md5] == filename
|
||||
and os.path.exists(self.hashes_and_paths[file_md5])):
|
||||
print(f'{os.path.basename(filename)} is already in database')
|
||||
return
|
||||
|
||||
file_extension = os.path.splitext(filename)[1][1:]
|
||||
@@ -247,6 +250,9 @@ class BookSorter:
|
||||
break
|
||||
|
||||
def initiate_threads(self):
|
||||
if not self.file_list:
|
||||
return None
|
||||
|
||||
def pool_creator():
|
||||
_pool = Pool(5)
|
||||
self.processed_books = _pool.map(
|
@@ -19,10 +19,10 @@
|
||||
import os
|
||||
import pathlib
|
||||
from multiprocessing.dummy import Pool
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5 import QtCore, QtGui
|
||||
|
||||
import sorter
|
||||
import database
|
||||
from lector import sorter
|
||||
from lector import database
|
||||
|
||||
|
||||
class BackGroundTabUpdate(QtCore.QThread):
|
||||
@@ -58,7 +58,11 @@ class BackGroundBookAddition(QtCore.QThread):
|
||||
self.database_path,
|
||||
self.parent.settings['auto_tags'],
|
||||
self.parent.temp_dir.path())
|
||||
|
||||
parsed_books = books.initiate_threads()
|
||||
if not parsed_books:
|
||||
return
|
||||
|
||||
self.parent.lib_ref.generate_model('addition', parsed_books, False)
|
||||
if self.prune_required:
|
||||
self.parent.lib_ref.prune_models(self.file_list)
|
||||
@@ -115,3 +119,47 @@ class BackGroundBookSearch(QtCore.QThread):
|
||||
|
||||
initiate_threads()
|
||||
print(len(self.valid_files), 'books found')
|
||||
|
||||
|
||||
class BackGroundCacheRefill(QtCore.QThread):
|
||||
def __init__(self, image_cache, remove_value, filetype, book, all_pages, parent=None):
|
||||
super(BackGroundCacheRefill, self).__init__(parent)
|
||||
|
||||
self.image_cache = image_cache
|
||||
self.remove_value = remove_value
|
||||
self.filetype = filetype
|
||||
self.book = book
|
||||
self.all_pages = all_pages
|
||||
|
||||
def run(self):
|
||||
def load_page(current_page):
|
||||
image_pixmap = QtGui.QPixmap()
|
||||
|
||||
if self.filetype in ('cbz', 'cbr'):
|
||||
page_data = self.book.read(current_page)
|
||||
image_pixmap.loadFromData(page_data)
|
||||
elif self.filetype == 'pdf':
|
||||
page_data = self.book.page(current_page)
|
||||
page_qimage = page_data.renderToImage(350, 350)
|
||||
image_pixmap.convertFromImage(page_qimage)
|
||||
return image_pixmap
|
||||
|
||||
remove_index = self.image_cache.index(self.remove_value)
|
||||
|
||||
if remove_index == 1:
|
||||
first_path = self.image_cache[0][0]
|
||||
self.image_cache.pop(3)
|
||||
previous_page = self.all_pages[self.all_pages.index(first_path) - 1]
|
||||
refill_pixmap = load_page(previous_page)
|
||||
self.image_cache.insert(0, (previous_page, refill_pixmap))
|
||||
|
||||
else:
|
||||
self.image_cache[0] = self.image_cache[1]
|
||||
self.image_cache.pop(1)
|
||||
try:
|
||||
last_page = self.image_cache[2][0]
|
||||
next_page = self.all_pages[self.all_pages.index(last_page) + 1]
|
||||
refill_pixmap = load_page(next_page)
|
||||
self.image_cache.append((next_page, refill_pixmap))
|
||||
except (IndexError, TypeError):
|
||||
self.image_cache.append(None)
|
@@ -38,22 +38,24 @@ class BookToolBar(QtWidgets.QToolBar):
|
||||
self.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
|
||||
self.setObjectName("LibraryToolBar")
|
||||
|
||||
image_factory = self.window().QImageFactory
|
||||
|
||||
# Buttons
|
||||
self.fontButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('gtk-select-font'),
|
||||
image_factory.get_image('gtk-select-font'),
|
||||
'View settings', self)
|
||||
self.fullscreenButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('view-fullscreen'),
|
||||
image_factory.get_image('view-fullscreen'),
|
||||
'Fullscreen', self)
|
||||
self.addBookmarkButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('bookmark-new'),
|
||||
image_factory.get_image('bookmark-new'),
|
||||
'Add bookmark', self)
|
||||
self.bookmarkButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('bookmarks'),
|
||||
image_factory.get_image('bookmarks'),
|
||||
'Bookmarks', self)
|
||||
self.bookmarkButton.setObjectName('bookmarkButton')
|
||||
self.resetProfile = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('view-refresh'),
|
||||
image_factory.get_image('reload'),
|
||||
'Reset profile', self)
|
||||
|
||||
# Add buttons
|
||||
@@ -77,43 +79,43 @@ class BookToolBar(QtWidgets.QToolBar):
|
||||
self.fontSizeBox.setEditable(True)
|
||||
|
||||
self.paddingUp = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('format-indent-less'),
|
||||
image_factory.get_image('format-indent-less'),
|
||||
'Increase padding', self)
|
||||
self.paddingUp.setObjectName('paddingUp')
|
||||
self.paddingDown = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('format-indent-more'),
|
||||
image_factory.get_image('format-indent-more'),
|
||||
'Decrease padding', self)
|
||||
self.paddingDown.setObjectName('paddingDown')
|
||||
|
||||
self.lineSpacingUp = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('format-line-spacing-triple'),
|
||||
image_factory.get_image('format-line-spacing-triple'),
|
||||
'Increase line spacing', self)
|
||||
self.lineSpacingUp.setObjectName('lineSpacingUp')
|
||||
self.lineSpacingDown = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('format-line-spacing-double'),
|
||||
image_factory.get_image('format-line-spacing-double'),
|
||||
'Decrease line spacing', self)
|
||||
self.lineSpacingDown.setObjectName('lineSpacingDown')
|
||||
|
||||
self.alignLeft = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('format-justify-left'),
|
||||
image_factory.get_image('format-justify-left'),
|
||||
'Left align text', self)
|
||||
self.alignLeft.setObjectName('alignLeft')
|
||||
self.alignLeft.setCheckable(True)
|
||||
|
||||
self.alignRight = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('format-justify-right'),
|
||||
image_factory.get_image('format-justify-right'),
|
||||
'Right align text', self)
|
||||
self.alignRight.setObjectName('alignRight')
|
||||
self.alignRight.setCheckable(True)
|
||||
|
||||
self.alignCenter = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('format-justify-center'),
|
||||
image_factory.get_image('format-justify-center'),
|
||||
'Center align text', self)
|
||||
self.alignCenter.setObjectName('alignCenter')
|
||||
self.alignCenter.setCheckable(True)
|
||||
|
||||
self.alignJustify = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('format-justify-fill'),
|
||||
image_factory.get_image('format-justify-fill'),
|
||||
'Justify text', self)
|
||||
self.alignJustify.setObjectName('alignJustify')
|
||||
self.alignJustify.setCheckable(True)
|
||||
@@ -184,26 +186,26 @@ class BookToolBar(QtWidgets.QToolBar):
|
||||
|
||||
# Comic view modification
|
||||
self.zoomIn = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('zoom-in'),
|
||||
image_factory.get_image('zoom-in'),
|
||||
'Zoom in', self)
|
||||
self.zoomIn.setObjectName('zoomIn')
|
||||
self.zoomOut = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('zoom-out'),
|
||||
image_factory.get_image('zoom-out'),
|
||||
'Zoom Out', self)
|
||||
self.zoomOut.setObjectName('zoomOut')
|
||||
|
||||
self.fitWidth = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('zoom-fit-width'),
|
||||
image_factory.get_image('zoom-fit-width'),
|
||||
'Fit Width', self)
|
||||
self.fitWidth.setObjectName('fitWidth')
|
||||
self.fitWidth.setCheckable(True)
|
||||
self.bestFit = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('zoom-fit-best'),
|
||||
image_factory.get_image('zoom-fit-best'),
|
||||
'Best Fit', self)
|
||||
self.bestFit.setObjectName('bestFit')
|
||||
self.bestFit.setCheckable(True)
|
||||
self.originalSize = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('zoom-original'),
|
||||
image_factory.get_image('zoom-original'),
|
||||
'Original size', self)
|
||||
self.originalSize.setObjectName('originalSize')
|
||||
self.originalSize.setCheckable(True)
|
||||
@@ -320,27 +322,29 @@ class LibraryToolBar(QtWidgets.QToolBar):
|
||||
self.setContextMenuPolicy(QtCore.Qt.PreventContextMenu)
|
||||
self.setObjectName("LibraryToolBar")
|
||||
|
||||
image_factory = self.window().QImageFactory
|
||||
|
||||
# Buttons
|
||||
self.addButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('add'), 'Add book', self)
|
||||
image_factory.get_image('add'), 'Add book', self)
|
||||
self.deleteButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('remove'), 'Delete book', self)
|
||||
image_factory.get_image('remove'), 'Delete book', self)
|
||||
self.colorButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('color-picker'), 'Library background color', self)
|
||||
image_factory.get_image('color-picker'), 'Library background color', self)
|
||||
self.colorButton.setObjectName('libraryBackground')
|
||||
self.settingsButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('settings'), 'Settings', self)
|
||||
image_factory.get_image('settings'), 'Settings', self)
|
||||
self.settingsButton.setCheckable(True)
|
||||
|
||||
self.coverViewButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('view-grid'), 'View as covers', self)
|
||||
image_factory.get_image('view-grid'), 'View as covers', self)
|
||||
self.coverViewButton.setCheckable(True)
|
||||
self.tableViewButton = QtWidgets.QAction(
|
||||
QtGui.QIcon.fromTheme('table'), 'View as table', self)
|
||||
image_factory.get_image('table'), 'View as table', self)
|
||||
self.tableViewButton.setCheckable(True)
|
||||
|
||||
self.libraryFilterButton = QtWidgets.QToolButton(self)
|
||||
self.libraryFilterButton.setIcon(QtGui.QIcon.fromTheme('view-readermode'))
|
||||
self.libraryFilterButton.setIcon(image_factory.get_image('view-readermode'))
|
||||
self.libraryFilterButton.setText('Filter library')
|
||||
self.libraryFilterButton.setToolTip('Filter library')
|
||||
|
@@ -24,12 +24,16 @@
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import zipfile
|
||||
from PyQt5 import QtWidgets, QtGui, QtCore
|
||||
|
||||
from resources import pie_chart
|
||||
from models import BookmarkProxyModel
|
||||
from sorter import resize_image
|
||||
from delegates import BookmarkDelegate
|
||||
import popplerqt5
|
||||
from rarfile import rarfile
|
||||
|
||||
from lector.models import BookmarkProxyModel
|
||||
from lector.delegates import BookmarkDelegate
|
||||
from lector.threaded import BackGroundCacheRefill
|
||||
from lector.sorter import resize_image
|
||||
|
||||
|
||||
class Tab(QtWidgets.QWidget):
|
||||
@@ -37,6 +41,7 @@ class Tab(QtWidgets.QWidget):
|
||||
super(Tab, self).__init__(parent)
|
||||
self.parent = parent
|
||||
self.metadata = metadata # Save progress data into this dictionary
|
||||
self.are_we_doing_images_only = self.metadata['images_only']
|
||||
|
||||
self.masterLayout = QtWidgets.QHBoxLayout(self)
|
||||
self.horzLayout = QtWidgets.QSplitter(self)
|
||||
@@ -60,10 +65,9 @@ class Tab(QtWidgets.QWidget):
|
||||
# such as in the case of comic book files,
|
||||
# we want a QGraphicsView widget doing all the heavy lifting
|
||||
# instead of a QTextBrowser
|
||||
self.are_we_doing_images_only = self.metadata['images_only']
|
||||
|
||||
if self.are_we_doing_images_only: # Boolean
|
||||
self.contentView = PliantQGraphicsView(self.window(), self)
|
||||
self.contentView = PliantQGraphicsView(
|
||||
self.metadata['path'], self.window(), self)
|
||||
self.contentView.loadImage(chapter_content)
|
||||
else:
|
||||
self.contentView = PliantQTextBrowser(self.window(), self)
|
||||
@@ -101,7 +105,7 @@ class Tab(QtWidgets.QWidget):
|
||||
self.contentView.setObjectName('contentView')
|
||||
self.contentView.verticalScrollBar().setSingleStep(7)
|
||||
self.contentView.setHorizontalScrollBarPolicy(
|
||||
QtCore.Qt.ScrollBarAlwaysOff)
|
||||
QtCore.Qt.ScrollBarAsNeeded)
|
||||
|
||||
# See bookmark availability
|
||||
if not self.metadata['bookmarks']:
|
||||
@@ -134,6 +138,8 @@ class Tab(QtWidgets.QWidget):
|
||||
self.horzLayout.addWidget(self.contentView)
|
||||
self.horzLayout.addWidget(self.dockWidget)
|
||||
title = self.metadata['title']
|
||||
if self.are_we_doing_images_only:
|
||||
title = os.path.basename(title)
|
||||
self.parent.addTab(self, title)
|
||||
|
||||
# Hide mouse cursor timer
|
||||
@@ -153,8 +159,11 @@ class Tab(QtWidgets.QWidget):
|
||||
self.metadata['hash'],
|
||||
1, QtCore.Qt.MatchExactly)
|
||||
|
||||
self.window().lib_ref.view_model.setData(
|
||||
matching_item[0], self.metadata['last_accessed'], QtCore.Qt.UserRole + 12)
|
||||
try:
|
||||
self.window().lib_ref.view_model.setData(
|
||||
matching_item[0], self.metadata['last_accessed'], QtCore.Qt.UserRole + 12)
|
||||
except IndexError: # The file has been deleted
|
||||
pass
|
||||
|
||||
def set_scroll_value(self, switch_widgets=True, search_data=None):
|
||||
# TODO
|
||||
@@ -177,7 +186,7 @@ class Tab(QtWidgets.QWidget):
|
||||
# This avoids confusion with potentially duplicate phrases
|
||||
# And the found result is at the top of the window
|
||||
scroll_position = scroll_value * self.contentView.verticalScrollBar().maximum()
|
||||
self.contentView.verticalScrollBar().setValue(scroll_position * 1.1)
|
||||
self.contentView.verticalScrollBar().setValue(scroll_position * 1.02)
|
||||
|
||||
try:
|
||||
search_text = self.metadata['position']['last_visible_text']
|
||||
@@ -185,7 +194,17 @@ class Tab(QtWidgets.QWidget):
|
||||
search_text = search_data[1]
|
||||
|
||||
if search_text:
|
||||
self.contentView.find(search_text)
|
||||
find_backward = False
|
||||
|
||||
find_forward = self.contentView.find(search_text)
|
||||
if not find_forward:
|
||||
find_backward = self.contentView.find(
|
||||
search_text, QtGui.QTextDocument.FindBackward)
|
||||
|
||||
if find_backward:
|
||||
current_scroll_position = self.contentView.verticalScrollBar().value()
|
||||
new_scroll_position = current_scroll_position * .98
|
||||
self.contentView.verticalScrollBar().setValue(new_scroll_position)
|
||||
|
||||
text_cursor = self.contentView.textCursor()
|
||||
text_cursor.clearSelection()
|
||||
@@ -197,9 +216,6 @@ class Tab(QtWidgets.QWidget):
|
||||
self.window().tabWidget.setCurrentWidget(previous_widget)
|
||||
|
||||
def generate_position(self, is_read=False):
|
||||
# TODO
|
||||
# Calculate lines to incorporate into progress
|
||||
|
||||
total_chapters = len(self.metadata['content'])
|
||||
|
||||
current_chapter = 1
|
||||
@@ -208,9 +224,30 @@ class Tab(QtWidgets.QWidget):
|
||||
current_chapter = total_chapters
|
||||
scroll_value = 1
|
||||
|
||||
# TODO
|
||||
# Use this to generate position
|
||||
|
||||
# Generate block count @ time of first read
|
||||
# Blocks are indexed from 0 up
|
||||
blocks_per_chapter = []
|
||||
total_blocks = 0
|
||||
|
||||
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)
|
||||
block_count = textDocument.blockCount()
|
||||
|
||||
blocks_per_chapter.append(block_count)
|
||||
total_blocks += block_count
|
||||
|
||||
self.metadata['position'] = {
|
||||
'current_chapter': current_chapter,
|
||||
'total_chapters': total_chapters,
|
||||
'blocks_per_chapter': blocks_per_chapter,
|
||||
'total_blocks': total_blocks,
|
||||
'scroll_value': scroll_value,
|
||||
'last_visible_text': None,
|
||||
'is_read': is_read}
|
||||
@@ -235,14 +272,6 @@ class Tab(QtWidgets.QWidget):
|
||||
self.exit_fs.setContext(QtCore.Qt.ApplicationShortcut)
|
||||
self.exit_fs.activated.connect(self.exit_fullscreen)
|
||||
|
||||
# TODO
|
||||
# See why Ctrl + Q won't work on a non fullscreened contentView
|
||||
# widget in case the following is in code
|
||||
|
||||
# self.exit_all = QtWidgets.QShortcut(
|
||||
# QtGui.QKeySequence('Ctrl+Q'), self.contentView)
|
||||
# self.exit_all.activated.connect(self.sneaky_exit)
|
||||
|
||||
def go_fullscreen(self):
|
||||
if self.contentView.windowState() == QtCore.Qt.WindowFullScreen:
|
||||
self.exit_fullscreen()
|
||||
@@ -411,11 +440,12 @@ class Tab(QtWidgets.QWidget):
|
||||
|
||||
bookmark_menu = QtWidgets.QMenu()
|
||||
editAction = bookmark_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('edit-rename'), 'Edit')
|
||||
self.window().QImageFactory.get_image('edit-rename'), 'Edit')
|
||||
deleteAction = bookmark_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('trash-empty'), 'Delete')
|
||||
self.window().QImageFactory.get_image('trash-empty'), 'Delete')
|
||||
|
||||
action = bookmark_menu.exec_(self.dockListView.mapToGlobal(position))
|
||||
action = bookmark_menu.exec_(
|
||||
self.dockListView.mapToGlobal(position))
|
||||
|
||||
if action == editAction:
|
||||
self.dockListView.edit(index)
|
||||
@@ -444,76 +474,100 @@ class Tab(QtWidgets.QWidget):
|
||||
|
||||
|
||||
class PliantQGraphicsView(QtWidgets.QGraphicsView):
|
||||
def __init__(self, main_window, parent=None):
|
||||
def __init__(self, filepath, main_window, parent=None):
|
||||
super(PliantQGraphicsView, self).__init__(parent)
|
||||
self.main_window = main_window
|
||||
self.parent = parent
|
||||
|
||||
self.qimage = None # Will be needed to resize pdf
|
||||
self.image_pixmap = None
|
||||
self.ignore_wheel_event = False
|
||||
self.ignore_wheel_event_number = 0
|
||||
self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
|
||||
self.viewport().setCursor(QtCore.Qt.ArrowCursor)
|
||||
self.common_functions = PliantWidgetsCommonFunctions(
|
||||
self, self.main_window)
|
||||
self.setMouseTracking(True)
|
||||
self.image_cache = [None for _ in range(4)]
|
||||
|
||||
def loadImage(self, current_image):
|
||||
self.thread = None
|
||||
|
||||
self.filepath = filepath
|
||||
self.filetype = os.path.splitext(self.filepath)[1][1:]
|
||||
|
||||
if self.filetype == 'cbz':
|
||||
self.book = zipfile.ZipFile(self.filepath)
|
||||
|
||||
elif self.filetype == 'cbr':
|
||||
self.book = rarfile.RarFile(self.filepath)
|
||||
|
||||
elif self.filetype == 'pdf':
|
||||
self.book = popplerqt5.Poppler.Document.load(self.filepath)
|
||||
self.book.setRenderHint(
|
||||
popplerqt5.Poppler.Document.Antialiasing
|
||||
and popplerqt5.Poppler.Document.TextAntialiasing)
|
||||
|
||||
self.common_functions = PliantWidgetsCommonFunctions(
|
||||
self, self.main_window)
|
||||
|
||||
# TODO
|
||||
# For double page view: 1 before, 1 after
|
||||
# Image panning with mouse
|
||||
self.ignore_wheel_event = False
|
||||
self.ignore_wheel_event_number = 0
|
||||
self.setMouseTracking(True)
|
||||
self.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag)
|
||||
self.viewport().setCursor(QtCore.Qt.ArrowCursor)
|
||||
|
||||
content = self.parent.metadata['content']
|
||||
image_paths = [i[1] for i in content]
|
||||
def loadImage(self, current_page):
|
||||
# TODO
|
||||
# Threaded caching will still work here
|
||||
# Look at a commit where it's not been deleted
|
||||
# For double page view: 1 before, 1 after
|
||||
all_pages = [i[1] for i in self.parent.metadata['content']]
|
||||
|
||||
def generate_image_cache(current_image):
|
||||
def load_page(current_page):
|
||||
image_pixmap = QtGui.QPixmap()
|
||||
|
||||
if self.filetype in ('cbz', 'cbr'):
|
||||
page_data = self.book.read(current_page)
|
||||
image_pixmap.loadFromData(page_data)
|
||||
elif self.filetype == 'pdf':
|
||||
page_data = self.book.page(current_page)
|
||||
page_qimage = page_data.renderToImage(350, 350)
|
||||
image_pixmap.convertFromImage(page_qimage)
|
||||
return image_pixmap
|
||||
|
||||
def generate_image_cache(current_page):
|
||||
print('Building image cache')
|
||||
current_image_index = image_paths.index(current_image)
|
||||
current_page_index = all_pages.index(current_page)
|
||||
|
||||
for i in (-1, 0, 1, 2):
|
||||
try:
|
||||
this_path = image_paths[current_image_index + i]
|
||||
this_pixmap = QtGui.QPixmap()
|
||||
this_pixmap.load(this_path)
|
||||
self.image_cache[i + 1] = (this_path, this_pixmap)
|
||||
this_page = all_pages[current_page_index + i]
|
||||
this_pixmap = load_page(this_page)
|
||||
self.image_cache[i + 1] = (this_page, this_pixmap)
|
||||
except IndexError:
|
||||
self.image_cache[i + 1] = None
|
||||
|
||||
def refill_cache(remove_value):
|
||||
remove_index = self.image_cache.index(remove_value)
|
||||
refill_pixmap = QtGui.QPixmap()
|
||||
# Do NOT put a parent in here or the mother of all
|
||||
# memory leaks will result
|
||||
self.thread = BackGroundCacheRefill(
|
||||
self.image_cache, remove_value,
|
||||
self.filetype, self.book, all_pages)
|
||||
self.thread.finished.connect(overwrite_cache)
|
||||
self.thread.start()
|
||||
|
||||
if remove_index == 1:
|
||||
first_path = self.image_cache[0][0]
|
||||
self.image_cache.pop(3)
|
||||
previous_path = image_paths[image_paths.index(first_path) - 1]
|
||||
refill_pixmap.load(previous_path)
|
||||
self.image_cache.insert(0, (previous_path, refill_pixmap))
|
||||
else:
|
||||
self.image_cache[0] = self.image_cache[1]
|
||||
self.image_cache.pop(1)
|
||||
try:
|
||||
last_path = self.image_cache[2][0]
|
||||
next_path = image_paths[image_paths.index(last_path) + 1]
|
||||
refill_pixmap.load(next_path)
|
||||
self.image_cache.append((next_path, refill_pixmap))
|
||||
except (IndexError, TypeError):
|
||||
self.image_cache.append(None)
|
||||
def overwrite_cache():
|
||||
self.image_cache = self.thread.image_cache
|
||||
|
||||
def check_cache(current_image):
|
||||
def check_cache(current_page):
|
||||
for i in self.image_cache:
|
||||
if i:
|
||||
if i[0] == current_image:
|
||||
if i[0] == current_page:
|
||||
return_pixmap = i[1]
|
||||
refill_cache(i)
|
||||
return return_pixmap
|
||||
|
||||
# No return happened so the image isn't in the cache
|
||||
generate_image_cache(current_image)
|
||||
generate_image_cache(current_page)
|
||||
|
||||
return_pixmap = None
|
||||
while not return_pixmap:
|
||||
return_pixmap = check_cache(current_image)
|
||||
return_pixmap = check_cache(current_page)
|
||||
|
||||
self.image_pixmap = return_pixmap
|
||||
self.resizeEvent()
|
||||
@@ -655,10 +709,12 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
|
||||
if selected_word and selected_word != '':
|
||||
selected_word = selected_word.split()[0]
|
||||
defineAction = context_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('view-readermode'), f'Define "{selected_word}"')
|
||||
self.window().QImageFactory.get_image('view-readermode'),
|
||||
f'Define "{selected_word}"')
|
||||
|
||||
searchAction = context_menu.addAction(
|
||||
QtGui.QIcon.fromTheme('search'), 'Search')
|
||||
self.window().QImageFactory.get_image('search'),
|
||||
'Search')
|
||||
|
||||
action = context_menu.exec_(self.sender().mapToGlobal(position))
|
||||
|
106
parsers/cbr.py
@@ -1,106 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This file is a part of Lector, a Qt based ebook reader
|
||||
# Copyright (C) 2017 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# TODO
|
||||
# Account for files with passwords
|
||||
|
||||
import os
|
||||
import time
|
||||
import collections
|
||||
from rarfile import rarfile
|
||||
|
||||
|
||||
class ParseCBR:
|
||||
def __init__(self, filename, temp_dir, file_md5):
|
||||
self.filename = filename
|
||||
self.book = None
|
||||
self.temp_dir = temp_dir
|
||||
self.file_md5 = file_md5
|
||||
|
||||
def read_book(self):
|
||||
try:
|
||||
self.book = rarfile.RarFile(self.filename)
|
||||
except: # Specifying no exception types might be warranted here
|
||||
print('Cannot parse ' + self.filename)
|
||||
return
|
||||
|
||||
def get_title(self):
|
||||
filename = os.path.basename(self.filename)
|
||||
filename_proper = os.path.splitext(filename)[0]
|
||||
return filename_proper
|
||||
|
||||
def get_author(self):
|
||||
return None
|
||||
|
||||
def get_year(self):
|
||||
creation_time = time.ctime(os.path.getctime(self.filename))
|
||||
creation_year = creation_time.split()[-1]
|
||||
return creation_year
|
||||
|
||||
def get_cover_image(self):
|
||||
# The first image in the archive may not be the cover
|
||||
# It is implied, however, that the first image in order
|
||||
# will be the cover
|
||||
|
||||
image_list = [i.filename for i in self.book.infolist() if not i.isdir()]
|
||||
image_list.sort()
|
||||
cover_image_filename = image_list[0]
|
||||
|
||||
for i in self.book.infolist():
|
||||
if not i.isdir():
|
||||
if i.filename == cover_image_filename:
|
||||
cover_image = self.book.read(i)
|
||||
return cover_image
|
||||
|
||||
def get_isbn(self):
|
||||
return
|
||||
|
||||
def get_tags(self):
|
||||
return
|
||||
|
||||
def get_contents(self):
|
||||
file_settings = {
|
||||
'images_only': True}
|
||||
|
||||
extract_path = os.path.join(self.temp_dir, self.file_md5)
|
||||
contents = []
|
||||
|
||||
# I'm currently choosing not to keep multiple files in memory
|
||||
self.book.extractall(extract_path)
|
||||
|
||||
found_images = []
|
||||
for i in os.walk(extract_path):
|
||||
if i[2]: # Implies files were found
|
||||
image_dir = i[0]
|
||||
add_path_to_file = [
|
||||
os.path.join(image_dir, j) for j in i[2]]
|
||||
found_images.extend(add_path_to_file)
|
||||
|
||||
if not found_images:
|
||||
print('Found nothing in ' + self.filename)
|
||||
return None, file_settings
|
||||
|
||||
found_images.sort()
|
||||
|
||||
for count, i in enumerate(found_images):
|
||||
page_name = 'Page ' + str(count + 1)
|
||||
image_path = os.path.join(extract_path, i)
|
||||
|
||||
contents.append((page_name, image_path))
|
||||
|
||||
return contents, file_settings
|
109
parsers/cbz.py
@@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This file is a part of Lector, a Qt based ebook reader
|
||||
# Copyright (C) 2017 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# TODO
|
||||
# Account for files with passwords
|
||||
|
||||
import os
|
||||
import time
|
||||
import zipfile
|
||||
import collections
|
||||
|
||||
|
||||
class ParseCBZ:
|
||||
def __init__(self, filename, temp_dir, file_md5):
|
||||
self.filename = filename
|
||||
self.book = None
|
||||
self.temp_dir = temp_dir
|
||||
self.file_md5 = file_md5
|
||||
|
||||
def read_book(self):
|
||||
try:
|
||||
self.book = zipfile.ZipFile(self.filename, mode='r', allowZip64=True)
|
||||
except FileNotFoundError:
|
||||
print('Invalid path for ' + self.filename)
|
||||
return
|
||||
except (KeyError, AttributeError, zipfile.BadZipFile):
|
||||
print('Cannot parse ' + self.filename)
|
||||
return
|
||||
|
||||
def get_title(self):
|
||||
filename = os.path.basename(self.book.filename)
|
||||
filename_proper = os.path.splitext(filename)[0]
|
||||
return filename_proper
|
||||
|
||||
def get_author(self):
|
||||
return None
|
||||
|
||||
def get_year(self):
|
||||
creation_time = time.ctime(os.path.getctime(self.filename))
|
||||
creation_year = creation_time.split()[-1]
|
||||
return creation_year
|
||||
|
||||
def get_cover_image(self):
|
||||
# The first image in the archive may not be the cover
|
||||
# It is implied, however, that the first image in order
|
||||
# will be the cover
|
||||
|
||||
image_list = [i.filename for i in self.book.infolist() if not i.is_dir()]
|
||||
image_list.sort()
|
||||
cover_image_filename = image_list[0]
|
||||
|
||||
for i in self.book.infolist():
|
||||
if not i.is_dir():
|
||||
if i.filename == cover_image_filename:
|
||||
cover_image = self.book.read(i)
|
||||
return cover_image
|
||||
|
||||
def get_isbn(self):
|
||||
return
|
||||
|
||||
def get_tags(self):
|
||||
return
|
||||
|
||||
def get_contents(self):
|
||||
file_settings = {
|
||||
'images_only': True}
|
||||
|
||||
extract_path = os.path.join(self.temp_dir, self.file_md5)
|
||||
contents = []
|
||||
|
||||
# I'm currently choosing not to keep multiple files in memory
|
||||
self.book.extractall(extract_path)
|
||||
|
||||
found_images = []
|
||||
for i in os.walk(extract_path):
|
||||
if i[2]: # Implies files were found
|
||||
image_dir = i[0]
|
||||
add_path_to_file = [
|
||||
os.path.join(image_dir, j) for j in i[2]]
|
||||
found_images.extend(add_path_to_file)
|
||||
|
||||
if not found_images:
|
||||
print('Found nothing in ' + self.filename)
|
||||
return None, file_settings
|
||||
|
||||
found_images.sort()
|
||||
|
||||
for count, i in enumerate(found_images):
|
||||
page_name = 'Page ' + str(count + 1)
|
||||
image_path = os.path.join(extract_path, i)
|
||||
|
||||
contents.append((page_name, image_path))
|
||||
|
||||
return contents, file_settings
|
78
parsers/comicbooks.py
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This file is a part of Lector, a Qt based ebook reader
|
||||
# Copyright (C) 2017-18 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# TODO
|
||||
# Account for files with passwords
|
||||
|
||||
import os
|
||||
import time
|
||||
import zipfile
|
||||
from rarfile import rarfile
|
||||
|
||||
|
||||
class ParseCOMIC:
|
||||
def __init__(self, filename, *args):
|
||||
self.filename = filename
|
||||
self.book = None
|
||||
self.image_list = None
|
||||
self.book_extension = os.path.splitext(self.filename)
|
||||
|
||||
def read_book(self):
|
||||
try:
|
||||
if self.book_extension[1] == '.cbz':
|
||||
self.book = zipfile.ZipFile(
|
||||
self.filename, mode='r', allowZip64=True)
|
||||
self.image_list = [i.filename for i in self.book.infolist() if not i.is_dir()]
|
||||
|
||||
elif self.book_extension[1] == '.cbr':
|
||||
self.book = rarfile.RarFile(self.filename)
|
||||
self.image_list = [i.filename for i in self.book.infolist() if not i.isdir()]
|
||||
|
||||
self.image_list.sort()
|
||||
except: # Specifying no exception here is warranted
|
||||
print('Cannot parse ' + self.filename)
|
||||
return
|
||||
|
||||
def get_title(self):
|
||||
return self.book_extension[0]
|
||||
|
||||
def get_author(self):
|
||||
return None
|
||||
|
||||
def get_year(self):
|
||||
creation_time = time.ctime(os.path.getctime(self.filename))
|
||||
creation_year = creation_time.split()[-1]
|
||||
return creation_year
|
||||
|
||||
def get_cover_image(self):
|
||||
# The first image in the archive may not be the cover
|
||||
# It is implied, however, that the first image in order
|
||||
# will be the cover
|
||||
return self.book.read(self.image_list[0])
|
||||
|
||||
def get_isbn(self):
|
||||
return None
|
||||
|
||||
def get_tags(self):
|
||||
return None
|
||||
|
||||
def get_contents(self):
|
||||
file_settings = {'images_only': True}
|
||||
contents = [(f'Page {count + 1}', i) for count, i in enumerate(self.image_list)]
|
||||
|
||||
return contents, file_settings
|
@@ -28,9 +28,8 @@ class ParseEPUB:
|
||||
# Maybe also include book description
|
||||
self.book_ref = None
|
||||
self.book = None
|
||||
self.temp_dir = temp_dir
|
||||
self.filename = filename
|
||||
self.file_md5 = file_md5
|
||||
self.extract_path = os.path.join(temp_dir, file_md5)
|
||||
|
||||
def read_book(self):
|
||||
self.book_ref = EPUB(self.filename)
|
||||
@@ -59,10 +58,9 @@ class ParseEPUB:
|
||||
return self.book['tags']
|
||||
|
||||
def get_contents(self):
|
||||
extract_path = os.path.join(self.temp_dir, self.file_md5)
|
||||
zipfile.ZipFile(self.filename).extractall(extract_path)
|
||||
zipfile.ZipFile(self.filename).extractall(self.extract_path)
|
||||
|
||||
self.book_ref.parse_chapters(temp_dir=self.temp_dir)
|
||||
self.book_ref.parse_chapters(temp_dir=self.extract_path)
|
||||
file_settings = {
|
||||
'images_only': False}
|
||||
return self.book['book_list'], file_settings
|
||||
|
104
parsers/pdf.py
Normal file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This file is a part of Lector, a Qt based ebook reader
|
||||
# Copyright (C) 2018 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
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import io
|
||||
from PyQt5 import QtCore
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
proceed = True
|
||||
try:
|
||||
import popplerqt5
|
||||
except ImportError:
|
||||
print('python-poppler-qt5 is not installed. Pdf files will not work.')
|
||||
proceed = False
|
||||
|
||||
class ParsePDF:
|
||||
def __init__(self, filename, *args):
|
||||
self.filename = filename
|
||||
self.book = None
|
||||
self.metadata = None
|
||||
|
||||
def read_book(self):
|
||||
if not proceed:
|
||||
return
|
||||
|
||||
self.book = popplerqt5.Poppler.Document.load(self.filename)
|
||||
if not self.book:
|
||||
return
|
||||
|
||||
self.metadata = BeautifulSoup(self.book.metadata(), 'xml')
|
||||
|
||||
def get_title(self):
|
||||
try:
|
||||
title = self.metadata.find('title').text
|
||||
return title.replace('\n', '')
|
||||
except AttributeError:
|
||||
return 'Unknown'
|
||||
|
||||
def get_author(self):
|
||||
try:
|
||||
author = self.metadata.find('creator').text
|
||||
return author.replace('\n', '')
|
||||
except AttributeError:
|
||||
return 'Unknown'
|
||||
|
||||
def get_year(self):
|
||||
try:
|
||||
year = self.metadata.find('MetadataDate').text
|
||||
return year.replace('\n', '')
|
||||
except AttributeError:
|
||||
return 9999
|
||||
|
||||
def get_cover_image(self):
|
||||
self.book.setRenderHint(
|
||||
popplerqt5.Poppler.Document.Antialiasing
|
||||
and popplerqt5.Poppler.Document.TextAntialiasing)
|
||||
|
||||
cover_page = self.book.page(0)
|
||||
cover_image = cover_page.renderToImage(300, 300)
|
||||
return resize_image(cover_image)
|
||||
|
||||
def get_isbn(self):
|
||||
return None
|
||||
|
||||
def get_tags(self):
|
||||
try:
|
||||
tags = self.metadata.find('Keywords').text
|
||||
return tags.replace('\n', '')
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
def get_contents(self):
|
||||
file_settings = {'images_only': True}
|
||||
contents = [(f'Page {i + 1}', i) for i in range(self.book.numPages())]
|
||||
|
||||
return contents, file_settings
|
||||
|
||||
|
||||
def resize_image(cover_image):
|
||||
cover_image = cover_image.scaled(
|
||||
420, 600, QtCore.Qt.IgnoreAspectRatio)
|
||||
|
||||
byte_array = QtCore.QByteArray()
|
||||
buffer = QtCore.QBuffer(byte_array)
|
||||
buffer.open(QtCore.QIODevice.WriteOnly)
|
||||
cover_image.save(buffer, 'jpg', 75)
|
||||
|
||||
cover_image_final = io.BytesIO(byte_array)
|
||||
cover_image_final.seek(0)
|
||||
return cover_image_final.getvalue()
|
8
resources/raw/DarkIcons/add.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 7 3 L 7 7 L 3 7 L 3 9 L 7 9 L 7 13 L 9 13 L 9 9 L 13 9 L 13 7 L 9 7 L 9 3 L 7 3 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 428 B |
8
resources/raw/DarkIcons/bookmark-new.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 4 0.00390625 C 4 0.00390625 3 0.00390625 3 1.0039062 L 3 15.003906 L 8 12.003906 L 13 15.003906 L 13 1.0039062 C 13 1.0039062 13 0.00390625 12 0.00390625 L 4 0.00390625 z M 7 3.0039062 L 9 3.0039062 L 9 5.0039062 L 11 5.0039062 L 11 7.0039062 L 9 7.0039062 L 9 9.0039062 L 7 9.0039062 L 7 7.0039062 L 5 7.0039062 L 5 5.0039062 L 7 5.0039062 L 7 3.0039062 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 703 B |
8
resources/raw/DarkIcons/bookmarks.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 8 0.390625 L 5.8808594 5.8847656 L 0 6.2011719 L 4.5722656 9.9160156 L 3.0566406 15.607422 L 8 12.40625 L 12.943359 15.607422 L 11.427734 9.9160156 L 16 6.2011719 L 10.119141 5.8847656 L 8 0.390625 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 546 B |
8
resources/raw/DarkIcons/color-picker.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 8 1 C 7.79297 1.66364 7.5132275 2.3110656 7.2109375 2.9472656 C 5.6704375 6.0974656 3.2599437 8.2540875 3.0273438 10.242188 C 3.0213438 10.271888 3.0052 10.304384 3 10.333984 L 3.0195312 10.339844 C 3.0145313 10.408244 3 10.476722 3 10.544922 C 3 13.005122 5.2386 15 8 15 C 10.7614 15 13 13.005122 13 10.544922 C 13 10.476722 12.985469 10.408214 12.980469 10.339844 L 13 10.333984 C 12.995 10.304484 12.978956 10.271887 12.972656 10.242188 C 12.740106 8.2539875 10.329662 6.0973656 8.7890625 2.9472656 C 8.4867825 2.3110456 8.20702 1.6636 8 1 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 891 B |
8
resources/raw/DarkIcons/edit-rename.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 12.210938 1 C 11.998438 1 11.784141 1.0830469 11.619141 1.2480469 L 9.9902344 2.8886719 L 13.109375 6.0078125 L 14.75 4.3789062 C 15.08 4.0489063 15.08 3.5272656 14.75 3.1972656 L 12.800781 1.2480469 C 12.635781 1.0830469 12.423437 1 12.210938 1 z M 8.8691406 4.0078125 L 0.99023438 11.888672 L 0.99023438 15.007812 L 4.109375 15.007812 L 11.990234 7.1289062 L 8.8691406 4.0078125 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 729 B |
8
resources/raw/DarkIcons/format-indent-less.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 1 5 L 1 7 L 9 7.0039062 L 9 5.0039062 L 1 5 z M 15 5.0039062 L 10 8.0039062 L 15 11.003906 L 15 5.0039062 z M 1 9 L 1 11 L 9 11 L 9 9 L 1 9 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 561 B |
8
resources/raw/DarkIcons/format-indent-more.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 1 5.0039062 L 1 11.003906 L 6 8.0039062 L 1 5.0039062 z M 7 5.0039062 L 7 7.0039062 L 15 7.0039062 L 15 5.0039062 L 7 5.0039062 z M 15 9 L 7 9.0039062 L 7 11.003906 L 15 11 L 15 9 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 601 B |
8
resources/raw/DarkIcons/format-justify-center.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 4 5.0039062 L 4 7.0039062 L 12 7.0039062 L 12 5.0039062 L 4 5.0039062 z M 4 9.0039062 L 4 11.003906 L 12 11.003906 L 12 9.0039062 L 4 9.0039062 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 565 B |
8
resources/raw/DarkIcons/format-justify-fill.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 1 5.0039062 L 1 7.0039062 L 15 7.0039062 L 15 5.0039062 L 1 5.0039062 z M 1 9.0039062 L 1 11.003906 L 15 11.003906 L 15 9.0039062 L 1 9.0039062 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 565 B |
8
resources/raw/DarkIcons/format-justify-left.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 1 5.0039062 L 1 7.0039062 L 9 7.0039062 L 9 5.0039062 L 1 5.0039062 z M 1 9.0039062 L 1 11.003906 L 9 11.003906 L 9 9.0039062 L 1 9.0039062 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 561 B |
8
resources/raw/DarkIcons/format-justify-right.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 7 5.0039062 L 7 7.0039062 L 15 7.0039062 L 15 5.0039062 L 7 5.0039062 z M 7 9.0039062 L 7 11.003906 L 15 11.003906 L 15 9.0039062 L 7 9.0039062 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 565 B |
8
resources/raw/DarkIcons/format-line-spacing-double.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 3 L 5 4 L 2 4 L 2 12 L 5 12 L 5 13 L 14 13 L 14 10 L 5 10 L 5 11 L 3 11 L 3 9 L 4 9 L 4 7 L 3 7 L 3 5 L 5 5 L 5 6 L 14 6 L 14 3 L 5 3 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 484 B |
8
resources/raw/DarkIcons/format-line-spacing-triple.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 2 L 5 3 L 2 3 L 2 13 L 5 13 L 5 14 L 14 14 L 14 11 L 5 11 L 5 12 L 3 12 L 3 9 L 4 9 L 4 7 L 3 7 L 3 4 L 5 4 L 5 5 L 14 5 L 14 2 L 5 2 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 484 B |
8
resources/raw/DarkIcons/gtk-select-font.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 7 1 L 2 15 L 4.5 15 L 5.5625 12 L 10.4375 12 L 11.5 15 L 14.28125 15 L 9 1 L 7 1 z M 14 1 A 1 1 0 0 0 13 2 A 1 1 0 0 0 14 3 A 1 1 0 0 0 15 2 A 1 1 0 0 0 14 1 z M 14 4 A 1 1 0 0 0 13 5 A 1 1 0 0 0 14 6 A 1 1 0 0 0 15 5 A 1 1 0 0 0 14 4 z M 8 5 L 9.75 10 L 6.25 10 L 8 5 z M 14 7 A 1 1 0 0 0 13 8 A 1 1 0 0 0 14 9 A 1 1 0 0 0 15 8 A 1 1 0 0 0 14 7 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 694 B |
8
resources/raw/DarkIcons/mail-thread-watch.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="m4.5 3a3.5 5 0 0 0 -3.5 5 3.5 5 0 0 0 3.5 5 3.5 5 0 0 0 3.5 -5 3.5 5 0 0 0 -3.5 -5zm3.5 5a3.5 5 0 0 0 3.5 5 3.5 5 0 0 0 3.5 -5 3.5 5 0 0 0 -3.5 -5 3.5 5 0 0 0 -3.5 5zm-3 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm7 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 642 B |
8
resources/raw/DarkIcons/reload.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 8 1.015625 C 4.134 1.015625 1 4.149625 1 8.015625 C 1 11.881625 4.134 15.015625 8 15.015625 C 11.1748 15.015625 13.86145 12.912425 14.71875 10.015625 L 12.5625 10.015625 C 11.78823 11.775125 10.0457 13.015625 8 13.015625 C 5.2386 13.015625 3 10.777025 3 8.015625 C 3 5.254225 5.2386 3.015625 8 3.015625 C 9.3816 3.015625 10.615525 3.59065 11.515625 4.5 L 9.0058594 7.015625 L 15.005859 7.015625 L 15.005859 1.015625 L 12.953125 3.0683594 C 11.683125 1.8033594 9.9339063 1.015625 8.0039062 1.015625 L 8 1.015625 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 859 B |
8
resources/raw/DarkIcons/remove.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 3 7 L 3 9 L 13 9 L 13 7 L 3 7 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 378 B |
8
resources/raw/DarkIcons/settings.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 6.25 1 L 6.0957031 2.84375 A 5.5 5.5 0 0 0 4.4882812 3.7734375 L 2.8125 2.984375 L 1.0625 6.015625 L 2.5839844 7.0722656 A 5.5 5.5 0 0 0 2.5 8 A 5.5 5.5 0 0 0 2.5800781 8.9316406 L 1.0625 9.984375 L 2.8125 13.015625 L 4.484375 12.228516 A 5.5 5.5 0 0 0 6.0957031 13.152344 L 6.2460938 15.001953 L 9.7460938 15.001953 L 9.9003906 13.158203 A 5.5 5.5 0 0 0 11.507812 12.228516 L 13.183594 13.017578 L 14.933594 9.9863281 L 13.412109 8.9296875 A 5.5 5.5 0 0 0 13.496094 8.0019531 A 5.5 5.5 0 0 0 13.416016 7.0703125 L 14.933594 6.0175781 L 13.183594 2.9863281 L 11.511719 3.7734375 A 5.5 5.5 0 0 0 9.9003906 2.8496094 L 9.75 1 L 6.25 1 z M 8 6 A 2 2 0 0 1 10 8 A 2 2 0 0 1 8 10 A 2 2 0 0 1 6 8 A 2 2 0 0 1 8 6 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
8
resources/raw/DarkIcons/table.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="m1 1v14h14v-14h-14zm2 2h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2zm-8 4h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2zm-8 4h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 501 B |
8
resources/raw/DarkIcons/trash-empty.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 6 0.9921875 C 5 0.9921875 5 1.9921875 5 1.9921875 L 2 1.9921875 C 2 1.9921875 1 1.9956938 1 2.9960938 L 1 3.9960938 L 14 3.9921875 L 14 2.9960938 C 14 1.9960938 13 1.9921875 13 1.9921875 L 10 1.9921875 C 10 1.9921875 10 0.9921875 9 0.9921875 L 6 0.9921875 z M 2 4.9960938 L 2 13.996094 C 2.00005 14.519674 2.47642 14.996044 3 14.996094 L 12 14.996094 C 12.52358 14.996044 12.99995 14.519674 13 13.996094 L 13 4.9960938 L 2 4.9960938 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 781 B |
8
resources/raw/DarkIcons/view-fullscreen.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 2 2.0039062 C 1 2.0039062 1 3.0039062 1 3.0039062 L 1 7.0039062 L 3 7.0039062 L 3 4.0039062 L 6 4.0039062 L 6 2.0039062 L 2 2.0039062 z M 10 2.0039062 L 10 4.0039062 L 13 4.0039062 L 13 7.0039062 L 15 7.0039062 L 15 3.0039062 C 15 2.0039062 14 2.0039062 14 2.0039062 L 10 2.0039062 z M 1 9.0039062 L 1 13.003906 C 1 14.003906 2 14.003906 2 14.003906 L 6 14.003906 L 6 12.003906 L 3 12.003906 L 3 9.0039062 L 1 9.0039062 z M 13 9.0039062 L 13 12.003906 L 10 12.003906 L 10 14.003906 L 14 14.003906 C 14 14.003906 15 14.003906 15 13.003906 L 15 9.0039062 L 13 9.0039062 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 916 B |
8
resources/raw/DarkIcons/view-grid.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 1.25 3.0039062 C 1.1115 3.0039063 1 3.1154062 1 3.2539062 L 1 4.7539062 C 1 4.8924062 1.1115 5.0039062 1.25 5.0039062 L 2.75 5.0039062 C 2.8885 5.0039062 3 4.8924062 3 4.7539062 L 3 3.2539062 C 3 3.1154062 2.8885 3.0039062 2.75 3.0039062 L 1.25 3.0039062 z M 5.25 3.0039062 C 5.1115 3.0039063 5 3.1154062 5 3.2539062 L 5 4.7539062 C 5 4.8924062 5.1115 5.0039062 5.25 5.0039062 L 6.75 5.0039062 C 6.8885 5.0039062 7 4.8924062 7 4.7539062 L 7 3.2539062 C 7 3.1154062 6.8885 3.0039062 6.75 3.0039062 L 5.25 3.0039062 z M 9.25 3.0039062 C 9.1115 3.0039063 9 3.1154062 9 3.2539062 L 9 4.7539062 C 9 4.8924062 9.1115 5.0039062 9.25 5.0039062 L 10.75 5.0039062 C 10.8885 5.0039062 11 4.8924062 11 4.7539062 L 11 3.2539062 C 11 3.1154062 10.8885 3.0039062 10.75 3.0039062 L 9.25 3.0039062 z M 13.25 3.0039062 C 13.1115 3.0039063 13 3.1154062 13 3.2539062 L 13 4.7539062 C 13 4.8924062 13.1115 5.0039062 13.25 5.0039062 L 14.75 5.0039062 C 14.8885 5.0039062 15 4.8924062 15 4.7539062 L 15 3.2539062 C 15 3.1154062 14.8885 3.0039062 14.75 3.0039062 L 13.25 3.0039062 z M 1.25 7.0039062 C 1.1115 7.0039063 1 7.1154063 1 7.2539062 L 1 8.7539062 C 1 8.8924063 1.1115 9.0039062 1.25 9.0039062 L 2.75 9.0039062 C 2.8885 9.0039062 3 8.8924063 3 8.7539062 L 3 7.2539062 C 3 7.1154063 2.8885 7.0039062 2.75 7.0039062 L 1.25 7.0039062 z M 5.25 7.0039062 C 5.1115 7.0039063 5 7.1154063 5 7.2539062 L 5 8.7539062 C 5 8.8924063 5.1115 9.0039062 5.25 9.0039062 L 6.75 9.0039062 C 6.8885 9.0039062 7 8.8924063 7 8.7539062 L 7 7.2539062 C 7 7.1154063 6.8885 7.0039062 6.75 7.0039062 L 5.25 7.0039062 z M 9.25 7.0039062 C 9.1115 7.0039063 9 7.1154063 9 7.2539062 L 9 8.7539062 C 9 8.8924063 9.1115 9.0039062 9.25 9.0039062 L 10.75 9.0039062 C 10.8885 9.0039062 11 8.8924063 11 8.7539062 L 11 7.2539062 C 11 7.1154063 10.8885 7.0039062 10.75 7.0039062 L 9.25 7.0039062 z M 13.25 7.0039062 C 13.1115 7.0039063 13 7.1154063 13 7.2539062 L 13 8.7539062 C 13 8.8924063 13.1115 9.0039062 13.25 9.0039062 L 14.75 9.0039062 C 14.8885 9.0039062 15 8.8924063 15 8.7539062 L 15 7.2539062 C 15 7.1154063 14.8885 7.0039062 14.75 7.0039062 L 13.25 7.0039062 z M 1.25 11.003906 C 1.1115 11.003906 1 11.115406 1 11.253906 L 1 12.753906 C 1 12.892406 1.1115 13.003906 1.25 13.003906 L 2.75 13.003906 C 2.8885 13.003906 3 12.892406 3 12.753906 L 3 11.253906 C 3 11.115406 2.8885 11.003906 2.75 11.003906 L 1.25 11.003906 z M 5.25 11.003906 C 5.1115 11.003906 5 11.115406 5 11.253906 L 5 12.753906 C 5 12.892406 5.1115 13.003906 5.25 13.003906 L 6.75 13.003906 C 6.8885 13.003906 7 12.892406 7 12.753906 L 7 11.253906 C 7 11.115406 6.8885 11.003906 6.75 11.003906 L 5.25 11.003906 z M 9.25 11.003906 C 9.1115 11.003906 9 11.115406 9 11.253906 L 9 12.753906 C 9 12.892406 9.1115 13.003906 9.25 13.003906 L 10.75 13.003906 C 10.8885 13.003906 11 12.892406 11 12.753906 L 11 11.253906 C 11 11.115406 10.8885 11.003906 10.75 11.003906 L 9.25 11.003906 z M 13.25 11.003906 C 13.1115 11.003906 13 11.115406 13 11.253906 L 13 12.753906 C 13 12.892406 13.1115 13.003906 13.25 13.003906 L 14.75 13.003906 C 14.8885 13.003906 15 12.892406 15 12.753906 L 15 11.253906 C 15 11.115406 14.8885 11.003906 14.75 11.003906 L 13.25 11.003906 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
8
resources/raw/DarkIcons/view-readermode.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 10.029297 1 C 9.8819169 1.003 9.7293425 1.0150094 9.5703125 1.0371094 C 9.0034025 1.1159094 8.3186875 1.3914781 7.5546875 1.7988281 C 6.0140875 0.94567812 4.8137406 0.89374688 3.8066406 1.1542969 C 2.7378406 1.4308069 1.868925 1.8823869 0.515625 1.8417969 L 0 1.8261719 L 0 16 L 15 16 L 15 1.84375 L 14.482422 1.8613281 C 12.965822 1.9165281 12.211922 1.464645 11.232422 1.171875 C 10.865122 1.062075 10.471417 0.99098 10.029297 1 z M 5.21875 1.9941406 C 5.71774 2.0327406 6.2822 2.213495 7 2.609375 L 7 11.333984 C 5.8956 10.692224 4.7902063 10.643969 3.8164062 10.886719 C 3.1632062 11.049539 2.5692 11.237652 2 11.388672 L 2 2.6621094 C 2.8021 2.5141794 3.4740875 2.2830225 4.0546875 2.1328125 C 4.2857975 2.0730125 4.5091312 2.02398 4.7382812 2 C 4.8933012 1.9838 5.05242 1.9813406 5.21875 1.9941406 z M 10.337891 2.0019531 C 10.543791 2.0284531 10.742569 2.079065 10.949219 2.140625 C 11.483649 2.300375 12.1426 2.5531719 13 2.7011719 L 13 11.384766 C 12.43016 11.232366 11.837453 11.042719 11.189453 10.880859 C 10.209613 10.636099 9.0981 10.696078 8 11.367188 L 8 2.6679688 C 8.70328 2.2824487 9.2453875 2.0716725 9.6796875 2.0078125 C 9.9189475 1.9726125 10.131991 1.9756531 10.337891 2.0019531 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
8
resources/raw/DarkIcons/visibility.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 8 3.0039062 C 6.4492 3.0190063 4.8879094 3.3732319 3.5371094 4.1386719 C 2.9987094 4.4892919 2.3523344 4.9421175 1.8652344 5.3984375 C 1.0987444 6.1488575 0.4427 7.0244062 0 8.0039062 C 1.2149 10.683506 3.8859187 12.6474 6.8242188 12.9375 C 8.7516188 13.15561 10.768591 12.822631 12.462891 11.869141 C 13.001291 11.518521 13.647666 11.065695 14.134766 10.609375 C 14.901256 9.858955 15.5573 8.9834063 16 8.0039062 C 14.785 5.3245062 12.114181 3.3601125 9.1757812 3.0703125 C 8.7859013 3.0248425 8.39251 3.0038963 8 3.0039062 z M 8 5.0019531 L 8 5.0039062 C 9.607 4.9683062 11.0303 6.4057062 11 8.0039062 C 11.0515 9.7703063 9.2909813 11.294844 7.5507812 10.964844 C 5.7931812 10.758504 4.5587188 8.7851344 5.1367188 7.1152344 C 5.5058788 5.8858344 6.7125 4.9866531 8 5.0019531 z M 8 7.0039062 A 1 1 0 0 0 7 8.0039062 A 1 1 0 0 0 8 9.0039062 A 1 1 0 0 0 9 8.0039062 A 1 1 0 0 0 8 7.0039062 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
8
resources/raw/DarkIcons/zoom-fit-best.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 3.1894531 2.0039062 C 2.5267531 2.0039062 2.0019531 2.5527963 2.0019531 3.2226562 L 2.0019531 7.0039062 L 4.0019531 7.0039062 L 4.0019531 4.0039062 L 7.0019531 4.0039062 L 7.0019531 2.0039062 L 3.1894531 2.0039062 z M 9.0019531 2.0039062 L 9.0019531 4.0039062 L 12.001953 4.0039062 L 12.001953 7.0039062 L 14.001953 7.0039062 L 14.001953 3.2226562 C 14.001953 2.5528963 13.477153 2.0039062 12.814453 2.0039062 L 9.0019531 2.0039062 z M 2.0019531 9.0039062 L 2.0019531 12.785156 C 2.0019531 13.454916 2.5267531 14.003906 3.1894531 14.003906 L 7.0019531 14.003906 L 7.0019531 12.003906 L 4.0019531 12.003906 L 4.0019531 9.0039062 L 2.0019531 9.0039062 z M 12.001953 9.0039062 L 12.001953 12.003906 L 9.0019531 12.003906 L 9.0019531 14.003906 L 12.814453 14.003906 C 13.477153 14.003906 14.001953 13.455016 14.001953 12.785156 L 14.001953 9.0039062 L 12.001953 9.0039062 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
8
resources/raw/DarkIcons/zoom-fit-width.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 3.1875 2 C 2.5248 2 2 2.54895 2 3.21875 L 2 7 L 4 7 L 4 4 L 7 4 L 7 2 L 3.1875 2 z M 9 2 L 9 4 L 12 4 L 12 7 L 14 7 L 14 3.21875 C 14 2.54885 13.4755 2 12.8125 2 L 9 2 z M 7 5 L 7 11 L 9 11 L 9 5 L 7 5 z M 6 6 L 4 8 L 6 10 L 6 6 z M 10 6 L 10 10 L 12 8 L 10 6 z M 2 9 L 2 12.78125 C 2 13.45125 2.5248 14 3.1875 14 L 7 14 L 7 12 L 4 12 L 4 9 L 2 9 z M 12 9 L 12 12 L 9 12 L 9 14 L 12.8125 14 C 13.4755 14 14 13.45125 14 12.78125 L 14 9 L 12 9 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 790 B |
8
resources/raw/DarkIcons/zoom-in.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 3 2 C 2.446 2 2 2.446 2 3 L 2 13 C 2 13.554 2.446 14 3 14 L 13 14 C 13.554 14 14 13.554 14 13 L 14 3 C 14 2.446 13.554 2 13 2 L 3 2 z M 7 5 L 9 5 L 9 7 L 11 7 L 11 9 L 9 9 L 9 11 L 7 11 L 7 9 L 5 9 L 5 7 L 7 7 L 7 5 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 564 B |
8
resources/raw/DarkIcons/zoom-original.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 3 2 C 2.446 2 2 2.446 2 3 L 2 13 C 2 13.554 2.446 14 3 14 L 13 14 C 13.554 14 14 13.554 14 13 L 14 3 C 14 2.446 13.554 2 13 2 L 3 2 z M 7 5 L 9 5 L 9 11 L 7 11 L 7 7 L 6 7 L 6 6 C 6 6 7 6 7 5 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 540 B |
8
resources/raw/DarkIcons/zoom-out.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 3 2 C 2.446 2 2 2.446 2 3 L 2 13 C 2 13.554 2.446 14 3 14 L 13 14 C 13.554 14 14 13.554 14 13 L 14 3 C 14 2.446 13.554 2 13 2 L 3 2 z M 5 7 L 11 7 L 11 9 L 5 9 L 5 7 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 514 B |
8
resources/raw/LightIcons/add.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 7 3 L 7 7 L 3 7 L 3 9 L 7 9 L 7 13 L 9 13 L 9 9 L 13 9 L 13 7 L 9 7 L 9 3 L 7 3 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 428 B |
8
resources/raw/LightIcons/bookmark-new.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 4 0.00390625 C 4 0.00390625 3 0.00390625 3 1.0039062 L 3 15.003906 L 8 12.003906 L 13 15.003906 L 13 1.0039062 C 13 1.0039062 13 0.00390625 12 0.00390625 L 4 0.00390625 z M 7 3.0039062 L 9 3.0039062 L 9 5.0039062 L 11 5.0039062 L 11 7.0039062 L 9 7.0039062 L 9 9.0039062 L 7 9.0039062 L 7 7.0039062 L 5 7.0039062 L 5 5.0039062 L 7 5.0039062 L 7 3.0039062 z" transform="translate(3 3)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 703 B |
8
resources/raw/LightIcons/bookmarks.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 8 0.390625 L 5.8808594 5.8847656 L 0 6.2011719 L 4.5722656 9.9160156 L 3.0566406 15.607422 L 8 12.40625 L 12.943359 15.607422 L 11.427734 9.9160156 L 16 6.2011719 L 10.119141 5.8847656 L 8 0.390625 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 546 B |
8
resources/raw/LightIcons/color-picker.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 8 1 C 7.79297 1.66364 7.5132275 2.3110656 7.2109375 2.9472656 C 5.6704375 6.0974656 3.2599437 8.2540875 3.0273438 10.242188 C 3.0213438 10.271888 3.0052 10.304384 3 10.333984 L 3.0195312 10.339844 C 3.0145313 10.408244 3 10.476722 3 10.544922 C 3 13.005122 5.2386 15 8 15 C 10.7614 15 13 13.005122 13 10.544922 C 13 10.476722 12.985469 10.408214 12.980469 10.339844 L 13 10.333984 C 12.995 10.304484 12.978956 10.271887 12.972656 10.242188 C 12.740106 8.2539875 10.329662 6.0973656 8.7890625 2.9472656 C 8.4867825 2.3110456 8.20702 1.6636 8 1 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 891 B |
8
resources/raw/LightIcons/edit-rename.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 12.210938 1 C 11.998438 1 11.784141 1.0830469 11.619141 1.2480469 L 9.9902344 2.8886719 L 13.109375 6.0078125 L 14.75 4.3789062 C 15.08 4.0489063 15.08 3.5272656 14.75 3.1972656 L 12.800781 1.2480469 C 12.635781 1.0830469 12.423437 1 12.210938 1 z M 8.8691406 4.0078125 L 0.99023438 11.888672 L 0.99023438 15.007812 L 4.109375 15.007812 L 11.990234 7.1289062 L 8.8691406 4.0078125 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 729 B |
8
resources/raw/LightIcons/format-indent-less.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 1 5 L 1 7 L 9 7.0039062 L 9 5.0039062 L 1 5 z M 15 5.0039062 L 10 8.0039062 L 15 11.003906 L 15 5.0039062 z M 1 9 L 1 11 L 9 11 L 9 9 L 1 9 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 561 B |
8
resources/raw/LightIcons/format-indent-more.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 1 5.0039062 L 1 11.003906 L 6 8.0039062 L 1 5.0039062 z M 7 5.0039062 L 7 7.0039062 L 15 7.0039062 L 15 5.0039062 L 7 5.0039062 z M 15 9 L 7 9.0039062 L 7 11.003906 L 15 11 L 15 9 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 601 B |
8
resources/raw/LightIcons/format-justify-center.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 4 5.0039062 L 4 7.0039062 L 12 7.0039062 L 12 5.0039062 L 4 5.0039062 z M 4 9.0039062 L 4 11.003906 L 12 11.003906 L 12 9.0039062 L 4 9.0039062 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 565 B |
8
resources/raw/LightIcons/format-justify-fill.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 1 5.0039062 L 1 7.0039062 L 15 7.0039062 L 15 5.0039062 L 1 5.0039062 z M 1 9.0039062 L 1 11.003906 L 15 11.003906 L 15 9.0039062 L 1 9.0039062 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 565 B |
8
resources/raw/LightIcons/format-justify-left.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 1 5.0039062 L 1 7.0039062 L 9 7.0039062 L 9 5.0039062 L 1 5.0039062 z M 1 9.0039062 L 1 11.003906 L 9 11.003906 L 9 9.0039062 L 1 9.0039062 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 561 B |
8
resources/raw/LightIcons/format-justify-right.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 1 1 L 1 3 L 15 3 L 15 1 L 1 1 z M 7 5.0039062 L 7 7.0039062 L 15 7.0039062 L 15 5.0039062 L 7 5.0039062 z M 7 9.0039062 L 7 11.003906 L 15 11.003906 L 15 9.0039062 L 7 9.0039062 z M 1 13 L 1 15 L 15 15 L 15 13 L 1 13 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 565 B |
8
resources/raw/LightIcons/format-line-spacing-double.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 3 L 5 4 L 2 4 L 2 12 L 5 12 L 5 13 L 14 13 L 14 10 L 5 10 L 5 11 L 3 11 L 3 9 L 4 9 L 4 7 L 3 7 L 3 5 L 5 5 L 5 6 L 14 6 L 14 3 L 5 3 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 484 B |
8
resources/raw/LightIcons/format-line-spacing-triple.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 2 L 5 3 L 2 3 L 2 13 L 5 13 L 5 14 L 14 14 L 14 11 L 5 11 L 5 12 L 3 12 L 3 9 L 4 9 L 4 7 L 3 7 L 3 4 L 5 4 L 5 5 L 14 5 L 14 2 L 5 2 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 484 B |
8
resources/raw/LightIcons/gtk-select-font.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 7 1 L 2 15 L 4.5 15 L 5.5625 12 L 10.4375 12 L 11.5 15 L 14.28125 15 L 9 1 L 7 1 z M 14 1 A 1 1 0 0 0 13 2 A 1 1 0 0 0 14 3 A 1 1 0 0 0 15 2 A 1 1 0 0 0 14 1 z M 14 4 A 1 1 0 0 0 13 5 A 1 1 0 0 0 14 6 A 1 1 0 0 0 15 5 A 1 1 0 0 0 14 4 z M 8 5 L 9.75 10 L 6.25 10 L 8 5 z M 14 7 A 1 1 0 0 0 13 8 A 1 1 0 0 0 14 9 A 1 1 0 0 0 15 8 A 1 1 0 0 0 14 7 z" transform="translate(3 3)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 694 B |
8
resources/raw/LightIcons/mail-thread-watch.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="m4.5 3a3.5 5 0 0 0 -3.5 5 3.5 5 0 0 0 3.5 5 3.5 5 0 0 0 3.5 -5 3.5 5 0 0 0 -3.5 -5zm3.5 5a3.5 5 0 0 0 3.5 5 3.5 5 0 0 0 3.5 -5 3.5 5 0 0 0 -3.5 -5 3.5 5 0 0 0 -3.5 5zm-3 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm7 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 642 B |
8
resources/raw/LightIcons/reload.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 8 1.015625 C 4.134 1.015625 1 4.149625 1 8.015625 C 1 11.881625 4.134 15.015625 8 15.015625 C 11.1748 15.015625 13.86145 12.912425 14.71875 10.015625 L 12.5625 10.015625 C 11.78823 11.775125 10.0457 13.015625 8 13.015625 C 5.2386 13.015625 3 10.777025 3 8.015625 C 3 5.254225 5.2386 3.015625 8 3.015625 C 9.3816 3.015625 10.615525 3.59065 11.515625 4.5 L 9.0058594 7.015625 L 15.005859 7.015625 L 15.005859 1.015625 L 12.953125 3.0683594 C 11.683125 1.8033594 9.9339063 1.015625 8.0039062 1.015625 L 8 1.015625 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 859 B |
8
resources/raw/LightIcons/remove.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 3 7 L 3 9 L 13 9 L 13 7 L 3 7 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 378 B |
8
resources/raw/LightIcons/settings.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 6.25 1 L 6.0957031 2.84375 A 5.5 5.5 0 0 0 4.4882812 3.7734375 L 2.8125 2.984375 L 1.0625 6.015625 L 2.5839844 7.0722656 A 5.5 5.5 0 0 0 2.5 8 A 5.5 5.5 0 0 0 2.5800781 8.9316406 L 1.0625 9.984375 L 2.8125 13.015625 L 4.484375 12.228516 A 5.5 5.5 0 0 0 6.0957031 13.152344 L 6.2460938 15.001953 L 9.7460938 15.001953 L 9.9003906 13.158203 A 5.5 5.5 0 0 0 11.507812 12.228516 L 13.183594 13.017578 L 14.933594 9.9863281 L 13.412109 8.9296875 A 5.5 5.5 0 0 0 13.496094 8.0019531 A 5.5 5.5 0 0 0 13.416016 7.0703125 L 14.933594 6.0175781 L 13.183594 2.9863281 L 11.511719 3.7734375 A 5.5 5.5 0 0 0 9.9003906 2.8496094 L 9.75 1 L 6.25 1 z M 8 6 A 2 2 0 0 1 10 8 A 2 2 0 0 1 8 10 A 2 2 0 0 1 6 8 A 2 2 0 0 1 8 6 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
8
resources/raw/LightIcons/table.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="m1 1v14h14v-14h-14zm2 2h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2zm-8 4h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2zm-8 4h2v2h-2v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 501 B |
8
resources/raw/LightIcons/trash-empty.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 6 0.9921875 C 5 0.9921875 5 1.9921875 5 1.9921875 L 2 1.9921875 C 2 1.9921875 1 1.9956938 1 2.9960938 L 1 3.9960938 L 14 3.9921875 L 14 2.9960938 C 14 1.9960938 13 1.9921875 13 1.9921875 L 10 1.9921875 C 10 1.9921875 10 0.9921875 9 0.9921875 L 6 0.9921875 z M 2 4.9960938 L 2 13.996094 C 2.00005 14.519674 2.47642 14.996044 3 14.996094 L 12 14.996094 C 12.52358 14.996044 12.99995 14.519674 13 13.996094 L 13 4.9960938 L 2 4.9960938 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 781 B |
8
resources/raw/LightIcons/view-fullscreen.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 2 2.0039062 C 1 2.0039062 1 3.0039062 1 3.0039062 L 1 7.0039062 L 3 7.0039062 L 3 4.0039062 L 6 4.0039062 L 6 2.0039062 L 2 2.0039062 z M 10 2.0039062 L 10 4.0039062 L 13 4.0039062 L 13 7.0039062 L 15 7.0039062 L 15 3.0039062 C 15 2.0039062 14 2.0039062 14 2.0039062 L 10 2.0039062 z M 1 9.0039062 L 1 13.003906 C 1 14.003906 2 14.003906 2 14.003906 L 6 14.003906 L 6 12.003906 L 3 12.003906 L 3 9.0039062 L 1 9.0039062 z M 13 9.0039062 L 13 12.003906 L 10 12.003906 L 10 14.003906 L 14 14.003906 C 14 14.003906 15 14.003906 15 13.003906 L 15 9.0039062 L 13 9.0039062 z" transform="translate(3 3)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 916 B |
8
resources/raw/LightIcons/view-grid.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 1.25 3.0039062 C 1.1115 3.0039063 1 3.1154062 1 3.2539062 L 1 4.7539062 C 1 4.8924062 1.1115 5.0039062 1.25 5.0039062 L 2.75 5.0039062 C 2.8885 5.0039062 3 4.8924062 3 4.7539062 L 3 3.2539062 C 3 3.1154062 2.8885 3.0039062 2.75 3.0039062 L 1.25 3.0039062 z M 5.25 3.0039062 C 5.1115 3.0039063 5 3.1154062 5 3.2539062 L 5 4.7539062 C 5 4.8924062 5.1115 5.0039062 5.25 5.0039062 L 6.75 5.0039062 C 6.8885 5.0039062 7 4.8924062 7 4.7539062 L 7 3.2539062 C 7 3.1154062 6.8885 3.0039062 6.75 3.0039062 L 5.25 3.0039062 z M 9.25 3.0039062 C 9.1115 3.0039063 9 3.1154062 9 3.2539062 L 9 4.7539062 C 9 4.8924062 9.1115 5.0039062 9.25 5.0039062 L 10.75 5.0039062 C 10.8885 5.0039062 11 4.8924062 11 4.7539062 L 11 3.2539062 C 11 3.1154062 10.8885 3.0039062 10.75 3.0039062 L 9.25 3.0039062 z M 13.25 3.0039062 C 13.1115 3.0039063 13 3.1154062 13 3.2539062 L 13 4.7539062 C 13 4.8924062 13.1115 5.0039062 13.25 5.0039062 L 14.75 5.0039062 C 14.8885 5.0039062 15 4.8924062 15 4.7539062 L 15 3.2539062 C 15 3.1154062 14.8885 3.0039062 14.75 3.0039062 L 13.25 3.0039062 z M 1.25 7.0039062 C 1.1115 7.0039063 1 7.1154063 1 7.2539062 L 1 8.7539062 C 1 8.8924063 1.1115 9.0039062 1.25 9.0039062 L 2.75 9.0039062 C 2.8885 9.0039062 3 8.8924063 3 8.7539062 L 3 7.2539062 C 3 7.1154063 2.8885 7.0039062 2.75 7.0039062 L 1.25 7.0039062 z M 5.25 7.0039062 C 5.1115 7.0039063 5 7.1154063 5 7.2539062 L 5 8.7539062 C 5 8.8924063 5.1115 9.0039062 5.25 9.0039062 L 6.75 9.0039062 C 6.8885 9.0039062 7 8.8924063 7 8.7539062 L 7 7.2539062 C 7 7.1154063 6.8885 7.0039062 6.75 7.0039062 L 5.25 7.0039062 z M 9.25 7.0039062 C 9.1115 7.0039063 9 7.1154063 9 7.2539062 L 9 8.7539062 C 9 8.8924063 9.1115 9.0039062 9.25 9.0039062 L 10.75 9.0039062 C 10.8885 9.0039062 11 8.8924063 11 8.7539062 L 11 7.2539062 C 11 7.1154063 10.8885 7.0039062 10.75 7.0039062 L 9.25 7.0039062 z M 13.25 7.0039062 C 13.1115 7.0039063 13 7.1154063 13 7.2539062 L 13 8.7539062 C 13 8.8924063 13.1115 9.0039062 13.25 9.0039062 L 14.75 9.0039062 C 14.8885 9.0039062 15 8.8924063 15 8.7539062 L 15 7.2539062 C 15 7.1154063 14.8885 7.0039062 14.75 7.0039062 L 13.25 7.0039062 z M 1.25 11.003906 C 1.1115 11.003906 1 11.115406 1 11.253906 L 1 12.753906 C 1 12.892406 1.1115 13.003906 1.25 13.003906 L 2.75 13.003906 C 2.8885 13.003906 3 12.892406 3 12.753906 L 3 11.253906 C 3 11.115406 2.8885 11.003906 2.75 11.003906 L 1.25 11.003906 z M 5.25 11.003906 C 5.1115 11.003906 5 11.115406 5 11.253906 L 5 12.753906 C 5 12.892406 5.1115 13.003906 5.25 13.003906 L 6.75 13.003906 C 6.8885 13.003906 7 12.892406 7 12.753906 L 7 11.253906 C 7 11.115406 6.8885 11.003906 6.75 11.003906 L 5.25 11.003906 z M 9.25 11.003906 C 9.1115 11.003906 9 11.115406 9 11.253906 L 9 12.753906 C 9 12.892406 9.1115 13.003906 9.25 13.003906 L 10.75 13.003906 C 10.8885 13.003906 11 12.892406 11 12.753906 L 11 11.253906 C 11 11.115406 10.8885 11.003906 10.75 11.003906 L 9.25 11.003906 z M 13.25 11.003906 C 13.1115 11.003906 13 11.115406 13 11.253906 L 13 12.753906 C 13 12.892406 13.1115 13.003906 13.25 13.003906 L 14.75 13.003906 C 14.8885 13.003906 15 12.892406 15 12.753906 L 15 11.253906 C 15 11.115406 14.8885 11.003906 14.75 11.003906 L 13.25 11.003906 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
8
resources/raw/LightIcons/view-readermode.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 10.029297 1 C 9.8819169 1.003 9.7293425 1.0150094 9.5703125 1.0371094 C 9.0034025 1.1159094 8.3186875 1.3914781 7.5546875 1.7988281 C 6.0140875 0.94567812 4.8137406 0.89374688 3.8066406 1.1542969 C 2.7378406 1.4308069 1.868925 1.8823869 0.515625 1.8417969 L 0 1.8261719 L 0 16 L 15 16 L 15 1.84375 L 14.482422 1.8613281 C 12.965822 1.9165281 12.211922 1.464645 11.232422 1.171875 C 10.865122 1.062075 10.471417 0.99098 10.029297 1 z M 5.21875 1.9941406 C 5.71774 2.0327406 6.2822 2.213495 7 2.609375 L 7 11.333984 C 5.8956 10.692224 4.7902063 10.643969 3.8164062 10.886719 C 3.1632062 11.049539 2.5692 11.237652 2 11.388672 L 2 2.6621094 C 2.8021 2.5141794 3.4740875 2.2830225 4.0546875 2.1328125 C 4.2857975 2.0730125 4.5091312 2.02398 4.7382812 2 C 4.8933012 1.9838 5.05242 1.9813406 5.21875 1.9941406 z M 10.337891 2.0019531 C 10.543791 2.0284531 10.742569 2.079065 10.949219 2.140625 C 11.483649 2.300375 12.1426 2.5531719 13 2.7011719 L 13 11.384766 C 12.43016 11.232366 11.837453 11.042719 11.189453 10.880859 C 10.209613 10.636099 9.0981 10.696078 8 11.367188 L 8 2.6679688 C 8.70328 2.2824487 9.2453875 2.0716725 9.6796875 2.0078125 C 9.9189475 1.9726125 10.131991 1.9756531 10.337891 2.0019531 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
8
resources/raw/LightIcons/visibility.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 8 3.0039062 C 6.4492 3.0190063 4.8879094 3.3732319 3.5371094 4.1386719 C 2.9987094 4.4892919 2.3523344 4.9421175 1.8652344 5.3984375 C 1.0987444 6.1488575 0.4427 7.0244062 0 8.0039062 C 1.2149 10.683506 3.8859187 12.6474 6.8242188 12.9375 C 8.7516188 13.15561 10.768591 12.822631 12.462891 11.869141 C 13.001291 11.518521 13.647666 11.065695 14.134766 10.609375 C 14.901256 9.858955 15.5573 8.9834063 16 8.0039062 C 14.785 5.3245062 12.114181 3.3601125 9.1757812 3.0703125 C 8.7859013 3.0248425 8.39251 3.0038963 8 3.0039062 z M 8 5.0019531 L 8 5.0039062 C 9.607 4.9683062 11.0303 6.4057062 11 8.0039062 C 11.0515 9.7703063 9.2909813 11.294844 7.5507812 10.964844 C 5.7931812 10.758504 4.5587188 8.7851344 5.1367188 7.1152344 C 5.5058788 5.8858344 6.7125 4.9866531 8 5.0019531 z M 8 7.0039062 A 1 1 0 0 0 7 8.0039062 A 1 1 0 0 0 8 9.0039062 A 1 1 0 0 0 9 8.0039062 A 1 1 0 0 0 8 7.0039062 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
8
resources/raw/LightIcons/zoom-fit-best.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 3.1894531 2.0039062 C 2.5267531 2.0039062 2.0019531 2.5527963 2.0019531 3.2226562 L 2.0019531 7.0039062 L 4.0019531 7.0039062 L 4.0019531 4.0039062 L 7.0019531 4.0039062 L 7.0019531 2.0039062 L 3.1894531 2.0039062 z M 9.0019531 2.0039062 L 9.0019531 4.0039062 L 12.001953 4.0039062 L 12.001953 7.0039062 L 14.001953 7.0039062 L 14.001953 3.2226562 C 14.001953 2.5528963 13.477153 2.0039062 12.814453 2.0039062 L 9.0019531 2.0039062 z M 2.0019531 9.0039062 L 2.0019531 12.785156 C 2.0019531 13.454916 2.5267531 14.003906 3.1894531 14.003906 L 7.0019531 14.003906 L 7.0019531 12.003906 L 4.0019531 12.003906 L 4.0019531 9.0039062 L 2.0019531 9.0039062 z M 12.001953 9.0039062 L 12.001953 12.003906 L 9.0019531 12.003906 L 9.0019531 14.003906 L 12.814453 14.003906 C 13.477153 14.003906 14.001953 13.455016 14.001953 12.785156 L 14.001953 9.0039062 L 12.001953 9.0039062 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
8
resources/raw/LightIcons/zoom-fit-width.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 3.1875 2 C 2.5248 2 2 2.54895 2 3.21875 L 2 7 L 4 7 L 4 4 L 7 4 L 7 2 L 3.1875 2 z M 9 2 L 9 4 L 12 4 L 12 7 L 14 7 L 14 3.21875 C 14 2.54885 13.4755 2 12.8125 2 L 9 2 z M 7 5 L 7 11 L 9 11 L 9 5 L 7 5 z M 6 6 L 4 8 L 6 10 L 6 6 z M 10 6 L 10 10 L 12 8 L 10 6 z M 2 9 L 2 12.78125 C 2 13.45125 2.5248 14 3.1875 14 L 7 14 L 7 12 L 4 12 L 4 9 L 2 9 z M 12 9 L 12 12 L 9 12 L 9 14 L 12.8125 14 C 13.4755 14 14 13.45125 14 12.78125 L 14 9 L 12 9 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 790 B |
8
resources/raw/LightIcons/zoom-in.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 3 2 C 2.446 2 2 2.446 2 3 L 2 13 C 2 13.554 2.446 14 3 14 L 13 14 C 13.554 14 14 13.554 14 13 L 14 3 C 14 2.446 13.554 2 13 2 L 3 2 z M 7 5 L 9 5 L 9 7 L 11 7 L 11 9 L 9 9 L 9 11 L 7 11 L 7 9 L 5 9 L 5 7 L 7 7 L 7 5 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 564 B |
8
resources/raw/LightIcons/zoom-original.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 3 2 C 2.446 2 2 2.446 2 3 L 2 13 C 2 13.554 2.446 14 3 14 L 13 14 C 13.554 14 14 13.554 14 13 L 14 3 C 14 2.446 13.554 2 13 2 L 3 2 z M 7 5 L 9 5 L 9 11 L 7 11 L 7 7 L 6 7 L 6 6 C 6 6 7 6 7 5 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 540 B |
8
resources/raw/LightIcons/zoom-out.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 3 2 C 2.446 2 2 2.446 2 3 L 2 13 C 2 13.554 2.446 14 3 14 L 13 14 C 13.554 14 14 13.554 14 13 L 14 3 C 14 2.446 13.554 2 13 2 L 3 2 z M 5 7 L 11 7 L 11 9 L 5 9 L 5 7 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 514 B |
@@ -1,5 +1,64 @@
|
||||
<RCC>
|
||||
<qresource prefix="images">
|
||||
<file>xmark.svg</file>
|
||||
<file>DarkIcons/add.svg</file>
|
||||
<file>DarkIcons/bookmark-new.svg</file>
|
||||
<file>DarkIcons/bookmarks.svg</file>
|
||||
<file>DarkIcons/color-picker.svg</file>
|
||||
<file>DarkIcons/edit-rename.svg</file>
|
||||
<file>DarkIcons/format-indent-less.svg</file>
|
||||
<file>DarkIcons/format-indent-more.svg</file>
|
||||
<file>DarkIcons/format-justify-center.svg</file>
|
||||
<file>DarkIcons/format-justify-fill.svg</file>
|
||||
<file>DarkIcons/format-justify-left.svg</file>
|
||||
<file>DarkIcons/format-justify-right.svg</file>
|
||||
<file>DarkIcons/format-line-spacing-double.svg</file>
|
||||
<file>DarkIcons/format-line-spacing-triple.svg</file>
|
||||
<file>DarkIcons/gtk-select-font.svg</file>
|
||||
<file>DarkIcons/mail-thread-watch.svg</file>
|
||||
<file>DarkIcons/reload.svg</file>
|
||||
<file>DarkIcons/remove.svg</file>
|
||||
<file>DarkIcons/settings.svg</file>
|
||||
<file>DarkIcons/table.svg</file>
|
||||
<file>DarkIcons/trash-empty.svg</file>
|
||||
<file>DarkIcons/view-fullscreen.svg</file>
|
||||
<file>DarkIcons/view-grid.svg</file>
|
||||
<file>DarkIcons/view-readermode.svg</file>
|
||||
<file>DarkIcons/visibility.svg</file>
|
||||
<file>DarkIcons/zoom-fit-best.svg</file>
|
||||
<file>DarkIcons/zoom-fit-width.svg</file>
|
||||
<file>DarkIcons/zoom-in.svg</file>
|
||||
<file>DarkIcons/zoom-original.svg</file>
|
||||
<file>DarkIcons/zoom-out.svg</file>
|
||||
<file>LightIcons/add.svg</file>
|
||||
<file>LightIcons/bookmark-new.svg</file>
|
||||
<file>LightIcons/bookmarks.svg</file>
|
||||
<file>LightIcons/color-picker.svg</file>
|
||||
<file>LightIcons/edit-rename.svg</file>
|
||||
<file>LightIcons/format-indent-less.svg</file>
|
||||
<file>LightIcons/format-indent-more.svg</file>
|
||||
<file>LightIcons/format-justify-center.svg</file>
|
||||
<file>LightIcons/format-justify-fill.svg</file>
|
||||
<file>LightIcons/format-justify-left.svg</file>
|
||||
<file>LightIcons/format-justify-right.svg</file>
|
||||
<file>LightIcons/format-line-spacing-double.svg</file>
|
||||
<file>LightIcons/format-line-spacing-triple.svg</file>
|
||||
<file>LightIcons/gtk-select-font.svg</file>
|
||||
<file>LightIcons/mail-thread-watch.svg</file>
|
||||
<file>LightIcons/reload.svg</file>
|
||||
<file>LightIcons/remove.svg</file>
|
||||
<file>LightIcons/settings.svg</file>
|
||||
<file>LightIcons/table.svg</file>
|
||||
<file>LightIcons/trash-empty.svg</file>
|
||||
<file>LightIcons/view-fullscreen.svg</file>
|
||||
<file>LightIcons/view-grid.svg</file>
|
||||
<file>LightIcons/view-readermode.svg</file>
|
||||
<file>LightIcons/visibility.svg</file>
|
||||
<file>LightIcons/zoom-fit-best.svg</file>
|
||||
<file>LightIcons/zoom-fit-width.svg</file>
|
||||
<file>LightIcons/zoom-in.svg</file>
|
||||
<file>LightIcons/zoom-original.svg</file>
|
||||
<file>LightIcons/zoom-out.svg</file>
|
||||
<file>QMPlay2.svg</file>
|
||||
<file>color.svg</file>
|
||||
<file>blank.png</file>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1009</width>
|
||||
<width>1216</width>
|
||||
<height>658</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -69,6 +69,29 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="languageLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dictionary:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="languageBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -93,25 +116,43 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<widget class="QCheckBox" name="comicsRemain">
|
||||
<property name="text">
|
||||
<string>Leave comics on disc</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="languageLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="toolTip">
|
||||
<string>Restart to see changes</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dictionary:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
<string>Icon theme: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="languageBox"/>
|
||||
<widget class="QRadioButton" name="darkIconsRadio">
|
||||
<property name="toolTip">
|
||||
<string>Restart to see changes</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dar&k</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="lightIconsRadio">
|
||||
<property name="toolTip">
|
||||
<string>Restart to see changes</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Light</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
7
resources/raw/xmark.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" version="1.1" viewBox="0 0 24 24">
|
||||
<circle style="fill:#252a35" cx="12" cy="12" r="10"/>
|
||||
<g transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,12,-4.9705627)">
|
||||
<rect style="fill:#ffffff" width="2" height="14" x="-13" y="5" transform="matrix(0,-1,1,0,0,0)"/>
|
||||
<rect style="fill:#ffffff" width="2" height="14" x="11" y="5"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 416 B |
@@ -11,7 +11,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
class Ui_Dialog(object):
|
||||
def setupUi(self, Dialog):
|
||||
Dialog.setObjectName("Dialog")
|
||||
Dialog.resize(1009, 658)
|
||||
Dialog.resize(1216, 658)
|
||||
self.gridLayout_3 = QtWidgets.QGridLayout(Dialog)
|
||||
self.gridLayout_3.setObjectName("gridLayout_3")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
|
||||
@@ -46,16 +46,6 @@ class Ui_Dialog(object):
|
||||
self.autoTags = QtWidgets.QCheckBox(self.groupBox)
|
||||
self.autoTags.setObjectName("autoTags")
|
||||
self.horizontalLayout_4.addWidget(self.autoTags)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
||||
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.coverShadows = QtWidgets.QCheckBox(self.groupBox)
|
||||
self.coverShadows.setObjectName("coverShadows")
|
||||
self.horizontalLayout.addWidget(self.coverShadows)
|
||||
self.performCulling = QtWidgets.QCheckBox(self.groupBox)
|
||||
self.performCulling.setObjectName("performCulling")
|
||||
self.horizontalLayout.addWidget(self.performCulling)
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
self.languageLabel = QtWidgets.QLabel(self.groupBox)
|
||||
@@ -70,7 +60,32 @@ class Ui_Dialog(object):
|
||||
self.languageBox = QtWidgets.QComboBox(self.groupBox)
|
||||
self.languageBox.setObjectName("languageBox")
|
||||
self.horizontalLayout_3.addWidget(self.languageBox)
|
||||
self.horizontalLayout.addLayout(self.horizontalLayout_3)
|
||||
self.horizontalLayout_4.addLayout(self.horizontalLayout_3)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
||||
self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.coverShadows = QtWidgets.QCheckBox(self.groupBox)
|
||||
self.coverShadows.setObjectName("coverShadows")
|
||||
self.horizontalLayout.addWidget(self.coverShadows)
|
||||
self.performCulling = QtWidgets.QCheckBox(self.groupBox)
|
||||
self.performCulling.setObjectName("performCulling")
|
||||
self.horizontalLayout.addWidget(self.performCulling)
|
||||
self.comicsRemain = QtWidgets.QCheckBox(self.groupBox)
|
||||
self.comicsRemain.setObjectName("comicsRemain")
|
||||
self.horizontalLayout.addWidget(self.comicsRemain)
|
||||
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
|
||||
self.label = QtWidgets.QLabel(self.groupBox)
|
||||
self.label.setObjectName("label")
|
||||
self.horizontalLayout_5.addWidget(self.label)
|
||||
self.darkIconsRadio = QtWidgets.QRadioButton(self.groupBox)
|
||||
self.darkIconsRadio.setObjectName("darkIconsRadio")
|
||||
self.horizontalLayout_5.addWidget(self.darkIconsRadio)
|
||||
self.lightIconsRadio = QtWidgets.QRadioButton(self.groupBox)
|
||||
self.lightIconsRadio.setObjectName("lightIconsRadio")
|
||||
self.horizontalLayout_5.addWidget(self.lightIconsRadio)
|
||||
self.horizontalLayout.addLayout(self.horizontalLayout_5)
|
||||
self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1)
|
||||
self.verticalLayout_2.addWidget(self.groupBox)
|
||||
self.gridLayout_3.addLayout(self.verticalLayout_2, 0, 0, 1, 1)
|
||||
@@ -99,10 +114,17 @@ class Ui_Dialog(object):
|
||||
self.refreshLibrary.setText(_translate("Dialog", "Startup: Refresh library"))
|
||||
self.fileRemember.setText(_translate("Dialog", "Remember open files"))
|
||||
self.autoTags.setText(_translate("Dialog", "Generate tags from files"))
|
||||
self.languageLabel.setText(_translate("Dialog", "Dictionary:"))
|
||||
self.coverShadows.setText(_translate("Dialog", "Cover shadows"))
|
||||
self.performCulling.setToolTip(_translate("Dialog", "Enabling reduces startup time and memory usage"))
|
||||
self.performCulling.setText(_translate("Dialog", "Load covers only when needed"))
|
||||
self.languageLabel.setText(_translate("Dialog", "Dictionary:"))
|
||||
self.comicsRemain.setText(_translate("Dialog", "Leave comics on disc"))
|
||||
self.label.setToolTip(_translate("Dialog", "Restart to see changes"))
|
||||
self.label.setText(_translate("Dialog", "Icon theme: "))
|
||||
self.darkIconsRadio.setToolTip(_translate("Dialog", "Restart to see changes"))
|
||||
self.darkIconsRadio.setText(_translate("Dialog", "Dar&k"))
|
||||
self.lightIconsRadio.setToolTip(_translate("Dialog", "Restart to see changes"))
|
||||
self.lightIconsRadio.setText(_translate("Dialog", "&Light"))
|
||||
self.okButton.setText(_translate("Dialog", "Scan Library"))
|
||||
self.cancelButton.setText(_translate("Dialog", "Close"))
|
||||
self.aboutButton.setText(_translate("Dialog", "About"))
|
||||
|
5
setup.cfg
Normal file
@@ -0,0 +1,5 @@
|
||||
[bdist_wheel]
|
||||
# This flag says that the code is written to work on both Python 2 and Python
|
||||
# 3. If at all possible, it is good practice to do this. If you cannot, you
|
||||
# will need to generate wheels for each Python version that you support.
|
||||
universal=1
|
77
setup.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import codecs
|
||||
from os import path
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
HERE = path.abspath(path.dirname(__file__))
|
||||
|
||||
MAJOR_VERSION = '0'
|
||||
MINOR_VERSION = '2'
|
||||
MICRO_VERSION = '0'
|
||||
VERSION = "{}.{}.{}".format(MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION)
|
||||
|
||||
# Get the long description from the README file
|
||||
with codecs.open(path.join(HERE, 'README.md'), encoding='utf-8') as f:
|
||||
LONG_DESC = f.read()
|
||||
|
||||
INSTALL_DEPS = ['PyQt5>=5.10.1',
|
||||
'requests>=2.18.4',
|
||||
'beautifulsoup4>=4.6.0']
|
||||
TEST_DEPS = ['pytest',
|
||||
'unittest2']
|
||||
DEV_DEPS = []
|
||||
|
||||
setup(
|
||||
name='lector',
|
||||
|
||||
description='Qt-based ebook reader',
|
||||
long_description=LONG_DESC,
|
||||
|
||||
url='https://github.com/BasioMeusPuga/Lector',
|
||||
|
||||
author='BasioMeusPuga',
|
||||
author_email='disgruntled.mob@gmail.com',
|
||||
|
||||
license='GPL v3.0',
|
||||
version=VERSION,
|
||||
|
||||
classifiers=[
|
||||
# How mature is this project? Common values are
|
||||
# 3 - Alpha
|
||||
# 4 - Beta
|
||||
# 5 - Production/Stable
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Intended Audience :: End Users/Desktop',
|
||||
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
],
|
||||
|
||||
# What does your project relate to?
|
||||
keywords='qt ebook epub kindle mobi comic cbz cbr pdf',
|
||||
|
||||
packages=find_packages(),
|
||||
|
||||
entry_points={
|
||||
'gui_scripts': [
|
||||
'lector = lector.__main__:main']
|
||||
},
|
||||
# List run-time dependencies here. These will be installed by pip when
|
||||
# your project is installed. For an analysis of "install_requires" vs pip's
|
||||
# requirements files see:
|
||||
# https://packaging.python.org/en/latest/requirements.html
|
||||
install_requires=INSTALL_DEPS,
|
||||
|
||||
python_requires='>=3.6, <4.0',
|
||||
|
||||
package_data={'': ['about.html']},
|
||||
include_package_data=True,
|
||||
|
||||
# List additional groups of dependencies here (e.g. development
|
||||
# dependencies). You can install these using the following syntax,
|
||||
# for example:
|
||||
# $ pip install -e .[dev,test]
|
||||
extras_require={
|
||||
'dev': DEV_DEPS,
|
||||
'test': TEST_DEPS,
|
||||
'PDF': ['python-poppler-qt5']
|
||||
},
|
||||
)
|