Add orientation toggle to browser view menu (#2074)

* Use horizontal orientation on browser splitter by default

* Add View menu action to toggle browser orientation

* Add shortcut for toggleOrientation action

based on the most popular add-on.

* Try to fix typing issue

* Make orientation respond to aspect ratio

aspect ratio < 1 means vertical orientation, >= 1 horizontal

* Implement three-way switch for browser orientation

* Fix typing

* Add separator before QWidgetAction

* Use submenu instead of widget and adjust enum

* Add accelerators; move non-accelerator strings into separate .ftl (dae)

* Move BrowserLayout to its own file (dae)
This commit is contained in:
Matthias Metelka 2022-09-20 04:56:59 +02:00 committed by GitHub
parent 6b894a076b
commit 52f52724fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 134 additions and 3 deletions

View File

@ -33,6 +33,10 @@ qt-accel-set-due-date = Set &Due Date...
qt-accel-forget = &Forget
qt-accel-view = &View
qt-accel-full-screen = Toggle &Full Screen
qt-accel-layout = &Layout
qt-accel-layout-auto = &Auto
qt-accel-layout-vertical = &Vertical
qt-accel-layout-horizontal = &Horizontal
qt-accel-zoom-in = Zoom &In
qt-accel-zoom-out = Zoom &Out
qt-accel-reset-zoom = &Reset Zoom

View File

@ -69,6 +69,9 @@ qt-misc-second =
[one] { $count } second
*[other] { $count } seconds
}
qt-misc-layout-auto-enabled = Responsive layout enabled
qt-misc-layout-vertical-enabled = Vertical layout enabled
qt-misc-layout-horizontal-enabled = Horizontal layout enabled
## deprecated- these strings will be removed in the future, and do not need
## to be translated

View File

@ -4,6 +4,7 @@
from __future__ import annotations
import json
import math
import re
from typing import Callable, Sequence
@ -63,12 +64,14 @@ from aqt.utils import (
saveState,
showWarning,
skip_if_selection_is_empty,
tooltip,
tr,
)
from ..changenotetype import change_notetype_dialog
from .card_info import BrowserCardInfo
from .find_and_replace import FindAndReplaceDialog
from .layout import BrowserLayout
from .previewer import BrowserPreviewer as PreviewDialog
from .previewer import Previewer
from .sidebar import SidebarTreeView
@ -136,6 +139,9 @@ class Browser(QMainWindow):
self.setupMenus()
self.setupHooks()
self.setupEditor()
# responsive layout
self.aspect_ratio = self.width() / self.height()
self.set_layout(self.mw.pm.browser_layout(), True)
# disable undo/redo
self.on_undo_state_change(mw.undo_actions_info())
# legacy alias
@ -179,6 +185,52 @@ class Browser(QMainWindow):
self.table.redraw_cells()
self.sidebar.refresh_if_needed()
def set_layout(self, mode: BrowserLayout, init: bool = False) -> None:
self.mw.pm.set_browser_layout(mode)
if mode == BrowserLayout.AUTO:
self.auto_layout = True
self.maybe_update_layout(self.aspect_ratio, True)
self.form.actionLayoutAuto.setChecked(True)
self.form.actionLayoutVertical.setChecked(False)
self.form.actionLayoutHorizontal.setChecked(False)
if not init:
tooltip(tr.qt_misc_layout_auto_enabled())
else:
self.auto_layout = False
self.form.actionLayoutAuto.setChecked(False)
if mode == BrowserLayout.VERTICAL:
self.form.splitter.setOrientation(Qt.Orientation.Vertical)
self.form.actionLayoutVertical.setChecked(True)
self.form.actionLayoutHorizontal.setChecked(False)
if not init:
tooltip(tr.qt_misc_layout_vertical_enabled())
elif mode == BrowserLayout.HORIZONTAL:
self.form.splitter.setOrientation(Qt.Orientation.Horizontal)
self.form.actionLayoutHorizontal.setChecked(True)
self.form.actionLayoutVertical.setChecked(False)
if not init:
tooltip(tr.qt_misc_layout_horizontal_enabled())
def maybe_update_layout(self, aspect_ratio: float, force: bool = False) -> None:
if force or math.floor(aspect_ratio) != math.floor(self.aspect_ratio):
if aspect_ratio < 1:
self.form.splitter.setOrientation(Qt.Orientation.Vertical)
else:
self.form.splitter.setOrientation(Qt.Orientation.Horizontal)
def resizeEvent(self, event: QResizeEvent) -> None:
aspect_ratio = self.width() / self.height()
if self.auto_layout:
self.maybe_update_layout(aspect_ratio)
self.aspect_ratio = aspect_ratio
QMainWindow.resizeEvent(self, event)
def setupMenus(self) -> None:
# actions
f = self.form
@ -207,6 +259,18 @@ class Browser(QMainWindow):
f.actionResetZoom.triggered,
lambda: self.editor.web.setZoomFactor(1),
)
qconnect(
self.form.actionLayoutAuto.triggered,
lambda: self.set_layout(BrowserLayout.AUTO),
)
qconnect(
self.form.actionLayoutVertical.triggered,
lambda: self.set_layout(BrowserLayout.VERTICAL),
)
qconnect(
self.form.actionLayoutHorizontal.triggered,
lambda: self.set_layout(BrowserLayout.HORIZONTAL),
)
# notes
qconnect(f.actionAdd.triggered, self.mw.onAddCard)

10
qt/aqt/browser/layout.py Normal file
View File

@ -0,0 +1,10 @@
# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
from enum import Enum
class BrowserLayout(Enum):
AUTO = "auto"
VERTICAL = "vertical"
HORIZONTAL = "horizontal"

View File

@ -46,7 +46,7 @@
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
@ -302,6 +302,15 @@
<property name="title">
<string>qt_accel_view</string>
</property>
<widget class="QMenu" name="menuLayout">
<property name="title">
<string>qt_accel_layout</string>
</property>
<addaction name="actionLayoutAuto"/>
<addaction name="separator"/>
<addaction name="actionLayoutVertical"/>
<addaction name="actionLayoutHorizontal"/>
</widget>
<addaction name="action_toggle_mode"/>
<addaction name="separator"/>
<addaction name="actionFullScreen"/>
@ -309,6 +318,8 @@
<addaction name="actionZoomIn"/>
<addaction name="actionZoomOut"/>
<addaction name="actionResetZoom"/>
<addaction name="separator"/>
<addaction name="menuLayout"/>
</widget>
<addaction name="menuEdit"/>
<addaction name="menuqt_accel_view"/>
@ -699,6 +710,30 @@
<string notr="true">Ctrl+0</string>
</property>
</action>
<action name="actionLayoutAuto">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>qt_accel_layout_auto</string>
</property>
</action>
<action name="actionLayoutVertical">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>qt_accel_layout_vertical</string>
</property>
</action>
<action name="actionLayoutHorizontal">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>qt_accel_layout_horizontal</string>
</property>
</action>
<action name="actionbrowsing_toggle_showing_cards_notes">
<property name="text">
<string>browsing_toggle_showing_cards_notes</string>

View File

@ -10,7 +10,7 @@ import shutil
import traceback
from enum import Enum
from pathlib import Path
from typing import Any
from typing import TYPE_CHECKING, Any
import anki.lang
import aqt.forms
@ -25,6 +25,10 @@ from aqt.qt import *
from aqt.theme import Theme
from aqt.utils import disable_help_button, send_to_trash, showWarning, tr
if TYPE_CHECKING:
from aqt.browser.layout import BrowserLayout
# Profile handling
##########################################################################
# - Saves in pickles rather than json to easily store Qt window state.
@ -542,6 +546,14 @@ create table if not exists profiles
def set_theme(self, theme: Theme) -> None:
self.meta["theme"] = theme.value
def browser_layout(self) -> BrowserLayout:
from aqt.browser.layout import BrowserLayout
return BrowserLayout(self.meta.get("browser_layout", "auto"))
def set_browser_layout(self, layout: BrowserLayout) -> None:
self.meta["browser_layout"] = layout.value
def legacy_import_export(self) -> bool:
return self.meta.get("legacy_import", False)

View File

@ -270,7 +270,10 @@ _enum_map = (
("QHeaderView", ("ResizeMode",)),
("QLayout", ("SizeConstraint",)),
("QLineEdit", ("EchoMode",)),
("QListView", ("Flow", "LayoutMode", "ResizeMode", "Movement", "ViewMode")),
(
"QListView",
("Flow", "BrowserLayout", "ResizeMode", "Movement", "ViewMode"),
),
("QListWidgetItem", ("ItemType",)),
("QMessageBox", ("StandardButton", "Icon", "ButtonRole")),
("QPlainTextEdit", ("LineWrapMode",)),