From 3170490a5857222ff64cd7660a5b403432e2e53d Mon Sep 17 00:00:00 2001 From: Ramon Figueiredo Date: Fri, 25 Oct 2024 15:14:07 -0700 Subject: [PATCH] [cuegui]: Fix multiple jobs and frames visualization This fixes the changes in PR: https://github.com/AcademySoftwareFoundation/OpenCue/pull/1513 Changes: - Fix multiple jobs and frames visualization with different viewers - Updated JobMonitorTree.py and FrameMonitorTree.py to enable select multiple jobs and multiple frames and play using the players (e.g., OpenRV, RV, Itview = SPI viewer) configured in `cuegui.yaml`, options `output_viewers` and `output_viewer_direct_cmd_call` - Enhanced cuegui.yaml to include configuration for multiple viewers. - Fix unit tests in `FrameMonitorTree_tests.py` > `test_rightClickItem()` to ensure the job attribute is set This change allows users to open multiple jobs (JobMonitorTree.py) and frames (FrameMonitorTree.py) using different configurable viewers. The option to open multiple layers (LayerMonitorTree.py) was working before and kept as it was. --- cuegui/cuegui/FrameMonitorTree.py | 15 +++++++++++---- cuegui/cuegui/JobMonitorTree.py | 12 ++++-------- cuegui/cuegui/config/cuegui.yaml | 24 ++++++++++-------------- cuegui/tests/FrameMonitorTree_tests.py | 3 +++ 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/cuegui/cuegui/FrameMonitorTree.py b/cuegui/cuegui/FrameMonitorTree.py index 9e29aa0b2..8131b6c2f 100644 --- a/cuegui/cuegui/FrameMonitorTree.py +++ b/cuegui/cuegui/FrameMonitorTree.py @@ -916,15 +916,22 @@ def __init__(self, widget, filterSelectedLayersCallback, readonly=False): if cuegui.Constants.OUTPUT_VIEWERS: job = widget.getJob() outputPaths = [] - for frame in widget.selectedObjects(): - layer = job.getLayer(frame.layer()) - outputPaths.extend(cuegui.Utils.getOutputFromFrame(layer, frame)) + selectedFrames = widget.selectedObjects() + + layers_dict = {layer.name(): layer for layer in job.getLayers()} + + for frame in selectedFrames: + layer_name = frame.layer() + layer = layers_dict.get(layer_name) + if layer: + outputPaths.extend(cuegui.Utils.getOutputFromFrame(layer, frame)) + if outputPaths: for viewer in cuegui.Constants.OUTPUT_VIEWERS: self.addAction(viewer['action_text'], functools.partial(cuegui.Utils.viewFramesOutput, job, - widget.selectedObjects(), + selectedFrames, viewer['action_text'])) if self.app.applicationName() == "CueCommander": diff --git a/cuegui/cuegui/JobMonitorTree.py b/cuegui/cuegui/JobMonitorTree.py index 901ae62e9..7a2946794 100644 --- a/cuegui/cuegui/JobMonitorTree.py +++ b/cuegui/cuegui/JobMonitorTree.py @@ -427,15 +427,11 @@ def contextMenuEvent(self, e): self.__menuActions.jobs().addAction(menu, "useLocalCores") if cuegui.Constants.OUTPUT_VIEWERS: - job = __selectedObjects[0] for viewer in cuegui.Constants.OUTPUT_VIEWERS: - viewer_menu = QtWidgets.QMenu(viewer['action_text'], self) - for layer in job.getLayers(): - viewer_menu.addAction(layer.name(), - functools.partial(cuegui.Utils.viewOutput, - [layer], - viewer['action_text'])) - menu.addMenu(viewer_menu) + menu.addAction(viewer['action_text'], + functools.partial(cuegui.Utils.viewOutput, + __selectedObjects, + viewer['action_text'])) depend_menu = QtWidgets.QMenu("&Dependencies",self) self.__menuActions.jobs().addAction(depend_menu, "viewDepends") diff --git a/cuegui/cuegui/config/cuegui.yaml b/cuegui/cuegui/config/cuegui.yaml index 546e52527..6553030d0 100644 --- a/cuegui/cuegui/config/cuegui.yaml +++ b/cuegui/cuegui/config/cuegui.yaml @@ -1,6 +1,6 @@ # Default CueGUI config file -# Configure how a version number should be acquired. +# Configure how a version number should be acquired. # - False, use the version number in VERSION.in # - True, run the commands defined at cuegui.custom.cmd.version.beta (for beta) or cuegui.custom.cmd.version.stable (for stable) to acquire the version number cuegui.use.custom.version: False @@ -133,23 +133,19 @@ startup_notice.msg: '' memory_warning_level: 5242880 # Output Viewers config. -# # ------------------------------------------------------------------------------------------------------ # Frame, Layer and Job objects have right click menu option for opening an output viewer # (eg. OpenRV) - -#output_viewers: +# output_viewers: # # Text to be displayed at the menu action button # - action_text: "View in OpenRV" -# # extract_args_regex: Regex to extract arguments from the output path produced by a job/layer/frame -# # cmd_pattern: Command pattern to be matched with the regex defined at extract_args_regex -# # if extract_args_regex is not provided, cmd_pattern is called directly with paths as arguments -# extract_args_regex: '/shots/(?P\w+)/(?Pshot\w+)/.*' -# cmd_pattern: "env SHOW={show} SHOT={shot} COLOR_IO=/{show}/home/colorspaces.xml OCIO=/{show}/home/config.ocio openrv {paths}" - -# # if provided, paths containing any of the two values are considered the same output and only one -# # of them will be passed to the viewer -# stereo_modifiers: "_rt_,_lf_" -# # ------------------------------------------------------------------------------------------------------ +# # extract_args_regex: Regex to extract arguments from the output path produced by a job/layer/frame +# # cmd_pattern: Command pattern to be matched with the regex defined at extract_args_regex +# # if extract_args_regex is not provided, cmd_pattern is called directly with paths as arguments +# extract_args_regex: '/shots/(?P\w+)/(?Pshot\w+)/.*' +# cmd_pattern: "env SHOW={show} SHOT={shot} COLOR_IO=/{show}/home/colorspaces.xml OCIO=/{show}/home/config.ocio openrv {paths}" +# # if provided, paths containing any of the two values are considered the same output and only one +# # of them will be passed to the viewer +# stereo_modifiers: "_rt_,_lf_" # Pattern to call viewer cmd directly without extracting environment variables. Used for previewing frames # output_viewer_direct_cmd_call: "openrv {paths}" diff --git a/cuegui/tests/FrameMonitorTree_tests.py b/cuegui/tests/FrameMonitorTree_tests.py index 75521572f..27190fd8d 100644 --- a/cuegui/tests/FrameMonitorTree_tests.py +++ b/cuegui/tests/FrameMonitorTree_tests.py @@ -128,6 +128,9 @@ def test_getCores(self): def test_rightClickItem(self, execMock): mouse_position = qtpy.QtCore.QPoint() + # Ensure the job attribute is set + self.frameMonitorTree.setJob(self.job) + self.frameMonitorTree.contextMenuEvent( qtpy.QtGui.QContextMenuEvent( qtpy.QtGui.QContextMenuEvent.Reason.Mouse, mouse_position, mouse_position))