74 lines
2.0 KiB
Python
74 lines
2.0 KiB
Python
"""Open a finished DOCX with the same office engine used for post-split."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from .detect import OfficeInstall, resolve_office_engine
|
|
from .uno_cli import soffice_cli_path
|
|
|
|
|
|
def open_document_with_engine(
|
|
path: str,
|
|
*,
|
|
engine: str,
|
|
install: OfficeInstall | None = None,
|
|
) -> None:
|
|
"""Open *path* in Word / LibreOffice / OpenOffice instead of the default app."""
|
|
abs_path = os.path.abspath(path)
|
|
resolved, detected = resolve_office_engine(engine) if install is None else (engine, install)
|
|
if resolved == "word" and sys.platform == "win32":
|
|
if _open_in_word(abs_path):
|
|
return
|
|
if resolved in ("libre", "openoffice") and detected and detected.soffice_path:
|
|
if _open_in_soffice(detected.soffice_path, abs_path):
|
|
return
|
|
_open_with_os_default(abs_path)
|
|
|
|
|
|
def _open_in_word(path: str) -> bool:
|
|
try:
|
|
import win32com.client # type: ignore
|
|
except ImportError:
|
|
return False
|
|
from ..word_fix import word_com_apartment
|
|
|
|
try:
|
|
with word_com_apartment():
|
|
word = win32com.client.DispatchEx("Word.Application")
|
|
try:
|
|
word.Visible = True
|
|
word.Documents.Open(path)
|
|
return True
|
|
finally:
|
|
word = None
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
def _open_in_soffice(soffice_path: str, path: str) -> bool:
|
|
try:
|
|
cli = soffice_cli_path(soffice_path)
|
|
subprocess.Popen(
|
|
[cli, os.path.abspath(path)],
|
|
cwd=str(Path(cli).parent),
|
|
)
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
def _open_with_os_default(path: str) -> None:
|
|
import platform
|
|
|
|
system = platform.system()
|
|
if system == "Darwin":
|
|
subprocess.call(("open", path))
|
|
elif system == "Windows":
|
|
os.startfile(path) # type: ignore[attr-defined]
|
|
else:
|
|
subprocess.call(("xdg-open", path))
|