mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
Quickview panel: Add actions to the context menu to search for book in library, open in viewer, etc. Fixes #1891765 [Enhancement Request: Add "Edit Metadata" and "view book details" to quickview right-click menu.](https://bugs.launchpad.net/calibre/+bug/1891765)
Merge branch 'master' of https://github.com/cbhaley/calibre into master
This commit is contained in:
commit
12e64d6e8b
@ -104,8 +104,6 @@ class ShowQuickviewAction(InterfaceAction):
|
||||
default_keys=('Shift+S',), action=self.search_action,
|
||||
group=self.action_spec[0])
|
||||
self.search_action.triggered.connect(self.search_quickview)
|
||||
self.search_action.changed.connect(self.set_search_shortcut_tooltip)
|
||||
self.menuless_qaction.changed.connect(self.set_search_shortcut_tooltip)
|
||||
|
||||
self.qv_button = QuickviewButton(self.gui, self)
|
||||
|
||||
@ -139,15 +137,9 @@ class ShowQuickviewAction(InterfaceAction):
|
||||
self.current_instance = Quickview(self.gui, index, self.qaction.shortcut())
|
||||
|
||||
self.current_instance.reopen_after_dock_change.connect(self.open_quickview)
|
||||
self.set_search_shortcut_tooltip()
|
||||
self.current_instance.show()
|
||||
self.current_instance.quickview_closed.connect(self.qv_button.set_state_to_show)
|
||||
|
||||
def set_search_shortcut_tooltip(self):
|
||||
if self.current_instance and not self.current_instance.is_closed:
|
||||
self.current_instance.addAction(self.focus_bl_action)
|
||||
self.current_instance.set_search_shortcut_tooltip(self.search_action.shortcut().toString())
|
||||
|
||||
def open_quickview(self):
|
||||
'''
|
||||
QV moved from/to dock. Close and reopen the pane/window.
|
||||
|
@ -173,6 +173,7 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
self.current_key = None # current lookup key in books list
|
||||
self.last_search = None
|
||||
self.no_valid_items = False
|
||||
self.follow_library_view = True
|
||||
|
||||
self.apply_vls.setCheckState(Qt.Checked if gprefs['qv_respects_vls']
|
||||
else Qt.Unchecked)
|
||||
@ -184,6 +185,8 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
self.items.currentTextChanged.connect(self.item_selected)
|
||||
self.items.setProperty('highlight_current_item', 150)
|
||||
self.items.itemDoubleClicked.connect(self.item_doubleclicked)
|
||||
self.items.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.items.customContextMenuRequested.connect(self.show_item_context_menu)
|
||||
|
||||
focus_filter = WidgetFocusFilter(self.items)
|
||||
focus_filter.focus_entered_signal.connect(self.focus_entered)
|
||||
@ -202,7 +205,7 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
self.refresh_button.clicked.connect(self.refill)
|
||||
|
||||
self.tab_order_widgets = [self.items, self.books_table, self.lock_qv,
|
||||
self.dock_button, self.search_button, self.refresh_button,
|
||||
self.dock_button, self.refresh_button,
|
||||
self.close_button]
|
||||
for idx,widget in enumerate(self.tab_order_widgets):
|
||||
widget.installEventFilter(WidgetTabFilter(widget, idx, self.tab_pressed_signal))
|
||||
@ -236,20 +239,16 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
self.view.clicked.connect(self.slave)
|
||||
self.view.selectionModel().currentColumnChanged.connect(self.column_slave)
|
||||
QCoreApplication.instance().aboutToQuit.connect(self.save_state)
|
||||
self.search_button.clicked.connect(self.do_search)
|
||||
self.view.model().new_bookdisplay_data.connect(self.book_was_changed)
|
||||
|
||||
self.close_button.setDefault(False)
|
||||
self.close_button_tooltip = _('The Quickview shortcut ({0}) shows/hides the Quickview panel')
|
||||
self.search_button_tooltip = _('Search in the library view for the currently highlighted selection')
|
||||
self.search_button.setToolTip(self.search_button_tooltip)
|
||||
if self.is_pane:
|
||||
self.dock_button.setText(_('Undock'))
|
||||
self.dock_button.setToolTip(_('Pop up the quickview panel into its own floating window'))
|
||||
self.dock_button.setIcon(QIcon(I('arrow-up.png')))
|
||||
# Remove the ampersands from the buttons because shortcuts exist.
|
||||
self.lock_qv.setText(_('Lock Quickview contents'))
|
||||
self.search_button.setText(_('Search'))
|
||||
self.refresh_button.setText(_('Refresh'))
|
||||
self.gui.quickview_splitter.add_quickview_dialog(self)
|
||||
self.close_button.setVisible(False)
|
||||
@ -268,6 +267,10 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
|
||||
self.view_icon = QIcon(I('view.png'))
|
||||
self.view_plugin = self.gui.iactions['View']
|
||||
self.edit_metadata_icon = QIcon(I('edit_input.png'))
|
||||
self.quickview_icon = QIcon(I('quickview.png'))
|
||||
self.select_book_icon = QIcon(I('library.png'))
|
||||
self.search_icon = QIcon(I('search.png'))
|
||||
self.books_table.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.books_table.customContextMenuRequested.connect(self.show_context_menu)
|
||||
|
||||
@ -288,14 +291,40 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
tb.item_search.lineEdit().setText(self.current_key + ':=' + item.text())
|
||||
tb.do_find()
|
||||
|
||||
def show_item_context_menu(self, point):
|
||||
item = self.items.currentItem()
|
||||
self.context_menu = QMenu(self)
|
||||
self.context_menu.addAction(self.search_icon, _('Search for item in tag browser'),
|
||||
partial(self.item_doubleclicked, item))
|
||||
self.context_menu.addAction(self.search_icon, _('Search for item in library'),
|
||||
partial(self.do_search, follow_library_view=False))
|
||||
self.context_menu.popup(self.items.mapToGlobal(point))
|
||||
self.context_menu = QMenu(self)
|
||||
|
||||
def show_context_menu(self, point):
|
||||
index = self.books_table.indexAt(point)
|
||||
row = index.row()
|
||||
column = index.column()
|
||||
item = self.books_table.item(index.row(), 0)
|
||||
if item is None:
|
||||
return False
|
||||
book_id = int(item.data(Qt.UserRole))
|
||||
self.context_menu = QMenu(self)
|
||||
self.context_menu.addAction(self.view_icon, _('View'),
|
||||
book_displayed = self.book_displayed_in_library_view(book_id)
|
||||
m = self.context_menu = QMenu(self)
|
||||
a = m.addAction(self.select_book_icon, _('Select book in library'),
|
||||
partial(self.select_book, book_id))
|
||||
a.setEnabled(book_displayed)
|
||||
m.addAction(self.search_icon, _('Search for item in library'),
|
||||
partial(self.do_search, follow_library_view=False))
|
||||
a = m.addAction(self.edit_metadata_icon, _('Edit book metadata'),
|
||||
partial(self.edit_metadata, book_id, follow_library_view=False))
|
||||
a.setEnabled(book_displayed)
|
||||
a = m.addAction(self.quickview_icon, _('Quickview this cell'),
|
||||
partial(self.quickview_item, row, column))
|
||||
a.setEnabled(self.is_category(self.column_order[column]) and
|
||||
book_displayed and not self.lock_qv.isChecked())
|
||||
m.addSeparator()
|
||||
m.addAction(self.view_icon, _('Open book in viewer'),
|
||||
partial(self.view_plugin._view_calibre_books, [book_id]))
|
||||
self.context_menu.popup(self.books_table.mapToGlobal(point))
|
||||
return True
|
||||
@ -324,16 +353,8 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
self._refresh(self.current_book_id, self.current_key)
|
||||
|
||||
def set_search_text(self, txt):
|
||||
if txt:
|
||||
self.search_button.setEnabled(True)
|
||||
else:
|
||||
self.search_button.setEnabled(False)
|
||||
self.last_search = txt
|
||||
|
||||
def set_search_shortcut_tooltip(self, search_sc):
|
||||
if self.is_pane:
|
||||
self.search_button.setToolTip(self.search_button_tooltip + ' (' + search_sc + ')')
|
||||
|
||||
def focus_entered(self, obj):
|
||||
if obj == self.books_table:
|
||||
self.books_table_set_search_string(self.books_table.currentRow(),
|
||||
@ -400,11 +421,15 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
self.reopen_after_dock_change.emit()
|
||||
|
||||
# search button
|
||||
def do_search(self):
|
||||
def do_search(self, follow_library_view=True):
|
||||
if self.no_valid_items:
|
||||
return
|
||||
if self.last_search is not None:
|
||||
try:
|
||||
self.follow_library_view = follow_library_view
|
||||
self.gui.search.set_search_string(self.last_search)
|
||||
finally:
|
||||
self.follow_library_view = True
|
||||
|
||||
def book_was_changed(self, mi):
|
||||
'''
|
||||
@ -412,7 +437,7 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
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:
|
||||
if self.is_closed or self.current_column is None or not self.follow_library_view:
|
||||
return
|
||||
# There is an ordering problem when libraries are changed. The library
|
||||
# view is changed, triggering a book_was_changed signal. Unfortunately
|
||||
@ -457,13 +482,16 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
traceback.print_exc()
|
||||
self.indicate_no_items()
|
||||
|
||||
def is_category(self, key):
|
||||
return key is not None and self.fm[key]['is_category']
|
||||
|
||||
def _refresh(self, book_id, key):
|
||||
'''
|
||||
Actually fill in the left-hand panel from the information in the
|
||||
selected column of the selected book
|
||||
'''
|
||||
# Only show items for categories
|
||||
if key is None or not self.fm[key]['is_category']:
|
||||
if not self.is_category(key):
|
||||
if self.current_key is None:
|
||||
self.indicate_no_items()
|
||||
return
|
||||
@ -643,28 +671,62 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
def return_pressed(self):
|
||||
row = self.books_table.currentRow()
|
||||
if gprefs['qv_retkey_changes_column']:
|
||||
self.select_book(row, self.books_table.currentColumn())
|
||||
self.select_book_and_qv(row, self.books_table.currentColumn())
|
||||
else:
|
||||
self.select_book(row, self.key_to_table_widget_column(self.current_key))
|
||||
self.select_book_and_qv(row, self.key_to_table_widget_column(self.current_key))
|
||||
|
||||
def book_not_in_view_error(self):
|
||||
from calibre.gui2 import error_dialog
|
||||
error_dialog(self, _('Quickview: Book not in library view'),
|
||||
_('The book you selected is not currently displayed in '
|
||||
'the library view, perhaps because of a search or a '
|
||||
'virtual library, so Quickview cannot select it.'),
|
||||
show=True,
|
||||
show_copy_button=False)
|
||||
|
||||
def book_displayed_in_library_view(self, book_id):
|
||||
try:
|
||||
self.db.data.index(book_id)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def quickview_item(self, row, column):
|
||||
self.select_book_and_qv(row, column)
|
||||
|
||||
def book_doubleclicked(self, row, column):
|
||||
if self.no_valid_items:
|
||||
return
|
||||
try:
|
||||
if gprefs['qv_dclick_changes_column']:
|
||||
self.select_book(row, column)
|
||||
self.quickview_item(row, column)
|
||||
else:
|
||||
self.select_book(row, self.key_to_table_widget_column(self.current_key))
|
||||
self.quickview_item(row, self.key_to_table_widget_column(self.current_key))
|
||||
except:
|
||||
from calibre.gui2 import error_dialog
|
||||
error_dialog(self, _('Quickview: Book not in library view'),
|
||||
_('The book you selected is not currently displayed in '
|
||||
'the library view, perhaps because of a search, so '
|
||||
'Quickview cannot select it.'),
|
||||
show=True,
|
||||
show_copy_button=False)
|
||||
self.book_not_in_view_error()
|
||||
|
||||
def select_book(self, row, column):
|
||||
def edit_metadata(self, book_id, follow_library_view=True):
|
||||
try:
|
||||
self.follow_library_view = follow_library_view
|
||||
self.view.select_rows([book_id])
|
||||
em = find_plugin('Edit Metadata')
|
||||
if em and em.actual_plugin_:
|
||||
em.actual_plugin_.edit_metadata(None)
|
||||
finally:
|
||||
self.follow_library_view = True
|
||||
|
||||
def select_book(self, book_id):
|
||||
'''
|
||||
Select a book in the library view without changing the QV lists
|
||||
'''
|
||||
try:
|
||||
self.follow_library_view = False
|
||||
self.view.select_cell(self.db.data.id_to_index(book_id),
|
||||
self.current_column)
|
||||
finally:
|
||||
self.follow_library_view = True
|
||||
|
||||
def select_book_and_qv(self, row, column):
|
||||
'''
|
||||
row and column both refer the qv table. In particular, column is not
|
||||
the logical column in the book list.
|
||||
@ -673,13 +735,13 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
if item is None:
|
||||
return
|
||||
book_id = int(self.books_table.item(row, column).data(Qt.UserRole))
|
||||
if not self.book_displayed_in_library_view(book_id):
|
||||
self.book_not_in_view_error()
|
||||
return
|
||||
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 and em.actual_plugin_:
|
||||
em.actual_plugin_.edit_metadata(None)
|
||||
self.edit_metadata(book_id)
|
||||
else:
|
||||
self.view.select_cell(self.db.data.id_to_index(book_id),
|
||||
self.view.column_map.index(key))
|
||||
@ -692,14 +754,14 @@ class Quickview(QDialog, Ui_Quickview):
|
||||
'''
|
||||
called when the column is changed on the booklist
|
||||
'''
|
||||
if gprefs['qv_follows_column']:
|
||||
if self.follow_library_view and gprefs['qv_follows_column']:
|
||||
self.slave(current)
|
||||
|
||||
def slave(self, current):
|
||||
'''
|
||||
called when a book is clicked on the library view
|
||||
'''
|
||||
if self.is_closed:
|
||||
if self.is_closed or not self.follow_library_view:
|
||||
return
|
||||
self.refresh(current)
|
||||
self.view.activateWindow()
|
||||
|
@ -86,17 +86,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="lock_qv">
|
||||
<property name="text">
|
||||
<string>&Lock Quickview contents</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><p>Select to prevent Quickview from changing content when the
|
||||
selection on the library view is changed</p></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
@ -111,54 +100,16 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="dock_button">
|
||||
<widget class="QCheckBox" name="lock_qv">
|
||||
<property name="text">
|
||||
<string>&Dock</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="search_button">
|
||||
<property name="text">
|
||||
<string>&Search</string>
|
||||
<string>&Lock Quickview contents</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Search in the library view for the currently highlighted selection</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
<string><p>Select to prevent Quickview from changing content when the
|
||||
selection on the library view is changed</p></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="refresh_button">
|
||||
<property name="text">
|
||||
@ -185,6 +136,29 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="dock_button">
|
||||
<property name="text">
|
||||
<string>&Dock</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="close_button">
|
||||
<property name="text">
|
||||
|
Loading…
x
Reference in New Issue
Block a user