diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py
index 9fde49eb87..bcf7c798f9 100644
--- a/src/calibre/gui2/custom_column_widgets.py
+++ b/src/calibre/gui2/custom_column_widgets.py
@@ -12,7 +12,7 @@ from functools import partial
from PyQt5.Qt import (Qt, QComboBox, QLabel, QSpinBox, QDoubleSpinBox,
QDateTime, QGroupBox, QVBoxLayout, QSizePolicy, QGridLayout, QUrl,
QSpacerItem, QIcon, QCheckBox, QWidget, QHBoxLayout, QLineEdit,
- QMessageBox, QToolButton, QPlainTextEdit)
+ QMessageBox, QToolButton, QPlainTextEdit, QApplication, QStyle)
from calibre.utils.date import qt_to_dt, now, as_local_time, as_utc, internal_iso_format_string
from calibre.gui2.complete2 import EditWithComplete
@@ -756,6 +756,9 @@ def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, pa
do_elision = tweaks['metadata_edit_elide_labels']
elide_pos = tweaks['metadata_edit_elision_point']
elide_pos = elide_pos if elide_pos in {'left', 'middle', 'right'} else 'right'
+ # make room on the right side for the scrollbar
+ sb_width = QApplication.instance().style().pixelMetric(QStyle.PM_ScrollBarExtent)
+ layout.setContentsMargins(0, 0, sb_width, 0)
for key in cols:
if not fm[key]['is_editable']:
continue # The job spy plugin can change is_editable
@@ -820,7 +823,6 @@ def populate_metadata_page(layout, db, book_id, bulk=False, two_column=False, pa
l.addWidget(w.widgets[c+1], c, 1)
else:
l.addWidget(w.widgets[0], 0, 0, 1, 2)
- l.addItem(QSpacerItem(0, 0, vPolicy=QSizePolicy.Expanding), c, 0, 1, 1)
max_row = max(max_row, row)
if row >= turnover_point:
column = 1
diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py
index 0e56510a42..c6b8ab7641 100644
--- a/src/calibre/gui2/dialogs/tag_list_editor.py
+++ b/src/calibre/gui2/dialogs/tag_list_editor.py
@@ -296,19 +296,20 @@ class TagListEditor(QDialog, Ui_TagListEditor):
ca.triggered.connect(partial(self.search_for_books, item))
if disable_copy_paste_search:
ca.setEnabled(False)
- m.addSeparator()
- case_menu = QMenu(_('Change case'))
- action_upper_case = case_menu.addAction(_('Upper case'))
- action_lower_case = case_menu.addAction(_('Lower case'))
- action_swap_case = case_menu.addAction(_('Swap case'))
- action_title_case = case_menu.addAction(_('Title case'))
- action_capitalize = case_menu.addAction(_('Capitalize'))
- action_upper_case.triggered.connect(partial(self.do_case, icu_upper))
- action_lower_case.triggered.connect(partial(self.do_case, icu_lower))
- action_swap_case.triggered.connect(partial(self.do_case, self.swap_case))
- action_title_case.triggered.connect(partial(self.do_case, titlecase))
- action_capitalize.triggered.connect(partial(self.do_case, capitalize))
- m.addMenu(case_menu)
+ if self.table.state() == self.table.EditingState:
+ m.addSeparator()
+ case_menu = QMenu(_('Change case'))
+ action_upper_case = case_menu.addAction(_('Upper case'))
+ action_lower_case = case_menu.addAction(_('Lower case'))
+ action_swap_case = case_menu.addAction(_('Swap case'))
+ action_title_case = case_menu.addAction(_('Title case'))
+ action_capitalize = case_menu.addAction(_('Capitalize'))
+ action_upper_case.triggered.connect(partial(self.do_case, icu_upper))
+ action_lower_case.triggered.connect(partial(self.do_case, icu_lower))
+ action_swap_case.triggered.connect(partial(self.do_case, self.swap_case))
+ action_title_case.triggered.connect(partial(self.do_case, titlecase))
+ action_capitalize.triggered.connect(partial(self.do_case, capitalize))
+ m.addMenu(case_menu)
m.exec_(self.table.mapToGlobal(point))
def search_for_books(self, item):
diff --git a/src/calibre/gui2/preferences/coloring.py b/src/calibre/gui2/preferences/coloring.py
index fed09e0b63..ad91f916b8 100644
--- a/src/calibre/gui2/preferences/coloring.py
+++ b/src/calibre/gui2/preferences/coloring.py
@@ -873,8 +873,9 @@ class RulesModel(QAbstractListModel): # {{{
_('
The condition using column %(col)s is invalid')
% dict(col=c))
return (
- _('If the %(col)s column %(action)s value: %(val)s') % dict(
- col=c, action=action_name, val=prepare_string_for_xml(v)))
+ _('If the %(col)s column %(action)s %(val_label)s%(val)s') % dict(
+ col=c, action=action_name, val=prepare_string_for_xml(v),
+ val_label=_('value: ') if v else ''))
# }}}
diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui
index e11a68cb81..8b52d5bda3 100644
--- a/src/calibre/gui2/preferences/look_feel.ui
+++ b/src/calibre/gui2/preferences/look_feel.ui
@@ -1122,6 +1122,17 @@ using the mouse.</p>
+ -
+
+
+ margin-left: 1.5em
+
+
+ <p>If you check this box then you probably want to define the
+keyboard shortcut 'Tag browser / Give the tag browser keyboard focus'</p>
+
+
+
diff --git a/src/calibre/gui2/tag_browser/ui.py b/src/calibre/gui2/tag_browser/ui.py
index a8c4127f4d..b07af28a02 100644
--- a/src/calibre/gui2/tag_browser/ui.py
+++ b/src/calibre/gui2/tag_browser/ui.py
@@ -688,22 +688,27 @@ class TagBrowserWidget(QFrame): # {{{
def give_tb_focus(self, *args):
if gprefs['tag_browser_allow_keyboard_focus']:
tb = self.tags_view
- idx = tb.currentIndex()
- if not idx.isValid:
- idx = tb.model().createIndex(0, 0)
- tb.setCurrentIndex(idx)
- tb.setFocus(Qt.OtherFocusReason)
+ if tb.hasFocus():
+ self._parent.shift_esc()
+ elif self._parent.current_view() == self._parent.library_view:
+ tb.setFocus()
+ idx = tb.currentIndex()
+ if not idx.isValid():
+ idx = tb.model().createIndex(0, 0)
+ tb.setCurrentIndex(idx)
def set_pane_is_visible(self, to_what):
self.tags_view.set_pane_is_visible(to_what)
+ if not to_what:
+ self._parent.shift_esc()
- def find_text_changed(self, str):
+ def find_text_changed(self, str_):
self.current_find_position = None
def set_focus_to_find_box(self):
self.tb_bar.set_focus_to_find_box()
- def do_find(self, str=None):
+ def do_find(self, str_=None):
self.current_find_position = None
self.find()
diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py
index 2639b8c01e..30e74ef600 100644
--- a/src/calibre/gui2/tag_browser/view.py
+++ b/src/calibre/gui2/tag_browser/view.py
@@ -12,7 +12,7 @@ from functools import partial
from PyQt5.Qt import (
QStyledItemDelegate, Qt, QTreeView, pyqtSignal, QSize, QIcon, QApplication,
QMenu, QPoint, QToolTip, QCursor, QDrag, QRect, QModelIndex,
- QLinearGradient, QPalette, QColor, QPen, QBrush, QFont
+ QLinearGradient, QPalette, QColor, QPen, QBrush, QFont, QTimer
)
from calibre import sanitize_file_name
@@ -22,7 +22,8 @@ from calibre.gui2.complete2 import EditWithComplete
from calibre.gui2.tag_browser.model import (TagTreeItem, TAG_SEARCH_STATES,
TagsModel, DRAG_IMAGE_ROLE, COUNT_ROLE)
from calibre.gui2.widgets import EnLineEdit
-from calibre.gui2 import config, gprefs, choose_files, pixmap_to_data, rating_font, empty_index
+from calibre.gui2 import (config, gprefs, choose_files, pixmap_to_data,
+ rating_font, empty_index)
from calibre.utils.icu import sort_key
from calibre.utils.serialize import json_loads
from polyglot.builtins import unicode_type, range, zip
@@ -198,6 +199,10 @@ class TagsView(QTreeView): # {{{
self.set_look_and_feel()
if not gprefs['tag_browser_allow_keyboard_focus']:
self.setFocusPolicy(Qt.NoFocus)
+ else:
+ # This is necessary because the context menu sets things up. F2
+ # and company don't.
+ self.setEditTriggers(QTreeView.NoEditTriggers)
QApplication.instance().palette_changed.connect(self.set_style_sheet, type=Qt.QueuedConnection)
def set_style_sheet(self):
@@ -294,10 +299,14 @@ class TagsView(QTreeView): # {{{
self.collapsed.connect(self.collapse_node_and_children)
def keyPressEvent(self, event):
- if event.key() == Qt.Key_Return and self.state() != self.EditingState:
- # I don't see how it can ever not be valid, but ...
- if self.currentIndex().isValid():
- self.toggle_current_index()
+ if (gprefs['tag_browser_allow_keyboard_focus'] and event.key() == Qt.Key_Return
+ and self.state() != self.EditingState
+ # I don't see how current_index can ever be not valid, but ...
+ and self.currentIndex().isValid()):
+ self.toggle_current_index()
+ # Reset the focus to the TB. Use the singleshot in case
+ # some of of searching is done using queued signals.
+ QTimer.singleShot(0, lambda: self.setFocus())
return
QTreeView.keyPressEvent(self, event)