diff --git a/pyblish_lite/control.py b/pyblish_lite/control.py index f1c140a..b7a6e2b 100644 --- a/pyblish_lite/control.py +++ b/pyblish_lite/control.py @@ -32,7 +32,7 @@ class Controller(QtCore.QObject): was_reset = QtCore.Signal() was_validated = QtCore.Signal() was_published = QtCore.Signal() - was_acted = QtCore.Signal() + was_acted = QtCore.Signal(dict) # Emitted when processing has finished finished = QtCore.Signal() @@ -90,8 +90,7 @@ def act(self, plugin, action): def on_next(): result = pyblish.plugin.process(plugin, context, None, action.id) - self.was_processed.emit(result) - util.defer(500, self.was_acted.emit) + self.was_acted.emit(result) util.defer(100, on_next) diff --git a/pyblish_lite/delegate.py b/pyblish_lite/delegate.py index 2dfc6d6..d1d2063 100644 --- a/pyblish_lite/delegate.py +++ b/pyblish_lite/delegate.py @@ -36,6 +36,7 @@ "record": awesome["circle"], "file": awesome["file"], "error": awesome["exclamation-triangle"], + "action": awesome["adn"], } @@ -93,6 +94,28 @@ def paint(self, painter, option, index): painter.setPen(QtGui.QPen(font_color)) painter.drawText(label_rect, label) + # Draw action icon + if index.data(model.ActionIconVisible): + painter.save() + + if index.data(model.ActionIdle): + color = colors["idle"] + elif index.data(model.IsProcessing): + color = colors["active"] + elif index.data(model.ActionFailed): + color = colors["warning"] + else: + color = colors["ok"] + + painter.setFont(fonts["smallAwesome"]) + painter.setPen(QtGui.QPen(color)) + + icon_rect = QtCore.QRectF(option.rect.adjusted( + label_rect.width() + 1, label_rect.height() / 3, 0, 0)) + painter.drawText(icon_rect, icons["action"]) + + painter.restore() + # Draw checkbox pen = QtGui.QPen(check_color, 1) painter.setPen(pen) diff --git a/pyblish_lite/model.py b/pyblish_lite/model.py index bd74e09..215f59d 100644 --- a/pyblish_lite/model.py +++ b/pyblish_lite/model.py @@ -62,6 +62,9 @@ # Available and context-sensitive actions Actions = QtCore.Qt.UserRole + 9 +ActionIconVisible = QtCore.Qt.UserRole + 13 +ActionIdle = QtCore.Qt.UserRole + 15 +ActionFailed = QtCore.Qt.UserRole + 17 Docstring = QtCore.Qt.UserRole + 12 # LOG RECORDS @@ -169,6 +172,8 @@ def __init__(self): self.schema.update({ IsChecked: "active", Docstring: "__doc__", + ActionIdle: "_action_idle", + ActionFailed: "_action_failed", }) def append(self, item): @@ -182,6 +187,11 @@ def append(self, item): item._has_failed = False item._type = "plugin" + item._action_idle = True + item._action_processing = False + item._action_succeeded = False + item._action_failed = False + return super(Plugin, self).append(item) def data(self, index, role): @@ -193,6 +203,30 @@ def data(self, index, role): if role == Icon: return awesome.get(getattr(item, "icon", "")) + if role == ActionIconVisible: + + # Can only run actions on active plug-ins. + if not item.active: + return + + actions = list(item.actions) + + # Context specific actions + for action in actions: + if action.on == "failed" and not item._has_failed: + actions.remove(action) + if action.on == "succeeded" and not item._has_succeeded: + actions.remove(action) + if action.on == "processed" and not item._has_processed: + actions.remove(action) + if action.on == "notProcessed" and item._has_processed: + actions.remove(action) + + if actions: + return True + + return False + if role == Actions: # Can only run actions on active plug-ins. @@ -268,11 +302,12 @@ def setData(self, index, value, role): else: self.dataChanged.emit(index, index, [role]) - def update_with_result(self, result): + def update_with_result(self, result, action=False): item = result["plugin"] index = self.items.index(item) index = self.createIndex(index, 0) + self.setData(index, False, IsIdle) self.setData(index, False, IsProcessing) self.setData(index, True, HasProcessed) diff --git a/pyblish_lite/version.py b/pyblish_lite/version.py index 1d327f8..9c2abd1 100644 --- a/pyblish_lite/version.py +++ b/pyblish_lite/version.py @@ -1,7 +1,7 @@ VERSION_MAJOR = 0 -VERSION_MINOR = 3 -VERSION_PATCH = 3 +VERSION_MINOR = 4 +VERSION_PATCH = 0 version_info = (VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH) version = '%i.%i.%i' % version_info diff --git a/pyblish_lite/window.py b/pyblish_lite/window.py index fc0bf1b..35e8e97 100644 --- a/pyblish_lite/window.py +++ b/pyblish_lite/window.py @@ -719,6 +719,7 @@ def on_plugin_action_menu_requested(self, pos): menu = QtWidgets.QMenu(self) plugin = self.data["models"]["plugins"].items[index.row()] + print("plugin is: %s" % plugin) for action in actions: qaction = QtWidgets.QAction(action.label or action.__name__, self) @@ -811,11 +812,23 @@ def on_was_processed(self, result): models["instances"].update_with_result(result) models["terminal"].update_with_result(result) - def on_was_acted(self): + def on_was_acted(self, result): buttons = self.data["buttons"] buttons["reset"].show() buttons["stop"].hide() + # Update action with result + model_ = self.data["models"]["plugins"] + + index = model_.items.index(result["plugin"]) + index = model_.createIndex(index, 0) + + model_.setData(index, not result["success"], model.ActionFailed) + model_.setData(index, False, model.IsProcessing) + + models = self.data["models"] + models["terminal"].update_with_result(result) + self.on_finished() def on_finished(self): @@ -873,7 +886,7 @@ def publish(self): util.defer(5, self.controller.publish) def act(self, plugin, action): - self.info("Preparing action..") + self.info("Preparing %s.." % action) for button in self.data["buttons"].values(): button.hide() @@ -881,7 +894,21 @@ def act(self, plugin, action): self.data["buttons"]["stop"].show() self.controller.is_running = True + # Cause view to update, but it won't visually + # happen until Qt is given time to idle.. + model_ = self.data["models"]["plugins"] + + index = model_.items.index(plugin) + index = model_.createIndex(index, 0) + + for key, value in {model.ActionIdle: False, + model.ActionFailed: False, + model.IsProcessing: True}.items(): + model_.setData(index, value, key) + + # Give Qt time to draw util.defer(100, lambda: self.controller.act(plugin, action)) + self.info("Action prepared.") def closeEvent(self, event):