mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
macOS: Fix keyboard shortcuts for select all, copy and paste not working in file dialogs. Fixes #1874499 [Select-All Broken in Import Dialogue](https://bugs.launchpad.net/calibre/+bug/1874499)
This commit is contained in:
parent
cdc68da194
commit
268a213659
@ -8,7 +8,7 @@ __docformat__ = 'restructuredtext en'
|
||||
|
||||
from functools import partial
|
||||
from PyQt5.Qt import (
|
||||
Qt, QAction, QMenu, QObject, QToolBar, QToolButton, QSize, pyqtSignal,
|
||||
Qt, QAction, QMenu, QObject, QToolBar, QToolButton, QSize, pyqtSignal, QKeySequence,
|
||||
QTimer, QPropertyAnimation, QEasingCurve, pyqtProperty, QPainter, QWidget)
|
||||
try:
|
||||
from PyQt5 import sip
|
||||
@ -423,12 +423,17 @@ if isosx:
|
||||
|
||||
@property
|
||||
def native_menubar(self):
|
||||
return self.gui.native_menubar
|
||||
mb = self.gui.native_menubar
|
||||
if mb.parent() is None:
|
||||
# Without this the menubar does not update correctly with Qt >=
|
||||
# 5.6. See the last couple of lines in updateMenuBarImmediately
|
||||
# in qcocoamenubar.mm
|
||||
mb.setParent(self.gui)
|
||||
return mb
|
||||
|
||||
def __init__(self, location_manager, parent):
|
||||
QObject.__init__(self, parent)
|
||||
self.gui = parent
|
||||
|
||||
self.location_manager = location_manager
|
||||
self.added_actions = []
|
||||
self.last_actions = []
|
||||
@ -440,14 +445,30 @@ if isosx:
|
||||
self.refresh_timer = t = QTimer(self)
|
||||
t.setInterval(200), t.setSingleShot(True), t.timeout.connect(self.refresh_bar)
|
||||
|
||||
def init_bar(self, actions):
|
||||
def adapt_for_dialog(self, enter):
|
||||
|
||||
def ac(text, key, role=QAction.TextHeuristicRole):
|
||||
ans = QAction(text, self)
|
||||
ans.setMenuRole(role)
|
||||
ans.setShortcut(QKeySequence(key))
|
||||
self.edit_menu.addAction(ans)
|
||||
return ans
|
||||
|
||||
mb = self.native_menubar
|
||||
if mb.parent() is None:
|
||||
# Without this the menubar does not update correctly with Qt >=
|
||||
# 5.6. See the last couple of lines in updateMenuBarImmediately
|
||||
# in qcocoamenubar.mm
|
||||
mb.setParent(self.gui)
|
||||
self.last_actions = actions
|
||||
if enter:
|
||||
self.clear_bar(mb)
|
||||
self.edit_menu = QMenu()
|
||||
self.edit_action = QAction(_('Edit'), self)
|
||||
self.edit_action.setMenu(self.edit_menu)
|
||||
ac(_('Copy'), QKeySequence.Copy),
|
||||
ac(_('Paste'), QKeySequence.Paste),
|
||||
ac(_('Select all'), QKeySequence.SelectAll),
|
||||
mb.addAction(self.edit_action)
|
||||
self.added_actions = [self.edit_action]
|
||||
else:
|
||||
self.refresh_bar()
|
||||
|
||||
def clear_bar(self, mb):
|
||||
for ac in self.added_actions:
|
||||
m = ac.menu()
|
||||
if m is not None:
|
||||
@ -460,6 +481,11 @@ if isosx:
|
||||
ac.deleteLater()
|
||||
self.added_actions = []
|
||||
|
||||
def init_bar(self, actions):
|
||||
mb = self.native_menubar
|
||||
self.last_actions = actions
|
||||
self.clear_bar(mb)
|
||||
|
||||
for what in actions:
|
||||
if what is None:
|
||||
continue
|
||||
@ -585,6 +611,20 @@ else:
|
||||
# }}}
|
||||
|
||||
|
||||
class AdaptMenuBarForDialog(object):
|
||||
|
||||
def __init__(self, menu_bar):
|
||||
self.menu_bar = menu_bar
|
||||
|
||||
def __enter__(self):
|
||||
if isosx and self.menu_bar.is_native_menubar:
|
||||
self.menu_bar.adapt_for_dialog(True)
|
||||
|
||||
def __exit__(self, *a):
|
||||
if isosx and self.menu_bar.is_native_menubar:
|
||||
self.menu_bar.adapt_for_dialog(False)
|
||||
|
||||
|
||||
class BarsManager(QObject):
|
||||
|
||||
def __init__(self, donate_action, location_manager, parent):
|
||||
@ -598,6 +638,7 @@ class BarsManager(QObject):
|
||||
|
||||
self.menu_bar = MenuBar(self.location_manager, self.parent())
|
||||
is_native_menubar = self.menu_bar.is_native_menubar
|
||||
self.adapt_menu_bar_for_dialog = AdaptMenuBarForDialog(self.menu_bar)
|
||||
self.menubar_fallback = native_menubar_defaults['action-layout-menubar'] if is_native_menubar else ()
|
||||
self.menubar_device_fallback = native_menubar_defaults['action-layout-menubar-device'] if is_native_menubar else ()
|
||||
|
||||
|
@ -24,6 +24,15 @@ def select_initial_dir(q):
|
||||
return os.path.expanduser(u'~')
|
||||
|
||||
|
||||
class Dummy(object):
|
||||
|
||||
def __enter__(self):
|
||||
pass
|
||||
|
||||
def __exit__(self, *a):
|
||||
pass
|
||||
|
||||
|
||||
class FileDialog(QObject):
|
||||
|
||||
def __init__(self, title=_('Choose Files'),
|
||||
@ -38,6 +47,9 @@ class FileDialog(QObject):
|
||||
combine_file_and_saved_dir=False
|
||||
):
|
||||
from calibre.gui2 import dynamic, sanitize_env_vars
|
||||
from calibre.gui2.ui import get_gui
|
||||
gui = get_gui()
|
||||
adapt_menubar = gui.bars_manager.adapt_menu_bar_for_dialog if gui is not None else Dummy()
|
||||
QObject.__init__(self)
|
||||
ftext = ''
|
||||
if filters:
|
||||
@ -82,18 +94,21 @@ class FileDialog(QObject):
|
||||
if not use_native_dialog:
|
||||
opts |= QFileDialog.DontUseNativeDialog
|
||||
if mode == QFileDialog.AnyFile:
|
||||
f = QFileDialog.getSaveFileName(parent, title,
|
||||
initial_dir, ftext, "", opts)
|
||||
with adapt_menubar:
|
||||
f = QFileDialog.getSaveFileName(parent, title,
|
||||
initial_dir, ftext, "", opts)
|
||||
if f and f[0]:
|
||||
self.selected_files.append(f[0])
|
||||
elif mode == QFileDialog.ExistingFile:
|
||||
f = QFileDialog.getOpenFileName(parent, title,
|
||||
initial_dir, ftext, "", opts)
|
||||
with adapt_menubar:
|
||||
f = QFileDialog.getOpenFileName(parent, title,
|
||||
initial_dir, ftext, "", opts)
|
||||
if f and f[0] and os.path.exists(f[0]):
|
||||
self.selected_files.append(f[0])
|
||||
elif mode == QFileDialog.ExistingFiles:
|
||||
fs = QFileDialog.getOpenFileNames(parent, title, initial_dir,
|
||||
ftext, "", opts)
|
||||
with adapt_menubar:
|
||||
fs = QFileDialog.getOpenFileNames(parent, title, initial_dir,
|
||||
ftext, "", opts)
|
||||
if fs and fs[0]:
|
||||
for f in fs[0]:
|
||||
f = unicode_type(f)
|
||||
@ -108,7 +123,8 @@ class FileDialog(QObject):
|
||||
else:
|
||||
if mode == QFileDialog.Directory:
|
||||
opts |= QFileDialog.ShowDirsOnly
|
||||
f = unicode_type(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts))
|
||||
with adapt_menubar:
|
||||
f = unicode_type(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts))
|
||||
if os.path.exists(f):
|
||||
self.selected_files.append(f)
|
||||
if self.selected_files:
|
||||
|
Loading…
x
Reference in New Issue
Block a user