From 7eef114a4364b702de16a124e370a545ecf26317 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 29 Jan 2018 12:12:24 +0530 Subject: [PATCH] Start work on splitting the book list Allows for pinned columns --- src/calibre/gui2/init.py | 2 +- src/calibre/gui2/library/alternate_views.py | 5 +- src/calibre/gui2/library/views.py | 63 ++++++++++++--------- src/calibre/gui2/pin_columns.py | 26 +++++++++ 4 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 src/calibre/gui2/pin_columns.py diff --git a/src/calibre/gui2/init.py b/src/calibre/gui2/init.py index 45d7de912a..6a81e192b3 100644 --- a/src/calibre/gui2/init.py +++ b/src/calibre/gui2/init.py @@ -159,7 +159,7 @@ class LibraryWidget(Splitter): # {{{ parent.library_view.setObjectName('library_view') stack = QStackedWidget(self) 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.setObjectName('grid_view') av.add_view('grid', parent.grid_view) diff --git a/src/calibre/gui2/library/alternate_views.py b/src/calibre/gui2/library/alternate_views.py index 55b7589a1d..e888973c0f 100644 --- a/src/calibre/gui2/library/alternate_views.py +++ b/src/calibre/gui2/library/alternate_views.py @@ -23,6 +23,7 @@ from PyQt5.Qt import ( from calibre import fit_image, prints, prepare_string_for_xml, human_readable 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.utils import join_with_timeout from calibre.gui2 import gprefs, config, rating_font, empty_index @@ -276,7 +277,9 @@ class AlternateViews(object): def set_stack(self, 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): self.views[key] = view diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py index bb635a5bdc..b934e76c48 100644 --- a/src/calibre/gui2/library/views.py +++ b/src/calibre/gui2/library/views.py @@ -21,6 +21,7 @@ from calibre.gui2.library.delegates import (RatingDelegate, PubDateDelegate, CcBoolDelegate, CcCommentsDelegate, CcDateDelegate, CcTemplateDelegate, CcEnumDelegate, CcNumberDelegate, LanguagesDelegate) 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.gestures import GestureManager 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): QTableView.__init__(self, parent) + self.pin_view = PinTableView(self, parent) self.gesture_manager = GestureManager(self) self.default_row_height = self.verticalHeader().defaultSectionSize() self.gui = parent self.setProperty('highlight_current_item', 150) + self.pin_view.setProperty('highlight_current_item', 150) self.row_sizing_done = False self.alternate_views = AlternateViews(self) @@ -231,9 +234,10 @@ class BooksView(QTableView): # {{{ self.setEditTriggers(self.DoubleClicked|self.editTriggers()) setup_dnd_interface(self) - self.setAlternatingRowColors(True) - self.setShowGrid(False) - self.setWordWrap(False) + for wv in self, self.pin_view: + wv.setAlternatingRowColors(True) + wv.setShowGrid(False) + wv.setWordWrap(False) self.rating_delegate = RatingDelegate(self) self.half_rating_delegate = RatingDelegate(self, is_half_star=True) @@ -258,10 +262,12 @@ class BooksView(QTableView): # {{{ self.display_parent = parent self._model = modelcls(self) self.setModel(self._model) + self.pin_view.setModel(self._model) self._model.count_changed_signal.connect(self.do_row_sizing, type=Qt.QueuedConnection) - self.setSelectionBehavior(QAbstractItemView.SelectRows) - self.setSortingEnabled(True) + for wv in self, self.pin_view: + wv.setSelectionBehavior(QAbstractItemView.SelectRows) + wv.setSortingEnabled(True) self.selectionModel().currentRowChanged.connect(self._model.current_changed) self.preserve_state = partial(PreserveViewState, self) self.marked_changed_listener = FunctionDispatcher(self.marked_changed) @@ -293,6 +299,8 @@ class BooksView(QTableView): # {{{ self._model.sorting_done.connect(self.sorting_done, type=Qt.QueuedConnection) self.set_row_header_visibility() + if modelcls is not BooksModel: + self.pin_view.close() # Column Header Context Menu {{{ def column_header_context_handler(self, action=None, column=None): @@ -780,56 +788,59 @@ class BooksView(QTableView): # {{{ def database_changed(self, db): db.data.add_marked_listener(self.marked_changed_listener) for i in range(self.model().columnCount(None)): - if self.itemDelegateForColumn(i) in ( - self.rating_delegate, self.timestamp_delegate, self.pubdate_delegate, - self.last_modified_delegate, self.languages_delegate, self.half_rating_delegate): - self.setItemDelegateForColumn(i, self.itemDelegate()) + for vw in self, self.pin_view: + if vw.itemDelegateForColumn(i) in ( + self.rating_delegate, self.timestamp_delegate, self.pubdate_delegate, + self.last_modified_delegate, self.languages_delegate, self.half_rating_delegate): + vw.setItemDelegateForColumn(i, vw.itemDelegate()) 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: if self._model.is_custom_column(colhead): cc = self._model.custom_columns[colhead] if cc['datatype'] == 'datetime': delegate = CcDateDelegate(self) delegate.set_format(cc['display'].get('date_format','')) - self.setItemDelegateForColumn(cm.index(colhead), delegate) + set_item_delegate(colhead, delegate) elif cc['datatype'] == 'comments': ctype = cc['display'].get('interpret_as', 'html') 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'): - self.setItemDelegateForColumn(cm.index(colhead), self.cc_longtext_delegate) + set_item_delegate(colhead, self.cc_longtext_delegate) else: - self.setItemDelegateForColumn(cm.index(colhead), self.cc_comments_delegate) + set_item_delegate(colhead, self.cc_comments_delegate) elif cc['datatype'] == 'text': if cc['is_multiple']: if cc['display'].get('is_names', False): - self.setItemDelegateForColumn(cm.index(colhead), - self.cc_names_delegate) + set_item_delegate(colhead, self.cc_names_delegate) else: - self.setItemDelegateForColumn(cm.index(colhead), - self.tags_delegate) + set_item_delegate(colhead, self.tags_delegate) else: - self.setItemDelegateForColumn(cm.index(colhead), self.cc_text_delegate) + set_item_delegate(colhead, self.cc_text_delegate) 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'): - self.setItemDelegateForColumn(cm.index(colhead), self.cc_number_delegate) + set_item_delegate(colhead, self.cc_number_delegate) 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': 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': - self.setItemDelegateForColumn(cm.index(colhead), self.cc_template_delegate) + set_item_delegate(colhead, self.cc_template_delegate) elif cc['datatype'] == 'enumeration': - self.setItemDelegateForColumn(cm.index(colhead), self.cc_enum_delegate) + set_item_delegate(colhead, self.cc_enum_delegate) else: dattr = colhead+'_delegate' delegate = colhead if hasattr(self, dattr) else 'text' - self.setItemDelegateForColumn(cm.index(colhead), getattr(self, - delegate+'_delegate')) + set_item_delegate(colhead, getattr(self, delegate+'_delegate')) self.restore_state() self.set_ondevice_column_visibility() diff --git a/src/calibre/gui2/pin_columns.py b/src/calibre/gui2/pin_columns.py new file mode 100644 index 0000000000..efafcf2169 --- /dev/null +++ b/src/calibre/gui2/pin_columns.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python2 +# vim:fileencoding=utf-8 +# License: GPLv3 Copyright: 2018, Kovid Goyal + +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)