Added text autoreplace functionality to doc editor.
This commit is contained in:
+28
-6
@@ -58,9 +58,14 @@ class Config:
|
|||||||
self.mainPanePos = [300, 800]
|
self.mainPanePos = [300, 800]
|
||||||
|
|
||||||
## Text Editor
|
## Text Editor
|
||||||
self.textFixedW = True
|
self.textFixedW = True
|
||||||
self.textWidth = 600
|
self.textWidth = 600
|
||||||
self.textMargin = [40, 40]
|
self.textMargin = [40, 40]
|
||||||
|
self.doReplace = True
|
||||||
|
self.doReplaceQuote = True
|
||||||
|
self.doReplaceDash = True
|
||||||
|
self.doReplaceDots = True
|
||||||
|
self.replaceQuotes = ["“","”"]
|
||||||
|
|
||||||
# Check if config file exists
|
# Check if config file exists
|
||||||
if path.isfile(path.join(self.confPath,self.confFile)):
|
if path.isfile(path.join(self.confPath,self.confFile)):
|
||||||
@@ -104,13 +109,25 @@ class Config:
|
|||||||
cnfSec = "Editor"
|
cnfSec = "Editor"
|
||||||
if confParser.has_section(cnfSec):
|
if confParser.has_section(cnfSec):
|
||||||
if confParser.has_option(cnfSec,"fixedwidth"):
|
if confParser.has_option(cnfSec,"fixedwidth"):
|
||||||
self.textFixedW = confParser.getboolean(cnfSec,"fixedwidth")
|
self.textFixedW = confParser.getboolean(cnfSec,"fixedwidth")
|
||||||
if confParser.has_option(cnfSec,"width"):
|
if confParser.has_option(cnfSec,"width"):
|
||||||
self.textWidth = confParser.getint(cnfSec,"width")
|
self.textWidth = confParser.getint(cnfSec,"width")
|
||||||
if confParser.has_option(cnfSec,"margins"):
|
if confParser.has_option(cnfSec,"margins"):
|
||||||
self.textMargin = self.unpackList(
|
self.textMargin = self.unpackList(
|
||||||
confParser.get(cnfSec,"margins"), 2, self.textMargin
|
confParser.get(cnfSec,"margins"), 2, self.textMargin
|
||||||
)
|
)
|
||||||
|
if confParser.has_option(cnfSec,"autoreplace"):
|
||||||
|
self.doReplace = confParser.getboolean(cnfSec,"autoreplace")
|
||||||
|
if confParser.has_option(cnfSec,"repquotes"):
|
||||||
|
self.doReplaceQuote = confParser.getboolean(cnfSec,"repquotes")
|
||||||
|
if confParser.has_option(cnfSec,"repdash"):
|
||||||
|
self.doReplaceDash = confParser.getboolean(cnfSec,"repdash")
|
||||||
|
if confParser.has_option(cnfSec,"repdots"):
|
||||||
|
self.doReplaceDots = confParser.getboolean(cnfSec,"repdots")
|
||||||
|
if confParser.has_option(cnfSec,"usequotes"):
|
||||||
|
self.replaceQuotes = self.unpackList(
|
||||||
|
confParser.get(cnfSec,"usequotes"), 2, self.replaceQuotes
|
||||||
|
)
|
||||||
|
|
||||||
## Path
|
## Path
|
||||||
cnfSec = "Path"
|
cnfSec = "Path"
|
||||||
@@ -146,6 +163,11 @@ class Config:
|
|||||||
confParser.set(cnfSec,"fixedwidth", str(self.textFixedW))
|
confParser.set(cnfSec,"fixedwidth", str(self.textFixedW))
|
||||||
confParser.set(cnfSec,"width", str(self.textWidth))
|
confParser.set(cnfSec,"width", str(self.textWidth))
|
||||||
confParser.set(cnfSec,"margins", self.packList(self.textMargin))
|
confParser.set(cnfSec,"margins", self.packList(self.textMargin))
|
||||||
|
confParser.set(cnfSec,"autoreplace",str(self.doReplace))
|
||||||
|
confParser.set(cnfSec,"repquotes", str(self.doReplaceQuote))
|
||||||
|
confParser.set(cnfSec,"repdash", str(self.doReplaceDash))
|
||||||
|
confParser.set(cnfSec,"repdots", str(self.doReplaceDots))
|
||||||
|
confParser.set(cnfSec,"usequotes", self.packList(self.replaceQuotes))
|
||||||
|
|
||||||
## Path
|
## Path
|
||||||
cnfSec = "Path"
|
cnfSec = "Path"
|
||||||
|
|||||||
+66
-5
@@ -13,6 +13,8 @@
|
|||||||
import logging
|
import logging
|
||||||
import nw
|
import nw
|
||||||
|
|
||||||
|
from time import time
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QWidget, QTextEdit, QHBoxLayout, QVBoxLayout, QFrame, QSplitter, QToolBar, QAction, QScrollArea
|
from PyQt5.QtWidgets import QWidget, QTextEdit, QHBoxLayout, QVBoxLayout, QFrame, QSplitter, QToolBar, QAction, QScrollArea
|
||||||
from PyQt5.QtCore import Qt, QSize, QSizeF
|
from PyQt5.QtCore import Qt, QSize, QSizeF
|
||||||
from PyQt5.QtGui import QIcon, QFont, QTextCursor, QTextFormat, QTextBlockFormat
|
from PyQt5.QtGui import QIcon, QFont, QTextCursor, QTextFormat, QTextBlockFormat
|
||||||
@@ -23,11 +25,14 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class GuiDocEditor(QWidget):
|
class GuiDocEditor(QWidget):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, theParent):
|
||||||
QWidget.__init__(self)
|
QWidget.__init__(self)
|
||||||
|
|
||||||
logger.debug("Initialising DocEditor ...")
|
logger.debug("Initialising DocEditor ...")
|
||||||
self.mainConf = nw.CONFIG
|
self.mainConf = nw.CONFIG
|
||||||
|
self.theParent = theParent
|
||||||
|
self.charCount = 0
|
||||||
|
self.lineCount = 0
|
||||||
|
|
||||||
self.outerBox = QVBoxLayout()
|
self.outerBox = QVBoxLayout()
|
||||||
self.guiEditor = QTextEdit()
|
self.guiEditor = QTextEdit()
|
||||||
@@ -51,9 +56,10 @@ class GuiDocEditor(QWidget):
|
|||||||
|
|
||||||
self.guiEditor.setMinimumWidth(400)
|
self.guiEditor.setMinimumWidth(400)
|
||||||
self.guiEditor.setAcceptRichText(False)
|
self.guiEditor.setAcceptRichText(False)
|
||||||
theDoc = self.guiEditor.document()
|
|
||||||
# theDoc.setDefaultFont(QFont("Source Sans Pro",13))
|
self.theDoc = self.guiEditor.document()
|
||||||
theDoc.setDocumentMargin(0)
|
self.theDoc.setDocumentMargin(0)
|
||||||
|
self.theDoc.contentsChange.connect(self._docChange)
|
||||||
|
|
||||||
logger.debug("DocEditor initialisation complete")
|
logger.debug("DocEditor initialisation complete")
|
||||||
|
|
||||||
@@ -61,6 +67,7 @@ class GuiDocEditor(QWidget):
|
|||||||
|
|
||||||
def setText(self, theText):
|
def setText(self, theText):
|
||||||
self.guiEditor.setPlainText(theText)
|
self.guiEditor.setPlainText(theText)
|
||||||
|
self.charCount = self.theDoc.characterCount()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getText(self):
|
def getText(self):
|
||||||
@@ -76,10 +83,64 @@ class GuiDocEditor(QWidget):
|
|||||||
sW = self.guiEditor.verticalScrollBar().width()
|
sW = self.guiEditor.verticalScrollBar().width()
|
||||||
tM = int((tW - sW - self.mainConf.textWidth)/2)
|
tM = int((tW - sW - self.mainConf.textWidth)/2)
|
||||||
mTB = self.mainConf.textMargin[0]
|
mTB = self.mainConf.textMargin[0]
|
||||||
# print(tW, sW, tM, mTB)
|
|
||||||
self.guiEditor.setViewportMargins(tM,mTB,0,mTB)
|
self.guiEditor.setViewportMargins(tM,mTB,0,mTB)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _docChange(self, thePos, charsRemoved, charsAdded):
|
||||||
|
tStart = time()
|
||||||
|
# logger.debug("Contents changed: %d %d %d" % (thePos, charsRemoved, charsAdded))
|
||||||
|
self.charCount = self.theDoc.characterCount()
|
||||||
|
self.lineCount = self.theDoc.lineCount()
|
||||||
|
self.theParent.statusBar.setCharCount(self.charCount)
|
||||||
|
if self.mainConf.doReplace:
|
||||||
|
self._docAutoReplace(self.theDoc.findBlock(thePos))
|
||||||
|
logger.verbose("Doc change signal took %.3f µs" % ((time()-tStart)*1e6))
|
||||||
|
return
|
||||||
|
|
||||||
|
def _docAutoReplace(self, theBlock):
|
||||||
|
|
||||||
|
theText = theBlock.text()
|
||||||
|
theCursor = self.guiEditor.textCursor()
|
||||||
|
thePos = theCursor.positionInBlock()
|
||||||
|
theLen = len(theText)
|
||||||
|
|
||||||
|
if theLen < 1 or thePos-1 > theLen:
|
||||||
|
return
|
||||||
|
|
||||||
|
theOne = theText[thePos-1:thePos]
|
||||||
|
theTwo = theText[thePos-2:thePos]
|
||||||
|
theThree = theText[thePos-3:thePos]
|
||||||
|
|
||||||
|
if self.mainConf.doReplaceQuote and theOne == "\"":
|
||||||
|
qOpen = self.mainConf.replaceQuotes[0]
|
||||||
|
qClose = self.mainConf.replaceQuotes[1]
|
||||||
|
nOpen = theText.count(qOpen)
|
||||||
|
nClose = theText.count(qClose)
|
||||||
|
if nOpen > nClose:
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().insertText(qClose)
|
||||||
|
else:
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().insertText(qOpen)
|
||||||
|
|
||||||
|
if self.mainConf.doReplaceDash and theTwo == "--":
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().insertText("–")
|
||||||
|
|
||||||
|
if self.mainConf.doReplaceDash and theTwo == "–-":
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().insertText("—")
|
||||||
|
|
||||||
|
if self.mainConf.doReplaceDots and theThree == "...":
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().deletePreviousChar()
|
||||||
|
self.guiEditor.textCursor().insertText("…")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def _buildTabToolBar(self):
|
def _buildTabToolBar(self):
|
||||||
toolBar = self.editToolBar
|
toolBar = self.editToolBar
|
||||||
toolBar.setToolButtonStyle(Qt.ToolButtonIconOnly)
|
toolBar.setToolButtonStyle(Qt.ToolButtonIconOnly)
|
||||||
|
|||||||
+22
-2
@@ -23,12 +23,18 @@ class NWDoc():
|
|||||||
|
|
||||||
FILE_MN = "main.nwd"
|
FILE_MN = "main.nwd"
|
||||||
|
|
||||||
def __init__(self, theProject):
|
def __init__(self, theProject, theParent):
|
||||||
|
|
||||||
self.mainConf = nw.CONFIG
|
self.mainConf = nw.CONFIG
|
||||||
self.theProject = theProject
|
self.theProject = theProject
|
||||||
self.docHandle = None
|
self.theParent = theParent
|
||||||
self.theItem = None
|
self.theItem = None
|
||||||
|
self.docHandle = None
|
||||||
|
|
||||||
|
# Document Info
|
||||||
|
self.charCount = None
|
||||||
|
self.lineCount = None
|
||||||
|
self.wordCount = None
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -36,6 +42,7 @@ class NWDoc():
|
|||||||
|
|
||||||
self.docHandle = tHandle
|
self.docHandle = tHandle
|
||||||
self.theItem = self.theProject.getItem(tHandle)
|
self.theItem = self.theProject.getItem(tHandle)
|
||||||
|
self.theParent.statusBar.setDocHandleCount(tHandle)
|
||||||
|
|
||||||
docDir, docFile = self._assemblePath(self.FILE_MN)
|
docDir, docFile = self._assemblePath(self.FILE_MN)
|
||||||
logger.debug("Opening document %s" % path.join(docDir,docFile))
|
logger.debug("Opening document %s" % path.join(docDir,docFile))
|
||||||
@@ -78,6 +85,7 @@ class NWDoc():
|
|||||||
|
|
||||||
docAna = TextAnalysis(docText,"en_GB")
|
docAna = TextAnalysis(docText,"en_GB")
|
||||||
wC, sC, pC = docAna.getStats()
|
wC, sC, pC = docAna.getStats()
|
||||||
|
# rScr, gLev = docAna.getReadabilityScore()
|
||||||
|
|
||||||
self.theItem.setWordCount(wC)
|
self.theItem.setWordCount(wC)
|
||||||
self.theItem.setSentCount(sC)
|
self.theItem.setSentCount(sC)
|
||||||
@@ -85,6 +93,18 @@ class NWDoc():
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
##
|
||||||
|
# Setters
|
||||||
|
##
|
||||||
|
|
||||||
|
def setCharCount(self, theCount):
|
||||||
|
self.charCount = theCount
|
||||||
|
return
|
||||||
|
|
||||||
|
def setLineCount(self, theCount):
|
||||||
|
self.lineCount = theCount
|
||||||
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Internal Functions
|
# Internal Functions
|
||||||
##
|
##
|
||||||
|
|||||||
@@ -6,3 +6,13 @@ QTextEdit {
|
|||||||
background-color: #141414;
|
background-color: #141414;
|
||||||
color: #c7cfd0;
|
color: #c7cfd0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStatusBar::item {
|
||||||
|
background-color: rgba(0,0,0,0.1);
|
||||||
|
border: 1px solid #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStatusBar::item QLabel {
|
||||||
|
background-color: rgba(0,0,0,0.0);
|
||||||
|
padding: 1px 4px;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user