Table improvements
This commit is contained in:
62
TODO
Normal file
62
TODO
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
TODO
|
||||||
|
Options:
|
||||||
|
Automatic library management
|
||||||
|
Auto deletion
|
||||||
|
Recursive file addition
|
||||||
|
Add only one file type if multiple are present
|
||||||
|
Remember files
|
||||||
|
Check files (hashes) upon restart
|
||||||
|
Show what on startup
|
||||||
|
Draw shadows
|
||||||
|
Library:
|
||||||
|
✓ sqlite3 for cover images cache
|
||||||
|
✓ sqlite3 for storing metadata
|
||||||
|
✓ Drop down for SortBy
|
||||||
|
✓ Image delegates
|
||||||
|
✓ Image reflow
|
||||||
|
✓ Search bar in toolbar
|
||||||
|
✓ Shift focus to the tab that has the book open
|
||||||
|
✓ Tie file deletion and tab closing to model updates
|
||||||
|
✓ Create separate thread for parser - Show progress in main window
|
||||||
|
? Create emblem per filetype
|
||||||
|
Table view
|
||||||
|
Ignore a / the / numbers for sorting purposes
|
||||||
|
Put the path in the scope of the search
|
||||||
|
maybe as a type: switch
|
||||||
|
Mass tagging
|
||||||
|
Information dialog widget
|
||||||
|
Context menu: Cache, Read, Edit database, delete, Mark read/unread
|
||||||
|
Set focus to newly added file
|
||||||
|
Reading:
|
||||||
|
✓ Drop down for TOC
|
||||||
|
✓ Override the keypress event of the textedit
|
||||||
|
✓ Use format* icons for toolbar buttons
|
||||||
|
✓ Implement book view settings with a(nother) toolbar
|
||||||
|
✓ Substitute textedit for another widget
|
||||||
|
✓ Theming
|
||||||
|
✓ Keep fontsize and margins consistent - Let page increase in length
|
||||||
|
✓ Fullscreening
|
||||||
|
✓ Remember open tabs
|
||||||
|
✓ Selectable background color for QGraphicsView
|
||||||
|
✓ View modes for QGraphicsView
|
||||||
|
✓ View and hide toolbar actions in a list
|
||||||
|
Graphical themes
|
||||||
|
Comic view keyboard shortcuts
|
||||||
|
Record progress
|
||||||
|
Pagination
|
||||||
|
Set context menu for definitions and the like
|
||||||
|
Filetypes:
|
||||||
|
✓ cbz, cbr support
|
||||||
|
✓ Keep font settings enabled but only for background color
|
||||||
|
Cache next and previous images
|
||||||
|
epub support
|
||||||
|
mobi, azw support
|
||||||
|
txt, doc, djvu, fb2 support
|
||||||
|
? Plugin system for parsers
|
||||||
|
? pdf support
|
||||||
|
Internet:
|
||||||
|
Goodreads API: Ratings, Read, Recommendations
|
||||||
|
Get ISBN using python-isbnlib
|
||||||
|
Other:
|
||||||
|
✓ Define every widget in code
|
||||||
|
✓ Include icons for emblems
|
90
__main__.py
90
__main__.py
@@ -1,69 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
""" TODO
|
|
||||||
Options:
|
|
||||||
Automatic library management
|
|
||||||
Auto deletion
|
|
||||||
Recursive file addition
|
|
||||||
Add only one file type if multiple are present
|
|
||||||
Remember files
|
|
||||||
Check files (hashes) upon restart
|
|
||||||
Show what on startup
|
|
||||||
Draw shadows
|
|
||||||
Library:
|
|
||||||
✓ sqlite3 for cover images cache
|
|
||||||
✓ sqlite3 for storing metadata
|
|
||||||
✓ Drop down for SortBy
|
|
||||||
✓ Image delegates
|
|
||||||
✓ Image reflow
|
|
||||||
✓ Search bar in toolbar
|
|
||||||
✓ Shift focus to the tab that has the book open
|
|
||||||
✓ Tie file deletion and tab closing to model updates
|
|
||||||
✓ Create separate thread for parser - Show progress in main window
|
|
||||||
? Create emblem per filetype
|
|
||||||
Table view
|
|
||||||
Ignore a / the / numbers for sorting purposes
|
|
||||||
Put the path in the scope of the search
|
|
||||||
maybe as a type: switch
|
|
||||||
Mass tagging
|
|
||||||
Information dialog widget
|
|
||||||
Context menu: Cache, Read, Edit database, delete, Mark read/unread
|
|
||||||
Set focus to newly added file
|
|
||||||
Reading:
|
|
||||||
✓ Drop down for TOC
|
|
||||||
✓ Override the keypress event of the textedit
|
|
||||||
✓ Use format* icons for toolbar buttons
|
|
||||||
✓ Implement book view settings with a(nother) toolbar
|
|
||||||
✓ Substitute textedit for another widget
|
|
||||||
✓ Theming
|
|
||||||
✓ Keep fontsize and margins consistent - Let page increase in length
|
|
||||||
✓ Fullscreening
|
|
||||||
✓ Remember open tabs
|
|
||||||
✓ Selectable background color for QGraphicsView
|
|
||||||
✓ View modes for QGraphicsView
|
|
||||||
✓ View and hide toolbar actions in a list
|
|
||||||
Graphical themes
|
|
||||||
Comic view keyboard shortcuts
|
|
||||||
Record progress
|
|
||||||
Pagination
|
|
||||||
Set context menu for definitions and the like
|
|
||||||
Filetypes:
|
|
||||||
✓ cbz, cbr support
|
|
||||||
✓ Keep font settings enabled but only for background color
|
|
||||||
Cache next and previous images
|
|
||||||
epub support
|
|
||||||
mobi, azw support
|
|
||||||
txt, doc, djvu, fb2 support
|
|
||||||
? Plugin system for parsers
|
|
||||||
? pdf support
|
|
||||||
Internet:
|
|
||||||
Goodreads API: Ratings, Read, Recommendations
|
|
||||||
Get ISBN using python-isbnlib
|
|
||||||
Other:
|
|
||||||
✓ Define every widget in code
|
|
||||||
✓ Include icons for emblems
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -89,10 +25,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
# Initialize settings dialog
|
# Initialize settings dialog
|
||||||
self.settings_dialog = SettingsUI()
|
self.settings_dialog = SettingsUI()
|
||||||
|
|
||||||
# Hide or show the main widget of the library
|
|
||||||
self.stackedWidget.setCurrentIndex(0)
|
|
||||||
|
|
||||||
# Empty variables that will be infested soon
|
# Empty variables that will be infested soon
|
||||||
|
self.current_view = None
|
||||||
self.last_open_books = None
|
self.last_open_books = None
|
||||||
self.last_open_tab = None
|
self.last_open_tab = None
|
||||||
self.last_open_path = None
|
self.last_open_path = None
|
||||||
@@ -101,6 +35,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.display_profiles = None
|
self.display_profiles = None
|
||||||
self.current_profile_index = None
|
self.current_profile_index = None
|
||||||
self.database_path = None
|
self.database_path = None
|
||||||
|
self.table_header_sizes = None
|
||||||
|
|
||||||
# Initialize application
|
# Initialize application
|
||||||
Settings(self).read_settings() # This should populate all variables that need
|
Settings(self).read_settings() # This should populate all variables that need
|
||||||
@@ -132,12 +67,18 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.libraryToolBar.addButton.triggered.connect(self.add_books)
|
self.libraryToolBar.addButton.triggered.connect(self.add_books)
|
||||||
self.libraryToolBar.deleteButton.triggered.connect(self.delete_books)
|
self.libraryToolBar.deleteButton.triggered.connect(self.delete_books)
|
||||||
self.libraryToolBar.coverViewButton.triggered.connect(self.switch_library_view)
|
self.libraryToolBar.coverViewButton.triggered.connect(self.switch_library_view)
|
||||||
self.libraryToolBar.coverViewButton.setChecked(True)
|
# self.libraryToolBar.coverViewButton.setChecked(True)
|
||||||
self.libraryToolBar.tableViewButton.triggered.connect(self.switch_library_view)
|
self.libraryToolBar.tableViewButton.triggered.connect(self.switch_library_view)
|
||||||
self.libraryToolBar.settingsButton.triggered.connect(self.show_settings)
|
self.libraryToolBar.settingsButton.triggered.connect(self.show_settings)
|
||||||
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_proxymodel)
|
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_proxymodel)
|
||||||
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_table_proxy_model)
|
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_table_proxy_model)
|
||||||
self.libraryToolBar.sortingBox.activated.connect(self.lib_ref.update_proxymodel)
|
self.libraryToolBar.sortingBox.activated.connect(self.lib_ref.update_proxymodel)
|
||||||
|
|
||||||
|
if self.current_view == 0:
|
||||||
|
self.libraryToolBar.coverViewButton.trigger()
|
||||||
|
elif self.current_view == 1:
|
||||||
|
self.libraryToolBar.tableViewButton.trigger()
|
||||||
|
|
||||||
self.addToolBar(self.libraryToolBar)
|
self.addToolBar(self.libraryToolBar)
|
||||||
|
|
||||||
# Book toolbar
|
# Book toolbar
|
||||||
@@ -204,11 +145,16 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.listView.setItemDelegate(LibraryDelegate(self.temp_dir.path()))
|
self.listView.setItemDelegate(LibraryDelegate(self.temp_dir.path()))
|
||||||
|
|
||||||
# TableView
|
# TableView
|
||||||
self.tableView.horizontalHeader().setSectionResizeMode(
|
|
||||||
QtWidgets.QHeaderView.ResizeToContents) # TODO Change this to manual column sizing
|
|
||||||
self.tableView.horizontalHeader().setStretchLastSection(True)
|
|
||||||
self.tableView.horizontalHeader().setSortIndicator(0, QtCore.Qt.AscendingOrder)
|
|
||||||
self.tableView.doubleClicked.connect(self.library_doubleclick)
|
self.tableView.doubleClicked.connect(self.library_doubleclick)
|
||||||
|
self.tableView.horizontalHeader().setSectionResizeMode(
|
||||||
|
QtWidgets.QHeaderView.Interactive)
|
||||||
|
self.tableView.horizontalHeader().setSortIndicator(0, QtCore.Qt.AscendingOrder)
|
||||||
|
self.tableView.horizontalHeader().setHighlightSections(False)
|
||||||
|
if self.table_header_sizes:
|
||||||
|
for count, i in enumerate(self.table_header_sizes):
|
||||||
|
self.tableView.horizontalHeader().resizeSection(count, int(i))
|
||||||
|
self.tableView.horizontalHeader().setStretchLastSection(True)
|
||||||
|
self.tableView.horizontalHeader().setSectionResizeMode(3, QtWidgets.QHeaderView.Stretch)
|
||||||
|
|
||||||
# Keyboard shortcuts
|
# Keyboard shortcuts
|
||||||
self.ks_close_tab = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+W'), self)
|
self.ks_close_tab = QtWidgets.QShortcut(QtGui.QKeySequence('Ctrl+W'), self)
|
||||||
|
17
library.py
17
library.py
@@ -76,6 +76,8 @@ class Library:
|
|||||||
if position:
|
if position:
|
||||||
position = pickle.loads(position)
|
position = pickle.loads(position)
|
||||||
|
|
||||||
|
file_exists = os.path.exists(path)
|
||||||
|
|
||||||
all_metadata = {
|
all_metadata = {
|
||||||
'title': title,
|
'title': title,
|
||||||
'author': author,
|
'author': author,
|
||||||
@@ -84,7 +86,8 @@ class Library:
|
|||||||
'position': position,
|
'position': position,
|
||||||
'isbn': i[6],
|
'isbn': i[6],
|
||||||
'tags': tags,
|
'tags': tags,
|
||||||
'hash': i[8]}
|
'hash': i[8],
|
||||||
|
'file_exists': file_exists}
|
||||||
|
|
||||||
tooltip_string = title + '\nAuthor: ' + author + '\nYear: ' + str(year)
|
tooltip_string = title + '\nAuthor: ' + author + '\nYear: ' + str(year)
|
||||||
if tags:
|
if tags:
|
||||||
@@ -96,8 +99,6 @@ class Library:
|
|||||||
if tags:
|
if tags:
|
||||||
search_workaround += tags
|
search_workaround += tags
|
||||||
|
|
||||||
file_exists = os.path.exists(path)
|
|
||||||
|
|
||||||
# Generate image pixmap and then pass it to the widget
|
# Generate image pixmap and then pass it to the widget
|
||||||
# as a QIcon
|
# as a QIcon
|
||||||
# Additional data can be set using an incrementing
|
# Additional data can be set using an incrementing
|
||||||
@@ -113,9 +114,6 @@ class Library:
|
|||||||
item = QtGui.QStandardItem()
|
item = QtGui.QStandardItem()
|
||||||
item.setToolTip(tooltip_string)
|
item.setToolTip(tooltip_string)
|
||||||
|
|
||||||
# TODO
|
|
||||||
# Simplify this mess
|
|
||||||
|
|
||||||
# The following order is needed to keep sorting working
|
# The following order is needed to keep sorting working
|
||||||
item.setData(title, QtCore.Qt.UserRole)
|
item.setData(title, QtCore.Qt.UserRole)
|
||||||
item.setData(author, QtCore.Qt.UserRole + 1)
|
item.setData(author, QtCore.Qt.UserRole + 1)
|
||||||
@@ -148,11 +146,8 @@ class Library:
|
|||||||
self.table_proxy_model.invalidateFilter()
|
self.table_proxy_model.invalidateFilter()
|
||||||
self.table_proxy_model.setFilterParams(
|
self.table_proxy_model.setFilterParams(
|
||||||
self.parent_window.libraryToolBar.searchBar.text(), [0, 1, 3])
|
self.parent_window.libraryToolBar.searchBar.text(), [0, 1, 3])
|
||||||
|
# This isn't needed, but it forces a model update every time the
|
||||||
# This isn't needed, but it forces a
|
# text in the line edit changes. So I guess it is needed.
|
||||||
# model update every time the
|
|
||||||
# text in the line edit changes.
|
|
||||||
# So I guess it is needed.
|
|
||||||
self.table_proxy_model.setFilterFixedString(
|
self.table_proxy_model.setFilterFixedString(
|
||||||
self.parent_window.libraryToolBar.searchBar.text())
|
self.parent_window.libraryToolBar.searchBar.text())
|
||||||
|
|
||||||
|
@@ -10,9 +10,6 @@ class LibraryItemModel(QtGui.QStandardItemModel, QtCore.QAbstractItemModel):
|
|||||||
|
|
||||||
|
|
||||||
class LibraryTableModel(QtCore.QAbstractTableModel):
|
class LibraryTableModel(QtCore.QAbstractTableModel):
|
||||||
# TODO
|
|
||||||
# Auto resize with emphasis on Name
|
|
||||||
|
|
||||||
# Sorting is taken care of by the QSortFilterProxy model
|
# Sorting is taken care of by the QSortFilterProxy model
|
||||||
# which has an inbuilt sort method
|
# which has an inbuilt sort method
|
||||||
|
|
||||||
@@ -33,6 +30,7 @@ class LibraryTableModel(QtCore.QAbstractTableModel):
|
|||||||
|
|
||||||
if role == QtCore.Qt.DisplayRole:
|
if role == QtCore.Qt.DisplayRole:
|
||||||
value = self.display_data[index.row()][index.column()]
|
value = self.display_data[index.row()][index.column()]
|
||||||
|
file_exists = self.display_data[index.row()][4]['file_exists']
|
||||||
return value
|
return value
|
||||||
elif role == QtCore.Qt.UserRole:
|
elif role == QtCore.Qt.UserRole:
|
||||||
# The rest of the roles can be accomodated here.
|
# The rest of the roles can be accomodated here.
|
||||||
|
18
settings.py
18
settings.py
@@ -1,4 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# Keep in mind that all integer settings are returned as strings
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from PyQt5 import QtCore, QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
@@ -43,12 +44,10 @@ class Settings:
|
|||||||
|
|
||||||
def read_settings(self):
|
def read_settings(self):
|
||||||
self.settings.beginGroup('mainWindow')
|
self.settings.beginGroup('mainWindow')
|
||||||
self.parent_window.resize(self.settings.value(
|
self.parent_window.resize(self.settings.value('windowSize', QtCore.QSize(1299, 748)))
|
||||||
'windowSize',
|
self.parent_window.move(self.settings.value('windowPosition', QtCore.QPoint(0, 0)))
|
||||||
QtCore.QSize(1299, 748)))
|
self.parent_window.current_view = int(self.settings.value('currentView', 0))
|
||||||
self.parent_window.move(self.settings.value(
|
self.parent_window.table_header_sizes = self.settings.value('tableHeaders', None)
|
||||||
'windowPosition',
|
|
||||||
QtCore.QPoint(0, 0)))
|
|
||||||
self.settings.endGroup()
|
self.settings.endGroup()
|
||||||
|
|
||||||
self.settings.beginGroup('runtimeVariables')
|
self.settings.beginGroup('runtimeVariables')
|
||||||
@@ -74,9 +73,16 @@ class Settings:
|
|||||||
|
|
||||||
def save_settings(self):
|
def save_settings(self):
|
||||||
print('Saving settings...')
|
print('Saving settings...')
|
||||||
|
|
||||||
self.settings.beginGroup('mainWindow')
|
self.settings.beginGroup('mainWindow')
|
||||||
self.settings.setValue('windowSize', self.parent_window.size())
|
self.settings.setValue('windowSize', self.parent_window.size())
|
||||||
self.settings.setValue('windowPosition', self.parent_window.pos())
|
self.settings.setValue('windowPosition', self.parent_window.pos())
|
||||||
|
self.settings.setValue('currentView', self.parent_window.stackedWidget.currentIndex())
|
||||||
|
|
||||||
|
table_headers = []
|
||||||
|
for i in range(3):
|
||||||
|
table_headers.append(self.parent_window.tableView.horizontalHeader().sectionSize(i))
|
||||||
|
self.settings.setValue('tableHeaders', table_headers)
|
||||||
self.settings.endGroup()
|
self.settings.endGroup()
|
||||||
|
|
||||||
self.settings.beginGroup('runtimeVariables')
|
self.settings.beginGroup('runtimeVariables')
|
||||||
|
Reference in New Issue
Block a user