diff --git a/icons/NumixMsk/128x128/actions/format-text-strikethrough.svg b/icons/NumixMsk/128x128/actions/format-text-strikethrough.svg
new file mode 100644
index 00000000..39d148f1
--- /dev/null
+++ b/icons/NumixMsk/128x128/actions/format-text-strikethrough.svg
@@ -0,0 +1,6 @@
+
diff --git a/icons/NumixMsk/16x16/actions/format-text-strikethrough.svg b/icons/NumixMsk/16x16/actions/format-text-strikethrough.svg
new file mode 100644
index 00000000..759dcafd
--- /dev/null
+++ b/icons/NumixMsk/16x16/actions/format-text-strikethrough.svg
@@ -0,0 +1,6 @@
+
diff --git a/icons/NumixMsk/22x22/actions/format-text-strikethrough.svg b/icons/NumixMsk/22x22/actions/format-text-strikethrough.svg
new file mode 100644
index 00000000..43c55933
--- /dev/null
+++ b/icons/NumixMsk/22x22/actions/format-text-strikethrough.svg
@@ -0,0 +1,7 @@
+
diff --git a/icons/NumixMsk/24x24/actions/format-text-strikethrough.svg b/icons/NumixMsk/24x24/actions/format-text-strikethrough.svg
new file mode 100644
index 00000000..e2e919fa
--- /dev/null
+++ b/icons/NumixMsk/24x24/actions/format-text-strikethrough.svg
@@ -0,0 +1,7 @@
+
diff --git a/icons/NumixMsk/256x256/actions/format-text-strikethrough.svg b/icons/NumixMsk/256x256/actions/format-text-strikethrough.svg
new file mode 100644
index 00000000..ed9f5160
--- /dev/null
+++ b/icons/NumixMsk/256x256/actions/format-text-strikethrough.svg
@@ -0,0 +1,6 @@
+
diff --git a/icons/NumixMsk/32x32/actions/format-text-strikethrough.svg b/icons/NumixMsk/32x32/actions/format-text-strikethrough.svg
new file mode 100644
index 00000000..55b1221a
--- /dev/null
+++ b/icons/NumixMsk/32x32/actions/format-text-strikethrough.svg
@@ -0,0 +1,6 @@
+
diff --git a/icons/NumixMsk/48x48/actions/format-text-strikethrough.svg b/icons/NumixMsk/48x48/actions/format-text-strikethrough.svg
new file mode 100644
index 00000000..292bdb53
--- /dev/null
+++ b/icons/NumixMsk/48x48/actions/format-text-strikethrough.svg
@@ -0,0 +1,7 @@
+
diff --git a/icons/NumixMsk/64x64/actions/format-text-strikethrough.svg b/icons/NumixMsk/64x64/actions/format-text-strikethrough.svg
new file mode 100644
index 00000000..84364b67
--- /dev/null
+++ b/icons/NumixMsk/64x64/actions/format-text-strikethrough.svg
@@ -0,0 +1,6 @@
+
diff --git a/manuskript/mainWindow.py b/manuskript/mainWindow.py
index 8fe626af..be771d09 100644
--- a/manuskript/mainWindow.py
+++ b/manuskript/mainWindow.py
@@ -28,6 +28,7 @@ from manuskript.ui.mainWindow import Ui_MainWindow
from manuskript.ui.tools.frequencyAnalyzer import frequencyAnalyzer
from manuskript.ui.views.outlineDelegates import outlineCharacterDelegate
from manuskript.ui.views.plotDelegate import plotDelegate
+from manuskript.ui.views.MDEditView import MDEditView
# Spellcheck support
from manuskript.ui.views.textEditView import textEditView
@@ -57,6 +58,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
# Var
self.currentProject = None
self._lastFocus = None
+ self._lastMDEditView = None
self._defaultCursorFlashTime = 1000 # Overriden at startup with system
# value. In manuskript.main.
@@ -113,19 +115,43 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.actSaveAs.triggered.connect(self.welcome.saveAsFile)
self.actImport.triggered.connect(self.doImport)
self.actCompile.triggered.connect(self.doCompile)
- self.actLabels.triggered.connect(self.settingsLabel)
- self.actStatus.triggered.connect(self.settingsStatus)
- self.actSettings.triggered.connect(self.settingsWindow)
self.actCloseProject.triggered.connect(self.closeProject)
self.actQuit.triggered.connect(self.close)
- # Main menu:: Documents
+ # Main menu:: Edit
self.actCopy.triggered.connect(self.documentsCopy)
self.actCut.triggered.connect(self.documentsCut)
self.actPaste.triggered.connect(self.documentsPaste)
self.actRename.triggered.connect(self.documentsRename)
self.actDuplicate.triggered.connect(self.documentsDuplicate)
self.actDelete.triggered.connect(self.documentsDelete)
+ self.actLabels.triggered.connect(self.settingsLabel)
+ self.actStatus.triggered.connect(self.settingsStatus)
+ self.actSettings.triggered.connect(self.settingsWindow)
+
+ # Main menu:: Edit:: Format
+ self.actHeaderSetextL1.triggered.connect(self.formatSetext1)
+ self.actHeaderSetextL2.triggered.connect(self.formatSetext2)
+ self.actHeaderAtxL1.triggered.connect(self.formatAtx1)
+ self.actHeaderAtxL2.triggered.connect(self.formatAtx2)
+ self.actHeaderAtxL3.triggered.connect(self.formatAtx3)
+ self.actHeaderAtxL4.triggered.connect(self.formatAtx4)
+ self.actHeaderAtxL5.triggered.connect(self.formatAtx5)
+ self.actHeaderAtxL6.triggered.connect(self.formatAtx6)
+ self.actFormatBold.triggered.connect(self.formatBold)
+ self.actFormatItalic.triggered.connect(self.formatItalic)
+ self.actFormatStrike.triggered.connect(self.formatStrike)
+ self.actFormatVerbatim.triggered.connect(self.formatVerbatim)
+ self.actFormatSuperscript.triggered.connect(self.formatSuperscript)
+ self.actFormatSubscript.triggered.connect(self.formatSubscript)
+ self.actFormatCommentLines.triggered.connect(self.formatCommentLines)
+ self.actFormatList.triggered.connect(self.formatList)
+ self.actFormatOrderedList.triggered.connect(self.formatOrderedList)
+ self.actFormatBlockquote.triggered.connect(self.formatBlockquote)
+ self.actFormatCommentBlock.triggered.connect(self.formatCommentBlock)
+ self.actFormatClear.triggered.connect(self.formatClear)
+
+ # Main menu:: Organize
self.actMoveUp.triggered.connect(self.documentsMoveUp)
self.actMoveDown.triggered.connect(self.documentsMoveDown)
self.actSplitDialog.triggered.connect(self.documentsSplitDialog)
@@ -225,6 +251,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
We get notified by qApp when focus changes, from old to new widget.
"""
+ # If new is a MDEditView, we keep it in memory
+ if issubclass(type(new), MDEditView):
+ self._lastMDEditView = new
+ else:
+ self._lastMDEditView = None
+
# Determine which view had focus last, to send the keyboard shortcuts
# to the right place
@@ -443,12 +475,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def openIndexes(self, indexes, newTab=True):
self.mainEditor.openIndexes(indexes, newTab=True)
- # Menu Documents #############################################################
+ # Menu #############################################################
- # Functions called by the menu Documents
+ # Functions called by the menus
# self._lastFocus is the last editor that had focus (either treeView or
# mainEditor). So we just pass along the signal.
+ # Edit
+
def documentsCopy(self):
"Copy selected item(s)."
if self._lastFocus: self._lastFocus.copy()
@@ -467,6 +501,38 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def documentsDelete(self):
"Delete selected item(s)."
if self._lastFocus: self._lastFocus.delete()
+
+ # Formats
+ def callLastMDEditView(self, functionName, param=[]):
+ """
+ If last focused widget was MDEditView, call the given function.
+ """
+ if self._lastMDEditView:
+ function = getattr(self._lastMDEditView, functionName)
+ function(*param)
+ def formatSetext1(self): self.callLastMDEditView("titleSetext", [1])
+ def formatSetext2(self): self.callLastMDEditView("titleSetext", [2])
+ def formatAtx1(self): self.callLastMDEditView("titleATX", [1])
+ def formatAtx2(self): self.callLastMDEditView("titleATX", [2])
+ def formatAtx3(self): self.callLastMDEditView("titleATX", [3])
+ def formatAtx4(self): self.callLastMDEditView("titleATX", [4])
+ def formatAtx5(self): self.callLastMDEditView("titleATX", [5])
+ def formatAtx6(self): self.callLastMDEditView("titleATX", [6])
+ def formatBold(self): self.callLastMDEditView("bold")
+ def formatItalic(self): self.callLastMDEditView("italic")
+ def formatStrike(self): self.callLastMDEditView("strike")
+ def formatVerbatim(self): self.callLastMDEditView("verbatim")
+ def formatSuperscript(self): self.callLastMDEditView("superscript")
+ def formatSubscript(self): self.callLastMDEditView("subscript")
+ def formatCommentLines(self): self.callLastMDEditView("commentLine")
+ def formatList(self): self.callLastMDEditView("unorderedList")
+ def formatOrderedList(self): self.callLastMDEditView("orderedList")
+ def formatBlockquote(self): self.callLastMDEditView("blockquote")
+ def formatCommentBlock(self): self.callLastMDEditView("comment")
+ def formatClear(self): self.callLastMDEditView("clearFormat")
+
+ # Organize
+
def documentsMoveUp(self):
"Move up selected item(s)."
if self._lastFocus: self._lastFocus.moveUp()
diff --git a/manuskript/ui/mainWindow.py b/manuskript/ui/mainWindow.py
index 484df035..b7514909 100644
--- a/manuskript/ui/mainWindow.py
+++ b/manuskript/ui/mainWindow.py
@@ -378,7 +378,7 @@ class Ui_MainWindow(object):
self.scrollAreaPersoInfos.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.scrollAreaPersoInfos.setObjectName("scrollAreaPersoInfos")
self.scrollAreaPersoInfosWidget = QtWidgets.QWidget()
- self.scrollAreaPersoInfosWidget.setGeometry(QtCore.QRect(0, 0, 426, 688))
+ self.scrollAreaPersoInfosWidget.setGeometry(QtCore.QRect(0, 0, 204, 606))
self.scrollAreaPersoInfosWidget.setObjectName("scrollAreaPersoInfosWidget")
self.formLayout_8 = QtWidgets.QFormLayout(self.scrollAreaPersoInfosWidget)
self.formLayout_8.setFieldGrowthPolicy(QtWidgets.QFormLayout.AllNonFixedFieldsGrow)
@@ -1040,6 +1040,12 @@ class Ui_MainWindow(object):
self.menuTools.setObjectName("menuTools")
self.menuEdit = QtWidgets.QMenu(self.menubar)
self.menuEdit.setObjectName("menuEdit")
+ self.mnuFormat = QtWidgets.QMenu(self.menuEdit)
+ icon = QtGui.QIcon.fromTheme("format-text-bold")
+ self.mnuFormat.setIcon(icon)
+ self.mnuFormat.setObjectName("mnuFormat")
+ self.mnuHeader = QtWidgets.QMenu(self.mnuFormat)
+ self.mnuHeader.setObjectName("mnuHeader")
self.menuView = QtWidgets.QMenu(self.menubar)
self.menuView.setObjectName("menuView")
self.menuMode = QtWidgets.QMenu(self.menuView)
@@ -1214,6 +1220,56 @@ class Ui_MainWindow(object):
icon = QtGui.QIcon.fromTheme("edit-rename")
self.actRename.setIcon(icon)
self.actRename.setObjectName("actRename")
+ self.actHeaderSetextL1 = QtWidgets.QAction(MainWindow)
+ self.actHeaderSetextL1.setObjectName("actHeaderSetextL1")
+ self.actHeaderSetextL2 = QtWidgets.QAction(MainWindow)
+ self.actHeaderSetextL2.setObjectName("actHeaderSetextL2")
+ self.actHeaderAtxL1 = QtWidgets.QAction(MainWindow)
+ self.actHeaderAtxL1.setObjectName("actHeaderAtxL1")
+ self.actHeaderAtxL2 = QtWidgets.QAction(MainWindow)
+ self.actHeaderAtxL2.setObjectName("actHeaderAtxL2")
+ self.actHeaderAtxL3 = QtWidgets.QAction(MainWindow)
+ self.actHeaderAtxL3.setObjectName("actHeaderAtxL3")
+ self.actHeaderAtxL4 = QtWidgets.QAction(MainWindow)
+ self.actHeaderAtxL4.setObjectName("actHeaderAtxL4")
+ self.actHeaderAtxL5 = QtWidgets.QAction(MainWindow)
+ self.actHeaderAtxL5.setObjectName("actHeaderAtxL5")
+ self.actHeaderAtxL6 = QtWidgets.QAction(MainWindow)
+ self.actHeaderAtxL6.setObjectName("actHeaderAtxL6")
+ self.actFormatBold = QtWidgets.QAction(MainWindow)
+ icon = QtGui.QIcon.fromTheme("format-text-bold")
+ self.actFormatBold.setIcon(icon)
+ self.actFormatBold.setObjectName("actFormatBold")
+ self.actFormatItalic = QtWidgets.QAction(MainWindow)
+ icon = QtGui.QIcon.fromTheme("format-text-italic")
+ self.actFormatItalic.setIcon(icon)
+ self.actFormatItalic.setObjectName("actFormatItalic")
+ self.actFormatStrike = QtWidgets.QAction(MainWindow)
+ icon = QtGui.QIcon.fromTheme("format-text-strikethrough")
+ self.actFormatStrike.setIcon(icon)
+ self.actFormatStrike.setObjectName("actFormatStrike")
+ self.actFormatVerbatim = QtWidgets.QAction(MainWindow)
+ self.actFormatVerbatim.setObjectName("actFormatVerbatim")
+ self.actFormatSuperscript = QtWidgets.QAction(MainWindow)
+ self.actFormatSuperscript.setObjectName("actFormatSuperscript")
+ self.actFormatSubscript = QtWidgets.QAction(MainWindow)
+ self.actFormatSubscript.setObjectName("actFormatSubscript")
+ self.actFormatCommentBlock = QtWidgets.QAction(MainWindow)
+ self.actFormatCommentBlock.setObjectName("actFormatCommentBlock")
+ self.actFormatClear = QtWidgets.QAction(MainWindow)
+ icon = QtGui.QIcon.fromTheme("format-text-none")
+ self.actFormatClear.setIcon(icon)
+ self.actFormatClear.setObjectName("actFormatClear")
+ self.actFormatCommentLines = QtWidgets.QAction(MainWindow)
+ self.actFormatCommentLines.setObjectName("actFormatCommentLines")
+ self.actFormatOrderedList = QtWidgets.QAction(MainWindow)
+ self.actFormatOrderedList.setObjectName("actFormatOrderedList")
+ self.actFormatList = QtWidgets.QAction(MainWindow)
+ icon = QtGui.QIcon.fromTheme("view-list")
+ self.actFormatList.setIcon(icon)
+ self.actFormatList.setObjectName("actFormatList")
+ self.actFormatBlockquote = QtWidgets.QAction(MainWindow)
+ self.actFormatBlockquote.setObjectName("actFormatBlockquote")
self.menuFile.addAction(self.actOpen)
self.menuFile.addAction(self.menuRecents.menuAction())
self.menuFile.addAction(self.actSave)
@@ -1228,12 +1284,39 @@ class Ui_MainWindow(object):
self.menuHelp.addAction(self.actAbout)
self.menuTools.addAction(self.actSpellcheck)
self.menuTools.addAction(self.actToolFrequency)
+ self.mnuHeader.addAction(self.actHeaderSetextL1)
+ self.mnuHeader.addAction(self.actHeaderSetextL2)
+ self.mnuHeader.addSeparator()
+ self.mnuHeader.addAction(self.actHeaderAtxL1)
+ self.mnuHeader.addAction(self.actHeaderAtxL2)
+ self.mnuHeader.addAction(self.actHeaderAtxL3)
+ self.mnuHeader.addAction(self.actHeaderAtxL4)
+ self.mnuHeader.addAction(self.actHeaderAtxL5)
+ self.mnuHeader.addAction(self.actHeaderAtxL6)
+ self.mnuFormat.addAction(self.mnuHeader.menuAction())
+ self.mnuFormat.addSeparator()
+ self.mnuFormat.addAction(self.actFormatBold)
+ self.mnuFormat.addAction(self.actFormatItalic)
+ self.mnuFormat.addAction(self.actFormatStrike)
+ self.mnuFormat.addAction(self.actFormatVerbatim)
+ self.mnuFormat.addAction(self.actFormatSuperscript)
+ self.mnuFormat.addAction(self.actFormatSubscript)
+ self.mnuFormat.addAction(self.actFormatCommentLines)
+ self.mnuFormat.addSeparator()
+ self.mnuFormat.addAction(self.actFormatList)
+ self.mnuFormat.addAction(self.actFormatOrderedList)
+ self.mnuFormat.addAction(self.actFormatBlockquote)
+ self.mnuFormat.addAction(self.actFormatCommentBlock)
+ self.mnuFormat.addSeparator()
+ self.mnuFormat.addAction(self.actFormatClear)
self.menuEdit.addAction(self.actCut)
self.menuEdit.addAction(self.actCopy)
self.menuEdit.addAction(self.actPaste)
self.menuEdit.addAction(self.actDelete)
self.menuEdit.addAction(self.actRename)
self.menuEdit.addSeparator()
+ self.menuEdit.addAction(self.mnuFormat.menuAction())
+ self.menuEdit.addSeparator()
self.menuEdit.addAction(self.actLabels)
self.menuEdit.addAction(self.actStatus)
self.menuEdit.addAction(self.actSettings)
@@ -1366,6 +1449,8 @@ class Ui_MainWindow(object):
self.menuHelp.setTitle(_translate("MainWindow", "&Help"))
self.menuTools.setTitle(_translate("MainWindow", "&Tools"))
self.menuEdit.setTitle(_translate("MainWindow", "&Edit"))
+ self.mnuFormat.setTitle(_translate("MainWindow", "&Format"))
+ self.mnuHeader.setTitle(_translate("MainWindow", "&Header"))
self.menuView.setTitle(_translate("MainWindow", "&View"))
self.menuMode.setTitle(_translate("MainWindow", "&Mode"))
self.menuOrganize.setTitle(_translate("MainWindow", "Organi&ze"))
@@ -1415,7 +1500,6 @@ class Ui_MainWindow(object):
self.actMerge.setText(_translate("MainWindow", "M&erge"))
self.actMerge.setShortcut(_translate("MainWindow", "Ctrl+M"))
self.actDuplicate.setText(_translate("MainWindow", "Dupl&icate"))
- self.actDuplicate.setShortcut(_translate("MainWindow", "Ctrl+D"))
self.actDelete.setText(_translate("MainWindow", "&Delete"))
self.actDelete.setShortcut(_translate("MainWindow", "Del"))
self.actMoveUp.setText(_translate("MainWindow", "&Move Up"))
@@ -1424,6 +1508,41 @@ class Ui_MainWindow(object):
self.actMoveDown.setShortcut(_translate("MainWindow", "Ctrl+Shift+Down"))
self.actRename.setText(_translate("MainWindow", "&Rename"))
self.actRename.setShortcut(_translate("MainWindow", "F2"))
+ self.actHeaderSetextL1.setText(_translate("MainWindow", "&Level 1 (setext)"))
+ self.actHeaderSetextL1.setShortcut(_translate("MainWindow", "Ctrl+Alt+1"))
+ self.actHeaderSetextL2.setText(_translate("MainWindow", "Level &2"))
+ self.actHeaderSetextL2.setShortcut(_translate("MainWindow", "Ctrl+Alt+2"))
+ self.actHeaderAtxL1.setText(_translate("MainWindow", "Level &1 (atx)"))
+ self.actHeaderAtxL1.setShortcut(_translate("MainWindow", "Ctrl+1"))
+ self.actHeaderAtxL2.setText(_translate("MainWindow", "L&evel 2"))
+ self.actHeaderAtxL2.setShortcut(_translate("MainWindow", "Ctrl+2"))
+ self.actHeaderAtxL3.setText(_translate("MainWindow", "Level &3"))
+ self.actHeaderAtxL3.setShortcut(_translate("MainWindow", "Ctrl+3"))
+ self.actHeaderAtxL4.setText(_translate("MainWindow", "Level &4"))
+ self.actHeaderAtxL4.setShortcut(_translate("MainWindow", "Ctrl+4"))
+ self.actHeaderAtxL5.setText(_translate("MainWindow", "Level &5"))
+ self.actHeaderAtxL5.setShortcut(_translate("MainWindow", "Ctrl+5"))
+ self.actHeaderAtxL6.setText(_translate("MainWindow", "Level &6"))
+ self.actHeaderAtxL6.setShortcut(_translate("MainWindow", "Ctrl+6"))
+ self.actFormatBold.setText(_translate("MainWindow", "&Bold"))
+ self.actFormatBold.setShortcut(_translate("MainWindow", "Ctrl+B"))
+ self.actFormatItalic.setText(_translate("MainWindow", "&Italic"))
+ self.actFormatItalic.setShortcut(_translate("MainWindow", "Ctrl+I"))
+ self.actFormatStrike.setText(_translate("MainWindow", "&Strike"))
+ self.actFormatVerbatim.setText(_translate("MainWindow", "&Verbatim"))
+ self.actFormatSuperscript.setText(_translate("MainWindow", "Su&perscript"))
+ self.actFormatSuperscript.setShortcut(_translate("MainWindow", "Ctrl++"))
+ self.actFormatSubscript.setText(_translate("MainWindow", "Subsc&ript"))
+ self.actFormatSubscript.setShortcut(_translate("MainWindow", "Ctrl+-"))
+ self.actFormatCommentBlock.setText(_translate("MainWindow", "Co&mment block"))
+ self.actFormatCommentBlock.setShortcut(_translate("MainWindow", "Ctrl+Shift+C"))
+ self.actFormatClear.setText(_translate("MainWindow", "Clear &formats"))
+ self.actFormatClear.setShortcut(_translate("MainWindow", "Ctrl+0"))
+ self.actFormatCommentLines.setText(_translate("MainWindow", "&Comment line(s)"))
+ self.actFormatCommentLines.setShortcut(_translate("MainWindow", "Ctrl+D"))
+ self.actFormatOrderedList.setText(_translate("MainWindow", "&Ordered list"))
+ self.actFormatList.setText(_translate("MainWindow", "&Unordered list"))
+ self.actFormatBlockquote.setText(_translate("MainWindow", "B&lockquote"))
from manuskript.ui.cheatSheet import cheatSheet
from manuskript.ui.editors.mainEditor import mainEditor
diff --git a/manuskript/ui/mainWindow.ui b/manuskript/ui/mainWindow.ui
index 150f7040..b7bd72df 100644
--- a/manuskript/ui/mainWindow.ui
+++ b/manuskript/ui/mainWindow.ui
@@ -629,7 +629,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
@@ -640,7 +640,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
@@ -651,7 +651,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
@@ -662,7 +662,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
@@ -737,7 +737,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -751,7 +751,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -815,8 +815,8 @@
0
0
- 426
- 688
+ 204
+ 606
@@ -905,7 +905,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -988,7 +988,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
@@ -1033,7 +1033,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
@@ -1044,7 +1044,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
@@ -1075,7 +1075,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
@@ -1136,7 +1136,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1150,7 +1150,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1264,7 +1264,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1281,7 +1281,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1355,7 +1355,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
Ctrl+Return
@@ -1375,7 +1375,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
Ctrl+Backspace
@@ -1405,7 +1405,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1557,7 +1557,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1571,7 +1571,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1770,7 +1770,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1784,7 +1784,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1798,7 +1798,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1825,7 +1825,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1917,7 +1917,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1931,7 +1931,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -1945,7 +1945,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
true
@@ -2137,12 +2137,53 @@
&Edit
+
+
+
@@ -2286,7 +2327,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
&Open
@@ -2298,7 +2339,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
&Save
@@ -2310,7 +2351,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
Sa&ve as...
@@ -2322,7 +2363,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
&Quit
@@ -2340,7 +2381,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
&Show help texts
@@ -2358,7 +2399,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
&Spellcheck
@@ -2430,7 +2471,7 @@
- ../../../../../../../.designer/backup../../../../../../../.designer/backup
+ ..
S&ettings
@@ -2569,9 +2610,6 @@
Dupl&icate
-
- Ctrl+D
-
@@ -2621,18 +2659,178 @@
F2
+
+
+ &Level 1 (setext)
+
+
+ Ctrl+Alt+1
+
+
+
+
+ Level &2
+
+
+ Ctrl+Alt+2
+
+
+
+
+ Level &1 (atx)
+
+
+ Ctrl+1
+
+
+
+
+ L&evel 2
+
+
+ Ctrl+2
+
+
+
+
+ Level &3
+
+
+ Ctrl+3
+
+
+
+
+ Level &4
+
+
+ Ctrl+4
+
+
+
+
+ Level &5
+
+
+ Ctrl+5
+
+
+
+
+ Level &6
+
+
+ Ctrl+6
+
+
+
+
+
+ ..
+
+
+ &Bold
+
+
+ Ctrl+B
+
+
+
+
+
+ ..
+
+
+ &Italic
+
+
+ Ctrl+I
+
+
+
+
+
+ ..
+
+
+ &Strike
+
+
+
+
+ &Verbatim
+
+
+
+
+ Su&perscript
+
+
+ Ctrl++
+
+
+
+
+ Subsc&ript
+
+
+ Ctrl+-
+
+
+
+
+ Co&mment block
+
+
+ Ctrl+Shift+C
+
+
+
+
+
+ ..
+
+
+ Clear &formats
+
+
+ Ctrl+0
+
+
+
+
+ &Comment line(s)
+
+
+ Ctrl+D
+
+
+
+
+ &Ordered list
+
+
+
+
+
+ ..
+
+
+ &Unordered list
+
+
+
+
+ B&lockquote
+
+
- textEditView
+ MDEditCompleter
QTextEdit
- manuskript.ui.views.textEditView.h
+ manuskript.ui.views.MDEditCompleter.h
-
- MDEditCompleter
- QTextEdit
- manuskript.ui.views.MDEditCompleter.h
-
lineEditView
QLineEdit
diff --git a/manuskript/ui/views/MDEditView.py b/manuskript/ui/views/MDEditView.py
index 5b020cf0..d021bf84 100644
--- a/manuskript/ui/views/MDEditView.py
+++ b/manuskript/ui/views/MDEditView.py
@@ -10,11 +10,14 @@ 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
+from manuskript.ui.highlighters.markdownEnums import MarkdownState as MS
class MDEditView(textEditView):
+
+ blockquoteRegex = QRegExp("^ {0,3}(>\\s*)+")
+ listRegex = QRegExp("^(\\s*)([+*-]|([0-9a-z])+([.\)]))(\\s+)")
+
def __init__(self, parent=None, index=None, html=None, spellcheck=True,
highlighting=False, dict="", autoResize=False):
textEditView.__init__(self, parent, index, html, spellcheck,
@@ -33,19 +36,131 @@ class MDEditView(textEditView):
self.verticalScrollBar().rangeChanged.connect(
self.scrollBarRangeChanged)
- # def focusInEvent(self, event):
- # """Finds textFormatter and attach them to that view."""
- # textEditView.focusInEvent(self, event)
- #
- # p = self.parent()
- # while p.parent():
- # p = p.parent()
- #
- # if self._index:
- # for tF in p.findChildren(textFormat, QRegExp(".*"),
- # Qt.FindChildrenRecursively):
- # tF.updateFromIndex(self._index)
- # tF.setTextEdit(self)
+ ###########################################################################
+ # KEYPRESS
+ ###########################################################################
+
+ def keyPressEvent(self, event):
+ k = event.key()
+ m = event.modifiers()
+ cursor = self.textCursor()
+
+ # RETURN
+ if k == Qt.Key_Return:
+ if not cursor.hasSelection():
+ if m & Qt.ShiftModifier:
+ # Insert Markdown-style line break
+ cursor.insertText(" ")
+
+ if m & Qt.ControlModifier:
+ cursor.insertText("\n")
+ else:
+ self.handleCarriageReturn()
+ else:
+ textEditView.keyPressEvent(self, event)
+
+ # TAB
+ elif k == Qt.Key_Tab:
+ #self.indentText()
+ # FIXME
+ textEditView.keyPressEvent(self, event)
+ elif k == Qt.Key_Backtab:
+ #self.unindentText()
+ # FIXME
+ textEditView.keyPressEvent(self, event)
+
+ else:
+ textEditView.keyPressEvent(self, event)
+
+ # Thanks to GhostWriter, mainly
+ def handleCarriageReturn(self):
+ autoInsertText = "";
+ cursor = self.textCursor()
+ endList = False
+ moveBack = False
+ text = cursor.block().text()
+
+ if cursor.positionInBlock() < cursor.block().length() - 1:
+ autoInsertText = self.getPriorIndentation()
+ if cursor.positionInBlock() < len(autoInsertText):
+ autoInsertText = autoInsertText[:cursor.positionInBlock()]
+
+ else:
+ s = cursor.block().userState()
+
+ if s in [MS.MarkdownStateNumberedList,
+ MS.MarkdownStateBulletPointList]:
+ self.listRegex.indexIn(text)
+ g = self.listRegex.capturedTexts()
+ # 0 = " a. " or " * "
+ # 1 = " " " "
+ # 2 = "a." "*"
+ # 3 = "a" ""
+ # 4 = "." ""
+ # 5 = " " " "
+
+ # If the line of text is an empty list item, end the list.
+ if len(g[0].strip()) == len(text.strip()):
+ endList = True
+
+ # Else increment the list number
+ elif g[3]: # Numbered list
+ try: # digit
+ i = int(g[3])+1
+
+ except: # letter
+ i = chr(ord(g[3])+1)
+
+ autoInsertText = "{}{}{}{}".format(
+ g[1], i, g[4], g[5])
+
+ else: # Bullet list
+ autoInsertText = g[0]
+
+ if text[-2:] == " ":
+ autoInsertText = " " * len(autoInsertText)
+
+ elif s == MS.MarkdownStateBlockquote:
+ self.blockquoteRegex.indexIn(text)
+ g = self.blockquoteRegex.capturedTexts()
+ autoInsertText = g[0]
+
+ elif s in [MS.MarkdownStateInGithubCodeFence,
+ MS.MarkdownStateInPandocCodeFence] and \
+ cursor.block().previous().userState() != s:
+ autoInsertText = "\n" + text
+ moveBack = True
+
+ else:
+ autoInsertText = self.getPriorIndentation()
+
+ # Clear the list
+ if endList:
+ autoInsertText = self.getPriorIndentation()
+ cursor.movePosition(QTextCursor.StartOfBlock)
+ cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor)
+ cursor.insertText(autoInsertText)
+ autoInsertText = ""
+
+ # Finally, we insert
+ cursor.insertText("\n" + autoInsertText)
+ if moveBack:
+ cursor.movePosition(QTextCursor.PreviousBlock)
+ self.setTextCursor(cursor)
+
+ self.ensureCursorVisible()
+
+ def getPriorIndentation(self):
+ text = self.textCursor().block().text()
+ l = len(text) - len(text.lstrip())
+ return text[:l]
+
+ def getPriorMarkdownBlockItemStart(self, itemRegex):
+ text = self.textCursor().block().text()
+ if itemRegex.indexIn(text) >= 0:
+ return text[itemRegex.matchedLength():]
+
+ return ""
###########################################################################
# TypeWriterScrolling
@@ -79,23 +194,18 @@ class MDEditView(textEditView):
self.verticalScrollBar().blockSignals(False)
###########################################################################
- # FORMATTING (#FIXME)
+ # FORMATTING
###########################################################################
- def applyFormat(self, _format):
-
- if self._textFormat == "md":
- if _format == "Bold": self.bold()
- elif _format == "Italic": self.italic()
- elif _format == "Code": self.verbatim()
- elif _format == "Clear": self.clearFormat()
-
def bold(self): self.insertFormattingMarkup("**")
def italic(self): self.insertFormattingMarkup("*")
def strike(self): self.insertFormattingMarkup("~~")
def verbatim(self): self.insertFormattingMarkup("`")
def superscript(self): self.insertFormattingMarkup("^")
def subscript(self): self.insertFormattingMarkup("~")
+ def blockquote(self): self.lineFormattingMarkup("> ")
+ def orderedList(self): self.lineFormattingMarkup(" 1. ")
+ def unorderedList(self): self.lineFormattingMarkup(" - ")
def selectWord(self, cursor):
if cursor.selectedText():
@@ -161,6 +271,14 @@ class MDEditView(textEditView):
self.selectBlock(cursor)
cursor.insertText(text2)
+ def lineFormattingMarkup(self, markup):
+ """
+ Adds `markup` at the begining of block.
+ """
+ cursor = self.textCursor()
+ cursor.movePosition(cursor.StartOfBlock)
+ cursor.insertText(markup)
+
def insertFormattingMarkup(self, markup):
cursor = self.textCursor()
@@ -211,8 +329,7 @@ class MDEditView(textEditView):
("~~(.*?)~~", "\\1", None), # strike
("\^(.*?)\^", "\\1", None), # superscript
("~(.*?)~", "\\1", None), # subscript
- ("", "\\1", re.S), # comments
-
+ ("", "\\1", re.S), # comments
# LINES OR BLOCKS
(r"^#*\s*(.+?)\s*", "\\1", re.M), # ATX