kopia lustrzana https://github.com/inkstitch/inkstitch
switch print pdf gui to electron
rodzic
75fdfe22de
commit
9ccf2f552b
|
@ -1,27 +1,27 @@
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
from threading import Thread
|
|
||||||
import socket
|
|
||||||
import errno
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
import wx
|
from datetime import date
|
||||||
import appdirs
|
import errno
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
from threading import Thread
|
||||||
|
import time
|
||||||
|
|
||||||
|
import appdirs
|
||||||
|
from flask import Flask, request, Response, send_from_directory, jsonify
|
||||||
import inkex
|
import inkex
|
||||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||||
from datetime import date
|
|
||||||
from flask import Flask, request, Response, send_from_directory, jsonify
|
|
||||||
import webbrowser
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from .base import InkstitchExtension
|
from ..gui import open_url
|
||||||
from ..i18n import _, translation as inkstitch_translation
|
from ..i18n import _, translation as inkstitch_translation
|
||||||
|
from ..stitch_plan import patches_to_stitch_plan
|
||||||
from ..svg import render_stitch_plan
|
from ..svg import render_stitch_plan
|
||||||
from ..svg.tags import INKSCAPE_GROUPMODE
|
from ..svg.tags import INKSCAPE_GROUPMODE
|
||||||
from ..stitch_plan import patches_to_stitch_plan
|
|
||||||
from ..threads import ThreadCatalog
|
from ..threads import ThreadCatalog
|
||||||
|
from .base import InkstitchExtension
|
||||||
|
|
||||||
|
|
||||||
def datetimeformat(value, format='%Y/%m/%d'):
|
def datetimeformat(value, format='%Y/%m/%d'):
|
||||||
|
@ -51,42 +51,6 @@ def save_defaults(defaults):
|
||||||
json.dump(defaults, defaults_file)
|
json.dump(defaults, defaults_file)
|
||||||
|
|
||||||
|
|
||||||
def open_url(url):
|
|
||||||
# Avoid spurious output from xdg-open. Any output on stdout will crash
|
|
||||||
# inkscape.
|
|
||||||
null = open(os.devnull, 'w')
|
|
||||||
old_stdout = os.dup(sys.stdout.fileno())
|
|
||||||
os.dup2(null.fileno(), sys.stdout.fileno())
|
|
||||||
|
|
||||||
if getattr(sys, 'frozen', False):
|
|
||||||
|
|
||||||
# PyInstaller sets LD_LIBRARY_PATH. We need to temporarily clear it
|
|
||||||
# to avoid confusing xdg-open, which webbrowser will run.
|
|
||||||
|
|
||||||
# The following code is adapted from PyInstaller's documentation
|
|
||||||
# http://pyinstaller.readthedocs.io/en/stable/runtime-information.html
|
|
||||||
|
|
||||||
old_environ = dict(os.environ) # make a copy of the environment
|
|
||||||
lp_key = 'LD_LIBRARY_PATH' # for Linux and *BSD.
|
|
||||||
lp_orig = os.environ.get(lp_key + '_ORIG') # pyinstaller >= 20160820 has this
|
|
||||||
if lp_orig is not None:
|
|
||||||
os.environ[lp_key] = lp_orig # restore the original, unmodified value
|
|
||||||
else:
|
|
||||||
os.environ.pop(lp_key, None) # last resort: remove the env var
|
|
||||||
|
|
||||||
webbrowser.open(url)
|
|
||||||
|
|
||||||
# restore the old environ
|
|
||||||
os.environ.clear()
|
|
||||||
os.environ.update(old_environ)
|
|
||||||
else:
|
|
||||||
webbrowser.open(url)
|
|
||||||
|
|
||||||
# restore file descriptors
|
|
||||||
os.dup2(old_stdout, sys.stdout.fileno())
|
|
||||||
os.close(old_stdout)
|
|
||||||
|
|
||||||
|
|
||||||
class PrintPreviewServer(Thread):
|
class PrintPreviewServer(Thread):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.html = kwargs.pop('html')
|
self.html = kwargs.pop('html')
|
||||||
|
@ -96,7 +60,6 @@ class PrintPreviewServer(Thread):
|
||||||
self.realistic_color_block_svgs = kwargs.pop('realistic_color_block_svgs')
|
self.realistic_color_block_svgs = kwargs.pop('realistic_color_block_svgs')
|
||||||
Thread.__init__(self, *args, **kwargs)
|
Thread.__init__(self, *args, **kwargs)
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
self.last_request_time = None
|
|
||||||
self.shutting_down = False
|
self.shutting_down = False
|
||||||
|
|
||||||
self.__setup_app()
|
self.__setup_app()
|
||||||
|
@ -111,16 +74,6 @@ class PrintPreviewServer(Thread):
|
||||||
self.__set_resources_path()
|
self.__set_resources_path()
|
||||||
self.app = Flask(__name__)
|
self.app = Flask(__name__)
|
||||||
|
|
||||||
@self.app.before_request
|
|
||||||
def request_started():
|
|
||||||
self.last_request_time = time.time()
|
|
||||||
|
|
||||||
@self.app.before_first_request
|
|
||||||
def start_watcher():
|
|
||||||
self.watcher_thread = Thread(target=self.watch)
|
|
||||||
self.watcher_thread.daemon = True
|
|
||||||
self.watcher_thread.start()
|
|
||||||
|
|
||||||
@self.app.route('/')
|
@self.app.route('/')
|
||||||
def index():
|
def index():
|
||||||
return self.html
|
return self.html
|
||||||
|
@ -129,17 +82,12 @@ class PrintPreviewServer(Thread):
|
||||||
def shutdown():
|
def shutdown():
|
||||||
self.shutting_down = True
|
self.shutting_down = True
|
||||||
request.environ.get('werkzeug.server.shutdown')()
|
request.environ.get('werkzeug.server.shutdown')()
|
||||||
return _('Closing...') + '<br/><br/>' + _('It is safe to close this window now.')
|
return "shutting down"
|
||||||
|
|
||||||
@self.app.route('/resources/<path:resource>', methods=['GET'])
|
@self.app.route('/resources/<path:resource>', methods=['GET'])
|
||||||
def resources(resource):
|
def resources(resource):
|
||||||
return send_from_directory(self.resources_path, resource, cache_timeout=1)
|
return send_from_directory(self.resources_path, resource, cache_timeout=1)
|
||||||
|
|
||||||
@self.app.route('/ping')
|
|
||||||
def ping():
|
|
||||||
# Javascript is letting us know it's still there. This resets self.last_request_time.
|
|
||||||
return "pong"
|
|
||||||
|
|
||||||
@self.app.route('/printing/start')
|
@self.app.route('/printing/start')
|
||||||
def printing_start():
|
def printing_start():
|
||||||
# temporarily turn off the watcher while the print dialog is up,
|
# temporarily turn off the watcher while the print dialog is up,
|
||||||
|
@ -215,21 +163,6 @@ class PrintPreviewServer(Thread):
|
||||||
# the context of a flask request, so we'll just make one
|
# the context of a flask request, so we'll just make one
|
||||||
requests.post("http://%s:%s/shutdown" % (self.host, self.port))
|
requests.post("http://%s:%s/shutdown" % (self.host, self.port))
|
||||||
|
|
||||||
def watch(self):
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
time.sleep(1)
|
|
||||||
if self.shutting_down:
|
|
||||||
break
|
|
||||||
|
|
||||||
if self.last_request_time is not None and \
|
|
||||||
(time.time() - self.last_request_time) > 3:
|
|
||||||
self.stop()
|
|
||||||
break
|
|
||||||
except BaseException:
|
|
||||||
# seems like sometimes this thread blows up during shutdown
|
|
||||||
pass
|
|
||||||
|
|
||||||
def disable_logging(self):
|
def disable_logging(self):
|
||||||
logging.getLogger('werkzeug').setLevel(logging.ERROR)
|
logging.getLogger('werkzeug').setLevel(logging.ERROR)
|
||||||
|
|
||||||
|
@ -252,42 +185,6 @@ class PrintPreviewServer(Thread):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
class PrintInfoFrame(wx.Frame):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.print_server = kwargs.pop("print_server")
|
|
||||||
wx.Frame.__init__(self, *args, **kwargs)
|
|
||||||
|
|
||||||
panel = wx.Panel(self)
|
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
||||||
|
|
||||||
message = _("A print preview has been opened in your web browser. "
|
|
||||||
"This window will stay open in order to communicate with the JavaScript code running in your browser.\n\n"
|
|
||||||
"This window will close after you close the print preview in your browser, or you can close it manually if necessary.")
|
|
||||||
text = wx.StaticText(panel, label=message)
|
|
||||||
font = wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
|
|
||||||
text.SetFont(font)
|
|
||||||
sizer.Add(text, proportion=1, flag=wx.ALL | wx.EXPAND, border=20)
|
|
||||||
|
|
||||||
stop_button = wx.Button(panel, id=wx.ID_CLOSE)
|
|
||||||
stop_button.Bind(wx.EVT_BUTTON, self.close_button_clicked)
|
|
||||||
sizer.Add(stop_button, proportion=0, flag=wx.ALIGN_CENTER | wx.ALL, border=10)
|
|
||||||
|
|
||||||
panel.SetSizer(sizer)
|
|
||||||
panel.Layout()
|
|
||||||
|
|
||||||
self.timer = wx.PyTimer(self.__watcher)
|
|
||||||
self.timer.Start(250)
|
|
||||||
|
|
||||||
def close_button_clicked(self, event):
|
|
||||||
self.print_server.stop()
|
|
||||||
|
|
||||||
def __watcher(self):
|
|
||||||
if not self.print_server.is_alive():
|
|
||||||
self.timer.Stop()
|
|
||||||
self.timer = None
|
|
||||||
self.Destroy()
|
|
||||||
|
|
||||||
|
|
||||||
class Print(InkstitchExtension):
|
class Print(InkstitchExtension):
|
||||||
def build_environment(self):
|
def build_environment(self):
|
||||||
if getattr(sys, 'frozen', False):
|
if getattr(sys, 'frozen', False):
|
||||||
|
@ -409,11 +306,7 @@ class Print(InkstitchExtension):
|
||||||
realistic_color_block_svgs=realistic_color_block_svgs
|
realistic_color_block_svgs=realistic_color_block_svgs
|
||||||
)
|
)
|
||||||
print_server.start()
|
print_server.start()
|
||||||
|
browser_window = open_url("http://%s:%s/" % (print_server.host, print_server.port))
|
||||||
time.sleep(1)
|
browser_window.wait()
|
||||||
open_url("http://%s:%s/" % (print_server.host, print_server.port))
|
print_server.stop()
|
||||||
|
print_server.join()
|
||||||
app = wx.App()
|
|
||||||
info_frame = PrintInfoFrame(None, title=_("Ink/Stitch Print"), size=(450, 350), print_server=print_server)
|
|
||||||
info_frame.Show()
|
|
||||||
app.MainLoop()
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
from dialogs import info_dialog, confirm_dialog
|
from dialogs import info_dialog, confirm_dialog
|
||||||
|
from electron import open_url
|
||||||
from presets import PresetsPanel
|
from presets import PresetsPanel
|
||||||
from simulator import EmbroiderySimulator, SimulatorPreview, show_simulator
|
from simulator import EmbroiderySimulator, SimulatorPreview, show_simulator
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from ..utils import get_bundled_dir
|
||||||
|
|
||||||
|
|
||||||
|
app_process = None
|
||||||
|
|
||||||
|
|
||||||
|
def open_url(url):
|
||||||
|
global app
|
||||||
|
|
||||||
|
electron_path = os.path.join(get_bundled_dir("electron"), "out", "inkstitch-linux-x64", "inkstitch-gui")
|
||||||
|
app_process = subprocess.Popen([electron_path, url])
|
||||||
|
|
||||||
|
return app_process
|
|
@ -11,12 +11,6 @@ var realistic_rendering = {};
|
||||||
var realistic_cache = {};
|
var realistic_cache = {};
|
||||||
var normal_rendering = {};
|
var normal_rendering = {};
|
||||||
|
|
||||||
function ping() {
|
|
||||||
$.get("/ping")
|
|
||||||
.done(function() { setTimeout(ping, 1000) })
|
|
||||||
.fail(function() { $('#errors').attr('class', 'show') });
|
|
||||||
}
|
|
||||||
|
|
||||||
//function to chunk opd view into pieces
|
//function to chunk opd view into pieces
|
||||||
// source: https://stackoverflow.com/questions/3366529/wrap-every-3-divs-in-a-div
|
// source: https://stackoverflow.com/questions/3366529/wrap-every-3-divs-in-a-div
|
||||||
$.fn.chunk = function(size) {
|
$.fn.chunk = function(size) {
|
||||||
|
@ -199,7 +193,6 @@ function setSVGTransform(figure, transform) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
setTimeout(ping, 1000);
|
|
||||||
/* SCALING AND MOVING SVG */
|
/* SCALING AND MOVING SVG */
|
||||||
|
|
||||||
/* Mousewheel scaling */
|
/* Mousewheel scaling */
|
||||||
|
@ -369,22 +362,7 @@ $(function() {
|
||||||
/* Settings Bar */
|
/* Settings Bar */
|
||||||
|
|
||||||
$('button.close').click(function() {
|
$('button.close').click(function() {
|
||||||
$.post('/shutdown', {})
|
window.close();
|
||||||
.always(function(data) {
|
|
||||||
window.close();
|
|
||||||
|
|
||||||
/* Chrome and Firefox both have a rule: scripts can only close windows
|
|
||||||
* that they opened. Chrome seems to have an exception for windows that
|
|
||||||
* were opened by an outside program, so the above works fine. Firefox
|
|
||||||
* steadfastly refuses to allow us to close the window, so we'll tell
|
|
||||||
* the user (in their language) that they can close it.
|
|
||||||
*/
|
|
||||||
setTimeout(function() {
|
|
||||||
document.open();
|
|
||||||
document.write("<html><body>" + data + "</body></html>");
|
|
||||||
document.close();
|
|
||||||
}, 1000);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('button.print').click(function() {
|
$('button.print').click(function() {
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Ink/Stitch Print Preview</title>
|
<title>Ink/Stitch Print Preview</title>
|
||||||
|
<!-- https://stackoverflow.com/a/37480521/4249120 -->
|
||||||
|
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
|
||||||
<script src="resources/jquery-3.3.1.min.js"></script>
|
<script src="resources/jquery-3.3.1.min.js"></script>
|
||||||
<script src="resources/inkstitch.js"></script>
|
<script src="resources/inkstitch.js"></script>
|
||||||
<link rel="stylesheet" href="resources/style.css" />
|
<link rel="stylesheet" href="resources/style.css" />
|
||||||
|
|
Ładowanie…
Reference in New Issue