Skip to content

Commit

Permalink
Merge pull request #901 from worstje/dot-twelve-assorted
Browse files Browse the repository at this point in the history
Fixes for a number of reported bugs
  • Loading branch information
TheJackiMonster committed Jul 10, 2021
2 parents 4bfd663 + d6e472b commit 731e017
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 14 deletions.
30 changes: 22 additions & 8 deletions manuskript/main.py
Expand Up @@ -20,6 +20,10 @@
LOGGER = logging.getLogger(__name__)

def prepare(arguments, tests=False):
# Qt WebEngine demands this attribute be set _before_ we create our QApplication object.
QApplication.setAttribute(Qt.AA_ShareOpenGLContexts, True)

# Create the foundation that provides our Qt application with its event loop.
app = QApplication(sys.argv)
app.setOrganizationName("manuskript" + ("_tests" if tests else ""))
app.setOrganizationDomain("www.theologeek.ch")
Expand Down Expand Up @@ -160,7 +164,7 @@ def respectSystemDarkThemeSetting():
QIcon.setThemeSearchPaths(QIcon.themeSearchPaths() + [appPath("icons")])
QIcon.setThemeName("NumixMsk")

# Font siue
# Font size
if settings.contains("appFontSize"):
f = qApp.font()
f.setPointSize(settings.value("appFontSize", type=int))
Expand All @@ -175,12 +179,12 @@ def respectSystemDarkThemeSetting():
MW._defaultCursorFlashTime = qApp.cursorFlashTime()

# Command line project
#if len(sys.argv) > 1 and sys.argv[1][-4:] == ".msk":
if arguments.filename is not None and arguments.filename[-4:] == ".msk":
#TODO: integrate better with argparsing.
if os.path.exists(sys.argv[1]):
path = os.path.abspath(sys.argv[1])
MW._autoLoadProject = path
# The file is verified to already exist during argument parsing.
# Our ".msk" check has been moved there too for better feedback,
# but leaving it here to err on the side of caution.
path = os.path.abspath(arguments.filename)
MW._autoLoadProject = path

return app, MW

Expand Down Expand Up @@ -255,14 +259,24 @@ def setup_signal_handlers(MW):
signal.signal(signal.SIGTERM, sigint_handler("SIGTERM", MW))


def is_valid_project(parser, arg):
if arg[-4:] != ".msk":
parser.error("only manuskript projects (.msk) are supported!")
if not os.path.isfile(arg):
parser.error("the project %s does not exist!" % arg)
else:
return arg


def process_commandline(argv):
import argparse
parser = argparse.ArgumentParser(description="Run the manuskript application.")
parser.add_argument("--console", help="open the IPython Jupyter QT Console as a debugging aid",
action="store_true")
parser.add_argument("-v", "--verbose", action="count", default=1, help="lower the threshold for messages logged to the terminal")
parser.add_argument("-L", "--logfile", default=None, help="override the default log file location")
parser.add_argument("filename", nargs="?", metavar="FILENAME", help="the manuskript project (.msk) to open")
parser.add_argument("filename", nargs="?", metavar="FILENAME", help="the manuskript project (.msk) to open",
type=lambda x: is_valid_project(parser, x))

args = parser.parse_args(args=argv)

Expand All @@ -283,7 +297,7 @@ def run():
2. So that prepare can be used in tests, without running the whole thing
"""
# Parse command-line arguments.
arguments = process_commandline(sys.argv)
arguments = process_commandline(sys.argv[1:])
# Initialize logging. (Does not include Qt integration yet.)
manuskript.logging.setUp(console_level=arguments.verbose)

Expand Down
8 changes: 6 additions & 2 deletions manuskript/models/characterPOVModel.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtCore import QModelIndex, QSortFilterProxyModel

from manuskript.enums import Character as C

class characterPOVModel(QSortFilterProxyModel):

Expand All @@ -14,7 +14,11 @@ def __init__(self, sourceModel, parent=None):
sourceModel.dataChanged.connect(self.sourceDataChanged)

def filterAcceptsRow(self, sourceRow, sourceParent):
return self.sourceModel().pov(sourceRow)
# Although I would prefer to reuse the existing characterModel.pov() method,
# this is simpler to do, actually works and also more ideomatic Qt code.
index = self.sourceModel().index(sourceRow, C.pov.value, sourceParent)
value = self.sourceModel().data(index)
return bool(value)

def rowToSource(self, row):
index = self.index(row, 0)
Expand Down
7 changes: 6 additions & 1 deletion manuskript/models/outlineItem.py
Expand Up @@ -98,7 +98,7 @@ def __str__(self):
)

__repr__ = __str__

def charCount(self):
return self._data.get(self.enum.charCount, 0)

Expand All @@ -116,6 +116,9 @@ def data(self, column, role=Qt.DisplayRole):
return []

else:
# Used to verify nbsp characters not getting clobbered.
#if column == E.text:
# print("GET", str(role), "-->", str([hex(ord(x)) for x in data]))
return data

elif role == Qt.DecorationRole and column == E.title:
Expand Down Expand Up @@ -158,6 +161,8 @@ def setData(self, column, data, role=Qt.DisplayRole):
# Stuff to do before
if column == E.text:
self.addRevision()
# Used to verify nbsp characters not getting clobbered.
#print("SET", str(role), "-->", str([hex(ord(x)) for x in data]))

# Calling base class implementation
abstractItem.setData(self, column, data, role)
Expand Down
5 changes: 4 additions & 1 deletion manuskript/ui/views/MDEditView.py
Expand Up @@ -500,7 +500,10 @@ def getClickRects(self):
r3.setLeft(self.viewport().geometry().left())
r3.setRight(self.viewport().geometry().right())
refs.append(ClickThing(r3, rx, rx.capturedTexts()))
cursor.movePosition(cursor.Down)
if not cursor.movePosition(cursor.Down):
# Super-rare failure. Leaving log message for future investigation.
LOGGER.debug("Failed to move cursor down while calculating clickables. Aborting.")
break

self.clickRects = refs

Expand Down
15 changes: 13 additions & 2 deletions manuskript/ui/views/textEditView.py
Expand Up @@ -20,7 +20,11 @@
import logging
LOGGER = logging.getLogger(__name__)

# See implementation of QTextDocument::toPlainText()
PLAIN_TRANSLATION_TABLE = {0x2028: "\n", 0x2029: "\n", 0xfdd0: "\n", 0xfdd1: "\n"}

class textEditView(QTextEdit):

def __init__(self, parent=None, index=None, html=None, spellcheck=None,
highlighting=False, dict="", autoResize=False):
QTextEdit.__init__(self, parent)
Expand Down Expand Up @@ -278,13 +282,20 @@ def disconnectDocument(self):
def reconnectDocument(self):
self.document().contentsChanged.connect(self.updateTimer.start, F.AUC)

def toIdealText(self):
"""QTextDocument::toPlainText() replaces NBSP with spaces, which we don't want.
QTextDocument::toRawText() replaces nothing, but that leaves fancy paragraph and line separators that users would likely complain about.
This reimplements toPlainText(), except without the NBSP destruction."""
return self.document().toRawText().translate(PLAIN_TRANSLATION_TABLE)
toPlainText = toIdealText

def updateText(self):
self._updating.lock()

# LOGGER.debug("Updating %s", self.objectName())
if self._index:
self.disconnectDocument()
if self.toPlainText() != F.toString(self._index.data()):
if self.toIdealText() != F.toString(self._index.data()):
# LOGGER.debug(" Updating plaintext")
self.document().setPlainText(F.toString(self._index.data()))
self.reconnectDocument()
Expand Down Expand Up @@ -319,7 +330,7 @@ def submit(self):
self.updateTimer.stop()

self._updating.lock()
text = self.toPlainText()
text = self.toIdealText()
self._updating.unlock()

# LOGGER.debug("Submitting %s", self.objectName())
Expand Down

0 comments on commit 731e017

Please sign in to comment.