Skip to content

Commit

Permalink
Merge pull request #232 from mottosso/implement9
Browse files Browse the repository at this point in the history
Implement support for adding a comment
  • Loading branch information
mottosso authored May 25, 2017
2 parents 9489329 + af6a91f commit 84cc26c
Show file tree
Hide file tree
Showing 14 changed files with 326 additions and 35 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Some data within each Instance and Context are special to QML.
|:----------|:-----------------|:-------------------
| `publish` | Instance | The on/off state of the toggle.
| `label` | Context/Instance | Draw this instead of an instance's `name`
| `comment` | Context | Display and edit comment in GUI

<br>

Expand Down
15 changes: 5 additions & 10 deletions pyblish_qml/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ def event(self, event):

return super(Window, self).event(event)

def keyPressEvent(self, event):
"""Delegate keyboard events"""

if event.key() == QtCore.Qt.Key_Return:
return self.on_enter()


class Application(QtGui.QGuiApplication):
"""Pyblish QML wrapper around QGuiApplication
Expand Down Expand Up @@ -169,7 +163,9 @@ def show(self, client_settings=None):
util.timer_end("ready", "Awaited statemachine for %.2f ms")

self.controller.show.emit()
self.controller.reset()

# Allow time for QML to initialise
util.schedule(self.controller.reset, 500, channel="main")

def hide(self):
"""Hide GUI
Expand Down Expand Up @@ -242,8 +238,7 @@ def main(demo=False, aschild=False):
service = ipc.service.MockService() if demo else ipc.service.Service()
server = ipc.server.Server(service)

if demo:
proxy = ipc.server.Proxy(server)
proxy.show(settings.to_dict())
proxy = ipc.server.Proxy(server)
proxy.show(settings.to_dict())

server.wait()
88 changes: 81 additions & 7 deletions pyblish_qml/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Controller(QtCore.QObject):
show = QtCore.pyqtSignal()
hide = QtCore.pyqtSignal()

firstRun = QtCore.pyqtSignal()
publishing = QtCore.pyqtSignal()
repairing = QtCore.pyqtSignal()
stopping = QtCore.pyqtSignal()
Expand All @@ -40,6 +41,10 @@ class Controller(QtCore.QObject):
saved = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
initialised = QtCore.pyqtSignal()
commented = QtCore.pyqtSignal()
commenting = QtCore.pyqtSignal(str,
str,
arguments=["summary", "description"])

state_changed = QtCore.pyqtSignal(str, arguments=["state"])

Expand All @@ -63,8 +68,11 @@ def __init__(self, host, parent=None):
"models": {
"item": models.ItemModel(),
"result": models.ResultModel(),
}
},
"comment": [],
"firstRun": True
}

self.data.update({
"proxies": {
"item": models.ProxyModel(self.data["models"]["item"]),
Expand Down Expand Up @@ -117,6 +125,7 @@ def __init__(self, host, parent=None):
QtCore.Qt.QueuedConnection)

self.state_changed.connect(self.on_state_changed)
self.commenting.connect(self.on_commenting)

def on_show(self):
self.host.emit("pyblishQmlShown")
Expand Down Expand Up @@ -254,10 +263,34 @@ def setup_statemachine(self):
machine.start()
return machine

@QtCore.pyqtSlot(result=str)
def summary(self):
"""Return first line of comment"""
try:
return self.data["comment"][0]
except IndexError:
return None

@QtCore.pyqtSlot(result=str)
def description(self):
"""Return subseqent lines of comment (if any)"""
try:
return self.data["comment"][1]
except IndexError:
return None

@QtCore.pyqtProperty(str, notify=state_changed)
def state(self):
return self.data["state"]["current"]

@QtCore.pyqtProperty(bool, notify=commented)
def hasComment(self):
return any(self.data["comment"])

@QtCore.pyqtProperty(bool, constant=True)
def commentEnabled(self):
return "comment" in self.host.cached_context.data

@property
def states(self):
return self.data["state"]["all"]
Expand Down Expand Up @@ -564,6 +597,28 @@ def echo(self, data):

# Event handlers

def on_commenting(self, summary, description):
"""The user is entering a comment"""

def update():
comment = "\n".join(
entry for entry in self.data["comment"]
if entry
)

context = self.host.cached_context
context.data["comment"] = comment
self.data.update({"comment": (summary, description)})

# Notify subscribers of the comment
self.host.update(key="comment", value=comment)
self.host.emit("commented", comment=comment)

self.commented.emit()

# Update local cache a little later
util.schedule(update, 100, channel="commenting")

def on_about_to_process(self, plugin, instance):
"""Reflect currently running pair in GUI"""

Expand Down Expand Up @@ -664,16 +719,35 @@ def on_finished(plugins, context):
% abs(stats["requestCount"]))

# Reset Context
context = self.data["models"]["item"].instances[0]
context.hasError = False
context.succeeded = False
context.processed = False
context.isProcessing = False
context.currentProgress = 0
context_item = self.data["models"]["item"].instances[0]
context_item.hasError = False
context_item.succeeded = False
context_item.processed = False
context_item.isProcessing = False
context_item.currentProgress = 0
context_item.label = context.data.get("label")

self.initialised.emit()

self.data["models"]["item"].update_compatibility()

# Remember comment across resets
comment = self.data["comment"]
if comment:
print("Installing local comment..")
self.host.cached_context.data["comment"] = comment
else:
print("No local comment, reading from context..")
summary, description = (self.host.cached_context.data.get(
"comment", "").split("\n", 1) + [None]
)[:2]

self.data["comment"] = [summary, description]

if self.data["firstRun"]:
self.firstRun.emit()
self.data["firstRun"] = False

self.host.emit("reset", context=None)

def on_run(plugins):
Expand Down
2 changes: 1 addition & 1 deletion pyblish_qml/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def on_shown():
try:
service = ipc.service.Service()
server = ipc.server.Server(service)
except:
except Exception:
# If for some reason, the GUI fails to show.
traceback.print_exc()
return on_shown()
Expand Down
3 changes: 3 additions & 0 deletions pyblish_qml/ipc/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def discover(self):
def emit(self, signal, **kwargs):
self._dispatch("emit", args=[signal, kwargs])

def update(self, key, value):
self._dispatch("update", args=[key, value])

def _listen(self):
"""Listen for messages passed from parent
Expand Down
1 change: 1 addition & 0 deletions pyblish_qml/ipc/formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def format_data(data):
"family",
"families",
"publish",
"comment",

# Provided by service.py
"host",
Expand Down
47 changes: 33 additions & 14 deletions pyblish_qml/ipc/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,47 @@ def __init__(self, service, python=None, pyqt5=None):
print("Using Python @ '%s'" % python)
print("Using PyQt5 @ '%s'" % pyqt5)

# Maintain the absolute minimum of environment variables,
# to avoid issues on invalid types.
if IS_WIN32:
environ = {
key: os.getenv(key)
for key in ("USERNAME",
"SYSTEMROOT",
"PYTHONPATH",
"PATH")
if os.getenv(key)
}
else:
# OSX and Linux users are left to fend for themselves.
environ = os.environ.copy()

# Append PyQt5 to existing PYTHONPATH, if available
environ["PYTHONPATH"] = os.pathsep.join(
path for path in [os.getenv("PYTHONPATH"), pyqt5]
if path is not None
)

# Protect against an erroneous parent environment
# The environment passed to subprocess is inherited from
# its parent, but the parent may - at run time - have
# made the environment invalid. For example, a unicode
# key or value in `os.environ` is not a valid environment.
assert all(isinstance(key, str) for key in os.environ), (
"One or more of your environment variable keys are not <str>")

assert all(isinstance(key, str) for key in os.environ.values()), (
"One or more of your environment variable values are not <str>")
if not all(isinstance(key, str) for key in environ):
print("One or more of your environment variable "
"keys are not <str>")

environ = os.environ.copy()
for key in os.environ:
if not isinstance(key, str):
print("- %s is not <str>" % key)

# Some hosts define their own home directories as Python's.
# This causes the subprocess to mistake it for its own home.
environ.pop("PYTHONHOME", None)
if not all(isinstance(key, str) for key in environ.values()):
print("One or more of your environment "
"variable values are not <str>")

# Append PyQt5 to existing PYTHONPATH, if available
environ["PYTHONPATH"] = os.pathsep.join(
path for path in [os.getenv("PYTHONPATH"), pyqt5]
if path is not None
)
for key, value in os.environ.items():
if not isinstance(value, str):
print("- Value of %s=%s is not <str>" % (key, value))

kwargs = dict(args=[
python, "-u", "-m", "pyblish_qml",
Expand Down
4 changes: 4 additions & 0 deletions pyblish_qml/ipc/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ def emit(self, signal, kwargs):

pyblish.api.emit(signal, **kwargs)

def update(self, key, value):
"""Write data to context from GUI"""
self._context.data[key] = value


class MockService(Service):
def __init__(self, delay=0.01, *args, **kwargs):
Expand Down
Loading

0 comments on commit 84cc26c

Please sign in to comment.