mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
macOS: Fix opening multiple books from Finder with the editor only opening one of the books
This commit is contained in:
parent
f524711a3b
commit
28fded9122
@ -1199,6 +1199,8 @@ class Application(QApplication):
|
|||||||
self.headless = headless
|
self.headless = headless
|
||||||
from calibre_extensions import progress_indicator
|
from calibre_extensions import progress_indicator
|
||||||
self.pi = progress_indicator
|
self.pi = progress_indicator
|
||||||
|
self._file_open_paths = []
|
||||||
|
self._file_open_lock = RLock()
|
||||||
QApplication.setOrganizationName('calibre-ebook.com')
|
QApplication.setOrganizationName('calibre-ebook.com')
|
||||||
QApplication.setOrganizationDomain(QApplication.organizationName())
|
QApplication.setOrganizationDomain(QApplication.organizationName())
|
||||||
QApplication.setApplicationVersion(__version__)
|
QApplication.setApplicationVersion(__version__)
|
||||||
@ -1258,8 +1260,6 @@ class Application(QApplication):
|
|||||||
self._translator = None
|
self._translator = None
|
||||||
self.load_translations()
|
self.load_translations()
|
||||||
qt_app = self
|
qt_app = self
|
||||||
self._file_open_paths = []
|
|
||||||
self._file_open_lock = RLock()
|
|
||||||
|
|
||||||
if not ismacos:
|
if not ismacos:
|
||||||
# OS X uses a native color dialog that does not support custom
|
# OS X uses a native color dialog that does not support custom
|
||||||
@ -1375,9 +1375,16 @@ class Application(QApplication):
|
|||||||
def _send_file_open_events(self):
|
def _send_file_open_events(self):
|
||||||
with self._file_open_lock:
|
with self._file_open_lock:
|
||||||
if self._file_open_paths:
|
if self._file_open_paths:
|
||||||
|
if callable(self.file_event_hook):
|
||||||
self.file_event_hook(self._file_open_paths)
|
self.file_event_hook(self._file_open_paths)
|
||||||
self._file_open_paths = []
|
self._file_open_paths = []
|
||||||
|
|
||||||
|
def get_pending_file_open_events(self):
|
||||||
|
with self._file_open_lock:
|
||||||
|
ans = self._file_open_paths
|
||||||
|
self._file_open_paths = []
|
||||||
|
return ans
|
||||||
|
|
||||||
def load_translations(self):
|
def load_translations(self):
|
||||||
if self._translator is not None:
|
if self._translator is not None:
|
||||||
self.removeTranslator(self._translator)
|
self.removeTranslator(self._translator)
|
||||||
@ -1386,7 +1393,7 @@ class Application(QApplication):
|
|||||||
|
|
||||||
def event(self, e):
|
def event(self, e):
|
||||||
etype = e.type()
|
etype = e.type()
|
||||||
if callable(self.file_event_hook) and etype == QEvent.Type.FileOpen:
|
if etype == QEvent.Type.FileOpen:
|
||||||
url = e.url().toString(QUrl.ComponentFormattingOption.FullyEncoded)
|
url = e.url().toString(QUrl.ComponentFormattingOption.FullyEncoded)
|
||||||
if url and url.startswith('calibre://'):
|
if url and url.startswith('calibre://'):
|
||||||
with self._file_open_lock:
|
with self._file_open_lock:
|
||||||
@ -1394,7 +1401,7 @@ class Application(QApplication):
|
|||||||
QTimer.singleShot(1000, self._send_file_open_events)
|
QTimer.singleShot(1000, self._send_file_open_events)
|
||||||
return True
|
return True
|
||||||
path = str(e.file())
|
path = str(e.file())
|
||||||
if os.access(path, os.R_OK):
|
if path and os.access(path, os.R_OK):
|
||||||
with self._file_open_lock:
|
with self._file_open_lock:
|
||||||
self._file_open_paths.append(path)
|
self._file_open_paths.append(path)
|
||||||
QTimer.singleShot(1000, self._send_file_open_events)
|
QTimer.singleShot(1000, self._send_file_open_events)
|
||||||
|
@ -8,7 +8,7 @@ import time
|
|||||||
|
|
||||||
from qt.core import QIcon
|
from qt.core import QIcon
|
||||||
|
|
||||||
from calibre.constants import EDITOR_APP_UID, islinux
|
from calibre.constants import EDITOR_APP_UID, islinux, ismacos
|
||||||
from calibre.ebooks.oeb.polish.check.css import shutdown as shutdown_css_check_pool
|
from calibre.ebooks.oeb.polish.check.css import shutdown as shutdown_css_check_pool
|
||||||
from calibre.gui2 import Application, decouple, set_gui_prefs, setup_gui_option_parser
|
from calibre.gui2 import Application, decouple, set_gui_prefs, setup_gui_option_parser
|
||||||
from calibre.ptempfile import reset_base_dir
|
from calibre.ptempfile import reset_base_dir
|
||||||
@ -34,19 +34,23 @@ files inside the book which will be opened for editing automatically.
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
class EventAccumulator:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.events = []
|
|
||||||
|
|
||||||
def __call__(self, ev):
|
|
||||||
self.events.append(ev)
|
|
||||||
|
|
||||||
|
|
||||||
def gui_main(path=None, notify=None):
|
def gui_main(path=None, notify=None):
|
||||||
_run(['ebook-edit', path], notify=notify)
|
_run(['ebook-edit', path], notify=notify)
|
||||||
|
|
||||||
|
|
||||||
|
def open_path_in_new_editor_instance(path: str):
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from calibre.gui2 import sanitize_env_vars
|
||||||
|
with sanitize_env_vars():
|
||||||
|
if ismacos:
|
||||||
|
from calibre.utils.ipc.launch import macos_edit_book_bundle_path
|
||||||
|
bundle = os.path.dirname(os.path.dirname(macos_edit_book_bundle_path().rstrip('/')))
|
||||||
|
subprocess.Popen(['open', '-n', '-a', bundle, path])
|
||||||
|
else:
|
||||||
|
subprocess.Popen([sys.executable, path])
|
||||||
|
|
||||||
|
|
||||||
def _run(args, notify=None):
|
def _run(args, notify=None):
|
||||||
from calibre.utils.webengine import setup_fake_protocol
|
from calibre.utils.webengine import setup_fake_protocol
|
||||||
# Ensure we can continue to function if GUI is closed
|
# Ensure we can continue to function if GUI is closed
|
||||||
@ -68,7 +72,6 @@ def _run(args, notify=None):
|
|||||||
app = Application(args, override_program_name=override, color_prefs=tprefs, windows_app_uid=EDITOR_APP_UID)
|
app = Application(args, override_program_name=override, color_prefs=tprefs, windows_app_uid=EDITOR_APP_UID)
|
||||||
from calibre.utils.webengine import setup_default_profile
|
from calibre.utils.webengine import setup_default_profile
|
||||||
setup_default_profile()
|
setup_default_profile()
|
||||||
app.file_event_hook = EventAccumulator()
|
|
||||||
app.load_builtin_fonts()
|
app.load_builtin_fonts()
|
||||||
app.setWindowIcon(QIcon.ic('tweak.png'))
|
app.setWindowIcon(QIcon.ic('tweak.png'))
|
||||||
main = Main(opts, notify=notify)
|
main = Main(opts, notify=notify)
|
||||||
@ -78,9 +81,16 @@ def _run(args, notify=None):
|
|||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
main.boss.open_book(args[1], edit_file=args[2:], clear_notify_data=False, search_text=opts.select_text)
|
main.boss.open_book(args[1], edit_file=args[2:], clear_notify_data=False, search_text=opts.select_text)
|
||||||
else:
|
else:
|
||||||
for path in reversed(app.file_event_hook.events):
|
paths = app.get_pending_file_open_events()
|
||||||
main.boss.open_book(path)
|
if paths:
|
||||||
break
|
if len(paths) > 1:
|
||||||
|
for path in paths[1:]:
|
||||||
|
try:
|
||||||
|
open_path_in_new_editor_instance(path)
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
main.boss.open_book(paths[0])
|
||||||
app.file_event_hook = main.boss.open_book
|
app.file_event_hook = main.boss.open_book
|
||||||
app.exec()
|
app.exec()
|
||||||
# Ensure that the parse worker has quit so that temp files can be deleted
|
# Ensure that the parse worker has quit so that temp files can be deleted
|
||||||
|
Loading…
x
Reference in New Issue
Block a user