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/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/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
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..5b020cf0 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,37 @@ class MDEditView(textEditView):
# tF.updateFromIndex(self._index)
# tF.setTextEdit(self)
+ ###########################################################################
+ # 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.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)
###########################################################################