From 2b1465a1f3fbfbe06b213d77d90c463e8b9d5854 Mon Sep 17 00:00:00 2001 From: Olivier Keshavjee Date: Tue, 28 Nov 2017 10:26:43 +0100 Subject: [PATCH 1/3] Adds #175: Typewriter scrolling --- manuskript/settings.py | 2 ++ manuskript/settingsWindow.py | 3 +++ manuskript/ui/settings_ui.py | 17 +++++++++------- manuskript/ui/settings_ui.ui | 15 ++++++++++++++- manuskript/ui/views/MDEditView.py | 32 +++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 8 deletions(-) diff --git a/manuskript/settings.py b/manuskript/settings.py index 8d5044ba..9f627105 100644 --- a/manuskript/settings.py +++ b/manuskript/settings.py @@ -74,6 +74,7 @@ textEditor = { "marginsLR": 0, "marginsTB": 20, "backgroundTransparent": False, + "alwaysCenter": False, } revisions = { @@ -273,6 +274,7 @@ def load(string, fromString=False, protocol=None): "marginsLR": 0, "marginsTB": 20, "backgroundTransparent": False, # Added in 0.6.0 + "alwaysCenter": False, # Added in 0.7.0 } for k in added: diff --git a/manuskript/settingsWindow.py b/manuskript/settingsWindow.py index 6fe5591e..79c9a7a1 100644 --- a/manuskript/settingsWindow.py +++ b/manuskript/settingsWindow.py @@ -198,6 +198,8 @@ class settingsWindow(QWidget, Ui_Settings): self.spnEditorCursorWidth.setEnabled(opt["cursorWidth"] != 1) self.chkEditorNoBlinking.setChecked(opt["cursorNotBlinking"]) self.chkEditorNoBlinking.stateChanged.connect(self.setApplicationCursorBlinking) + self.chkEditorTypeWriterMode.setChecked(opt["alwaysCenter"]) + self.chkEditorTypeWriterMode.stateChanged.connect(self.updateEditorSettings) # Text areas self.chkEditorMaxWidth.setChecked(opt["maxWidth"] != 0) self.chkEditorMaxWidth.stateChanged.connect(self.updateEditorSettings) @@ -479,6 +481,7 @@ class settingsWindow(QWidget, Ui_Settings): 1 if not self.chkEditorCursorWidth.isChecked() else \ self.spnEditorCursorWidth.value() self.spnEditorCursorWidth.setEnabled(self.chkEditorCursorWidth.isChecked()) + settings.textEditor["alwaysCenter"] = self.chkEditorTypeWriterMode.isChecked() # Text area settings.textEditor["maxWidth"] = \ diff --git a/manuskript/ui/settings_ui.py b/manuskript/ui/settings_ui.py index 1fc7ec65..0a81e423 100644 --- a/manuskript/ui/settings_ui.py +++ b/manuskript/ui/settings_ui.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'manuskript/ui/settings_ui.ui' # -# Created by: PyQt5 UI code generator 5.9 +# Created by: PyQt5 UI code generator 5.5.1 # # WARNING! All changes made in this file will be lost! @@ -1291,6 +1291,13 @@ class Ui_Settings(object): self.chkEditorNoBlinking.setFont(font) self.chkEditorNoBlinking.setObjectName("chkEditorNoBlinking") self.formLayout_10.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.chkEditorNoBlinking) + self.chkEditorTypeWriterMode = QtWidgets.QCheckBox(self.groupBox_15) + font = QtGui.QFont() + font.setBold(False) + font.setWeight(50) + self.chkEditorTypeWriterMode.setFont(font) + self.chkEditorTypeWriterMode.setObjectName("chkEditorTypeWriterMode") + self.formLayout_10.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.chkEditorTypeWriterMode) self.verticalLayout_22.addWidget(self.groupBox_15) self.horizontalLayout_4.addLayout(self.verticalLayout_22) icon = QtGui.QIcon.fromTheme("view-text") @@ -1480,7 +1487,6 @@ class Ui_Settings(object): self.layoutWidget = QtWidgets.QWidget(self.splitter) self.layoutWidget.setObjectName("layoutWidget") self.verticalLayout_14 = QtWidgets.QVBoxLayout(self.layoutWidget) - self.verticalLayout_14.setContentsMargins(0, 0, 0, 0) self.verticalLayout_14.setObjectName("verticalLayout_14") self.cmbThemeEdit = QtWidgets.QComboBox(self.layoutWidget) self.cmbThemeEdit.setObjectName("cmbThemeEdit") @@ -1495,7 +1501,6 @@ class Ui_Settings(object): self.stackedWidgetPage1_2.setObjectName("stackedWidgetPage1_2") self.formLayout_4 = QtWidgets.QFormLayout(self.stackedWidgetPage1_2) self.formLayout_4.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_4.setContentsMargins(0, 0, 0, 0) self.formLayout_4.setObjectName("formLayout_4") self.label_17 = QtWidgets.QLabel(self.stackedWidgetPage1_2) self.label_17.setObjectName("label_17") @@ -1527,7 +1532,6 @@ class Ui_Settings(object): self.stackedWidgetPage2_2.setObjectName("stackedWidgetPage2_2") self.formLayout_5 = QtWidgets.QFormLayout(self.stackedWidgetPage2_2) self.formLayout_5.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_5.setContentsMargins(0, 0, 0, 0) self.formLayout_5.setObjectName("formLayout_5") self.label_20 = QtWidgets.QLabel(self.stackedWidgetPage2_2) self.label_20.setObjectName("label_20") @@ -1625,7 +1629,6 @@ class Ui_Settings(object): self.page_2.setObjectName("page_2") self.formLayout_7 = QtWidgets.QFormLayout(self.page_2) self.formLayout_7.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_7.setContentsMargins(0, 0, 0, 0) self.formLayout_7.setObjectName("formLayout_7") self.label_29 = QtWidgets.QLabel(self.page_2) self.label_29.setObjectName("label_29") @@ -1675,7 +1678,6 @@ class Ui_Settings(object): self.stackedWidgetPage3_2.setObjectName("stackedWidgetPage3_2") self.formLayout_6 = QtWidgets.QFormLayout(self.stackedWidgetPage3_2) self.formLayout_6.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_6.setContentsMargins(0, 0, 0, 0) self.formLayout_6.setObjectName("formLayout_6") self.label_26 = QtWidgets.QLabel(self.stackedWidgetPage3_2) self.label_26.setObjectName("label_26") @@ -1778,7 +1780,7 @@ class Ui_Settings(object): self.horizontalLayout_8.addWidget(self.stack) self.retranslateUi(Settings) - self.stack.setCurrentIndex(5) + self.stack.setCurrentIndex(2) self.tabViews.setCurrentIndex(3) self.themeStack.setCurrentIndex(1) self.themeEditStack.setCurrentIndex(3) @@ -1970,6 +1972,7 @@ class Ui_Settings(object): self.chkEditorCursorWidth.setText(_translate("Settings", "Use block insertion of")) self.spnEditorCursorWidth.setSuffix(_translate("Settings", " px")) self.chkEditorNoBlinking.setText(_translate("Settings", "Disable blinking")) + self.chkEditorTypeWriterMode.setText(_translate("Settings", "Typewriter mode")) self.tabViews.setTabText(self.tabViews.indexOf(self.tab_4), _translate("Settings", "Text editor")) self.lblTitleLabels.setText(_translate("Settings", "Labels")) self.btnLabelColor.setShortcut(_translate("Settings", "Ctrl+S")) diff --git a/manuskript/ui/settings_ui.ui b/manuskript/ui/settings_ui.ui index 194161de..385ac5ca 100644 --- a/manuskript/ui/settings_ui.ui +++ b/manuskript/ui/settings_ui.ui @@ -54,7 +54,7 @@ - 5 + 2 @@ -2619,6 +2619,19 @@ + + + + + 50 + false + + + + Typewriter mode + + + diff --git a/manuskript/ui/views/MDEditView.py b/manuskript/ui/views/MDEditView.py index 4521906b..e4209b2b 100644 --- a/manuskript/ui/views/MDEditView.py +++ b/manuskript/ui/views/MDEditView.py @@ -9,6 +9,7 @@ from PyQt5.QtGui import QTextCursor from manuskript.ui.views.textEditView import textEditView from manuskript.ui.highlighters import MarkdownHighlighter +from manuskript import settings # from manuskript.ui.editors.textFormat import textFormat # from manuskript.ui.editors.MDFunctions import MDFormatSelection @@ -28,6 +29,10 @@ class MDEditView(textEditView): # We have to setup things anew, for the highlighter notably self.setCurrentModelIndex(index) + self.cursorPositionChanged.connect(self.cursorPositionHasChanged) + self.verticalScrollBar().rangeChanged.connect( + self.scrollBarRangeChanged) + # def focusInEvent(self, event): # """Finds textFormatter and attach them to that view.""" # textEditView.focusInEvent(self, event) @@ -42,6 +47,33 @@ class MDEditView(textEditView): # tF.updateFromIndex(self._index) # tF.setTextEdit(self) + ########################################################################### + # TypeWriterScrolling + ########################################################################### + + def cursorPositionHasChanged(self): + self.centerCursor() + + def centerCursor(self, force=False): + cursor = self.cursorRect() + viewport = self.viewport().rect() + if (force or settings.textEditor["alwaysCenter"] + or cursor.bottom() >= viewport.bottom() + or cursor.top() <= viewport.top()): + offset = viewport.center() - cursor.center() + scrollbar = self.verticalScrollBar() + scrollbar.setValue(scrollbar.value() - offset.y()) + + def scrollBarRangeChanged(self, min, max): + """ + Adds viewport height to scrollbar max so that we can center cursor + on screen. + """ + if settings.textEditor["alwaysCenter"]: + self.verticalScrollBar().blockSignals(True) + self.verticalScrollBar().setMaximum(max + self.viewport().height()) + self.verticalScrollBar().blockSignals(False) + ########################################################################### # FORMATTING (#FIXME) ########################################################################### From 91989269f1aef841107b328a74044fe1a95fe607 Mon Sep 17 00:00:00 2001 From: Olivier Keshavjee Date: Tue, 28 Nov 2017 16:24:58 +0100 Subject: [PATCH 2/3] Fixes a bug in highlighter that makes it slow --- manuskript/ui/highlighters/markdownTokenizer.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/manuskript/ui/highlighters/markdownTokenizer.py b/manuskript/ui/highlighters/markdownTokenizer.py index ffb4d7ba..91a824f5 100644 --- a/manuskript/ui/highlighters/markdownTokenizer.py +++ b/manuskript/ui/highlighters/markdownTokenizer.py @@ -260,7 +260,7 @@ class MarkdownTokenizer(HighlightTokenizer): else: # Restart tokenizing on the previous line. self.requestBacktrack() - False + return False return False @@ -450,7 +450,6 @@ class MarkdownTokenizer(HighlightTokenizer): MS.MarkdownStateBlockquote, MS.MarkdownStateNumberedList, MS.MarkdownStateBulletPointList,]: - self.requestBacktrack() if self.lineBreakRegex.exactMatch(text): token = Token() token.type = MTT.TokenLineBreak From c504cb510e17fe003ad7f733805484ce60276948 Mon Sep 17 00:00:00 2001 From: Olivier Keshavjee Date: Tue, 28 Nov 2017 19:58:23 +0100 Subject: [PATCH 3/3] Fixes fullScreen scrollbar range --- manuskript/ui/editors/fullScreenEditor.py | 12 ++++++++++++ manuskript/ui/views/MDEditView.py | 6 +++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/manuskript/ui/editors/fullScreenEditor.py b/manuskript/ui/editors/fullScreenEditor.py index 4de5ba80..cc0f0650 100644 --- a/manuskript/ui/editors/fullScreenEditor.py +++ b/manuskript/ui/editors/fullScreenEditor.py @@ -206,6 +206,7 @@ class fullScreenEditor(QWidget): # self.lblWC.setPalette(p) self.update() + self.editor.centerCursor() def paintEvent(self, event): if self._background: @@ -307,10 +308,21 @@ class myScrollBar(QScrollBar): self.timer.timeout.connect(lambda: self.parent().hideWidget(self)) self.valueChanged.connect(lambda v: self.timer.start()) self.valueChanged.connect(lambda: self.parent().showWidget(self)) + self.rangeChanged.connect(self.rangeHasChanged) def setColor(self, color): self._color = color + def rangeHasChanged(self, min, max): + """ + Adds viewport height to scrollbar max so that we can center cursor + on screen. + """ + if settings.textEditor["alwaysCenter"]: + self.blockSignals(True) + self.setMaximum(max + self.parent().height()) + self.blockSignals(False) + def paintEvent(self, event): opt = QStyleOptionSlider() self.initStyleOption(opt) diff --git a/manuskript/ui/views/MDEditView.py b/manuskript/ui/views/MDEditView.py index e4209b2b..5b020cf0 100644 --- a/manuskript/ui/views/MDEditView.py +++ b/manuskript/ui/views/MDEditView.py @@ -51,17 +51,21 @@ class MDEditView(textEditView): # TypeWriterScrolling ########################################################################### + def setCurrentModelIndex(self, index): + textEditView.setCurrentModelIndex(self, index) + self.centerCursor() + def cursorPositionHasChanged(self): self.centerCursor() def centerCursor(self, force=False): cursor = self.cursorRect() + scrollbar = self.verticalScrollBar() viewport = self.viewport().rect() if (force or settings.textEditor["alwaysCenter"] or cursor.bottom() >= viewport.bottom() or cursor.top() <= viewport.top()): offset = viewport.center() - cursor.center() - scrollbar = self.verticalScrollBar() scrollbar.setValue(scrollbar.value() - offset.y()) def scrollBarRangeChanged(self, min, max):