Пример #1
0
 def insertRows(self, row, count, parent=QtCore.QModelIndex()):
     self.beginInsertRows(QtCore.QModelIndex(), row, row + count - 1)
     self._stringDataList[row:row] = [('', None)] * count
     self.endInsertRows()
     return True
Пример #2
0
 def columnCount(self, parent=QtCore.QModelIndex()):
     column_names = self.columnNames()
     return len(column_names.keys())
Пример #3
0
 def rowCount(self, parent=QtCore.QModelIndex()):
     return len(self._node_list)
Пример #4
0
class FrameRangeWidget(QtWidgets.QWidget, ui_framerange_widget.Ui_Form):

    rangeTypeChanged = QtCore.Signal()
    framesChanged = QtCore.Signal()
    incrementByFrameChanged = QtCore.Signal()

    def __init__(self, parent=None, *args, **kwargs):
        super(FrameRangeWidget, self).__init__(*args, **kwargs)
        self.setupUi(self)

        # Range Type Combo Box.
        self.model = uimodels.StringDataListModel()
        self.rangeType_comboBox.setModel(self.model)
        self.rangeType_comboBox.currentIndexChanged.connect(
            self.rangeTypeIndexChanged)

        # Frames Line Edit
        self.frames_lineEdit.editingFinished.connect(self.framesTextEntered)

        # Increment by Frames Line Edit
        self.incrementByFrame_spinBox.valueChanged.connect(
            self.incrementByFrameValueChanged)

        self.rangeTypeChanged.connect(self.updateModel)
        return

    def getRangeTypeStringDataList(self):
        values = zip(const.RANGE_TYPE_NAME_LIST, const.RANGE_TYPE_VALUE_LIST)
        return list(values)

    def getRangeTypeValue(self, col):
        raise NotImplementedError

    def setRangeTypeValue(self, col, value):
        raise NotImplementedError

    def getFramesValue(self, col):
        raise NotImplementedError

    def setFramesValue(self, col, value):
        raise NotImplementedError

    def getIncrementByFrameValue(self, col):
        raise NotImplementedError

    def setIncrementByFrameValue(self, col, value):
        raise NotImplementedError

    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

    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 updateModel(self):
        """
        Refresh the name_comboBox with the current Maya scene state.
        """
        self.populateModel(self.model)

        col = lib_state.get_active_collection()
        if col is None:
            return

        # range_type_value = self.getRangeTypeValue(col)
        index = self.getRangeTypeActiveIndex(self.model, col)
        if index is None:
            LOG.error('Could not get the active range type index.')
            return

        frames_string = '1001-1101'
        increment = self.getIncrementByFrameValue(col)
        frames_enabled = False
        increment_enabled = False
        if index == const.RANGE_TYPE_CURRENT_FRAME_VALUE:
            frames_string = 'CURRENT FRAME'
            frames_enabled = False
            increment_enabled = False
        elif index == const.RANGE_TYPE_TIMELINE_INNER_VALUE:
            start, end = utils_time.get_maya_timeline_range_inner()
            frames_string = '{0}-{1}'.format(int(start), int(end))
            frames_enabled = False
            increment_enabled = True
        elif index == const.RANGE_TYPE_TIMELINE_OUTER_VALUE:
            start, end = utils_time.get_maya_timeline_range_outer()
            frames_string = '{0}-{1}'.format(int(start), int(end))
            frames_enabled = False
            increment_enabled = True
        elif index == const.RANGE_TYPE_CUSTOM_FRAMES_VALUE:
            frames_string = self.getFramesValue(col)
            if frames_string is None:
                start, end = utils_time.get_maya_timeline_range_outer()
                frames_string = '{0}-{1}'.format(int(start), int(end))
            frames_enabled = True
            increment_enabled = True
        else:
            msg = "Not a valid 'range type' value: %r" % index
            raise ValueError(msg)

        block = self.blockSignals(True)
        self.rangeType_comboBox.setCurrentIndex(index)
        self.frames_lineEdit.setEnabled(frames_enabled)
        self.frames_lineEdit.setText(frames_string)
        self.incrementByFrame_spinBox.setEnabled(increment_enabled)
        self.incrementByFrame_spinBox.setValue(increment)
        self.blockSignals(block)
        return

    @QtCore.Slot(int)
    def rangeTypeIndexChanged(self, index):
        """
        Run when the rangeType_comboBox index is changed.
        """
        if index < 0:
            return
        col = lib_state.get_active_collection()
        if col is None:
            return
        model_index = self.model.index(index, 0)
        data = self.model.data(model_index, role=QtCore.Qt.UserRole)
        if data is None:
            return
        assert isinstance(data, pycompat.INT_TYPES)
        self.setRangeTypeValue(col, data)
        self.rangeTypeChanged.emit()
        return

    @QtCore.Slot()
    def framesTextEntered(self):
        """
        Run when the frames_lineEdit text is has been entered (for example
        the user presses the <Enter> key to confirm the field value).
        """
        text = self.frames_lineEdit.text()

        col = lib_state.get_active_collection()
        if col is None:
            return

        # Round-trip conversion will make sure there are no syntax
        # errors given by the user.
        int_list = converttypes.stringToIntList(text)
        frames_string = converttypes.intListToString(int_list)

        self.frames_lineEdit.setText(frames_string)
        self.setFramesValue(col, frames_string)
        self.framesChanged.emit()
        return

    @QtCore.Slot(int)
    def incrementByFrameValueChanged(self, value):
        """
        Run when the incrementByFrame_spinBox value is changed.
        """
        assert value > 0
        col = lib_state.get_active_collection()
        if col is None:
            return
        self.setIncrementByFrameValue(col, value)
        self.incrementByFrameChanged.emit()
        return
class SolverStandardWidget(QtWidgets.QWidget,
                           ui_solver_standard_widget.Ui_Form):

    viewUpdated = QtCore.Signal()
    dataChanged = QtCore.Signal()
    globalSolveChanged = QtCore.Signal()
    onlyRootFramesChanged = QtCore.Signal()
    evalObjectRelationshipsChanged = QtCore.Signal()
    evalComplexGraphsChanged = QtCore.Signal()
    sendWarning = QtCore.Signal(str)

    def __init__(self, parent=None, *args, **kwargs):
        s = time.time()
        super(SolverStandardWidget, self).__init__(*args, **kwargs)
        self.setupUi(self)

        self.frameRange_widget = StandardFrameRangeWidget(self)
        self.frameRange_layout.addWidget(self.frameRange_widget)

        self.rootFrames_widget = StandardRootFrameWidget(self)
        self.rootFrames_layout.addWidget(self.rootFrames_widget)

        self.globalSolve_checkBox.toggled.connect(self.globalSolveValueToggled)
        self.onlyRootFrames_checkBox.toggled.connect(self.onlyRootFramesValueToggled)
        self.evalObjectRelationships_checkBox.toggled.connect(
            self.evalObjectRelationshipsValueToggled)
        self.evalComplexGraphs_checkBox.toggled.connect(
            self.evalComplexGraphsValueToggled)

        desc = const.SOLVER_STD_DESC_DEFAULT
        self.description_label.setText(desc)

        self.dataChanged.connect(self.updateModel)
        self.frameRange_widget.rangeTypeChanged.connect(self.updateModel)
        self.rootFrames_widget.sendWarning.connect(self._sendWarningToUser)
        e = time.time()
        LOG.debug('SolverStandardWidget init: %r seconds', e - s)
        return

    def getOnlyRootFramesValue(self, col):
        value = lib_col_state.get_solver_only_root_frames_from_collection(col)
        return value

    def setOnlyRootFramesValue(self, col, value):
        lib_col_state.set_solver_only_root_frames_on_collection(col, value)
        return

    def getGlobalSolveValue(self, col):
        value = lib_col_state.get_solver_global_solve_from_collection(col)
        return value

    def setGlobalSolveValue(self, col, value):
        lib_col_state.set_solver_global_solve_on_collection(col, value)
        return

    def getEvalObjectRelationshipsValue(self, col):
        allow_obj_relations = _getAllowObjectRelations()
        if allow_obj_relations is False:
            return False
        value = lib_col_state.get_solver_eval_object_relationships_from_collection(col)
        return value

    def setEvalObjectRelationshipsValue(self, col, value):
        lib_col_state.set_solver_eval_object_relationships_on_collection(col, value)
        return

    def getEvalComplexGraphsValue(self, col):
        value = lib_col_state.get_solver_eval_complex_graphs_from_collection(col)
        return value

    def setEvalComplexGraphsValue(self, col, value):
        lib_col_state.set_solver_eval_complex_graphs_on_collection(col, value)
        return

    def event(self, ev):
        if ev.type() == QtCore.QEvent.WindowActivate:
            LOG.debug('window activated')
            self.updateObjectRelationshipsWidgets()
        return super(SolverStandardWidget, self).event(ev)

    def updateObjectRelationshipsWidgets(self):
        LOG.debug('updateObjectRelationshipsWidgets')
        allow_obj_relations = _getAllowObjectRelations()
        self.evalObjectRelationships_checkBox.setEnabled(allow_obj_relations)

        col = lib_state.get_active_collection()
        if col is None:
            return
        value = self.getEvalObjectRelationshipsValue(col)
        self.evalObjectRelationships_checkBox.setChecked(value)
        return

    def updateModel(self):
        self.frameRange_widget.updateModel()
        self.rootFrames_widget.updateModel()

        col = lib_state.get_active_collection()
        if col is None:
            return

        allow_obj_relations = _getAllowObjectRelations()
        range_type = self.frameRange_widget.getRangeTypeValue(col)
        global_solve = self.getGlobalSolveValue(col)
        only_root_frames = self.getOnlyRootFramesValue(col)
        eval_obj_conns = self.getEvalObjectRelationshipsValue(col)
        eval_complex_graphs = self.getEvalComplexGraphsValue(col)
        global_solve_enabled = True
        only_root_frames_enabled = True
        eval_obj_conns_enabled = allow_obj_relations
        eval_complex_graphs_enabled = True
        frameRange_enabled = True
        rootFrames_enabled = True
        if range_type == const.RANGE_TYPE_CURRENT_FRAME_VALUE:
            global_solve_enabled = False
            only_root_frames_enabled = False
            eval_complex_graphs_enabled = False
            frameRange_enabled = True
            rootFrames_enabled = False
        else:
            if global_solve is True:
                only_root_frames_enabled = False
                only_root_frames = False
                eval_complex_graphs_enabled = False
                rootFrames_enabled = True
                frameRange_enabled = True
            if only_root_frames is True:
                global_solve_enabled = False
                global_solve = False
                frameRange_enabled = False
                rootFrames_enabled = True
                eval_complex_graphs_enabled = True

        block = self.blockSignals(True)
        self.globalSolve_checkBox.setChecked(global_solve)
        self.globalSolve_checkBox.setEnabled(global_solve_enabled)
        self.onlyRootFrames_checkBox.setChecked(only_root_frames)
        self.onlyRootFrames_checkBox.setEnabled(only_root_frames_enabled)
        self.evalObjectRelationships_checkBox.setChecked(eval_obj_conns)
        self.evalObjectRelationships_checkBox.setEnabled(eval_obj_conns_enabled)
        self.evalComplexGraphs_checkBox.setChecked(eval_complex_graphs)
        self.evalComplexGraphs_checkBox.setEnabled(eval_complex_graphs_enabled)
        self.frameRange_widget.setEnabled(frameRange_enabled)
        self.rootFrames_widget.setEnabled(rootFrames_enabled)
        self.blockSignals(block)

        self.setGlobalSolveValue(col, global_solve)
        self.setOnlyRootFramesValue(col, only_root_frames)
        self.setEvalObjectRelationshipsValue(col, eval_obj_conns)
        self.setEvalComplexGraphsValue(col, eval_complex_graphs)
        return

    def queryInfo(self):
        LOG.debug('RUN standard queryInfo')
        col = lib_state.get_active_collection()
        text = lib_col.query_solver_info_text(col)
        return text

    @QtCore.Slot(bool)
    def onlyRootFramesValueToggled(self, value):
        col = lib_state.get_active_collection()
        if col is None:
            return
        if value:
            # 'Global Solve' cannot be used at the same time as 'Only
            # Root Frames'
            self.setGlobalSolveValue(col, False)
            self.globalSolveChanged.emit()
        self.setOnlyRootFramesValue(col, value)
        self.onlyRootFramesChanged.emit()
        self.dataChanged.emit()
        return

    @QtCore.Slot(bool)
    def globalSolveValueToggled(self, value):
        col = lib_state.get_active_collection()
        if col is None:
            return
        if value:
            # 'Only Root Frames' is only valid if 'Global Solve' is off.
            self.setOnlyRootFramesValue(col, False)
            self.onlyRootFramesChanged.emit()
        self.setGlobalSolveValue(col, value)
        self.globalSolveChanged.emit()
        self.dataChanged.emit()
        return

    @QtCore.Slot(bool)
    def evalObjectRelationshipsValueToggled(self, value):
        col = lib_state.get_active_collection()
        if col is None:
            return
        self.setEvalObjectRelationshipsValue(col, value)
        self.evalObjectRelationshipsChanged.emit()
        self.dataChanged.emit()
        return

    @QtCore.Slot(bool)
    def evalComplexGraphsValueToggled(self, value):
        col = lib_state.get_active_collection()
        if col is None:
            return
        self.setEvalComplexGraphsValue(col, value)
        self.evalComplexGraphsChanged.emit()
        self.dataChanged.emit()
        return

    @QtCore.Slot(str)
    def _sendWarningToUser(self, value):
        self.sendWarning.emit(value)
        return
class SolverLegacyWidget(QtWidgets.QWidget, ui_solver_legacy_widget.Ui_Form):

    itemAdded = QtCore.Signal()
    itemRemoved = QtCore.Signal()
    viewUpdated = QtCore.Signal()
    dataChanged = QtCore.Signal()

    def __init__(self, parent=None, *args, **kwargs):
        s = time.time()
        super(SolverLegacyWidget, self).__init__(*args, **kwargs)
        self.setupUi(self)

        self.createTableView()

        # Solver Add and Remove buttons
        self.add_toolButton.clicked.connect(self.addClicked)
        self.remove_toolButton.clicked.connect(self.removeClicked)

        # Override Current Frame
        self.overrideCurrentFrame_checkBox.stateChanged.connect(
            self.overrideCurrentFrameChanged)

        # Ensure the model is updated when data is changed.
        self.dataChanged.connect(self.updateModel)
        e = time.time()
        LOG.debug('SolverLegacyWidget init: %r seconds', e - s)
        return

    def createTableView(self):
        self.model = solver_nodes.SolverModel(font=self.font)
        self.filterModel = QtCore.QSortFilterProxyModel()
        self.filterModel.setSourceModel(self.model)
        self.filterModel.setDynamicSortFilter(False)
        self.tableView.setModel(self.filterModel)
        self.tableView.setSortingEnabled(False)
        self.selModel = self.tableView.selectionModel()

        # Set up custom widgets for viewing and editing the columns.
        self.attrFilterDelegate = solver_nodes.AttributeComboBoxDelegate()
        attr_idx = self.model.getColumnIndexFromColumnName(
            const.SOLVER_COLUMN_NAME_ATTRIBUTES)
        strategy_idx = self.model.getColumnIndexFromColumnName(
            const.SOLVER_COLUMN_NAME_STRATEGY)
        self.tableView.setItemDelegateForColumn(
            attr_idx,
            self.attrFilterDelegate,
        )
        self.strategyDelegate = solver_nodes.StrategyComboBoxDelegate()
        self.tableView.setItemDelegateForColumn(
            strategy_idx,
            self.strategyDelegate,
        )
        return

    def populateModel(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.model.setNodeList(node_list)
        return

    def populateOverrideCurrentFrame(self):
        cur_frame = False
        col = lib_state.get_active_collection()
        if col is not None:
            cur_frame = lib_col.get_override_current_frame_from_collection(col)
        self.overrideCurrentFrame_checkBox.setChecked(cur_frame)
        return

    def updateModel(self):
        self.populateOverrideCurrentFrame()
        self.populateModel(self.model)

        widgets = [self]
        _populateWidgetsEnabled(widgets)
        return

    def queryInfo(self):
        LOG.debug('RUN legacy queryInfo')
        col = lib_state.get_active_collection()
        text = lib_col.query_solver_info_text(col)
        return text

    def addClicked(self):
        col = lib_state.get_active_collection()
        if col is None:
            msg = 'Cannot add Solver Step, active collection is invalid,'
            LOG.warning(msg)
            return
        step = lib_col.create_solver_step()
        lib_col.add_solver_step_to_collection(col, step)

        self.itemAdded.emit()
        self.dataChanged.emit()
        self.viewUpdated.emit()
        return

    def removeClicked(self):
        ui_nodes = lib_uiquery.get_selected_ui_table_row(
            self.tableView, self.model, self.filterModel)
        names = map(lambda x: x.name(), ui_nodes)
        col_nodes = lib_uiquery.convert_ui_nodes_to_nodes(
            ui_nodes, 'collection_node')
        assert len(names) == len(col_nodes)
        for name, col in zip(names, col_nodes):
            step = lib_col.get_named_solver_step_from_collection(col, name)
            lib_col.remove_solver_step_from_collection(col, step)

        self.itemRemoved.emit()
        self.dataChanged.emit()
        self.viewUpdated.emit()
        return

    def setOverrideCurrentFrame(self, col, value):
        """
        Set the override status for the collection given.

        Updates the relevant UI components with the new data.

        :param col: The Collection to set.
        :type col: Collection

        :param value: Should we override the current frame? Yes or No.
        :type value: bool
        """
        assert isinstance(value, bool)
        lib_col.set_override_current_frame_on_collection(col, value)

        self.dataChanged.emit()
        self.viewUpdated.emit()
        return

    @QtCore.Slot(int)
    def overrideCurrentFrameChanged(self, value):
        col = lib_state.get_active_collection()
        if col is None:
            LOG.warning('No active collection, cannot override Solver Step.')
            return
        # 'value' from Qt is expected to be an int, we expect a bool.
        value = bool(value)
        self.setOverrideCurrentFrame(col, value)
        return
class CollectionWidget(QtWidgets.QWidget, ui_collection_widget.Ui_Form):

    # Signals; events that may 'happen' to this widget.
    itemAdded = QtCore.Signal()
    itemRemoved = QtCore.Signal()
    itemChanged = QtCore.Signal()
    nameChanged = QtCore.Signal()
    selectClicked = QtCore.Signal()

    def __init__(self, parent=None, *args, **kwargs):
        s = time.time()
        super(CollectionWidget, self).__init__(parent, *args, **kwargs)
        self.setupUi(self)

        # Collection Combo Box.
        self.model = uimodels.StringDataListModel()
        self.name_comboBox.setModel(self.model)
        self.name_comboBox.currentIndexChanged.connect(self.indexChanged)

        # Collection Select
        self.select_pushButton.clicked.connect(self.selectClickedButton)

        self.itemChanged.connect(self.updateModel)
        e = time.time()
        LOG.debug('CollectionWidget init: %r seconds', e - s)
        return

    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 updateModel(self):
        """
        Refresh the name_comboBox with the current Maya scene state.
        """
        self.populateModel(self.model)

        index = None
        col = lib_state.get_active_collection()
        if col is None:
            cols = lib_col.get_collections()
            if len(cols) > 0:
                # If there is no active collection, but there are
                # collections already created, we make sure the first
                # collection is marked active.
                col = cols[0]
                lib_state.set_active_collection(col)
        else:
            index = self.getActiveIndex(self.model, col)

        block = self.blockSignals(True)
        if index is not None:
            self.name_comboBox.setCurrentIndex(index)
        self.nameChanged.emit()
        self.blockSignals(block)
        return

    def getActiveIndex(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

    def createNewNode(self):
        """
        Create a new Collection node, and set it active.
        """
        col = lib_col.create_collection()
        lib_state.set_active_collection(col)

        self.itemAdded.emit()
        self.itemChanged.emit()
        self.nameChanged.emit()
        return

    def renameActiveNode(self):
        """
        Dialog prompt the user to rename the currently active node.
        """
        col = lib_state.get_active_collection()
        if col is None:
            LOG.warning('No active collection to rename. Skipping rename.')
            return
        node_name = col.get_node()
        title = 'Rename Collection node'
        msg = 'Enter new node name'
        new_name = lib_maya_utils.prompt_for_new_node_name(title, msg, node_name)
        if new_name is not None:
            lib_col.rename_collection(col, new_name)

        self.itemChanged.emit()
        self.nameChanged.emit()
        return

    def removeActiveNode(self):
        """
        Delete the currently active collection.
        """
        col = lib_state.get_active_collection()
        if col is None:
            LOG.warning('No active collection to delete.')
            return
        title = 'Remove Collection?'
        text = 'Would you like to remove the current Collection?'
        text += '\n\nRemove "' + str(col.get_node()) + '"?'
        clicked_button = QtWidgets.QMessageBox.question(self, title, text)
        if clicked_button != QtWidgets.QMessageBox.Yes:
            LOG.warn('User cancelled operation.')
            return

        cols = lib_col.get_collections()
        prev_col = lib_col.get_previous_collection(cols, col)

        steps = lib_col.get_solver_steps_from_collection(col)
        for step in steps:
            lib_col.remove_solver_step_from_collection(col, step)

        lib_col.delete_collection(col)
        lib_state.set_active_collection(prev_col)

        self.itemRemoved.emit()
        self.itemChanged.emit()
        self.nameChanged.emit()
        return

    def selectClickedButton(self):
        """
        Run when the user presses the 'select' button.
        """
        col = lib_state.get_active_collection()
        if col is None:
            LOG.warning('No active collection to select.')
            return
        lib_col.select_collection(col)
        self.nameChanged.emit()
        return

    @QtCore.Slot(int)
    def indexChanged(self, index):
        """
        Run when the name_comboBox index is changed.
        """
        if index < 0:
            return
        model_index = self.model.index(index, 0)
        data = self.model.data(
            model_index,
            role=QtCore.Qt.UserRole
        )
        if data is None:
            return
        lib_state.set_active_collection(data)
        self.itemChanged.emit()
        self.nameChanged.emit()
        return
class SolverWidget(QtWidgets.QWidget, ui_solver_widget.Ui_Form):

    tabChanged = QtCore.Signal()
    dataChanged = QtCore.Signal()
    sendWarning = QtCore.Signal(str)

    def __init__(self, parent=None, *args, **kwargs):
        s = time.time()
        super(SolverWidget, self).__init__(parent, *args, **kwargs)
        self.setupUi(self)

        # Solver Settings Basic Widget
        self.basic_widget = solver_basic_widget.SolverBasicWidget(self)
        self.basic_layout.addWidget(self.basic_widget)

        # Solver Settings Standard Widget
        self.standard_widget = solver_standard_widget.SolverStandardWidget(
            self)
        self.standard_layout.addWidget(self.standard_widget)

        # Solver Settings Legacy Widget
        self.legacy_widget = solver_legacy_widget.SolverLegacyWidget(self)
        self.legacy_layout.addWidget(self.legacy_widget)

        self._tab_name_to_index_map = {
            'basic': 0,
            'standard': 1,
            'legacy': 2,
        }
        self._tab_index_to_widget_map = {
            0: self.basic_widget,
            1: self.standard_widget,
            2: self.legacy_widget,
        }
        self.all_tab_widgets = [
            self.basic_widget, self.standard_widget, self.legacy_widget
        ]

        self.validate_pushButton.setEnabled(False)

        self.createConnections()

        e = time.time()
        LOG.debug('SolverWidget init: %r seconds', e - s)
        return

    def createConnections(self):
        self.tabWidget.currentChanged.connect(self._tabChanged)
        self.basic_widget.dataChanged.connect(self._dataChanged)
        self.standard_widget.dataChanged.connect(self._dataChanged)
        self.legacy_widget.dataChanged.connect(self._dataChanged)
        self.standard_widget.sendWarning.connect(self._sendWarningToUser)
        self.standard_widget.sendWarning.connect(self._sendWarningToUser)

        self.basic_widget.frameRange_widget.rangeTypeChanged.connect(
            self.updateInfo)
        self.basic_widget.frameRange_widget.framesChanged.connect(
            self.updateInfo)
        self.basic_widget.frameRange_widget.incrementByFrameChanged.connect(
            self.updateInfo)
        self.standard_widget.frameRange_widget.rangeTypeChanged.connect(
            self.updateInfo)
        self.validate_pushButton.clicked.connect(self.runUpdateInfo)

    def getSolverTabValue(self, col):
        value = lib_col_state.get_solver_tab_from_collection(col)
        return value

    def setSolverTabValue(self, col, value):
        lib_col_state.set_solver_tab_on_collection(col, value)
        return

    def event(self, ev):
        if ev.type() == QtCore.QEvent.WindowActivate:
            LOG.debug('window was activated')
            self.updateValidationWidgets()
        return super(SolverWidget, self).event(ev)

    @QtCore.Slot(int)
    def _tabChanged(self, idx):
        self.updateModel()

        # Store the tab name we've changed to.
        col = lib_state.get_active_collection()
        if col is not None:
            name = self.tabWidget.tabText(idx)
            name = name.lower()
            self.setSolverTabValue(col, name)

        self.tabChanged.emit()
        return

    def _dataChanged(self):
        self.dataChanged.emit()
        return

    def _getTabWidget(self, idx):
        widget = self._tab_index_to_widget_map.get(idx, None)
        if widget is None:
            raise RuntimeError('tab index is not valid: %r' % idx)
        assert widget is not None
        return widget

    def updateModel(self):
        is_running = mmapi.is_solver_running()
        if is_running is True:
            return
        col = lib_state.get_active_collection()
        if col is not None:
            tab_name = self.getSolverTabValue(col)
            tab_name = tab_name.lower()
            idx = self._tab_name_to_index_map.get(tab_name, None)
            if idx is None:
                msg = 'Solver tab name is not valid: %r' % tab_name
                raise ValueError(msg)
            self.tabWidget.setCurrentIndex(idx)

        idx = self.tabWidget.currentIndex()
        tab_widget = self._getTabWidget(idx)
        tab_widget.updateModel()

        widgets = [
            tab_widget,
            self.info_label,
        ]
        _populateWidgetsEnabled(widgets)
        self.updateInfo()
        return

    def updateValidationWidgets(self):
        LOG.debug('updateValidationWidgets')

        # Show the validate button?
        visible = _getShowValidateButton()
        self.info_groupBox.setVisible(visible)

        # Only run a solver validation if the user wants updates.
        validate_on_open = _getValidateOnOpen()
        if validate_on_open:
            value = lib_state.get_auto_update_solver_validation_state()
            if value is False:
                self.validate_pushButton.clicked.emit()
        return

    def updateInfo(self):
        is_running = mmapi.is_solver_running()
        if is_running is True:
            return

        value = lib_state.get_auto_update_solver_validation_state()
        self.validate_pushButton.setEnabled(not value)
        if value is not True:
            return

        self.runUpdateInfo()
        return

    def runUpdateInfo(self):
        s = time.time()
        idx = self.tabWidget.currentIndex()
        tab_widget = self._getTabWidget(idx)
        text = tab_widget.queryInfo()
        self.info_label.setText(text)
        e = time.time()
        LOG.debug('SolverWidget runUpdateInfo: %r seconds', e - s)
        return

    @QtCore.Slot(bool)
    def autoUpdateSolverValidationChanged(self, value):
        lib_state.set_auto_update_solver_validation_state(value)
        self.updateInfo()
        return

    @QtCore.Slot(str)
    def _sendWarningToUser(self, value):
        self.sendWarning.emit(value)
        return
class SolverBasicWidget(QtWidgets.QWidget,
                        ui_solver_basic_widget.Ui_Form):

    viewUpdated = QtCore.Signal()
    dataChanged = QtCore.Signal()
    evalObjectRelationshipsChanged = QtCore.Signal()
    evalComplexGraphsChanged = QtCore.Signal()

    def __init__(self, parent=None, *args, **kwargs):
        s = time.time()
        super(SolverBasicWidget, self).__init__(*args, **kwargs)
        self.setupUi(self)

        self.frameRange_widget = BasicFrameRangeWidget(self)
        self.frameRange_layout.addWidget(self.frameRange_widget)

        self.evalObjectRelationships_checkBox.toggled.connect(
            self.evalObjectRelationshipsValueToggled)
        self.evalComplexGraphs_checkBox.toggled.connect(
            self.evalComplexGraphsValueToggled)

        desc = const.SOLVER_BASIC_DESC_DEFAULT
        self.description_label.setText(desc)
        e = time.time()
        LOG.debug('SolverBasicWidget init: %r seconds', e - s)
        return

    def getEvalObjectRelationshipsValue(self, col):
        allow_obj_relations = _getAllowObjectRelations()
        if allow_obj_relations is False:
            return False
        value = lib_col_state.get_solver_eval_object_relationships_from_collection(col)
        return value

    def setEvalObjectRelationshipsValue(self, col, value):
        lib_col_state.set_solver_eval_object_relationships_on_collection(col, value)
        return

    def getEvalComplexGraphsValue(self, col):
        value = lib_col_state.get_solver_eval_complex_graphs_from_collection(col)
        return value

    def setEvalComplexGraphsValue(self, col, value):
        lib_col_state.set_solver_eval_complex_graphs_on_collection(col, value)
        return

    def event(self, ev):
        if ev.type() == QtCore.QEvent.WindowActivate:
            LOG.debug('window activated')
            self.updateObjectRelationshipsWidgets()
        return super(SolverBasicWidget, self).event(ev)

    def updateObjectRelationshipsWidgets(self):
        LOG.debug('updateObjectRelationshipsWidgets')
        allow_obj_relations = _getAllowObjectRelations()
        self.evalObjectRelationships_checkBox.setEnabled(allow_obj_relations)

        col = lib_state.get_active_collection()
        if col is None:
            return
        value = self.getEvalObjectRelationshipsValue(col)
        self.evalObjectRelationships_checkBox.setChecked(value)
        return

    def updateModel(self):
        LOG.debug('UpdateModel Basic')
        self.frameRange_widget.updateModel()

        col = lib_state.get_active_collection()
        if col is None:
            return
        allow_obj_relations = _getAllowObjectRelations()
        eval_obj_conns = self.getEvalObjectRelationshipsValue(col)
        eval_complex_graphs = self.getEvalComplexGraphsValue(col)
        if allow_obj_relations is False:
            eval_obj_conns = False

        block = self.blockSignals(True)
        self.evalObjectRelationships_checkBox.setEnabled(allow_obj_relations)
        self.evalObjectRelationships_checkBox.setChecked(eval_obj_conns)
        self.evalComplexGraphs_checkBox.setChecked(eval_complex_graphs)
        self.blockSignals(block)

        self.setEvalObjectRelationshipsValue(col, eval_obj_conns)
        self.setEvalComplexGraphsValue(col, eval_complex_graphs)
        return

    def queryInfo(self):
        LOG.debug('RUN basic queryInfo')
        col = lib_state.get_active_collection()
        text = lib_col.query_solver_info_text(col)
        return text

    @QtCore.Slot(bool)
    def evalObjectRelationshipsValueToggled(self, value):
        col = lib_state.get_active_collection()
        if col is None:
            return
        self.setEvalObjectRelationshipsValue(col, value)
        self.evalObjectRelationshipsChanged.emit()
        self.dataChanged.emit()
        return

    @QtCore.Slot(bool)
    def evalComplexGraphsValueToggled(self, value):
        col = lib_state.get_active_collection()
        if col is None:
            return
        self.setEvalComplexGraphsValue(col, value)
        self.evalComplexGraphsChanged.emit()
        self.dataChanged.emit()
        return
Пример #10
0
class SolverStateWidget(QtWidgets.QWidget, ui_solverstate_widget.Ui_Form):

    statusUpdated = QtCore.Signal()
    infoUpdated = QtCore.Signal()

    def __init__(self, parent=None, *args, **kwargs):
        s = time.time()
        super(SolverStateWidget, self).__init__(*args, **kwargs)
        self.setupUi(self)
        e = time.time()
        LOG.debug('SolverStateWidget init: %r seconds', e - s)
        return

    def updateModel(self):
        return

    def updateStatusWithSolveResult(self):
        col = lib_state.get_active_collection()
        if col is None:
            return
        info_fn = self.setSolveInfoLine
        solres_list = col.get_last_solve_results()
        timestamp = col.get_last_solve_timestamp()
        total_time = col.get_last_solve_duration()

        msg = 'No solve performed.'
        if len(solres_list) == 0:
            info_fn(msg)
        if timestamp is None:
            timestamp = time.time()
        if total_time is None:
            total_time = 0.0

        # We don't want to log every time we open the UI.
        log = None
        lib_collection.log_solve_results(log,
                                         solres_list,
                                         timestamp=timestamp,
                                         total_time=total_time,
                                         status_fn=info_fn)
        return

    @QtCore.Slot(str)
    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)
        self.statusUpdated.emit()
        return

    @QtCore.Slot(str)
    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)
        self.infoUpdated.emit()
        return