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:
parent
6b894a076b
commit
52f52724fa
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
10
qt/aqt/browser/layout.py
Normal 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"
|
@ -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>
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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",)),
|
||||
|
Loading…
Reference in New Issue
Block a user