Start work on splitting the book list

Allows for pinned columns
This commit is contained in:
Kovid Goyal 2018-01-29 12:12:24 +05:30
parent d9a610547d
commit 7eef114a43
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 68 additions and 28 deletions

View File

@ -159,7 +159,7 @@ class LibraryWidget(Splitter): # {{{
parent.library_view.setObjectName('library_view') parent.library_view.setObjectName('library_view')
stack = QStackedWidget(self) stack = QStackedWidget(self)
av = parent.library_view.alternate_views av = parent.library_view.alternate_views
av.set_stack(stack) parent.pin_container = av.set_stack(stack)
parent.grid_view = GridView(parent) parent.grid_view = GridView(parent)
parent.grid_view.setObjectName('grid_view') parent.grid_view.setObjectName('grid_view')
av.add_view('grid', parent.grid_view) av.add_view('grid', parent.grid_view)

View File

@ -23,6 +23,7 @@ from PyQt5.Qt import (
from calibre import fit_image, prints, prepare_string_for_xml, human_readable from calibre import fit_image, prints, prepare_string_for_xml, human_readable
from calibre.constants import DEBUG, config_dir, islinux from calibre.constants import DEBUG, config_dir, islinux
from calibre.gui2.pin_columns import PinContainer
from calibre.ebooks.metadata import fmt_sidx, rating_to_stars from calibre.ebooks.metadata import fmt_sidx, rating_to_stars
from calibre.utils import join_with_timeout from calibre.utils import join_with_timeout
from calibre.gui2 import gprefs, config, rating_font, empty_index from calibre.gui2 import gprefs, config, rating_font, empty_index
@ -276,7 +277,9 @@ class AlternateViews(object):
def set_stack(self, stack): def set_stack(self, stack):
self.stack = stack self.stack = stack
self.stack.addWidget(self.main_view) pin_container = PinContainer(self.main_view, stack)
self.stack.addWidget(pin_container)
return pin_container
def add_view(self, key, view): def add_view(self, key, view):
self.views[key] = view self.views[key] = view

View File

@ -21,6 +21,7 @@ from calibre.gui2.library.delegates import (RatingDelegate, PubDateDelegate,
CcBoolDelegate, CcCommentsDelegate, CcDateDelegate, CcTemplateDelegate, CcBoolDelegate, CcCommentsDelegate, CcDateDelegate, CcTemplateDelegate,
CcEnumDelegate, CcNumberDelegate, LanguagesDelegate) CcEnumDelegate, CcNumberDelegate, LanguagesDelegate)
from calibre.gui2.library.models import BooksModel, DeviceBooksModel from calibre.gui2.library.models import BooksModel, DeviceBooksModel
from calibre.gui2.pin_columns import PinTableView
from calibre.gui2.library.alternate_views import AlternateViews, setup_dnd_interface, handle_enter_press from calibre.gui2.library.alternate_views import AlternateViews, setup_dnd_interface, handle_enter_press
from calibre.gui2.gestures import GestureManager from calibre.gui2.gestures import GestureManager
from calibre.utils.config import tweaks, prefs from calibre.utils.config import tweaks, prefs
@ -204,10 +205,12 @@ class BooksView(QTableView): # {{{
def __init__(self, parent, modelcls=BooksModel, use_edit_metadata_dialog=True): def __init__(self, parent, modelcls=BooksModel, use_edit_metadata_dialog=True):
QTableView.__init__(self, parent) QTableView.__init__(self, parent)
self.pin_view = PinTableView(self, parent)
self.gesture_manager = GestureManager(self) self.gesture_manager = GestureManager(self)
self.default_row_height = self.verticalHeader().defaultSectionSize() self.default_row_height = self.verticalHeader().defaultSectionSize()
self.gui = parent self.gui = parent
self.setProperty('highlight_current_item', 150) self.setProperty('highlight_current_item', 150)
self.pin_view.setProperty('highlight_current_item', 150)
self.row_sizing_done = False self.row_sizing_done = False
self.alternate_views = AlternateViews(self) self.alternate_views = AlternateViews(self)
@ -231,9 +234,10 @@ class BooksView(QTableView): # {{{
self.setEditTriggers(self.DoubleClicked|self.editTriggers()) self.setEditTriggers(self.DoubleClicked|self.editTriggers())
setup_dnd_interface(self) setup_dnd_interface(self)
self.setAlternatingRowColors(True) for wv in self, self.pin_view:
self.setShowGrid(False) wv.setAlternatingRowColors(True)
self.setWordWrap(False) wv.setShowGrid(False)
wv.setWordWrap(False)
self.rating_delegate = RatingDelegate(self) self.rating_delegate = RatingDelegate(self)
self.half_rating_delegate = RatingDelegate(self, is_half_star=True) self.half_rating_delegate = RatingDelegate(self, is_half_star=True)
@ -258,10 +262,12 @@ class BooksView(QTableView): # {{{
self.display_parent = parent self.display_parent = parent
self._model = modelcls(self) self._model = modelcls(self)
self.setModel(self._model) self.setModel(self._model)
self.pin_view.setModel(self._model)
self._model.count_changed_signal.connect(self.do_row_sizing, self._model.count_changed_signal.connect(self.do_row_sizing,
type=Qt.QueuedConnection) type=Qt.QueuedConnection)
self.setSelectionBehavior(QAbstractItemView.SelectRows) for wv in self, self.pin_view:
self.setSortingEnabled(True) wv.setSelectionBehavior(QAbstractItemView.SelectRows)
wv.setSortingEnabled(True)
self.selectionModel().currentRowChanged.connect(self._model.current_changed) self.selectionModel().currentRowChanged.connect(self._model.current_changed)
self.preserve_state = partial(PreserveViewState, self) self.preserve_state = partial(PreserveViewState, self)
self.marked_changed_listener = FunctionDispatcher(self.marked_changed) self.marked_changed_listener = FunctionDispatcher(self.marked_changed)
@ -293,6 +299,8 @@ class BooksView(QTableView): # {{{
self._model.sorting_done.connect(self.sorting_done, self._model.sorting_done.connect(self.sorting_done,
type=Qt.QueuedConnection) type=Qt.QueuedConnection)
self.set_row_header_visibility() self.set_row_header_visibility()
if modelcls is not BooksModel:
self.pin_view.close()
# Column Header Context Menu {{{ # Column Header Context Menu {{{
def column_header_context_handler(self, action=None, column=None): def column_header_context_handler(self, action=None, column=None):
@ -780,56 +788,59 @@ class BooksView(QTableView): # {{{
def database_changed(self, db): def database_changed(self, db):
db.data.add_marked_listener(self.marked_changed_listener) db.data.add_marked_listener(self.marked_changed_listener)
for i in range(self.model().columnCount(None)): for i in range(self.model().columnCount(None)):
if self.itemDelegateForColumn(i) in ( for vw in self, self.pin_view:
self.rating_delegate, self.timestamp_delegate, self.pubdate_delegate, if vw.itemDelegateForColumn(i) in (
self.last_modified_delegate, self.languages_delegate, self.half_rating_delegate): self.rating_delegate, self.timestamp_delegate, self.pubdate_delegate,
self.setItemDelegateForColumn(i, self.itemDelegate()) self.last_modified_delegate, self.languages_delegate, self.half_rating_delegate):
vw.setItemDelegateForColumn(i, vw.itemDelegate())
cm = self.column_map cm = self.column_map
def set_item_delegate(colhead, delegate):
idx = cm.index(colhead)
self.setItemDelegateForColumn(idx, delegate)
self.pin_view.setItemDelegateForColumn(idx, delegate)
for colhead in cm: for colhead in cm:
if self._model.is_custom_column(colhead): if self._model.is_custom_column(colhead):
cc = self._model.custom_columns[colhead] cc = self._model.custom_columns[colhead]
if cc['datatype'] == 'datetime': if cc['datatype'] == 'datetime':
delegate = CcDateDelegate(self) delegate = CcDateDelegate(self)
delegate.set_format(cc['display'].get('date_format','')) delegate.set_format(cc['display'].get('date_format',''))
self.setItemDelegateForColumn(cm.index(colhead), delegate) set_item_delegate(colhead, delegate)
elif cc['datatype'] == 'comments': elif cc['datatype'] == 'comments':
ctype = cc['display'].get('interpret_as', 'html') ctype = cc['display'].get('interpret_as', 'html')
if ctype == 'short-text': if ctype == 'short-text':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate) set_item_delegate(colhead, self.cc_text_delegate)
elif ctype in ('long-text', 'markdown'): elif ctype in ('long-text', 'markdown'):
self.setItemDelegateForColumn(cm.index(colhead), self.cc_longtext_delegate) set_item_delegate(colhead, self.cc_longtext_delegate)
else: else:
self.setItemDelegateForColumn(cm.index(colhead), self.cc_comments_delegate) set_item_delegate(colhead, self.cc_comments_delegate)
elif cc['datatype'] == 'text': elif cc['datatype'] == 'text':
if cc['is_multiple']: if cc['is_multiple']:
if cc['display'].get('is_names', False): if cc['display'].get('is_names', False):
self.setItemDelegateForColumn(cm.index(colhead), set_item_delegate(colhead, self.cc_names_delegate)
self.cc_names_delegate)
else: else:
self.setItemDelegateForColumn(cm.index(colhead), set_item_delegate(colhead, self.tags_delegate)
self.tags_delegate)
else: else:
self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate) set_item_delegate(colhead, self.cc_text_delegate)
elif cc['datatype'] == 'series': elif cc['datatype'] == 'series':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate) set_item_delegate(colhead, self.cc_text_delegate)
elif cc['datatype'] in ('int', 'float'): elif cc['datatype'] in ('int', 'float'):
self.setItemDelegateForColumn(cm.index(colhead), self.cc_number_delegate) set_item_delegate(colhead, self.cc_number_delegate)
elif cc['datatype'] == 'bool': elif cc['datatype'] == 'bool':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_bool_delegate) set_item_delegate(colhead, self.cc_bool_delegate)
elif cc['datatype'] == 'rating': elif cc['datatype'] == 'rating':
d = self.half_rating_delegate if cc['display'].get('allow_half_stars', False) else self.rating_delegate d = self.half_rating_delegate if cc['display'].get('allow_half_stars', False) else self.rating_delegate
self.setItemDelegateForColumn(cm.index(colhead), d) set_item_delegate(colhead, d)
elif cc['datatype'] == 'composite': elif cc['datatype'] == 'composite':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_template_delegate) set_item_delegate(colhead, self.cc_template_delegate)
elif cc['datatype'] == 'enumeration': elif cc['datatype'] == 'enumeration':
self.setItemDelegateForColumn(cm.index(colhead), self.cc_enum_delegate) set_item_delegate(colhead, self.cc_enum_delegate)
else: else:
dattr = colhead+'_delegate' dattr = colhead+'_delegate'
delegate = colhead if hasattr(self, dattr) else 'text' delegate = colhead if hasattr(self, dattr) else 'text'
self.setItemDelegateForColumn(cm.index(colhead), getattr(self, set_item_delegate(colhead, getattr(self, delegate+'_delegate'))
delegate+'_delegate'))
self.restore_state() self.restore_state()
self.set_ondevice_column_visibility() self.set_ondevice_column_visibility()

View File

@ -0,0 +1,26 @@
#!/usr/bin/env python2
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
from __future__ import absolute_import, division, print_function, unicode_literals
from PyQt5.Qt import QWidget, QHBoxLayout, QTableView
class PinTableView(QTableView):
def __init__(self, books_view, parent=None):
QTableView.__init__(self, parent)
self.books_view = books_view
self.verticalHeader().close()
class PinContainer(QWidget):
def __init__(self, books_view, parent=None):
QWidget.__init__(self, parent)
self.books_view = books_view
self.l = l = QHBoxLayout(self)
l.addWidget(books_view)
l.addWidget(books_view.pin_view)
l.setContentsMargins(0, 0, 0, 0)