diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 25daf9862c..6324320005 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -152,6 +152,7 @@ def create_defs(): defs['tag_browser_old_look'] = False defs['tag_browser_hide_empty_categories'] = False defs['tag_browser_always_autocollapse'] = False + defs['tag_browser_allow_keyboard_focus'] = False defs['book_list_tooltips'] = True defs['show_layout_buttons'] = False defs['bd_show_cover'] = True diff --git a/src/calibre/gui2/preferences/look_feel.py b/src/calibre/gui2/preferences/look_feel.py index 5445ca38f1..e798946eb6 100644 --- a/src/calibre/gui2/preferences/look_feel.py +++ b/src/calibre/gui2/preferences/look_feel.py @@ -414,6 +414,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): r('tag_browser_hide_empty_categories', gprefs) r('tag_browser_always_autocollapse', gprefs) r('tag_browser_show_tooltips', gprefs) + r('tag_browser_allow_keyboard_focus', gprefs, restart_required=True) r('bd_show_cover', gprefs) r('bd_overlay_cover_size', gprefs) r('cover_grid_width', gprefs) diff --git a/src/calibre/gui2/preferences/look_feel.ui b/src/calibre/gui2/preferences/look_feel.ui index 37e4c58606..e11a68cb81 100644 --- a/src/calibre/gui2/preferences/look_feel.ui +++ b/src/calibre/gui2/preferences/look_feel.ui @@ -893,6 +893,27 @@ A value of zero means calculate automatically. QFormLayout::ExpandingFieldsGrow + + + + Choose how Tag browser subcategories are displayed when +there are more items than the limit. Select by first +letter to see an A, B, C list. Choose partitioned to +have a list of fixed-sized groups. Set to disabled +if you never want subcategories + + + + + + + &Category partitioning method: + + + opt_tags_browser_partition_method + + + @@ -939,6 +960,38 @@ not set to first letter, this value is ignored. Set to zero to disable. + + + + Spacing between &items: + + + opt_tag_browser_item_padding + + + + + + + The spacing between consecutive items in the Tag browser. In units of (ex) which is the approximate height of the letter 'x' in the currently used font. + + + ex + + + 1 + + + -1.000000000000000 + + + 2.000000000000000 + + + 0.100000000000000 + + + @@ -994,6 +1047,35 @@ then the tags will be displayed each on their own line. + + + + Show &tooltips + + + + + + + Show &average ratings + + + true + + + + + + + Show counts for items in the Tag browser. Such as the number of books +by each author, the number of authors, etc. If you turn it off, you can still +see the counts by hovering your mouse over any item. + + + Show &counts + + + @@ -1026,85 +1108,17 @@ then the tags will be displayed each on their own line. - - + + + + Allow the Tag browser to have keyboard focus (needs restart) + - Choose how Tag browser subcategories are displayed when -there are more items than the limit. Select by first -letter to see an A, B, C list. Choose partitioned to -have a list of fixed-sized groups. Set to disabled -if you never want subcategories - - - - - - - &Category partitioning method: - - - opt_tags_browser_partition_method - - - - - - - Show &average ratings - - - true - - - - - - - Show counts for items in the Tag browser. Such as the number of books -by each author, the number of authors, etc. If you turn it off, you can still -see the counts by hovering your mouse over any item. - - - Show &counts - - - - - - - Spacing between &items: - - - opt_tag_browser_item_padding - - - - - - - The spacing between consecutive items in the Tag browser. In units of (ex) which is the approximate height of the letter 'x' in the currently used font. - - - ex - - - 1 - - - -1.000000000000000 - - - 2.000000000000000 - - - 0.100000000000000 - - - - - - - Show &tooltips + <p>When checked, the Tag browser can get keyboard focus, allowing +use of the keyboard to navigate the tree using the arrow keys. The RETURN key simulates +a click on the selected item. The keyboard shortcut 'Tag browser / +Give the Tag browser keyboard focus' changes the keyboard focus without +using the mouse.</p> diff --git a/src/calibre/gui2/tag_browser/ui.py b/src/calibre/gui2/tag_browser/ui.py index ef1a95b768..c182b13626 100644 --- a/src/calibre/gui2/tag_browser/ui.py +++ b/src/calibre/gui2/tag_browser/ui.py @@ -661,6 +661,13 @@ class TagBrowserWidget(QFrame): # {{{ action=ac, group=_('Tag browser')) ac.triggered.connect(self.toggle_item) + ac = QAction(parent) + parent.addAction(ac) + parent.keyboard.register_shortcut('tag browser set focus', + _("Give the Tag browser keyboard focus"), default_keys=(), + action=ac, group=_('Tag browser')) + ac.triggered.connect(self.give_tb_focus) + # self.leak_test_timer = QTimer(self) # self.leak_test_timer.timeout.connect(self.test_for_leak) # self.leak_test_timer.start(5000) @@ -671,6 +678,15 @@ class TagBrowserWidget(QFrame): # {{{ def toggle_item(self): self.tags_view.toggle_current_index() + 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) + def set_pane_is_visible(self, to_what): self.tags_view.set_pane_is_visible(to_what) diff --git a/src/calibre/gui2/tag_browser/view.py b/src/calibre/gui2/tag_browser/view.py index 7cb0fdc36b..738e8cf925 100644 --- a/src/calibre/gui2/tag_browser/view.py +++ b/src/calibre/gui2/tag_browser/view.py @@ -195,9 +195,8 @@ class TagsView(QTreeView): # {{{ type=Qt.QueuedConnection) self._model.drag_drop_finished.connect(self.drag_drop_finished) self.set_look_and_feel() - # Allowing keyboard focus looks bad in the Qt Fusion style and is useless - # anyway since the enter/spacebar keys do nothing - self.setFocusPolicy(Qt.NoFocus) + if not gprefs['tag_browser_allow_keyboard_focus']: + self.setFocusPolicy(Qt.NoFocus) QApplication.instance().palette_changed.connect(self.set_style_sheet, type=Qt.QueuedConnection) def set_style_sheet(self): @@ -291,6 +290,15 @@ class TagsView(QTreeView): # {{{ self.refresh_signal_processed = True db.add_listener(self.database_changed) self.expanded.connect(self.item_expanded) + self.collapsed.connect(self.collapse_node_and_children) + + def keyPressEvent(self, event): + if event.key() == Qt.Key_Return: + # I don't see how it can ever not be valid, but ... + if self.currentIndex().isValid(): + self.toggle_current_index() + return + QTreeView.keyPressEvent(self, event) def database_changed(self, event, ids): if self.refresh_signal_processed: