Esempio n. 1
0
class _StyleEditor(QtWidgets.QWidget):
    def __init__(
        self,
        api: Api,
        model: AssStylesModel,
        selection_model: QtCore.QItemSelectionModel,
        parent: QtWidgets.QWidget,
    ) -> None:
        super().__init__(parent)
        self._mapper = ImmediateDataWidgetMapper(
            model, {_AlignmentGroupBox: "changed"}
        )
        selection_model.selectionChanged.connect(self._on_selection_change)

        self.font_group_box = _FontGroupBox(api, self, self._mapper)
        self.colors_group_box = _ColorsGroupBox(self, self._mapper)
        self.outline_group_box = _OutlineGroupBox(self, self._mapper)
        self.misc_group_box = _MiscGroupBox(self, self._mapper)
        self.margins_group_box = _MarginGroupBox(self, self._mapper)
        self.alignment_group_box = _AlignmentGroupBox(self, self._mapper)

        left_widget = QtWidgets.QWidget(self)
        left_layout = QtWidgets.QVBoxLayout(left_widget)
        left_layout.setContentsMargins(0, 0, 0, 0)
        left_layout.addWidget(self.font_group_box)
        left_layout.addWidget(self.colors_group_box)
        left_layout.addWidget(self.outline_group_box)

        right_widget = QtWidgets.QWidget(self)
        right_layout = QtWidgets.QVBoxLayout(right_widget)
        right_layout.setContentsMargins(0, 0, 0, 0)
        right_layout.addWidget(self.misc_group_box)
        right_layout.addWidget(self.margins_group_box)
        right_layout.addWidget(self.alignment_group_box)

        layout = QtWidgets.QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(left_widget)
        layout.addWidget(right_widget)

    def _on_selection_change(
        self,
        selected: QtCore.QItemSelection,
        _deselected: QtCore.QItemSelection,
    ) -> None:
        if len(selected.indexes()) == 1:
            self.setEnabled(True)
            self._mapper.set_current_index(selected.indexes()[0].row())
        else:
            self.setEnabled(False)
            self._mapper.set_current_index(None)
Esempio n. 2
0
class Editor(QtWidgets.QWidget):
    def __init__(
        self, api: Api, theme_mgr: ThemeManager, parent: QtWidgets.QWidget
    ) -> None:
        super().__init__(parent)
        self._api = api
        self._theme_mgr = theme_mgr

        self.style_edit = QtWidgets.QComboBox(
            self,
            editable=True,
            minimumWidth=200,
            insertPolicy=QtWidgets.QComboBox.NoInsert,
            objectName="style-editor",
        )

        self.actor_edit = QtWidgets.QComboBox(
            self,
            editable=True,
            insertPolicy=QtWidgets.QComboBox.NoInsert,
            objectName="actor-editor",
        )

        self.layer_edit = QtWidgets.QSpinBox(
            self, minimum=0, objectName="layer-editor"
        )

        self.margin_l_edit = QtWidgets.QSpinBox(
            self, minimum=0, maximum=999, objectName="margin-left-editor"
        )

        self.margin_v_edit = QtWidgets.QSpinBox(
            self, minimum=0, maximum=999, objectName="margin-vertical-editor"
        )

        self.margin_r_edit = QtWidgets.QSpinBox(
            self, minimum=0, maximum=999, objectName="margin-right-editor"
        )

        self.start_time_edit = TimeEdit(self, objectName="start-time-editor")
        self.end_time_edit = TimeEdit(self, objectName="end-time-editor")
        self.duration_edit = TimeEdit(self, objectName="duration-editor")

        self.comment_checkbox = QtWidgets.QCheckBox(
            "Comment", self, objectName="comment-checkbox"
        )

        self.text_edit = TextEdit(
            api, self, tabChangesFocus=True, objectName="text-editor"
        )
        self.text_edit.highlighter = SpellCheckHighlighter(
            self._api, self.text_edit.document()
        )

        self.note_edit = TextEdit(
            api,
            self,
            tabChangesFocus=True,
            placeholderText="Notes",
            objectName="note-editor",
        )

        margins_layout = QtWidgets.QHBoxLayout(spacing=4)
        margins_layout.setContentsMargins(0, 0, 0, 0)
        margins_layout.addWidget(self.margin_l_edit)
        margins_layout.addWidget(self.margin_v_edit)
        margins_layout.addWidget(self.margin_r_edit)

        bar_layout = QtWidgets.QGridLayout(spacing=4)
        bar_layout.setContentsMargins(0, 0, 0, 0)
        for row, column, label, widget in {
            (0, 0, "Style:", self.style_edit),
            (1, 0, "Actor:", self.actor_edit),
            (2, 0, "Layer:", self.layer_edit),
            (3, 0, "Margin:", margins_layout),
            (0, 1, "Start time:", self.start_time_edit),
            (1, 1, "End time:", self.end_time_edit),
            (2, 1, "Duration:", self.duration_edit),
            (3, 1, "", self.comment_checkbox),
        }:
            if label:
                bar_layout.addWidget(
                    QtWidgets.QLabel(label, self), row, column * 2
                )
            if isinstance(widget, QtWidgets.QLayout):
                bar_layout.addLayout(widget, row, column * 2 + 1)
            else:
                bar_layout.addWidget(widget, row, column * 2 + 1)

        layout = QtWidgets.QHBoxLayout(self, spacing=6)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addLayout(bar_layout)
        layout.addWidget(self.text_edit)
        layout.addWidget(self.note_edit)
        layout.setStretchFactor(self.text_edit, 1)
        layout.setStretchFactor(self.note_edit, 1)
        self.setEnabled(False)

        self._data_widget_mapper = ImmediateDataWidgetMapper(
            model=AssEventsModel(api, self._theme_mgr, self),
            signal_map={TextEdit: "textChanged"},
        )
        for column, widget in {
            (AssEventsModelColumn.Start, self.start_time_edit),
            (AssEventsModelColumn.End, self.end_time_edit),
            (AssEventsModelColumn.LongDuration, self.duration_edit),
            (AssEventsModelColumn.Layer, self.layer_edit),
            (AssEventsModelColumn.Actor, self.actor_edit),
            (AssEventsModelColumn.AssStyle, self.style_edit),
            (AssEventsModelColumn.MarginVertical, self.margin_v_edit),
            (AssEventsModelColumn.MarginLeft, self.margin_l_edit),
            (AssEventsModelColumn.MarginRight, self.margin_r_edit),
            (AssEventsModelColumn.IsComment, self.comment_checkbox),
            (AssEventsModelColumn.Text, self.text_edit),
            (AssEventsModelColumn.Note, self.note_edit),
        }:
            self._data_widget_mapper.add_mapping(widget, column)

        api.subs.selection_changed.connect(self._on_selection_change)

        QtWidgets.QApplication.instance().installEventFilter(self)

    def eventFilter(
        self, source: QtCore.QObject, event: QtCore.QEvent
    ) -> bool:
        if isinstance(source, QtWidgets.QWidget) and self.isAncestorOf(source):
            if event.type() == QtCore.QEvent.FocusOut:
                self._api.undo.push()
        return False

    def _on_selection_change(
        self, selected: T.List[int], _changed: bool
    ) -> None:
        self._api.undo.push()

        if len(selected) != 1:
            self.setEnabled(False)
            self._data_widget_mapper.set_current_index(None)
            return

        self.actor_edit.blockSignals(True)
        self.actor_edit.clear()
        self.actor_edit.addItems(
            sorted(list(set(sub.actor for sub in self._api.subs.events)))
        )
        self.actor_edit.blockSignals(False)

        self.style_edit.blockSignals(True)
        self.style_edit.clear()
        self.style_edit.addItems(
            sorted(list(set(sub.style for sub in self._api.subs.events)))
        )
        self.style_edit.blockSignals(False)

        self.setEnabled(True)
        self.text_edit.reset()
        self.note_edit.reset()
        self._data_widget_mapper.set_current_index(selected[0])
Esempio n. 3
0
class Editor(QWidget):
    def __init__(self, api: Api, theme_mgr: ThemeManager,
                 parent: QWidget) -> None:
        # pylint: disable=too-many-statements
        super().__init__(parent)
        self._api = api
        self._theme_mgr = theme_mgr

        self.style_edit = QComboBox(self)
        self.style_edit.setEditable(True)
        self.style_edit.setMinimumWidth(200)
        self.style_edit.setInsertPolicy(QComboBox.NoInsert)
        self.style_edit.setObjectName("style-editor")

        self.actor_edit = QComboBox(self)
        self.actor_edit.setEditable(True)
        self.actor_edit.setInsertPolicy(QComboBox.NoInsert)
        self.actor_edit.setObjectName("actor-editor")

        self.layer_edit = QSpinBox(self)
        self.layer_edit.setObjectName("layer-editor")
        self.layer_edit.setMinimum(0)

        self.margin_l_edit = QSpinBox(self)
        self.margin_l_edit.setObjectName("margin-left-editor")
        self.margin_l_edit.setMinimum(0)
        self.margin_l_edit.setMaximum(999)

        self.margin_v_edit = QSpinBox(self)
        self.margin_v_edit.setObjectName("margin-vertical-editor")
        self.margin_v_edit.setMinimum(0)
        self.margin_v_edit.setMaximum(999)

        self.margin_r_edit = QSpinBox(self)
        self.margin_r_edit.setObjectName("margin-right-editor")
        self.margin_r_edit.setMinimum(0)
        self.margin_r_edit.setMaximum(999)

        self.start_time_edit = TimeEdit(self)
        self.start_time_edit.setObjectName("start-time-editor")

        self.end_time_edit = TimeEdit(self)
        self.end_time_edit.setObjectName("end-time-editor")

        self.duration_edit = TimeEdit(self)
        self.duration_edit.setObjectName("duration-editor")
        self.duration_edit.setDisabled(True)

        self.comment_checkbox = QCheckBox("Comment", self)
        self.comment_checkbox.setObjectName("comment-checkbox")

        self.text_edit = TextEdit(api, self)
        self.text_edit.setTabChangesFocus(True)
        self.text_edit.setObjectName("text-editor")

        self.note_edit = TextEdit(api, self)
        self.note_edit.setTabChangesFocus(True)
        self.note_edit.setPlaceholderText("Notes")
        self.note_edit.setObjectName("note-editor")

        margins_layout = QHBoxLayout()
        margins_layout.setSpacing(4)
        margins_layout.setContentsMargins(0, 0, 0, 0)
        margins_layout.addWidget(self.margin_l_edit)
        margins_layout.addWidget(self.margin_v_edit)
        margins_layout.addWidget(self.margin_r_edit)

        bar_layout = QGridLayout()
        bar_layout.setSpacing(4)
        bar_layout.setContentsMargins(0, 0, 0, 0)

        widget_map: set[tuple[int, int, str, Union[QWidget, QLayout]]] = {
            (0, 0, "Style:", self.style_edit),
            (1, 0, "Actor:", self.actor_edit),
            (2, 0, "Layer:", self.layer_edit),
            (3, 0, "Margin:", margins_layout),
            (0, 1, "Start time:", self.start_time_edit),
            (1, 1, "End time:", self.end_time_edit),
            (2, 1, "Duration:", self.duration_edit),
            (3, 1, "", self.comment_checkbox),
        }
        for row, column, label, widget in widget_map:
            if label:
                bar_layout.addWidget(QLabel(label, self), row, column * 2)
            if isinstance(widget, QLayout):
                bar_layout.addLayout(widget, row, column * 2 + 1)
            else:
                bar_layout.addWidget(widget, row, column * 2 + 1)

        layout = QHBoxLayout(self)
        layout.setSpacing(6)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addLayout(bar_layout)
        layout.addWidget(self.text_edit)
        layout.addWidget(self.note_edit)
        layout.setStretchFactor(self.text_edit, 1)
        layout.setStretchFactor(self.note_edit, 1)
        self.setEnabled(False)

        api.subs.loaded.connect(self._on_subs_load)
        api.subs.selection_changed.connect(self._on_selection_change)

        self._data_widget_mapper: Optional[ImmediateDataWidgetMapper] = None

        app = QApplication.instance()
        assert app
        app.installEventFilter(self)

    def eventFilter(self, source: QObject, event: QEvent) -> bool:
        if isinstance(source, QWidget) and self.isAncestorOf(source):
            if event.type() == QEvent.Type.FocusOut:
                self._api.undo.push()
        return False

    def _on_subs_load(self) -> None:
        self._data_widget_mapper = ImmediateDataWidgetMapper(
            model=AssEventsModel(self._api, self._theme_mgr, self),
            signal_map={TextEdit: "textChanged"},
        )
        widget_map: set[tuple[AssEventsModelColumn, QWidget]] = {
            (AssEventsModelColumn.START, self.start_time_edit),
            (AssEventsModelColumn.END, self.end_time_edit),
            (AssEventsModelColumn.LONG_DURATION, self.duration_edit),
            (AssEventsModelColumn.LAYER, self.layer_edit),
            (AssEventsModelColumn.ACTOR, self.actor_edit),
            (AssEventsModelColumn.ASS_STYLE, self.style_edit),
            (AssEventsModelColumn.MARGIN_VERTICAL, self.margin_v_edit),
            (AssEventsModelColumn.MARGIN_LEFT, self.margin_l_edit),
            (AssEventsModelColumn.MARGIN_RIGHT, self.margin_r_edit),
            (AssEventsModelColumn.IS_COMMENT, self.comment_checkbox),
            (AssEventsModelColumn.TEXT, self.text_edit),
            (AssEventsModelColumn.NOTE, self.note_edit),
        }
        for column, widget in widget_map:
            self._data_widget_mapper.add_mapping(widget, column)

        self.text_edit.highlighter = SpellCheckHighlighter(
            self._api, self.text_edit.document())

    def _on_selection_change(self, selected: list[int],
                             _changed: bool) -> None:
        if not self._data_widget_mapper:
            return

        self._api.undo.push()

        if len(selected) != 1:
            self.setEnabled(False)
            self._data_widget_mapper.set_current_index(None)
            return

        self.actor_edit.blockSignals(True)
        self.actor_edit.clear()
        self.actor_edit.addItems(
            sorted(list(set(sub.actor for sub in self._api.subs.events))))
        self.actor_edit.blockSignals(False)

        self.style_edit.blockSignals(True)
        self.style_edit.clear()
        self.style_edit.addItems(
            sorted(list(set(sub.style_name for sub in self._api.subs.events))))
        self.style_edit.blockSignals(False)

        self.setEnabled(True)
        self._data_widget_mapper.set_current_index(selected[0])
        self.text_edit.reset()
        self.note_edit.reset()