From 8a029635ee19ad18569a585433cd36eac32e212b Mon Sep 17 00:00:00 2001 From: Jimmy Christensen Date: Fri, 13 Dec 2024 17:50:48 +0100 Subject: [PATCH] [cuegui] feat: Add job node graph plugin v2 (#1400) **Link the Issue(s) this Pull Request is related to.** #888 (original PR) **Summarize your change.** This is an adapted PR to support QtPy and PySide6 It depends a fork of NodeGraphQt that has been adapted to use QtPy instead of Qt directly. --- cuegui/cuegui/AbstractGraphWidget.py | 126 +++++++++++++++ cuegui/cuegui/App.py | 1 + cuegui/cuegui/JobMonitorGraph.py | 153 ++++++++++++++++++ cuegui/cuegui/LayerMonitorTree.py | 50 +++++- cuegui/cuegui/images/apps/blender.png | Bin 0 -> 5663 bytes cuegui/cuegui/images/apps/ffmpeg.png | Bin 0 -> 6791 bytes cuegui/cuegui/images/apps/gaffer.png | Bin 0 -> 3404 bytes cuegui/cuegui/images/apps/krita.png | Bin 0 -> 9406 bytes cuegui/cuegui/images/apps/natron.png | Bin 0 -> 4285 bytes cuegui/cuegui/images/apps/oiio.png | Bin 0 -> 2679 bytes cuegui/cuegui/images/apps/placeholder.png | Bin 0 -> 695 bytes cuegui/cuegui/images/apps/postprocess.png | Bin 0 -> 65812 bytes cuegui/cuegui/images/apps/rm.png | Bin 0 -> 1499 bytes cuegui/cuegui/images/apps/shell.png | Bin 0 -> 5422 bytes cuegui/cuegui/images/apps/terminal.png | Bin 0 -> 5422 bytes cuegui/cuegui/nodegraph/__init__.py | 21 +++ cuegui/cuegui/nodegraph/nodes/__init__.py | 19 +++ cuegui/cuegui/nodegraph/nodes/base.py | 79 +++++++++ cuegui/cuegui/nodegraph/nodes/layer.py | 97 +++++++++++ cuegui/cuegui/nodegraph/widgets/__init__.py | 0 .../cuegui/nodegraph/widgets/nodeWidgets.py | 112 +++++++++++++ .../cuegui/plugins/MonitorJobGraphPlugin.py | 103 ++++++++++++ cuegui/tests/plugins/JobGraphPlugin_tests.py | 64 ++++++++ pycue/opencue/wrappers/layer.py | 7 + requirements_gui.txt | 1 + 25 files changed, 829 insertions(+), 4 deletions(-) create mode 100644 cuegui/cuegui/AbstractGraphWidget.py create mode 100644 cuegui/cuegui/JobMonitorGraph.py create mode 100644 cuegui/cuegui/images/apps/blender.png create mode 100644 cuegui/cuegui/images/apps/ffmpeg.png create mode 100644 cuegui/cuegui/images/apps/gaffer.png create mode 100644 cuegui/cuegui/images/apps/krita.png create mode 100644 cuegui/cuegui/images/apps/natron.png create mode 100644 cuegui/cuegui/images/apps/oiio.png create mode 100644 cuegui/cuegui/images/apps/placeholder.png create mode 100644 cuegui/cuegui/images/apps/postprocess.png create mode 100644 cuegui/cuegui/images/apps/rm.png create mode 100644 cuegui/cuegui/images/apps/shell.png create mode 100644 cuegui/cuegui/images/apps/terminal.png create mode 100644 cuegui/cuegui/nodegraph/__init__.py create mode 100644 cuegui/cuegui/nodegraph/nodes/__init__.py create mode 100644 cuegui/cuegui/nodegraph/nodes/base.py create mode 100644 cuegui/cuegui/nodegraph/nodes/layer.py create mode 100644 cuegui/cuegui/nodegraph/widgets/__init__.py create mode 100644 cuegui/cuegui/nodegraph/widgets/nodeWidgets.py create mode 100644 cuegui/cuegui/plugins/MonitorJobGraphPlugin.py create mode 100644 cuegui/tests/plugins/JobGraphPlugin_tests.py diff --git a/cuegui/cuegui/AbstractGraphWidget.py b/cuegui/cuegui/AbstractGraphWidget.py new file mode 100644 index 000000000..8b4880644 --- /dev/null +++ b/cuegui/cuegui/AbstractGraphWidget.py @@ -0,0 +1,126 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Base class for CueGUI graph widgets.""" + +from qtpy import QtCore +from qtpy import QtWidgets + +from NodeGraphQtPy import NodeGraph +from NodeGraphQtPy.errors import NodeRegistrationError +from cuegui.nodegraph import CueLayerNode +from cuegui import app + + +class AbstractGraphWidget(QtWidgets.QWidget): + """Base class for CueGUI graph widgets""" + + def __init__(self, parent=None): + super(AbstractGraphWidget, self).__init__(parent=parent) + self.graph = NodeGraph() + self.setupUI() + + self.timer = QtCore.QTimer(self) + # pylint: disable=no-member + self.timer.timeout.connect(self.update) + self.timer.setInterval(1000 * 20) + + self.graph.node_selection_changed.connect(self.onNodeSelectionChanged) + app().quit.connect(self.timer.stop) + + def setupUI(self): + """Setup the UI.""" + try: + self.graph.register_node(CueLayerNode) + except NodeRegistrationError: + pass + self.graph.viewer().installEventFilter(self) + + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(self.graph.viewer()) + + def onNodeSelectionChanged(self): + """Slot run when a node is selected. + + Updates the nodes to ensure they're visualising current data. + Can be used to notify other widgets of object selection. + """ + self.update() + + def handleSelectObjects(self, rpcObjects): + """Select incoming objects in graph. + """ + received = [o.name() for o in rpcObjects] + current = [rpcObject.name() for rpcObject in self.selectedObjects()] + if received == current: + # prevent recursing + return + + for node in self.graph.all_nodes(): + node.set_selected(False) + for rpcObject in rpcObjects: + node = self.graph.get_node_by_name(rpcObject.name()) + node.set_selected(True) + + def selectedObjects(self): + """Return the selected nodes rpcObjects in the graph. + :rtype: [opencue.wrappers.layer.Layer] + :return: List of selected layers + """ + rpcObjects = [n.rpcObject for n in self.graph.selected_nodes()] + return rpcObjects + + def eventFilter(self, target, event): + """Override eventFilter + + Centre nodes in graph viewer on 'F' key press. + + @param target: widget event occurred on + @type target: QtWidgets.QWidget + @param event: Qt event + @type event: QtCore.QEvent + """ + if hasattr(self, "graph"): + viewer = self.graph.viewer() + if target == viewer: + if event.type() == QtCore.QEvent.KeyPress: + if event.key() == QtCore.Qt.Key_F: + self.graph.center_on() + if event.key() == QtCore.Qt.Key_L: + self.graph.auto_layout_nodes() + + return super(AbstractGraphWidget, self).eventFilter(target, event) + + def clearGraph(self): + """Clear all nodes from the graph + """ + for node in self.graph.all_nodes(): + for port in node.output_ports(): + port.unlock() + for port in node.input_ports(): + port.unlock() + self.graph.clear_session() + + def createGraph(self): + """Create the graph to visualise OpenCue objects + """ + raise NotImplementedError() + + def update(self): + """Update nodes with latest data + + This is run every 20 seconds by the timer. + """ + raise NotImplementedError() diff --git a/cuegui/cuegui/App.py b/cuegui/cuegui/App.py index 8e5409520..eaf48c500 100644 --- a/cuegui/cuegui/App.py +++ b/cuegui/cuegui/App.py @@ -40,6 +40,7 @@ class CueGuiApplication(QtWidgets.QApplication): request_update = QtCore.Signal() status = QtCore.Signal() quit = QtCore.Signal() + select_layers = QtCore.Signal(list) # Thread pool threadpool = None diff --git a/cuegui/cuegui/JobMonitorGraph.py b/cuegui/cuegui/JobMonitorGraph.py new file mode 100644 index 000000000..4e0bbe882 --- /dev/null +++ b/cuegui/cuegui/JobMonitorGraph.py @@ -0,0 +1,153 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Node graph to display Layers of a Job""" + + +from qtpy import QtWidgets + +import cuegui.Utils +import cuegui.MenuActions +from cuegui.nodegraph import CueLayerNode +from cuegui.AbstractGraphWidget import AbstractGraphWidget + + +class JobMonitorGraph(AbstractGraphWidget): + """Graph widget to display connections of layers in a job""" + + def __init__(self, parent=None): + super(JobMonitorGraph, self).__init__(parent=parent) + self.job = None + self.setupContextMenu() + + # wire signals + cuegui.app().select_layers.connect(self.handleSelectObjects) + + def onNodeSelectionChanged(self): + """Notify other widgets of Layer selection. + + Emit signal to notify other widgets of Layer selection, this keeps + all widgets with selectable Layers in sync with each other. + + Also force updates the nodes, as the timed updates are infrequent. + """ + self.update() + layers = self.selectedObjects() + cuegui.app().select_layers.emit(layers) + + def setupContextMenu(self): + """Setup context menu for nodes in node graph""" + self.__menuActions = cuegui.MenuActions.MenuActions( + self, self.update, self.selectedObjects, self.getJob + ) + + menu = self.graph.context_menu().qmenu + + dependMenu = QtWidgets.QMenu("&Dependencies", self) + self.__menuActions.layers().addAction(dependMenu, "viewDepends") + self.__menuActions.layers().addAction(dependMenu, "dependWizard") + dependMenu.addSeparator() + self.__menuActions.layers().addAction(dependMenu, "markdone") + menu.addMenu(dependMenu) + menu.addSeparator() + self.__menuActions.layers().addAction(menu, "useLocalCores") + self.__menuActions.layers().addAction(menu, "reorder") + self.__menuActions.layers().addAction(menu, "stagger") + menu.addSeparator() + self.__menuActions.layers().addAction(menu, "setProperties") + menu.addSeparator() + self.__menuActions.layers().addAction(menu, "kill") + self.__menuActions.layers().addAction(menu, "eat") + self.__menuActions.layers().addAction(menu, "retry") + menu.addSeparator() + self.__menuActions.layers().addAction(menu, "retryDead") + + def setJob(self, job): + """Set Job to be displayed + @param job: Job to display as node graph + @type job: opencue.wrappers.job.Job + """ + self.timer.stop() + self.clearGraph() + + if job is None: + self.job = None + return + + job = cuegui.Utils.findJob(job) + self.job = job + self.createGraph() + self.timer.start() + + def getJob(self): + """Return the currently set job + :rtype: opencue.wrappers.job.Job + :return: Currently set job + """ + return self.job + + def selectedObjects(self): + """Return the selected Layer rpcObjects in the graph. + :rtype: [opencue.wrappers.layer.Layer] + :return: List of selected layers + """ + layers = [n.rpcObject for n in self.graph.selected_nodes() if isinstance(n, CueLayerNode)] + return layers + + def createGraph(self): + """Create the graph to visualise the grid job submission + """ + if not self.job: + return + + layers = self.job.getLayers() + + # add job layers to tree + for layer in layers: + node = CueLayerNode(layer) + self.graph.add_node(node) + node.set_name(layer.name()) + + # setup connections + self.setupNodeConnections() + + self.graph.auto_layout_nodes() + self.graph.center_on() + + def setupNodeConnections(self): + """Setup connections between nodes based on their dependencies""" + for node in self.graph.all_nodes(): + for depend in node.rpcObject.getWhatDependsOnThis(): + child_node = self.graph.get_node_by_name(depend.dependErLayer()) + if child_node: + # todo check if connection exists + child_node.set_input(0, node.output(0)) + + for node in self.graph.all_nodes(): + for port in node.output_ports(): + port.lock() + for port in node.input_ports(): + port.lock() + + def update(self): + """Update nodes with latest Layer data + + This is run every 20 seconds by the timer. + """ + if self.job is not None: + layers = self.job.getLayers() + for layer in layers: + node = self.graph.get_node_by_name(layer.name()) + node.setRpcObject(layer) diff --git a/cuegui/cuegui/LayerMonitorTree.py b/cuegui/cuegui/LayerMonitorTree.py index 83b615f68..70059391b 100644 --- a/cuegui/cuegui/LayerMonitorTree.py +++ b/cuegui/cuegui/LayerMonitorTree.py @@ -150,7 +150,9 @@ def __init__(self, parent): tip="Timeout for a frames\' LLU, Hours:Minutes") cuegui.AbstractTreeWidget.AbstractTreeWidget.__init__(self, parent) - self.itemDoubleClicked.connect(self.__itemDoubleClickedFilterLayer) + # pylint: disable=no-member + self.itemSelectionChanged.connect(self.__itemSelectionChangedFilterLayer) + cuegui.app().select_layers.connect(self.__handle_select_layers) # Used to build right click context menus self.__menuActions = cuegui.MenuActions.MenuActions( @@ -277,9 +279,49 @@ def contextMenuEvent(self, e): menu.exec_(e.globalPos()) - def __itemDoubleClickedFilterLayer(self, item, col): - del col - self.handle_filter_layers_byLayer.emit([item.rpcObject.data.name]) + def __itemSelectionChangedFilterLayer(self): + """Filter FrameMonitor to selected Layers. + Emits signal to filter FrameMonitor to selected Layers. + Also emits signal for other widgets to select Layers. + """ + layers = self.selectedObjects() + layer_names = [layer.data.name for layer in layers] + + # emit signal to filter Frame Monitor + self.handle_filter_layers_byLayer.emit(layer_names) + + # emit signal to select Layers in other widgets + cuegui.app().select_layers.emit(layers) + + def __handle_select_layers(self, layerRpcObjects): + """Select incoming Layers in tree. + Slot connected to QtGui.qApp.select_layers inorder to handle + selecting Layers in Tree. + Also emits signal to filter FrameMonitor + """ + received_layers = [l.data.name for l in layerRpcObjects] + current_layers = [l.data.name for l in self.selectedObjects()] + if received_layers == current_layers: + # prevent recursion + return + + # prevent unnecessary calls to __itemSelectionChangedFilterLayer + self.blockSignals(True) + try: + for item in self._items.values(): + item.setSelected(False) + for layer in layerRpcObjects: + objectKey = cuegui.Utils.getObjectKey(layer) + if objectKey not in self._items: + self.addObject(layer) + item = self._items[objectKey] + item.setSelected(True) + finally: + # make sure signals are re-enabled + self.blockSignals(False) + + # emit signal to filter Frame Monitor + self.handle_filter_layers_byLayer.emit(received_layers) class LayerWidgetItem(cuegui.AbstractWidgetItem.AbstractWidgetItem): diff --git a/cuegui/cuegui/images/apps/blender.png b/cuegui/cuegui/images/apps/blender.png new file mode 100644 index 0000000000000000000000000000000000000000..c32f78a085ffd91113eec88e71f93c70ddcd175c GIT binary patch literal 5663 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 WV&enrxBZV$3s6(i23IIp2mcop#MpNL literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/ffmpeg.png b/cuegui/cuegui/images/apps/ffmpeg.png new file mode 100644 index 0000000000000000000000000000000000000000..1c1644247dbd5ca90a3cd82b5b5865cb1a129c70 GIT binary patch literal 6791 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 KU!z(L6ZJo<`-E%& literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/gaffer.png b/cuegui/cuegui/images/apps/gaffer.png new file mode 100644 index 0000000000000000000000000000000000000000..293bf70286dbd2b2121ea4f97e8226791d890330 GIT binary patch literal 3404 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 NFf+0;e5UUa_aDY)H$VUY literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/krita.png b/cuegui/cuegui/images/apps/krita.png new file mode 100644 index 0000000000000000000000000000000000000000..7515f0b70c1386a92cc81c85ade7d074eb564939 GIT binary patch literal 9406 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 Si&MTR0TkubWNV}?;QtGnh_QA6 literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/natron.png b/cuegui/cuegui/images/apps/natron.png new file mode 100644 index 0000000000000000000000000000000000000000..6d8b56ba84e75e2e17cf2ae0ee51d9060769fa5b GIT binary patch literal 4285 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 Xhy4#Bgum*TNC0Rd^x)O1Pa^&U0-*A? literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/oiio.png b/cuegui/cuegui/images/apps/oiio.png new file mode 100644 index 0000000000000000000000000000000000000000..7396c24c440f52ee4d8d8c7ec0ec10c345e3cf71 GIT binary patch literal 2679 zcmV--3W)WIP)Px#AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU!)=*4TMgRZ*>+9>8nVFWBmXwr~m6es3mzToA!u|dI{{H^S$;p_Q znB?T-;o;$AWMo@gTR=cSA0HnI3JM7c2^AF;H#av`RaIeOVWOg<{QUf_t*v5WVpLRA zG&D2_2nZk`AVWh#*Votk`}^PD-^Innw6wIVtE;N2s0000P85xX>jNstlj*gB20RcQbJhip8^YioN<>kuC%D1<-udlDYy}i`b z)ZE+LBK0ZEUV`Fx9 zb^`+g9UUEOYirKV&hql|FE1~Vk&)Ti*}lHMaBy%sIy(6H_-Scr)z#JK=jTE~LVbOG z%gf8n&CM(gwuUU0n+c3x|h?f`Wo6DJgn-dZD4Afq{W7EiE}Y zIra7RoSdAzyu2G58_&U1ZBqVWhacymFN=iymQBlXo$2d4RFfcHRii*t4%$=Q` zlarGU4i4Jd+C)S|Mn*>T^z`ZJ=}k>dAt515OiVjFJ5y6rNJvQL=H|%A$W~TXK|w(^ zH8pZ_a=^gAOG`_#va+M2qZk+%prD|Lh=^ZbUv6%0iHV7xo}Saw(-agGxw*MqTwGpW zUYnbn?d|P%cXwxJXDTWxGBPr3Y;3!`yN!*FF)=ZknwrGK#H6I85)u+wSy`~Kuz-Mo zrKP2Re}AT?rb$UjD=RBp{b;TL0004EOGiWihy@);00009a7bBm000XU000XU0RWnu z7ytkUYDq*vRA}DqSm{?3M-X37a7H-Ag@5H%V#@rVg(4$U2N{|D*nJ=kMrdA@wedwEkIc6zGo z=;^BZb@hrw0tqCLKmrLQkU#Og38QVoGo9nG-uiJSkGMKzhdPK z!<1qb7>s+>R6NfEc=-i}_rjv$5^3q`HDz;sSI2RBTME3<3jHQTY?PzLn>H&zTT!>N9-%Eo;g&vE;E%+oytY!Tu72#=c=X?bN~|rE8%ntF=vuP-LOG;|4c`+7EygCd;Oi zrZ?RY>IgE|4!~>Fc$q9)bx@9N1k>hXs;opDh-7*&C)A;Mgxn_wTI7*;975S|F-FF? zSqMpe6_#-dSb@zH=MCm$^I<$Vl4OMy>7Wx~%)Us-_+YDq6K};uDBZ5G?c`_{t(r z+)vwbLcIr=b4qKiE!hncow{;8or=erWb5x06|{j^mo|{!iNxs)JhK=M2st1f_{Ot1 ziBQQoE~HsWj8{?oP69(nM->T3720hVD=UmUbf>B+tmwmE!u;8PI8?4;IS}+OWWx~GM9jdb&FxRO3Nj7 zn#^6f#P1~GDm>2QacN&033K%j?F=G)xs^-oBjV(`9lw)Fr})3*+708E^wg8^)N+Xh z%_K32;*Uw~6?m+e&beJF#+cZB%%5FV$UfoH4g>IFy`WC$GN`x`&LsR4D(z0RjXDwEg;J6pgT8{Ii5E3sw)b@Guc{Xh67aULz-J0A{zxdE{{MP@_T5KwGiH|C5J1KaQY3w>9lY=47XWROdGzy z?p%C0Jy4lh*^r1dozA3#{F*p1L!M>=Yu^x+c~79FGTShTgA6w(r_KB}b>rZBoHw~w zIBgw;$B`1B#hZwdmybBD<%ntI0fElQ`(a=qw{XvR6T(6Qy{TiUZ!KlJ2hyPYi?uRIG>F+T;t+Ytn6VUL?U&r%UTU8mR@1m3Hyf?YDw7C57 zXNH~4n<eNB;ntXI$^ay=++k000?uMObu0 zZ*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0000bbVXQnWMOn=I%9HWVRU5xGB7bX zEif`IFgH{&Fgi3dIxsmaFfckWFc}W(ZvX%QC3HntbYx+4WjbwdWNBu305UK!G%YbP lEiyAyF*Q0dGdeOkD=;uRFfe7%pHKh*002ovPDHLkV1gR*-Jt*g literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/placeholder.png b/cuegui/cuegui/images/apps/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..dad292e86a3ecf208fab872b2e9e4a45d6f4776b GIT binary patch literal 695 zcmYL_TS!v@7{||yQa1%t$|!s|B9?U3QbSa7ZMBJae8|WM(a_AWyw@H?%pt8DM1^KS z=tEQr7D-Gu-TiDk+u6=;=j?WNchhYqG{_#bvnN0Jf8U?~!=I1eWJBG}bm~be008N1 z7Nd#0P(mq($UQT0_Zt9Ek{W87nc>)uKqOXZw85>I-R)ahlZ2wbRa(6cHLpn(zR(tI zFl|J(g<{$2x>Tvr`NI)+AcVU-h{oTQ6tu>f2u^jRQ!+JBOGg@H1QKC>GMvGLbhG4|$@muXK%t5Tl zlrC>Tq0w1vP9tVF;||>EHsKD3$FD}v;AV84ED3}#ryI54sMV%~5sTfW(Hl*e-RAPR zd_lq&G~1lsVA$dIX;HISp)!)+`8Q-LSPE${Cjn{oaR_%_`@s5&q6>ol`7VU5G=Sc#s9VYG&W^<{K=<)0;0%L z@8{dBb2(=Rt9bIcpN|^bb~zoZUFEG4WeWp$kk)WXWvpT@n>xAjHGP2Y-4n2<`L|jq zUotbhyIZEOE8e~$!dYDS$cuPfz6$2=Sw~c2XP~Izb|-2SU$T`+_A&KwtJEe b0FbWfA7zP4gQ%TqLn3E0>llmldt?6r`w4(b literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/postprocess.png b/cuegui/cuegui/images/apps/postprocess.png new file mode 100644 index 0000000000000000000000000000000000000000..74978c2f60e98a7d169d2fd74271728e805cd8a2 GIT binary patch literal 65812 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 PGX~kQdwbP3|3Cf*(77D) literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/rm.png b/cuegui/cuegui/images/apps/rm.png new file mode 100644 index 0000000000000000000000000000000000000000..689f725fd3647a9588a11cebc774d74483817ad2 GIT binary patch literal 1499 zcmeAS@N?(olHy`uVBq!ia0vp^DIm45bDP46hOx7_4S6Fo+k-*%fF5)E5)r z6XFU~U_1(F5CZ@I|7YTSQwI#+qLLuLUP~hGQU^fKfeEv z`D?lB$sC23^SwTECH>f&`+E{o;h%op?2fMXzo#RfOFv9xlaVUAea^yMZP)q@xAyNj zah`|wnH8U)knmGOqZ#vTrUZTq`0_3|Rl8+^Nuz0rPt;Nt(NlLDdY<1qeHdsvW0JSK zOR*!T?KvQav%n*=n1NAX0thp9uDP^>fr070r;B4q#=W<*(!(D)h_t0|SfG#*(ACB2 z7`U-r3$)`51vTKdE~v~WX6T2rimxdOrLnu#sA=novr$- zr=?|aJ=59Kq$9ITcgfW75baXU+@mpJv+urRxcSyB`(nmo-6gRnu3UU+QnQWc+&R93 z*~@j7dV5?s>#4gg`opdlUN2v^+N{&hwie%Y;LY2GO<#5@_Pd|^+VJw-;-)YB6HMZE zZtj~neFyX3kO>DBC#6N)lT&+lVZp4OEf(`VGE$~2k#x3`Txj^Hug@cA-JQFYHHYMX ztntjBuw91e&Of}) ze9?33?(P3~ulT$7u0FGk_3aHub44Gu`2YL%lzT!V`$;de*H0KNtsZDw_c;Em;t7l^ow0Efm6u=aKBI;|=4WGM z#q|GQdNyeJ?)FK#IZ0z|cb1 zz)07?JjBqz%EZ{pz*5`5z{5>! VYDg@t<_BtE@O1TaS?83{1OW7HHy{82 literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/shell.png b/cuegui/cuegui/images/apps/shell.png new file mode 100644 index 0000000000000000000000000000000000000000..f9a53c4ce153d33fe902c54794ad559c3af021bc GIT binary patch literal 5422 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 literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/images/apps/terminal.png b/cuegui/cuegui/images/apps/terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..f9a53c4ce153d33fe902c54794ad559c3af021bc GIT binary patch literal 5422 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 literal 0 HcmV?d00001 diff --git a/cuegui/cuegui/nodegraph/__init__.py b/cuegui/cuegui/nodegraph/__init__.py new file mode 100644 index 000000000..625cfd879 --- /dev/null +++ b/cuegui/cuegui/nodegraph/__init__.py @@ -0,0 +1,21 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""nodegraph is an OpenCue specific extension of NodeGraphQtPy + +The docs for NodeGraphQtPy can be found at: +http://chantasticvfx.com/nodeGraphQt/html/nodes.html +""" +from .nodes import CueLayerNode diff --git a/cuegui/cuegui/nodegraph/nodes/__init__.py b/cuegui/cuegui/nodegraph/nodes/__init__.py new file mode 100644 index 000000000..bd04f566e --- /dev/null +++ b/cuegui/cuegui/nodegraph/nodes/__init__.py @@ -0,0 +1,19 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Module housing node implementations that work with NodeGraphQtPy""" + + +from .layer import CueLayerNode diff --git a/cuegui/cuegui/nodegraph/nodes/base.py b/cuegui/cuegui/nodegraph/nodes/base.py new file mode 100644 index 000000000..6665c6faf --- /dev/null +++ b/cuegui/cuegui/nodegraph/nodes/base.py @@ -0,0 +1,79 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Base class for any cue nodes to work with NodeGraphQtPy""" + + +from builtins import str +from NodeGraphQtPy import BaseNode +from cuegui.nodegraph.widgets.nodeWidgets import NodeProgressBar + + +class CueBaseNode(BaseNode): + """Base class for any cue nodes to work with NodeGraphQtPy""" + + __identifier__ = "aswf.opencue" + + NODE_NAME = "Base" + + def __init__(self, rpcObject=None): + super(CueBaseNode, self).__init__() + self.add_input(name="parent", multi_input=True, display_name=False) + self.add_output(name="children", multi_output=True, display_name=False) + + self.rpcObject = rpcObject + + def setRpcObject(self, rpcObject): + """Set the nodes rpc object + @param rpc object to set on node + @type opencue.wrappers.layer.Layer + """ + self.rpcObject = rpcObject + + def addProgressBar( + self, + name="", + label="", + value=0, + max_value=100, + display_format="%p%", + tab=None + ): + """Add progress bar property to node + @param name: name of the custom property + @type name: str + @param label: label to be displayed + @type label: str + @param value: value to set progress bar to + @type value: int + @param max_value: max_value value progress bar can go up to + @type max_value: int + @param display_format: string format to display value on progress bar with + @type display_format: str + @param tab:name of the widget tab to display in. + @type tab: str + """ + self.create_property( + name, str(value), tab=tab + ) + widget = NodeProgressBar( + self.view,name, + label, + value, + max_value=max_value, + display_format=display_format + ) + widget.value_changed.connect(self.set_property) + self.view.add_widget(widget) diff --git a/cuegui/cuegui/nodegraph/nodes/layer.py b/cuegui/cuegui/nodegraph/nodes/layer.py new file mode 100644 index 000000000..7c9ec2f14 --- /dev/null +++ b/cuegui/cuegui/nodegraph/nodes/layer.py @@ -0,0 +1,97 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Implementation of a Cue Layer node that works with NodeGraphQtPy""" + + +from __future__ import division +import os +from qtpy import QtGui +import opencue +import NodeGraphQtPy.qgraphics.node_base +import cuegui.images +from cuegui.Constants import RGB_FRAME_STATE +from cuegui.nodegraph.nodes.base import CueBaseNode + + +class CueLayerNode(CueBaseNode): + """Implementation of a Cue Layer node that works with NodeGraphQtPy""" + + __identifier__ = "aswf.opencue" + + NODE_NAME = "Layer" + + def __init__(self, layerRpcObject=None): + super(CueLayerNode, self).__init__(rpcObject=layerRpcObject) + + self.set_name(layerRpcObject.name()) + + NodeGraphQtPy.qgraphics.node_base.NODE_ICON_SIZE = 30 + services = layerRpcObject.services() + if services: + app = services[0].name() + imagesPath = cuegui.images.__path__[0] + iconPath = os.path.join(imagesPath, "apps", app + ".png") + if os.path.exists(iconPath): + self.set_icon(iconPath) + + self.addProgressBar( + name="succeededFrames", + label="", + value=layerRpcObject.succeededFrames(), + max_value=layerRpcObject.totalFrames(), + display_format="%v / %m" + ) + + font = self.view.text_item.font() + font.setPointSize(16) + self.view.text_item.setFont(font) + # Lock the node text so it can't be edited + self.view.text_item.set_locked(True) + + self.setRpcObject(layerRpcObject) + + def updateNodeColour(self): + """Update the colour of the node to reflect the status of the layer""" + # default colour + r, g, b = self.color() + color = QtGui.QColor(r, g, b) + + # state specific colours + if self.rpcObject.totalFrames() == self.rpcObject.succeededFrames(): + color = RGB_FRAME_STATE[opencue.api.job_pb2.SUCCEEDED] + if self.rpcObject.waitingFrames() > 0: + color = RGB_FRAME_STATE[opencue.api.job_pb2.WAITING] + if self.rpcObject.dependFrames() > 0: + color = RGB_FRAME_STATE[opencue.api.job_pb2.DEPEND] + if self.rpcObject.runningFrames() > 0: + color = RGB_FRAME_STATE[opencue.api.job_pb2.RUNNING] + if self.rpcObject.deadFrames() > 0: + color = RGB_FRAME_STATE[opencue.api.job_pb2.DEAD] + + self.set_color( + color.red() // 2, + color.green() // 2, + color.blue() // 2 + ) + + def setRpcObject(self, rpcObject): + """Set the nodes layer rpc object + @param rpc object to set on node + @type opencue.wrappers.layer.Layer + """ + super(CueLayerNode, self).setRpcObject(rpcObject) + self.set_property("succeededFrames", rpcObject.succeededFrames()) + self.updateNodeColour() diff --git a/cuegui/cuegui/nodegraph/widgets/__init__.py b/cuegui/cuegui/nodegraph/widgets/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/cuegui/cuegui/nodegraph/widgets/nodeWidgets.py b/cuegui/cuegui/nodegraph/widgets/nodeWidgets.py new file mode 100644 index 000000000..e881f0a27 --- /dev/null +++ b/cuegui/cuegui/nodegraph/widgets/nodeWidgets.py @@ -0,0 +1,112 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Module defining custom widgets that appear on nodes in the nodegraph. + +The classes defined here inherit from NodeGraphQtPy base classes, therefore any +snake_case methods defined here are overriding the base class and must remain +snake_case to work properly. +""" + + +from qtpy import QtWidgets +from qtpy import QtCore +from NodeGraphQtPy.widgets.node_widgets import NodeBaseWidget + + +class NodeProgressBar(NodeBaseWidget): + """ + ProgressBar Node Widget. + """ + + def __init__( + self, + parent=None, + name="", + label="", + value=0, + max_value=100, + display_format="%p%" + ): + super(NodeProgressBar, self).__init__(parent, name, label) + self._progressbar = QtWidgets.QProgressBar() + self._progressbar.setAlignment(QtCore.Qt.AlignCenter) + self._progressbar.setFormat(display_format) + self._progressbar.setMaximum(max_value) + self._progressbar.setValue(value) + progress_style = """ +QProgressBar { + background-color: rgba(40, 40, 40, 255); + border: 1px solid grey; + border-radius: 1px; + margin: 0px; +} +QProgressBar::chunk { + background-color: rgba(100, 120, 250, 150); +} + """ + self._progressbar.setStyleSheet(progress_style) + self.set_custom_widget(self._progressbar) + self.text = str(value) + + @property + def type_(self): + """ + @return: Name of widget type + @rtype: str + """ + return "ProgressBarNodeWidget" + + def get_value(self): + """Get value from progress bar on node + @return: progress bar value + @rtype: int + """ + return self._progressbar.value() + + def set_value(self, text=0): + """Set value on progress bar + @param text: Text value to set on progress bar + @type text: int + """ + if int(float(text)) != self.get_value(): + self._progressbar.setValue(int(float(text))) + self.on_value_changed() + + @property + def value(self): + """Get value from progress bar on node + XXX: This property shouldn't be required as it's been superseded by get_value, + however the progress bar doesn't update without it. Believe it may be + a bug in NodeGraphQtPy's `NodeObject.set_property`. We should remove this + once it's been resolved. + @return: progress bar value + @rtype: int + """ + return self._progressbar.value() + + @value.setter + def value(self, value=0): + """Set value on progress bar + XXX: This property shouldn't be required as it's been superseded by set_value, + however the progress bar doesn't update without it. Believe it may be + a bug in NodeGraphQtPy's `NodeObject.set_property`. We should remove this + once it's been resolved. + @param value: Value to set on progress bar + @type value: int + """ + if int(float(value)) != self.value: + self._progressbar.setValue(int(float(value))) + self.on_value_changed() diff --git a/cuegui/cuegui/plugins/MonitorJobGraphPlugin.py b/cuegui/cuegui/plugins/MonitorJobGraphPlugin.py new file mode 100644 index 000000000..9d93e27f0 --- /dev/null +++ b/cuegui/cuegui/plugins/MonitorJobGraphPlugin.py @@ -0,0 +1,103 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + + +"""Plugin for displaying node graph representation of layer in the selected job. + +Job selection is triggered by other plugins using the application's view_object signal.""" + + +from __future__ import print_function +from __future__ import division +from __future__ import absolute_import + +import opencue + +import cuegui.AbstractDockWidget +import cuegui.Logger +import cuegui.Utils + +import cuegui.JobMonitorGraph + + +logger = cuegui.Logger.getLogger(__file__) + +PLUGIN_NAME = "Job Graph" +PLUGIN_CATEGORY = "Cuetopia" +PLUGIN_DESCRIPTION = "Visualise a job's layers in a node graph" +PLUGIN_PROVIDES = "MonitorGraphDockWidget" + + +class MonitorGraphDockWidget(cuegui.AbstractDockWidget.AbstractDockWidget): + """Plugin for displaying node graph representation of layer in the selected job.""" + + def __init__(self, parent): + """Creates the dock widget and docks it to the parent. + @param parent: The main window to dock to + @type parent: QMainWindow""" + cuegui.AbstractDockWidget.AbstractDockWidget.__init__(self, parent, PLUGIN_NAME) + + self.__job = None + + self.__monitorGraph = cuegui.JobMonitorGraph.JobMonitorGraph(self) + + self.setAcceptDrops(True) + + self.layout().addWidget(self.__monitorGraph) + + cuegui.app().view_object.connect(self.__setJob) + cuegui.app().unmonitor.connect(self.__unmonitor) + cuegui.app().facility_changed.connect(self.__setJob) + + # pylint: disable=missing-function-docstring + def dragEnterEvent(self, event): + cuegui.Utils.dragEnterEvent(event) + + # pylint: disable=missing-function-docstring + def dragMoveEvent(self, event): + cuegui.Utils.dragMoveEvent(event) + + # pylint: disable=missing-function-docstring + def dropEvent(self, event): + for jobName in cuegui.Utils.dropEvent(event): + self.__setJob(jobName) + + def __setJob(self, job = None): + """Set the job to be displayed + @param job: Selected job + @type job: opencue.wrappers.job.Job + """ + if cuegui.Utils.isJob(job) and self.__job and opencue.id(job) == opencue.id(self.__job): + return + + newJob = cuegui.Utils.findJob(job) + if newJob: + self.__job = newJob + self.setWindowTitle("%s" % newJob.name()) + self.raise_() + + self.__monitorGraph.setJob(newJob) + elif not job and self.__job: + self.__unmonitor(self.__job) + + def __unmonitor(self, proxy): + """Unmonitors the current job if it matches the supplied proxy. + @param proxy: A job proxy + @type proxy: proxy""" + if self.__job and self.__job == proxy: + self.__job = None + self.setWindowTitle("Monitor Job Graph") + + self.__monitorGraph.setJob(None) diff --git a/cuegui/tests/plugins/JobGraphPlugin_tests.py b/cuegui/tests/plugins/JobGraphPlugin_tests.py new file mode 100644 index 000000000..4912825fe --- /dev/null +++ b/cuegui/tests/plugins/JobGraphPlugin_tests.py @@ -0,0 +1,64 @@ +# Copyright Contributors to the OpenCue Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +"""Tests for cuegui.plugins.MonitorJobGraphPlugin.""" + + +import unittest + +import mock + +import opencue.compiled_proto.job_pb2 +import opencue.compiled_proto.depend_pb2 +import opencue.wrappers.job +import opencue.wrappers.layer +import opencue.wrappers.depend + +import qtpy.QtCore +import qtpy.QtGui +import qtpy.QtTest +import qtpy.QtWidgets + +import cuegui.Main +import cuegui.plugins.MonitorJobGraphPlugin +import cuegui.JobMonitorGraph +import cuegui.Style +from .. import test_utils + + +@mock.patch('opencue.cuebot.Cuebot.getStub', new=mock.Mock()) +class MonitorJobGraphPluginTests(unittest.TestCase): + + @mock.patch('opencue.cuebot.Cuebot.getStub', new=mock.Mock()) + @mock.patch('opencue.api.getJob') + def setUp(self, getJobMock): + app = test_utils.createApplication() + app.settings = qtpy.QtCore.QSettings() + cuegui.Style.init() + self.main_window = qtpy.QtWidgets.QMainWindow() + + self.job = opencue.wrappers.job.Job(opencue.compiled_proto.job_pb2.Job(id='foo')) + layer = opencue.wrappers.layer.Layer(opencue.compiled_proto.job_pb2.Layer(name='layer1')) + depend = opencue.wrappers.depend.Depend(opencue.compiled_proto.depend_pb2.Depend()) + layer.getWhatDependsOnThis = lambda: [depend] + self.job.getLayers = lambda: [layer] + self.jobGraph = cuegui.JobMonitorGraph.JobMonitorGraph(self.main_window) + self.jobGraph.setJob(self.job) + + def test_setup(self): + pass + + def test_job(self): + self.assertNotEqual(None, self.jobGraph.getJob()) diff --git a/pycue/opencue/wrappers/layer.py b/pycue/opencue/wrappers/layer.py index 264ac8bf3..778580fc8 100644 --- a/pycue/opencue/wrappers/layer.py +++ b/pycue/opencue/wrappers/layer.py @@ -591,3 +591,10 @@ def parent(self): :return: the layer's parent job """ return opencue.api.getJob(self.data.parent_id) + + def services(self): + """Returns list of services applied to this layer + :rtype: opencue.wrappers.service.Service + :return: the layer's services + """ + return [opencue.api.getService(service) for service in self.data.services] diff --git a/requirements_gui.txt b/requirements_gui.txt index 1f5b19637..b93a77357 100644 --- a/requirements_gui.txt +++ b/requirements_gui.txt @@ -3,3 +3,4 @@ PySide6==6.5.3;python_version=="3.11" PySide2==5.15.2.1;python_version<="3.10" QtPy==1.11.3;python_version<"3.7" QtPy==2.4.1;python_version>="3.7" +NodeGraphQtPy==0.6.38.6