Exemplo n.º 1
0
Arquivo: view.py Projeto: Mysenu/Yak
class HistoryListView(QListView):
    def __init__(self, parent=None) -> None:
        super().__init__(parent)

        self.setMovement(QListView.Snap)
        self.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.setTextElideMode(Qt.ElideNone)

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.showContextMenu)

        self._settings = QSettings('Egor', 'Yak')

        self.setObjectName('History')

        # Menus
        self._context_menu = None
        self._copy_submenu = None

        # Actions
        self._copy_equations_action: QAction
        self._copy_expressions_action: QAction
        self._copy_results_action: QAction
        self._cut_equations_action: QAction
        self._edit_expression_action: QAction
        self._delete_action: QAction
        self._clear_action: QAction
        self._save_action: QAction
        self._request_restore_history_action: QAction

        self._createActions()

    def _createActions(self) -> None:
        self._copy_expressions_action = QAction('Expressions')
        self._copy_expressions_action.triggered.connect(
            self._copySelectedExpressions)
        self._copy_expressions_action.setShortcut(QKeySequence.Copy)
        self.addAction(self._copy_expressions_action)

        self._copy_equations_action = QAction('Equations')
        self._copy_equations_action.triggered.connect(
            self._copySelectedEquations)
        self._copy_equations_action.setShortcut(Qt.CTRL + Qt.ALT + Qt.Key_C)
        self.addAction(self._copy_equations_action)

        self._copy_results_action = QAction('Results')
        self._copy_results_action.triggered.connect(self._copySelectedResults)
        self._copy_results_action.setShortcut(Qt.CTRL + Qt.SHIFT + Qt.Key_C)
        self.addAction(self._copy_results_action)

        self._cut_equations_action = QAction('Cut equations')
        self._cut_equations_action.triggered.connect(
            self._cutSelectedEquations)
        self._cut_equations_action.setShortcut(QKeySequence.Cut)
        self.addAction(self._cut_equations_action)

        self._edit_expression_action = QAction('Edit expression')
        self._edit_expression_action.triggered.connect(
            self._editSelectedExpression)
        self._edit_expression_action.setShortcut(Qt.CTRL + Qt.Key_E)
        self.addAction(self._edit_expression_action)

        self._delete_action = QAction('Delete')
        self._delete_action.triggered.connect(self._deleteSelectedEquations)
        self._delete_action.setShortcut(QKeySequence.Delete)
        self.addAction(self._delete_action)

        self._clear_action = QAction('Clear')
        self._clear_action.triggered.connect(self.clear)

        self._save_action = QAction('Save...')
        self._save_action.triggered.connect(self._saveHistory)
        self._save_action.setShortcut(QKeySequence.Save)
        self.addAction(self._save_action)

        self._request_restore_history_action = QAction(
            'Request to restore history on startup')
        self._request_restore_history_action.setCheckable(True)
        self._request_restore_history_action.triggered.connect(
            self._changeStateRequestRestoreHistoryAction)
        self.updateRequestRestoreHistoryAction()

    def _deleteSelectedEquations(self) -> None:
        for index in reversed(
                sorted(self.selectedIndexes(), key=QModelIndex.row)):
            self.model().removeRow(index.row(), QModelIndex())

    def _copySelectedEquations(self) -> None:
        equations = []
        for index in self.selectedIndexes():
            equations.append(self.model().data(index, Qt.DisplayRole))
        text_to_copy = '\n'.join(equations)
        text_to_copy = toEditableExpr(text_to_copy)

        clipboard = QApplication.clipboard()
        clipboard.setText(text_to_copy)

    def _copySelectedExpressions(self) -> None:
        expressions = []
        for index in self.selectedIndexes():
            expressions.append(self.model().data(index, ExpressionRole))
        text_to_copy = '\n'.join(expressions)
        text_to_copy = toEditableExpr(text_to_copy)

        clipboard = QApplication.clipboard()
        clipboard.setText(text_to_copy)

    def _copySelectedResults(self) -> None:
        results = []
        for index in self.selectedIndexes():
            results.append(str(self.model().data(index, ResultRole)))
        text_to_copy = '\n'.join(results)

        clipboard = QApplication.clipboard()
        clipboard.setText(text_to_copy)

    def _cutSelectedEquations(self) -> None:
        self._copySelectedEquations()
        self._deleteSelectedEquations()

    def _editSelectedExpression(self) -> None:
        indexes = self.selectedIndexes()
        if len(indexes) == 1:
            self.edit(indexes[0])

    def _saveHistory(self) -> None:
        self.model().saveHistory()

    def updateRequestRestoreHistoryAction(self) -> None:
        if self._settings.value('show_request_restore_history'):
            self._request_restore_history_action.blockSignals(True)
            self._request_restore_history_action.setChecked(True)
            self._request_restore_history_action.blockSignals(False)

    def _changeStateRequestRestoreHistoryAction(self) -> None:
        self._settings.setValue(
            'show_request_restore_history',
            self._request_restore_history_action.isChecked())

    def _askUserToClear(self) -> bool:
        button = QMessageBox.question(self, 'Clear', 'Clear all history?')
        return button == QMessageBox.Yes

    def clear(self) -> None:
        if self._askUserToClear():
            self.model().clear()

    def _createContextMenu(self) -> None:
        self._context_menu = QMenu()

        self._copy_submenu = QMenu('Copy')
        self._context_menu.addMenu(self._copy_submenu)

        self._copy_submenu.addAction(self._copy_equations_action)
        self._copy_submenu.addAction(self._copy_expressions_action)
        self._copy_submenu.addAction(self._copy_results_action)

        self._context_menu.addAction(self._cut_equations_action)
        self._context_menu.addAction(self._delete_action)
        self._context_menu.addSeparator()
        self._context_menu.addAction(self._clear_action)
        self._context_menu.addAction(self._save_action)
        self._context_menu.addSeparator()
        self._context_menu.addAction(self._request_restore_history_action)

    def _setActionsEnabled(self, enable: bool = True) -> None:
        self._copy_submenu.setEnabled(enable)
        self._copy_equations_action.setEnabled(enable)
        self._copy_expressions_action.setEnabled(enable)
        self._copy_results_action.setEnabled(enable)

        self._cut_equations_action.setEnabled(enable)
        self._edit_expression_action.setEnabled(enable)
        self._delete_action.setEnabled(enable)

        self._clear_action.setEnabled(enable)
        self._save_action.setEnabled(enable)

    def _updateContextMenu(self) -> None:
        if not self._context_menu:
            self._createContextMenu()

        if self.model().rowCount(QModelIndex()) <= 0:
            self._setActionsEnabled(False)
        else:
            indexes = self.selectedIndexes()
            if not indexes:
                self._setActionsEnabled(False)
            elif len(indexes) == 1:
                self._setActionsEnabled(True)
            else:
                self._setActionsEnabled(True)
                self._edit_expression_action.setDisabled(True)

            self._clear_action.setEnabled(True)
            self._save_action.setEnabled(True)

        self.updateRequestRestoreHistoryAction()

    def showContextMenu(self, local_pos: QPoint) -> None:
        if not self._context_menu:
            self._createContextMenu()

        self._updateContextMenu()

        self._context_menu.exec_(self.mapToGlobal(local_pos))

    def resizeEvent(self, event: QResizeEvent) -> None:
        super().resizeEvent(event)

        font = self.font()
        font.setPointSize(self.height() * 0.13 * 0.4)
        self.viewport().setFont(font)
        self.setFont(font)

    def paintEvent(self, event: QPaintEvent) -> None:
        super().paintEvent(event)

        placeholder_text = 'No history'

        p = QPainter(self.viewport())
        p.setPen(self.palette().placeholderText().color())
        p.setFont(
            fitTextToWidth(placeholder_text, self.font(),
                           self.width() - 20))

        if not self.model():
            return

        if self.model().rowCount(QModelIndex()) <= 0:
            p.drawText(self.rect(), Qt.AlignCenter, placeholder_text)