def open_window(cls, show=True, auto_raise=True, delete=False, dock=False):
        s = time.time()
        if (cls is not None and uiutils.isValidQtObject(cls.instance) is True):
            if delete is True:
                cls.instance.close()
                cls.instance.deleteLater()

        if (cls.instance is None
                or uiutils.isValidQtObject(cls.instance) is False):
            name = cls.name
            app, parent = uiutils.getParent()
            cls.instance = cls(parent=parent, name=name)
            cls.instance.setDockableParameters(dockable=dock)

        # Make sure the user can see this window.
        if cls.instance.isHidden():
            if show is True:
                cls.instance.show()
        if auto_raise is True:
            # Force the window state to bring the window to the
            # front, and "restore" the state, even if the window
            # is minimised. Confirmed to work on MS Windows 10.
            state = cls.instance.windowState()
            state = QtCore.Qt.WindowNoState
            state |= QtCore.Qt.WindowActive
            cls.instance.setWindowState(state)

            cls.instance.raise_()
            cls.instance.show()
            cls.instance.activateWindow()
        e = time.time()
        LOG.debug('BaseWindow init: %r seconds', e - s)
        return cls.instance
Exemple #2
0
 def setSolveInfoLine(self, text):
     valid = uiutils.isValidQtObject(self)
     if valid is False:
         return
     valid = uiutils.isValidQtObject(self.solver_state)
     if valid is False:
         return
     self.solver_state.setSolveInfoLine(text)
     return
Exemple #3
0
 def setSolveInfoLine(self, text):
     valid = uiutils.isValidQtObject(self)
     if valid is False:
         return
     valid = uiutils.isValidQtObject(self.solveInfoLine_lineEdit)
     if valid is False:
         return
     self.solveInfoLine_lineEdit.setText(text)
     return
Exemple #4
0
 def setStatusLine(self, text):
     valid = uiutils.isValidQtObject(self)
     if valid is False:
         return
     valid = uiutils.isValidQtObject(self.statusLine_label)
     if valid is False:
         return
     self.statusLine_label.setText(text)
     return
def setNodeSelectionWithUUID(tree_view, model, filter_model, sel_model,
                             column_name, values):
    """
    Override the tree view selection based on Maya Node UUIDs.
    """
    # Ensure we don't try to access the Qt objects if they no longer
    # exist in memory.
    objs = [tree_view, model, filter_model, sel_model]
    for obj in objs:
        valid = uiutils.isValidQtObject(obj)
        if valid is False:
            return

    root_index = tree_view.rootIndex()
    column = model.getColumnIndexFromColumnName(column_name)
    indexes = _lookupIndexesFromMayaNodeUUIDs(
        values,
        root_index,
        column,
        model,
    )
    sel_model.clearSelection()  # replace the selection.
    flags = QtCore.QItemSelectionModel.Select
    flags |= QtCore.QItemSelectionModel.Rows
    for index in indexes:
        new_index = filter_model.mapFromSource(index)
        sel_model.select(new_index, flags)
    return
    def populateModel(self, model, col):
        s = time.time()
        valid = uiutils.isValidQtObject(model)
        if valid is False:
            return
        attr_list = []
        show_anm = const.ATTRIBUTE_TOGGLE_ANIMATED_DEFAULT_VALUE
        show_stc = const.ATTRIBUTE_TOGGLE_STATIC_DEFAULT_VALUE
        show_lck = const.ATTRIBUTE_TOGGLE_LOCKED_DEFAULT_VALUE
        if col is not None:
            attr_list = lib_attr.get_attributes_from_collection(col)
            show_anm = lib_col.get_attribute_toggle_animated_from_collection(
                col)
            show_stc = lib_col.get_attribute_toggle_static_from_collection(col)
            show_lck = lib_col.get_attribute_toggle_locked_from_collection(col)

        # Add Callbacks
        #
        # When querying attributes, we must make sure they have a Maya
        # callback attached to the node to update the UI.
        callback_manager = self.callback_manager
        if callback_manager is not None:
            lib_attr.add_callbacks_to_attributes(
                attr_list,
                callback_manager,
            )
        root = convert_to_ui.attributesToUINodes(col, attr_list, show_anm,
                                                 show_stc, show_lck)
        model.setRootNode(root)

        e = time.time()
        LOG.debug('populateModel: %r', e - s)
        return
    def populateModel(self, model):
        valid = uiutils.isValidQtObject(model)
        if valid is False:
            return
        col = lib_state.get_active_collection()
        attr_list = []
        show_anm = const.ATTRIBUTE_TOGGLE_ANIMATED_DEFAULT_VALUE
        show_stc = const.ATTRIBUTE_TOGGLE_STATIC_DEFAULT_VALUE
        show_lck = const.ATTRIBUTE_TOGGLE_LOCKED_DEFAULT_VALUE
        if col is not None:
            attr_list = lib_attr.get_attributes_from_collection(col)
            show_anm = lib_col.get_attribute_toggle_animated_from_collection(
                col)
            show_stc = lib_col.get_attribute_toggle_static_from_collection(col)
            show_lck = lib_col.get_attribute_toggle_locked_from_collection(col)

        def update_func():
            if uiutils.isValidQtObject(self) is False:
                return
            self.dataChanged.emit()
            return

        # Add Callbacks
        #
        # When querying attributes, we must make sure they have a Maya
        # callback attached to the node to update the UI.
        callback_manager = self.callback_manager
        if callback_manager is not None:
            lib_attr.add_callbacks_to_attributes(attr_list, update_func,
                                                 callback_manager)
        root = convert_to_ui.attributesToUINodes(col, attr_list, show_anm,
                                                 show_stc, show_lck)
        model.setRootNode(root)
        return
def main(show=True, widthHeight=(800, 600)):
    # Force the Plug-in to load.  If the plug-in cannot load, the UI
    # will not open and an error will be given.
    lib_maya_utils.ensure_plugin_loaded()

    global UI

    valid = uiutils.isValidQtObject(UI)
    if UI is not None and valid is True:
        UI.close()

    name = 'SolverWindow'
    app, parent = uiutils.getParent()
    UI = SolverWindow(parent=parent, name=name)
    if not UI:
        return UI
    if show:
        UI.show()

    if ((isinstance(widthHeight, (tuple, list)) is True)
            and (len(widthHeight) == 2)):
        pos = UI.pos()
        UI.setGeometry(pos.x(), pos.y(), widthHeight[0], widthHeight[1])

    # Enter Qt application main loop
    if app is not None:
        sys.exit(app.exec_())
    return UI
Exemple #9
0
    def populateAttributeModel(self, model):
        valid = uiutils.isValidQtObject(model)
        if valid is False:
            return
        col = lib_state.get_active_collection()
        attr_list = []
        if col is not None:
            attr_list = lib_attr.get_attributes_from_collection(col)

        def update_func():
            if uiutils.isValidQtObject(self) is False:
                return
            self.updateAttributeModel()
            return

        # Add Callbacks
        #
        # When querying attributes, we must make sure they have a Maya
        # callback attached to the node to update the UI.
        callback_manager = self.getCallbackManager()
        if callback_manager is not None:
            lib_attr.add_callbacks_to_attributes(
                attr_list,
                update_func,
                callback_manager
            )
        root = convert_to_ui.attributesToUINodes(attr_list)
        model.setRootNode(root)
        return
def run_solve(override_current_frame=None):
    """
    Run the solver for the active collection.

    If the Solver UI is found, the window will update and show
    progress messages.

    This function is strongly dependant on the Solver UI.
    The following state information is set via the Solver UI.

    - Active Collection
    - Log Level
    - Refresh Viewport

    :param override_current_frame: Before running the solver, change
                                   the "override current frame" state to
                                   this value.
    :type override_current_frame: bool
    """
    assert (override_current_frame is None
            or isinstance(override_current_frame, bool))
    if override_current_frame is None:
        override_current_frame = False

    col = lib_state.get_active_collection()
    if col is None:
        msg = 'No active Collection found. Skipping solve.'
        LOG.warning(msg)
        return
    log_level = lib_state.get_log_level()

    layout = None
    win = solver_window.SolverWindow.get_instance()
    win_valid = uiutils.isValidQtObject(win)
    if win is None and win_valid:
        msg = 'Could not get window.'
        LOG.warning(msg)
    else:
        layout = win.getSubForm()

    # Set 'override current frame' value.
    tab = lib_col_state.get_solver_tab_from_collection(col)
    prev_value = None
    if override_current_frame is True:
        prev_value = __get_override_current_frame_value(col, tab)
        __set_override_current_frame_value(col, layout, tab, override_current_frame)

    # Run Solver
    options = lib_col.gather_execute_options()
    lib_col.run_solve_ui(
        col,
        options,
        log_level,
        win,
    )

    # Restore previous value.
    if override_current_frame is True:
        __set_override_current_frame_value(col, layout, tab, prev_value)
    return
def main(show=True, widthHeight=(400, 100)):
    global MM_SOLVER_CHAN_SENSE_UI

    valid = uiutils.isValidQtObject(MM_SOLVER_CHAN_SENSE_UI)
    if MM_SOLVER_CHAN_SENSE_UI is not None and valid is True:
        MM_SOLVER_CHAN_SENSE_UI.close()

    name = 'ChannelSenWindow'
    app, parent = uiutils.getParent()
    MM_SOLVER_CHAN_SENSE_UI = ChannelSenWindow(parent=parent, name=name)
    if not MM_SOLVER_CHAN_SENSE_UI:
        return MM_SOLVER_CHAN_SENSE_UI
    if show:
        MM_SOLVER_CHAN_SENSE_UI.show()

    if ((isinstance(widthHeight, (tuple, list)) is True)
            and (len(widthHeight) == 2)):
        pos = MM_SOLVER_CHAN_SENSE_UI.pos()
        MM_SOLVER_CHAN_SENSE_UI.setGeometry(pos.x(), pos.y(), widthHeight[0],
                                            widthHeight[1])

    # Enter Qt application main loop
    if app is not None:
        sys.exit(app.exec_())
    return MM_SOLVER_CHAN_SENSE_UI
Exemple #12
0
 def update_func():
     if uiutils.isValidQtObject(self) is False:
         return
     self.updateObjectToggleButtons()
     self.updateObjectModel()
     self.updateSolveValidState()
     return
Exemple #13
0
 def update_func():
     if uiutils.isValidQtObject(self) is False:
         return
     self.updateAttributeToggleButtons()
     self.updateAttributeColumnVisibility()
     self.updateAttributeModel()
     self.updateSolveValidState()
     return
Exemple #14
0
def __set_window_instance(window):
    """
    Set the stored instance of the Solver window.
    """
    global MM_SOLVER_SOLVER_UI
    valid = uiutils.isValidQtObject(MM_SOLVER_SOLVER_UI)
    if valid is True:
        MM_SOLVER_SOLVER_UI = window
    return
Exemple #15
0
    def updateAttributeModel(self):
        self.populateAttributeModel(self.attribute_model)
        valid = uiutils.isValidQtObject(self.attribute_treeView)
        if valid is False:
            return
        self.attribute_treeView.expandAll()

        widgets = [self.attribute_frame]
        self.populateWidgetsEnabled(widgets)
        return
Exemple #16
0
 def populateModel(self, model):
     """
     Set the model based on the current Maya scene state.
     """
     valid = uiutils.isValidQtObject(model)
     if valid is False:
         return
     string_data_list = self.getRangeTypeStringDataList()
     model.setStringDataList(string_data_list)
     return
Exemple #17
0
 def populateCollectionModel(self, model):
     valid = uiutils.isValidQtObject(model)
     if valid is False:
         return
     cols = lib_col.get_collections()
     string_data_list = []
     for col in cols:
         node = col.get_node()
         string_data_list.append((node, col))
     model.setStringDataList(string_data_list)
     return
Exemple #18
0
 def populateSolverModel(self, model):
     valid = uiutils.isValidQtObject(model)
     if valid is False:
         return
     col = lib_state.get_active_collection()
     if col is None:
         step_list = []
     else:
         step_list = lib_col.get_solver_steps_from_collection(col)
     node_list = convert_to_ui.solverStepsToUINodes(step_list, col)
     self.solver_model.setNodeList(node_list)
     return
Exemple #19
0
def get_window_instance():
    """
    Get the currently running instance of the Solver window.

    :returns: An object of SolverWindow, or None.
    :rtype: SolverWindow or None
    """
    global MM_SOLVER_SOLVER_UI
    valid = uiutils.isValidQtObject(MM_SOLVER_SOLVER_UI)
    if MM_SOLVER_SOLVER_UI is None or valid is False:
        return None
    return MM_SOLVER_SOLVER_UI
 def apply(self):
     """
     This button launches a solve, but can also be used to cancel a solve.
     """
     running_state = lib_state.get_solver_is_running_state()
     if running_state is True:
         # Cancel out of a running solve if the user presses
         # the button again.
         lib_state.set_solver_user_interrupt_state(True)
         return
     if uiutils.isValidQtObject(self) is False:
         return
     undo_id = 'mmSolver: '
     undo_id += str(datetime.datetime.isoformat(datetime.datetime.now()))
     undo_id += ' '
     undo_id += str(uuid.uuid4())
     with tools_utils.tool_context(use_undo_chunk=True,
                                   undo_chunk_name=undo_id,
                                   restore_current_frame=False,
                                   pre_update_frame=False,
                                   post_update_frame=False,
                                   use_dg_evaluation_mode=True,
                                   disable_viewport=False):
         block = self.blockSignals(True)
         try:
             mmapi.set_solver_running(True)
             self.applyBtn.setText(const.WINDOW_BUTTON_SOLVE_STOP_LABEL)
             self.closeBtn.setText(const.WINDOW_BUTTON_CLOSE_AND_STOP_LABEL)
             options = lib_collection.gather_execute_options()
             log_level = lib_state.get_log_level()
             col = lib_state.get_active_collection()
             lib_collection.run_solve_ui(col, options, log_level, self)
         finally:
             mmapi.set_solver_running(False)
             if uiutils.isValidQtObject(self) is True:
                 self.applyBtn.setText(
                     const.WINDOW_BUTTON_SOLVE_START_LABEL)
                 self.closeBtn.setText(const.WINDOW_BUTTON_CLOSE_LABEL)
                 self.blockSignals(block)
     return
Exemple #21
0
 def close_all_instances(cls):
     global ALL_CLASS_INSTANCES
     for instance in ALL_CLASS_INSTANCES:
         if not instance:
             continue
         if uiutils.isValidQtObject(instance) is False:
             continue
         LOG.debug("Closing: %r", instance.objectName())
         instance.deleteLater()
         instance.close()
     del ALL_CLASS_INSTANCES
     ALL_CLASS_INSTANCES = set()
     return
    def open_window(cls, show=True, auto_raise=True, delete=False):
        if (cls is not None
                and uiutils.isValidQtObject(cls.instance) is False):
            if delete is True:
                cls.instance.close()
                cls.instance.deleteLater()

        if (cls.instance is None
                or uiutils.isValidQtObject(cls.instance) is False):
            name = cls.name
            app, parent = uiutils.getParent()
            cls.instance = cls(parent=parent, name=name)

        # Make sure the user can see this window.
        if cls.instance.isHidden():
            if show is True:
                cls.instance.show()
        else:
            if auto_raise is True:
                cls.instance.raise_()
                cls.instance.activateWindow()
        return cls.instance
Exemple #23
0
 def populateModel(self, model):
     """
     Set the model based on the current Maya scene state.
     """
     valid = uiutils.isValidQtObject(model)
     if valid is False:
         return
     cols = lib_col.get_collections()
     string_data_list = []
     for col in cols:
         node = col.get_node()
         string_data_list.append((node, col))
     model.setStringDataList(string_data_list)
     return
    def setMinimalUI(self, value):
        """
        Change the currently open Solver window to be "minimal", or not.

        If the Solver window is not open, nothing happens.

        "minimal" UI means hiding most widgets in the Solver UI, and not
        "minimal" means showing all widgets as a user normally would
        expect.
        """
        assert isinstance(value, bool)

        def _set_widget_visibilty(window, visible):
            self.menubar.setVisible(visible)
            self.subForm.collection_widget.setVisible(visible)
            self.subForm.object_browser.setVisible(visible)
            self.subForm.attribute_browser.setVisible(visible)
            self.subForm.solver_settings.setVisible(visible)
            self.subForm.ui.objectAttribute_splitter.setVisible(visible)
            self.subForm.ui.line_1.setVisible(visible)
            self.subForm.ui.line_2.setVisible(visible)

        if uiutils.isValidQtObject(self) is True:
            QtWidgets.QApplication.processEvents()
            if value is False:
                _set_widget_visibilty(self, True)

                # Restore non-minimal window size.
                QtWidgets.QApplication.processEvents()
                self.resize(self._saved_ui_size)
            else:
                self._saved_ui_size = self.size()

                # QtWidgets.QApplication.processEvents()
                _set_widget_visibilty(self, False)
                QtWidgets.QApplication.processEvents()

                # Resize the bottom window edge upwards.
                width = self.size().width()
                self.resize(width, 1)
                QtWidgets.QApplication.processEvents()

                # Run again to trigger the UI to resize properly.
                _set_widget_visibilty(self, False)
                self.resize(width, 1)
                QtWidgets.QApplication.processEvents()

        QtWidgets.QApplication.processEvents()
        return
 def populateModel(self, model, col):
     valid = uiutils.isValidQtObject(model)
     if valid is False:
         return
     mkr_list = []
     show_cam = const.OBJECT_TOGGLE_CAMERA_DEFAULT_VALUE
     show_mkr = const.OBJECT_TOGGLE_MARKER_DEFAULT_VALUE
     show_bnd = const.OBJECT_TOGGLE_BUNDLE_DEFAULT_VALUE
     if col is not None:
         mkr_list = lib_marker.get_markers_from_collection(col)
         show_cam = lib_col.get_object_toggle_camera_from_collection(col)
         show_mkr = lib_col.get_object_toggle_marker_from_collection(col)
         show_bnd = lib_col.get_object_toggle_bundle_from_collection(col)
     root = convert_to_ui.markersToUINodes(mkr_list, show_cam, show_mkr, show_bnd)
     model.setRootNode(root)
     return
def selection_changed_func(clientData):
    """The Maya selection has changed, we must synchronize the Maya
    selection with the Solver UI.

    :param clientData: The Qt window object class.
    :type clientData: SolverWindow

    :return: Nothing.
    :rtype: None
    """
    if mmapi.is_solver_running() is True:
        return
    sel_uuids = maya.cmds.ls(selection=True, uuid=True) or []
    valid = uiutils.isValidQtObject(clientData)
    if clientData is not None and valid is True:
        clientData.setNodeSelection(sel_uuids)
    return
    def updateModel(self):
        is_running = mmapi.is_solver_running()
        if is_running is True:
            return
        self.populateModel(self.model)
        valid = uiutils.isValidQtObject(self.treeView)
        if valid is False:
            return
        self.treeView.expandAll()

        widgets = [self]
        _populateWidgetsEnabled(widgets)

        block = self.blockSignals(True)
        self.dataChanged.emit()
        self.blockSignals(block)
        return
Exemple #28
0
 def getDefaultCollectionIndex(self, model, col):
     """
     Get the index for the 'currently selected' collection.
     """
     valid = uiutils.isValidQtObject(model)
     if valid is False:
         return
     if col is None:
         return None
     active_node = col.get_node()
     if active_node is None:
         return None
     string_data_list = model.stringDataList()
     string_list = [string for string, data in string_data_list]
     index = None
     if active_node in string_list:
         index = string_list.index(active_node)
     return index
Exemple #29
0
 def getRangeTypeActiveIndex(self, model, col):
     """
     Get the index for the 'currently selected' frame range type.
     """
     valid = uiutils.isValidQtObject(model)
     if valid is False:
         return
     if col is None:
         return None
     active_node = col.get_node()
     if active_node is None:
         return None
     value = self.getRangeTypeValue(col)
     string_data_list = model.stringDataList()
     data_list = [data for string, data in string_data_list]
     index = None
     if value in data_list:
         index = data_list.index(value)
     return index
def new_scene_func(clientData):
    """
    Create a callback called just before a new scene file is created
    or before a new file is loaded. The UI must be closed. All data
    structures stored must be removed.

    :param clientData: The Qt window object class.
    :type clientData: SolverWindow

    :return: Nothing.
    :rtype: None
    """
    try:
        valid = uiutils.isValidQtObject(clientData)
        if clientData is not None and valid is True:
            clientData.close()
    except RuntimeError:
        msg = 'New Maya Scene callback failed to close UI: ui=%r'
        LOG.warning(msg, clientData)
    return