# HG changeset patch # User Edouard Tisserant # Date 1659974966 -7200 # Node ID 1ee56fb544fc28135d6829e4d6075b41557a954b # Parent b46af5b80c7d6de71748316fc7751f6d4364cc55 IDE, SVGHMI: Workaround Snap package not launching Inskape, POEdit or Chromium directly, producing lot of output in Incskape CLI, and messing with TMPDIR diff -r b46af5b80c7d -r 1ee56fb544fc dialogs/MessageBoxOnce.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dialogs/MessageBoxOnce.py Mon Aug 08 18:09:26 2022 +0200 @@ -0,0 +1,57 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This file is part of Beremiz +# Copyright (C) 2022: Edouard TISSERANT +# +# See COPYING file for copyrights details. + + +from __future__ import absolute_import +import wx + + +# class RichMessageDialog is still not available in wxPython 3.0.2 +class MessageBoxOnce(wx.Dialog): + """ + wx.MessageBox that user can ask not to show again + """ + def __init__(self, title, message, config_key): + self.Config = wx.ConfigBase.Get() + self.config_key = config_key + dont_show = self.Config.Read(self.config_key) == "True" + + if dont_show: + return + + wx.Dialog.__init__(self, None, title=title) + + main_sizer = wx.BoxSizer(wx.VERTICAL) + + message = wx.StaticText(self, label=message) + main_sizer.Add(message, border=20, + flag=wx.ALIGN_CENTER_HORIZONTAL | wx.TOP | wx.LEFT | wx.RIGHT) + + self.check = wx.CheckBox(self, label=_("don't show this message again")) + main_sizer.Add(self.check, border=20, + flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL) + + buttons_sizer = wx.BoxSizer(wx.HORIZONTAL) + + Button = wx.Button(self, label="OK") + + self.Bind(wx.EVT_BUTTON, self.OnOKButton, Button) + buttons_sizer.Add(Button) + + main_sizer.Add(buttons_sizer, border=20, + flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_RIGHT) + + self.SetSizer(main_sizer) + self.Fit() + + self.ShowModal() + + def OnOKButton(self, event): + if self.check.GetValue(): + self.Config.Write(self.config_key, "True") + self.EndModal(wx.ID_OK) diff -r b46af5b80c7d -r 1ee56fb544fc dialogs/__init__.py --- a/dialogs/__init__.py Mon Aug 08 18:07:23 2022 +0200 +++ b/dialogs/__init__.py Mon Aug 08 18:09:26 2022 +0200 @@ -51,3 +51,4 @@ from dialogs.BrowseValuesLibraryDialog import BrowseValuesLibraryDialog from dialogs.UriEditor import UriEditor from dialogs.IDManager import IDManager +from dialogs.MessageBoxOnce import MessageBoxOnce diff -r b46af5b80c7d -r 1ee56fb544fc docutil/docsvg.py --- a/docutil/docsvg.py Mon Aug 08 18:07:23 2022 +0200 +++ b/docutil/docsvg.py Mon Aug 08 18:09:26 2022 +0200 @@ -24,8 +24,10 @@ from __future__ import absolute_import +import os import wx import subprocess +from dialogs import MessageBoxOnce def _get_inkscape_path(): @@ -86,11 +88,23 @@ _inkscape_version = _get_inkscape_version() return _inkscape_version -def open_svg(svgfile): - """ Generic function to open SVG file """ - - inkpath = get_inkscape_path() - if inkpath is None: - wx.MessageBox("Inkscape is not found or installed !") - else: - subprocess.Popen([inkpath,svgfile]) +if os.environ.has_key("SNAP"): + def open_svg(svgfile): + MessageBoxOnce("Launching Inkscape with xdg-open", + "Confined app can't launch Inkscape directly.\n"+ + "Instead, SVG file is passed to xdg-open.\n"+ + "Please select Inskape when proposed.\n\n"+ + "Notes: \n"+ + " - Inkscape must be installed on you system.\n"+ + " - If no choice is proposed, use file manager to change SVG file properties.\n", + "DocSVGSnapWarning") + + subprocess.Popen(["xdg-open",svgfile]) +else: + def open_svg(svgfile): + """ Generic function to open SVG file """ + inkpath = get_inkscape_path() + if inkpath is None: + wx.MessageBox("Inkscape is not found or installed !") + else: + subprocess.Popen([inkpath,svgfile]) diff -r b46af5b80c7d -r 1ee56fb544fc svghmi/i18n.py --- a/svghmi/i18n.py Mon Aug 08 18:07:23 2022 +0200 +++ b/svghmi/i18n.py Mon Aug 08 18:09:26 2022 +0200 @@ -20,6 +20,7 @@ # https://pypi.org/project/pycountry/18.12.8/ # python2 -m pip install pycountry==18.12.8 --user import pycountry +from dialogs import MessageBoxOnce cmd_parser = re.compile(r'(?:"([^"]+)"\s*|([^\s]+)\s*)?') @@ -39,10 +40,21 @@ poedit_path = None else: - try: - poedit_path = subprocess.check_output("command -v poedit", shell=True).strip() - except subprocess.CalledProcessError: - poedit_path = None + if os.environ.has_key("SNAP"): + MessageBoxOnce("Launching POEdit with xdg-open", + "Confined app can't launch POEdit directly.\n"+ + "Instead, PO/POT file is passed to xdg-open.\n"+ + "Please select POEdit when proposed.\n\n"+ + "Notes: \n"+ + " - POEdit must be installed on you system.\n"+ + " - If no choice is proposed, use file manager to change POT/PO file properties.\n", + "SVGHMII18SnapWarning") + poedit_path = "xdg-open" + else: + try: + poedit_path = subprocess.check_output("command -v poedit", shell=True).strip() + except subprocess.CalledProcessError: + poedit_path = None if poedit_path is None: wx.MessageBox("POEdit is not found or installed !") diff -r b46af5b80c7d -r 1ee56fb544fc svghmi/svghmi.py --- a/svghmi/svghmi.py Mon Aug 08 18:07:23 2022 +0200 +++ b/svghmi/svghmi.py Mon Aug 08 18:09:26 2022 +0200 @@ -8,6 +8,7 @@ from __future__ import absolute_import import os +import sys import shutil import hashlib import shlex @@ -302,10 +303,14 @@ return ret -if wx.Platform == '__WXMSW__': +if sys.platform.startswith('win'): default_cmds={ "launch":"cmd.exe /c 'start msedge {url}'", "watchdog":"cmd.exe /k 'echo watchdog for {url} !'"} +elif os.environ.has_key("SNAP"): + default_cmds={ + "launch":"xdg-open {url}", + "watchdog":"echo Watchdog for {name} !"} else: default_cmds={ "launch":"chromium {url}", diff -r b46af5b80c7d -r 1ee56fb544fc svghmi/ui.py --- a/svghmi/ui.py Mon Aug 08 18:07:23 2022 +0200 +++ b/svghmi/ui.py Mon Aug 08 18:09:26 2022 +0200 @@ -31,6 +31,19 @@ from util.ProcessLogger import ProcessLogger +# When running as a confined Snap, /tmp isn't accessible from the outside +# and Widget DnD to Inkscape can't work, since it can't find generated svg +# This forces tmp directory in $SNAP_USER_DATA, accessible from other apps +if os.environ.has_key("SNAP"): + NamedTemporaryFile_orig = NamedTemporaryFile + tmpdir = os.path.join(os.environ["SNAP_USER_DATA"], ".tmp") + if not os.path.exists(tmpdir): + os.mkdir(tmpdir) + def NamedTemporaryFile(*args,**kwargs): + kwargs["dir"] = tmpdir + return NamedTemporaryFile_orig(*args, **kwargs) + + ScriptDirectory = paths.AbsDir(__file__) HMITreeDndMagicWord = "text/beremiz-hmitree" @@ -464,7 +477,8 @@ # TODO: spawn a thread, to decouple thumbnail gen status, result, _err_result = ProcessLogger( - self.Controler.GetCTRoot().logger, + #self.Controler.GetCTRoot().logger, + None, '"' + inkpath + '" "' + svgpath + '" ' + export_opt + ' "' + thumbpath + '" -D -h ' + str(_preview_height)).spin()