From 976e298376db8add57b799ed25ceb9af6432b3e6 Mon Sep 17 00:00:00 2001
From: Charles Haley
Date: Mon, 3 Jul 2017 12:48:24 +0200
Subject: [PATCH] Enhancement request #1701833: ability to add columns to
quickview pane.
This commit contains many improvements and changes to Quickview.
- Add preference tab in Look & Feel to choose columns displayed in QV table and their order
- Option to permit changing the selected column from the quickview widget with return or double-click
- Option to show QV at startup
- Option to ignore virtual libraries in QV searches
- Remove margins on the docked window (tighter display
- Better handling of changes made on the booklist
- Many bugs fixed, some refactoring
---
src/calibre/db/backend.py | 1 +
src/calibre/gui2/__init__.py | 4 +
src/calibre/gui2/actions/edit_metadata.py | 4 +
src/calibre/gui2/actions/show_quickview.py | 13 +-
src/calibre/gui2/dialogs/quickview.py | 222 +++++++++++++++------
src/calibre/gui2/dialogs/quickview.ui | 30 ++-
src/calibre/gui2/init.py | 4 +-
src/calibre/gui2/library/views.py | 9 +
src/calibre/gui2/preferences/look_feel.py | 69 +++++--
src/calibre/gui2/preferences/look_feel.ui | 106 ++++++++++
src/calibre/gui2/ui.py | 7 +-
11 files changed, 385 insertions(+), 84 deletions(-)
diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py
index da669a16cb..1ed2e6c661 100644
--- a/src/calibre/db/backend.py
+++ b/src/calibre/db/backend.py
@@ -471,6 +471,7 @@ class DB(object):
('uuid', False), ('comments', True), ('id', False), ('pubdate', False),
('last_modified', False), ('size', False), ('languages', False),
]
+ defs['qv_display_fields'] = [('title', True), ('authors', True), ('series', True)]
defs['virtual_libraries'] = {}
defs['virtual_lib_on_startup'] = defs['cs_virtual_lib_on_startup'] = ''
defs['virt_libs_hidden'] = defs['virt_libs_order'] = ()
diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py
index 58a615ff12..4950c76745 100644
--- a/src/calibre/gui2/__init__.py
+++ b/src/calibre/gui2/__init__.py
@@ -152,6 +152,10 @@ def create_defs():
defs['hidpi'] = 'auto'
defs['tag_browser_item_padding'] = 0.5
defs['paste_isbn_prefixes'] = ['isbn', 'url', 'amazon', 'google']
+ defs['qv_respects_vls'] = True
+ defs['qv_dclick_changes_column'] = True
+ defs['qv_retkey_changes_column'] = True
+ defs['qv_show_on_startup'] = False
create_defs()
diff --git a/src/calibre/gui2/actions/edit_metadata.py b/src/calibre/gui2/actions/edit_metadata.py
index f444fd023e..e84682431d 100644
--- a/src/calibre/gui2/actions/edit_metadata.py
+++ b/src/calibre/gui2/actions/edit_metadata.py
@@ -24,6 +24,7 @@ from calibre.utils.icu import sort_key
from calibre.db.errors import NoSuchFormat
from calibre.library.comments import merge_comments
from calibre.ebooks.metadata.sources.prefs import msprefs
+from calibre.customize.ui import find_plugin
class EditMetadataAction(InterfaceAction):
@@ -347,6 +348,9 @@ class EditMetadataAction(InterfaceAction):
self.gui.refresh_cover_browser()
m.current_changed(current, previous or current)
self.gui.tags_view.recount_with_position_based_index()
+ qv = find_plugin('Show Quickview')
+ if qv is not None:
+ qv.actual_plugin_.refill_quickview()
def do_edit_metadata(self, row_list, current_row, editing_multiple):
from calibre.gui2.metadata.single import edit_metadata
diff --git a/src/calibre/gui2/actions/show_quickview.py b/src/calibre/gui2/actions/show_quickview.py
index a8cb914ee4..163bb02755 100644
--- a/src/calibre/gui2/actions/show_quickview.py
+++ b/src/calibre/gui2/actions/show_quickview.py
@@ -56,11 +56,10 @@ class ShowQuickviewAction(InterfaceAction):
'on the device.')).exec_()
return
index = self.gui.library_view.currentIndex()
- if index.isValid():
- self.current_instance = Quickview(self.gui, index)
- self.current_instance.reopen_quickview.connect(self.reopen_quickview)
- self.set_search_shortcut()
- self.current_instance.show()
+ self.current_instance = Quickview(self.gui, index)
+ self.current_instance.reopen_quickview.connect(self.reopen_quickview)
+ self.set_search_shortcut()
+ self.current_instance.show()
def set_search_shortcut(self):
if self.current_instance and not self.current_instance.is_closed:
@@ -73,6 +72,10 @@ class ShowQuickviewAction(InterfaceAction):
self.current_instance = None
self.show_quickview()
+ def refill_quickview(self):
+ if self.current_instance and not self.current_instance.is_closed:
+ self.current_instance.refill()
+
def change_quickview_column(self, idx):
self.show_quickview()
if self.current_instance:
diff --git a/src/calibre/gui2/dialogs/quickview.py b/src/calibre/gui2/dialogs/quickview.py
index c2267b4d03..e81d86d43f 100644
--- a/src/calibre/gui2/dialogs/quickview.py
+++ b/src/calibre/gui2/dialogs/quickview.py
@@ -108,6 +108,10 @@ class Quickview(QDialog, Ui_Quickview):
Ui_Quickview.__init__(self)
self.setupUi(self)
self.isClosed = False
+ self.current_book = None
+
+ if self.is_pane:
+ self.main_grid_layout.setContentsMargins(0, 0, 0, 0)
self.books_table_column_widths = None
try:
@@ -130,19 +134,13 @@ class Quickview(QDialog, Ui_Quickview):
self.db = self.view.model().db
self.gui = gui
self.is_closed = False
- self.current_book_id = None
- self.current_key = None
+ self.current_book_id = None # the db id of the book used to fill the lh pane
+ self.current_column = None # current logical column in books list
+ self.current_key = None # current lookup key in books list
self.last_search = None
- self.current_column = None
- self.current_item = None
self.no_valid_items = False
- column_positions = self.view.get_state()['column_positions']
- column_order = ['title', 'authors', 'series']
- column_order.sort(key=lambda col: column_positions[col])
- self.title_column = column_order.index('title')
- self.author_column = column_order.index('authors')
- self.series_column = column_order.index('series')
+ self.fm = self.db.field_metadata
self.items.setSelectionMode(QAbstractItemView.SingleSelection)
self.items.currentTextChanged.connect(self.item_selected)
@@ -153,7 +151,6 @@ class Quickview(QDialog, Ui_Quickview):
self.items.installEventFilter(focus_filter)
self.tab_pressed_signal.connect(self.tab_pressed)
- # Set up the books table columns
return_filter = BooksTableFilter(self.books_table)
return_filter.return_pressed_signal.connect(self.return_pressed)
self.books_table.installEventFilter(return_filter)
@@ -172,19 +169,16 @@ class Quickview(QDialog, Ui_Quickview):
self.books_table.setSelectionBehavior(QAbstractItemView.SelectRows)
self.books_table.setSelectionMode(QAbstractItemView.SingleSelection)
self.books_table.setProperty('highlight_current_item', 150)
- self.books_table.setColumnCount(3)
- t = QTableWidgetItem(_('Title'))
- self.books_table.setHorizontalHeaderItem(self.title_column, t)
- t = QTableWidgetItem(_('Authors'))
- self.books_table.setHorizontalHeaderItem(self.author_column, t)
- t = QTableWidgetItem(ngettext("Series", 'Series', 1))
- self.books_table.setHorizontalHeaderItem(self.series_column, t)
+
+ # Set up the books table columns
+ self.add_columns_to_widget()
+
self.books_table_header_height = self.books_table.height()
self.books_table.cellDoubleClicked.connect(self.book_doubleclicked)
self.books_table.currentCellChanged.connect(self.books_table_cell_changed)
self.books_table.cellClicked.connect(self.books_table_set_search_string)
self.books_table.cellActivated.connect(self.books_table_set_search_string)
- self.books_table.sortByColumn(self.title_column, Qt.AscendingOrder)
+ self.books_table.sortByColumn(0, Qt.AscendingOrder)
# get the standard table row height. Do this here because calling
# resizeRowsToContents can word wrap long cell contents, creating
@@ -225,6 +219,25 @@ class Quickview(QDialog, Ui_Quickview):
self.books_table.horizontalHeader().sectionResized.connect(self.section_resized)
self.dock_button.clicked.connect(self.show_as_pane_changed)
+ def add_columns_to_widget(self):
+ '''
+ Get the list of columns from the preferences. Clear the current table
+ and add the current column set
+ '''
+ self.column_order = [x[0] for x in get_qv_field_list(self.fm) if x[1]]
+ self.books_table.clear()
+ self.books_table.setColumnCount(len(self.column_order))
+ for idx,col in enumerate(self.column_order):
+ t = QTableWidgetItem(self.fm[col]['name'])
+ self.books_table.setHorizontalHeaderItem(idx, t)
+
+ def refill(self):
+ '''
+ Refill the table in case the book data changes
+ '''
+ self.add_columns_to_widget()
+ self._refresh(self.current_book_id, self.current_key)
+
def set_search_text(self, txt):
if txt:
self.search_button.setEnabled(True)
@@ -248,22 +261,39 @@ class Quickview(QDialog, Ui_Quickview):
self.books_table_set_search_string(cur_row, cur_col)
def books_table_set_search_string(self, current_row, current_col):
- current = self.books_table.currentItem()
+ '''
+ Given the contents of a cell, compute a search string that will find
+ that book and any others with identical contents in the cell.
+ '''
+ current = self.books_table.item(current_row, current_col)
if current is None:
return
- if current.column() == 0:
+ book_id = current.data(Qt.UserRole)
+
+ if current is None:
+ return
+ col = self.column_order[current.column()]
+ if col == 'title':
self.set_search_text('title:="' + current.text().replace('"', '\\"') + '"')
- elif current.column() == 1:
+ elif col == 'authors':
authors = []
for aut in [t.strip() for t in current.text().split('&')]:
authors.append('authors:="' + aut.replace('"', '\\"') + '"')
self.set_search_text(' and '.join(authors))
- else:
- t = current.text().rpartition('[')[0].strip()
+ elif self.fm[col]['datatype'] == 'series':
+ mi = self.db.get_metadata(book_id, index_is_id=True, get_user_categories=False)
+ t = mi.get(col)
if t:
- self.set_search_text('series:="' + t.replace('"', '\\"') + '"')
+ self.set_search_text(col+ ':="' + t + '"')
else:
self.set_search_text(None)
+ else:
+ if self.fm[col]['is_multiple']:
+ items = [(col + ':"=' + v.strip() + '"') for v in
+ current.text().split(self.fm[col]['is_multiple']['ui_to_list'])]
+ self.set_search_text(' and '.join(items))
+ else:
+ self.set_search_text(col + ':"=' + current.text() + '"')
def tab_pressed(self, in_widget, isForward):
if isForward:
@@ -292,10 +322,13 @@ class Quickview(QDialog, Ui_Quickview):
if self.last_search is not None:
self.gui.search.set_search_string(self.last_search)
- # Called when book information is changed in the library view. Make that
- # book current. This means that prev and next in edit metadata will move
- # the current book.
+
def book_was_changed(self, mi):
+ '''
+ Called when book information is changed in the library view. Make that
+ book info current. This means that prev and next in edit metadata will move
+ the current book and change quickview
+ '''
if self.is_closed or self.current_column is None:
return
# There is an ordering problem when libraries are changed. The library
@@ -305,7 +338,7 @@ class Quickview(QDialog, Ui_Quickview):
# operation if we get an exception. The "close" will come
# eventually.
try:
- self.refresh(self.view.model().index(self.db.row(mi.id), self.current_column))
+ self._refresh(mi.get('id'), self.current_key)
except:
pass
@@ -316,21 +349,29 @@ class Quickview(QDialog, Ui_Quickview):
self.fill_in_books_box(unicode(txt))
self.set_search_text(self.current_key + ':"=' + txt.replace('"', '\\"') + '"')
- # Given a cell in the library view, display the information
def refresh(self, idx):
+ '''
+ Given a cell in the library view, display the information. This method
+ converts the index into the lookup ken
+ '''
if self.lock_qv.isChecked():
return
bv_row = idx.row()
self.current_column = idx.column()
- key = self.view.model().column_map[self.current_column]
+ key = self.view.column_map[self.current_column]
book_id = self.view.model().id(bv_row)
-
if self.current_book_id == book_id and self.current_key == key:
return
+ self._refresh(book_id, key)
+ def _refresh(self, book_id, key):
+ '''
+ Actually fill in the left-hand pane from the information in the
+ selected column of the selected book
+ '''
# Only show items for categories
- if not self.db.field_metadata[key]['is_category']:
+ if key is None or not self.fm[key]['is_category']:
if self.current_key is None:
self.indicate_no_items()
return
@@ -338,7 +379,7 @@ class Quickview(QDialog, Ui_Quickview):
label_text = _('&Item: {0} ({1})')
if self.is_pane:
label_text = label_text.replace('&', '')
- self.items_label.setText(label_text.format(self.db.field_metadata[key]['name'], key))
+ self.items_label.setText(label_text.format(self.fm[key]['name'], key))
self.items.blockSignals(True)
self.items.clear()
@@ -349,8 +390,11 @@ class Quickview(QDialog, Ui_Quickview):
if vals:
self.no_valid_items = False
- if self.db.field_metadata[key]['datatype'] == 'rating':
- vals = unicode(vals/2)
+ if self.fm[key]['datatype'] == 'rating':
+ if self.fm[key]['display'].get('allow_half_stars', False):
+ vals = unicode(vals/2.0)
+ else:
+ vals = unicode(vals/2)
if not isinstance(vals, list):
vals = [vals]
vals.sort(key=sort_key)
@@ -377,15 +421,20 @@ class Quickview(QDialog, Ui_Quickview):
'to see the information for that book'))
def fill_in_books_box(self, selected_item):
- self.current_item = selected_item
+ '''
+ Given the selected row in the left-hand box, fill in the grid with
+ the books that contain that data.
+ '''
# Do a bit of fix-up on the items so that the search works.
if selected_item.startswith('.'):
sv = '.' + selected_item
else:
sv = selected_item
sv = self.current_key + ':"=' + sv.replace('"', r'\"') + '"'
- books = self.db.search(sv, return_matches=True,
- sort_results=False)
+ if gprefs['qv_respects_vls']:
+ books = self.db.search(sv, return_matches=True, sort_results=False)
+ else:
+ books = self.db.new_api.search(sv)
self.books_table.setRowCount(len(books))
label_text = _('&Books with selected item "{0}": {1}')
@@ -395,28 +444,39 @@ class Quickview(QDialog, Ui_Quickview):
select_item = None
self.books_table.setSortingEnabled(False)
+ self.books_table.blockSignals(True)
tt = ('' +
- _('Double-click on a book to change the selection in the library view. '
- 'Shift- or control-double-click to edit the metadata of a book') + '
')
+ _('Double-click on a book to change the selection in the library view or '
+ 'change the column shown in the left-hand pane. '
+ 'Shift- or control-double-click to edit the metadata of a book, '
+ 'which also changes the selected book.'
+ ) + '
')
for row, b in enumerate(books):
mi = self.db.get_metadata(b, index_is_id=True, get_user_categories=False)
- a = TableItem(mi.title, mi.title_sort)
- a.setData(Qt.UserRole, b)
- a.setToolTip(tt)
- self.books_table.setItem(row, self.title_column, a)
- if b == self.current_book_id:
- select_item = a
- a = TableItem(' & '.join(mi.authors), mi.author_sort)
- a.setToolTip(tt)
- self.books_table.setItem(row, self.author_column, a)
- series = mi.format_field('series')[1]
- if series is None:
- series = ''
- a = TableItem(series, mi.series, mi.series_index)
- a.setToolTip(tt)
- self.books_table.setItem(row, self.series_column, a)
- self.books_table.setRowHeight(row, self.books_table_row_height)
+ for col in self.column_order:
+ if col == 'title':
+ a = TableItem(mi.title, mi.title_sort)
+ if b == self.current_book_id:
+ select_item = a
+ elif col == 'authors':
+ a = TableItem(' & '.join(mi.authors), mi.author_sort)
+ elif col == 'series':
+ series = mi.format_field('series')[1]
+ if series is None:
+ series = ''
+ a = TableItem(series, mi.series, mi.series_index)
+ elif self.fm[col]['datatype'] == 'series':
+ v = mi.format_field(col)[1]
+ a = TableItem(v, mi.get(col), mi.get(col+'_index'))
+ else:
+ v = mi.format_field(col)[1]
+ a = TableItem(v, v)
+ a.setData(Qt.UserRole, b)
+ a.setToolTip(tt)
+ self.books_table.setItem(row, self.key_to_table_widget_column(col), a)
+ self.books_table.setRowHeight(row, self.books_table_row_height)
+ self.books_table.blockSignals(False)
self.books_table.setSortingEnabled(True)
if select_item is not None:
self.books_table.setCurrentItem(select_item)
@@ -445,22 +505,43 @@ class Quickview(QDialog, Ui_Quickview):
self.books_table.setColumnWidth(c, w)
self.save_state()
+ def key_to_table_widget_column(self, key):
+ return self.column_order.index(key)
+
def return_pressed(self):
- self.select_book(self.books_table.currentRow())
+ row = self.books_table.currentRow()
+ if gprefs['qv_retkey_changes_column']:
+ self.select_book(row, self.books_table.currentColumn())
+ else:
+ self.select_book(row, self.key_to_table_widget_column(self.current_key))
def book_doubleclicked(self, row, column):
if self.no_valid_items:
return
- self.select_book(row)
+ if gprefs['qv_dclick_changes_column']:
+ self.select_book(row, column)
+ else:
+ self.select_book(row, self.key_to_table_widget_column(self.current_key))
- def select_book(self, row):
- book_id = int(self.books_table.item(row, self.title_column).data(Qt.UserRole))
- self.view.select_rows([book_id])
+ def select_book(self, row, column):
+ '''
+ row and column both refer the qv table. In particular, column is not
+ the logical column in the book list.
+ '''
+ item = self.books_table.item(row, column)
+ if item is None:
+ return
+ book_id = int(self.books_table.item(row, column).data(Qt.UserRole))
+ key = self.column_order[column]
modifiers = int(QApplication.keyboardModifiers())
if modifiers in (Qt.CTRL, Qt.SHIFT):
+ self.view.select_rows([book_id])
em = find_plugin('Edit Metadata')
if em is not None:
em.actual_plugin_.edit_metadata(None)
+ else:
+ self.view.select_cell(self.db.data.id_to_index(book_id),
+ self.view.column_map.index(key))
def set_focus(self):
self.items.setFocus(Qt.ActiveWindowFocusReason)
@@ -498,3 +579,20 @@ class Quickview(QDialog, Ui_Quickview):
self.gui.library_view.setFocus(Qt.ActiveWindowFocusReason)
self._close()
QDialog.reject(self)
+
+def get_qv_field_list(fm, use_defaults=False):
+ from calibre.gui2.ui import get_gui
+ db = get_gui().current_db
+ if use_defaults:
+ src = db.prefs.defaults
+ else:
+ src = db.prefs
+ fieldlist = list(src['qv_display_fields'])
+ names = frozenset([x[0] for x in fieldlist])
+ for field in fm.displayable_field_keys():
+ if (field != 'comments'
+ and fm[field]['datatype'] != 'comments'
+ and field not in names):
+ fieldlist.append((field, False))
+ available = frozenset(fm.displayable_field_keys())
+ return [(f, d) for f, d in fieldlist if f in available]
diff --git a/src/calibre/gui2/dialogs/quickview.ui b/src/calibre/gui2/dialogs/quickview.ui
index 2f22f193c3..f0517e00b4 100644
--- a/src/calibre/gui2/dialogs/quickview.ui
+++ b/src/calibre/gui2/dialogs/quickview.ui
@@ -19,7 +19,7 @@
Quickview
-
+
-
@@ -62,6 +62,19 @@
-
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 200
+ 0
+
+
+
+
-
@@ -80,7 +93,7 @@
- 0
+ 20
0
@@ -145,6 +158,19 @@
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 200
+ 0
+
+
+
+
diff --git a/src/calibre/gui2/init.py b/src/calibre/gui2/init.py
index 712ef409c0..16aec295e9 100644
--- a/src/calibre/gui2/init.py
+++ b/src/calibre/gui2/init.py
@@ -164,7 +164,9 @@ class LibraryWidget(Splitter): # {{{
av.add_view('grid', parent.grid_view)
parent.quickview_splitter.addWidget(stack)
- quickview_widget.setLayout(QVBoxLayout())
+ l = QVBoxLayout()
+ l.setContentsMargins(0, 0, 0, 0)
+ quickview_widget.setLayout(l)
parent.quickview_splitter.addWidget(quickview_widget)
parent.quickview_splitter.hide_quickview_widget()
diff --git a/src/calibre/gui2/library/views.py b/src/calibre/gui2/library/views.py
index c8a8b58d89..e5598e3270 100644
--- a/src/calibre/gui2/library/views.py
+++ b/src/calibre/gui2/library/views.py
@@ -921,6 +921,15 @@ class BooksView(QTableView): # {{{
sm = self.selectionModel()
sm.select(index, sm.ClearAndSelect|sm.Rows)
+ def select_cell(self, row_number=0, logical_column=0):
+ if row_number > -1 and row_number < self.model().rowCount(QModelIndex()):
+ index = self.model().index(row_number, logical_column)
+ self.setCurrentIndex(index)
+ sm = self.selectionModel()
+ sm.select(index, sm.ClearAndSelect|sm.Rows)
+ sm.select(index, sm.Current)
+ self.clicked.emit(index)
+
def row_at_top(self):
pos = 0
while pos < 100:
diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py
index fafbb771c8..081f176be7 100644
--- a/src/calibre/gui2/preferences/look_feel.py
+++ b/src/calibre/gui2/preferences/look_feel.py
@@ -32,9 +32,11 @@ from calibre.utils.localization import (available_translations,
from calibre.utils.config import prefs
from calibre.utils.icu import sort_key
from calibre.gui2.book_details import get_field_list
+from calibre.gui2.dialogs.quickview import get_qv_field_list
from calibre.gui2.preferences.coloring import EditRules
from calibre.gui2.library.alternate_views import auto_height, CM_TO_INCH
from calibre.gui2.widgets2 import Dialog
+from calibre.customize.ui import find_plugin
class BusyCursor(object):
@@ -209,7 +211,6 @@ class IdLinksEditor(Dialog):
self.table.removeRow(r)
# }}}
-
class DisplayedFields(QAbstractListModel): # {{{
def __init__(self, db, parent=None):
@@ -285,6 +286,25 @@ class DisplayedFields(QAbstractListModel): # {{{
# }}}
+class QVDisplayedFields(DisplayedFields): # {{{
+
+ def __init__(self, db, parent=None):
+ DisplayedFields.__init__(self, db, parent)
+
+ def initialize(self, use_defaults=False):
+ self.beginResetModel()
+ self.fields = [[x[0], x[1]] for x in
+ get_qv_field_list(self.db.field_metadata, use_defaults=use_defaults)]
+ self.endResetModel()
+ self.changed = True
+
+ def commit(self):
+ if self.changed:
+ self.db.new_api.set_pref('qv_display_fields', self.fields)
+
+# }}}
+
+
class Background(QWidget): # {{{
def __init__(self, parent):
@@ -363,6 +383,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
r('tag_browser_show_counts', gprefs)
r('tag_browser_item_padding', gprefs)
+ r('qv_respects_vls', gprefs)
+ r('qv_dclick_changes_column', gprefs)
+ r('qv_retkey_changes_column', gprefs)
+ r('qv_show_on_startup', gprefs)
+
+
r('cover_flow_queue_length', config, restart_required=True)
r('cover_browser_reflections', gprefs)
r('cover_browser_title_template', db.prefs)
@@ -443,8 +469,19 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.field_display_order)
self.display_model.dataChanged.connect(self.changed_signal)
self.field_display_order.setModel(self.display_model)
- self.df_up_button.clicked.connect(self.move_df_up)
- self.df_down_button.clicked.connect(self.move_df_down)
+ self.df_up_button.clicked.connect(partial(self.move_field_up,
+ self.field_display_order, self.display_model))
+ self.df_down_button.clicked.connect(partial(self.move_field_down,
+ self.field_display_order, self.display_model))
+
+ self.qv_display_model = QVDisplayedFields(self.gui.current_db,
+ self.qv_display_order)
+ self.qv_display_model.dataChanged.connect(self.changed_signal)
+ self.qv_display_order.setModel(self.qv_display_model)
+ self.qv_up_button.clicked.connect(partial(self.move_field_up,
+ self.qv_display_order, self.qv_display_model))
+ self.qv_down_button.clicked.connect(partial(self.move_field_down,
+ self.qv_display_order, self.qv_display_model))
self.edit_rules = EditRules(self.tabWidget)
self.edit_rules.changed.connect(self.changed_signal)
@@ -553,6 +590,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.current_font = self.initial_font = font
self.update_font_display()
self.display_model.initialize()
+ self.qv_display_model.initialize()
db = self.gui.current_db
try:
idx = self.gui.library_view.currentIndex().row()
@@ -606,6 +644,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.changed_signal.emit()
self.update_font_display()
self.display_model.restore_defaults()
+ self.qv_display_model.restore_defaults();
self.edit_rules.clear()
self.icon_rules.clear()
self.grid_rules.clear()
@@ -654,23 +693,23 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
self.font_display.setText(name +
' [%dpt]'%fi.pointSize())
- def move_df_up(self):
- idx = self.field_display_order.currentIndex()
+ def move_field_up(self, widget, model):
+ idx = widget.currentIndex()
if idx.isValid():
- idx = self.display_model.move(idx, -1)
+ idx = model.move(idx, -1)
if idx is not None:
- sm = self.field_display_order.selectionModel()
+ sm = widget.selectionModel()
sm.select(idx, sm.ClearAndSelect)
- self.field_display_order.setCurrentIndex(idx)
+ widget.setCurrentIndex(idx)
- def move_df_down(self):
- idx = self.field_display_order.currentIndex()
+ def move_field_down(self, widget, model):
+ idx = widget.currentIndex()
if idx.isValid():
- idx = self.display_model.move(idx, 1)
+ idx = model.move(idx, 1)
if idx is not None:
- sm = self.field_display_order.selectionModel()
+ sm = widget.selectionModel()
sm.select(idx, sm.ClearAndSelect)
- self.field_display_order.setCurrentIndex(idx)
+ widget.setCurrentIndex(idx)
def change_font(self, *args):
fd = QFontDialog(self.build_font_obj(), self)
@@ -693,6 +732,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
QApplication.setFont(self.font_display.font())
rr = True
self.display_model.commit()
+ self.qv_display_model.commit()
self.edit_rules.commit(self.gui.current_db.prefs)
self.icon_rules.commit(self.gui.current_db.prefs)
self.grid_rules.commit(self.gui.current_db.prefs)
@@ -720,6 +760,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
getattr(gui, view + '_view').set_row_header_visibility()
gui.library_view.refresh_row_sizing()
gui.grid_view.refresh_settings()
+ qv = find_plugin('Show Quickview')
+ if qv is not None:
+ qv.actual_plugin_.refill_quickview()
if __name__ == '__main__':
diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui
index a9485722e0..2d0dc05dd2 100644
--- a/src/calibre/gui2/preferences/look_feel.ui
+++ b/src/calibre/gui2/preferences/look_feel.ui
@@ -1131,6 +1131,112 @@ them to all have the same width and height
+
+
+
+ :/images/search.png:/images/search.png
+
+
+ &Quickview
+
+
+ -
+
+
-
+
+
+ &Apply virtual libraries in Quickview pane
+
+
+ Check this box to make Quickview show books only in the
+current virtual library. If unchecked, Quickview ignores virtual libraries.
+
+
+
+ -
+
+
+ &Show Quickview on startup
+
+
+
+ -
+
+
+ Pressing return in a cell changes both the book and the
+column being examined (the left-hand pane)
+
+
+ &Pressing 'return' changes examined column
+
+
+
+ -
+
+
+ Double-clicking in a cell changes both the book and the
+column being examined (the left-hand pane)
+
+
+ &Doubleclick changes examined column
+
+
+
+
+
+ -
+
+
+ Select displayed columns
+
+
+
-
+
+
+ Move up
+
+
+
+ :/images/arrow-up.png:/images/arrow-up.png
+
+
+
+ -
+
+
+ Move down
+
+
+
+ :/images/arrow-down.png:/images/arrow-down.png
+
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py
index 5802a34afb..9f58a2fa0d 100644
--- a/src/calibre/gui2/ui.py
+++ b/src/calibre/gui2/ui.py
@@ -26,7 +26,7 @@ from calibre.constants import (
from calibre.utils.config import prefs, dynamic
from calibre.utils.ipc.pool import Pool
from calibre.db.legacy import LibraryDatabase
-from calibre.customize.ui import interface_actions, available_store_plugins
+from calibre.customize.ui import interface_actions, available_store_plugins, find_plugin
from calibre.gui2 import (error_dialog, GetMetadata, open_url,
gprefs, max_available_height, config, info_dialog, Dispatcher,
question_dialog, warning_dialog)
@@ -428,6 +428,11 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
self.auto_adder = AutoAdder(gprefs['auto_add_path'], self)
self.save_layout_state()
+ if gprefs['qv_show_on_startup']:
+ qv = find_plugin('Show Quickview')
+ if qv is not None:
+ qv.actual_plugin_.show_quickview()
+
# Collect cycles now
gc.collect()