IDE, SVGHMI: Workaround Snap package not launching Inskape, POEdit or Chromium directly, producing lot of output in Incskape CLI, and messing with TMPDIR
--- /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)
--- 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
--- 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])
--- 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 !")
--- 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}",
--- 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()