Merge branch 'dev' into text_align

This commit is contained in:
Veronica Berglyd Olsen
2021-06-10 22:52:47 +02:00
19 changed files with 285 additions and 311 deletions
+4 -4
View File
@@ -413,10 +413,10 @@ Most features are available as keyboard shortcuts. These are as follows:
:widths: 30, 70 :widths: 30, 70
:class: "tight-table" :class: "tight-table"
":kbd:`Alt`:kbd:`1`", "Switch focus to the project tree." ":kbd:`Alt`:kbd:`1`", "Switch focus to the project tree. On Windows, use :kbd:`Ctrl`:kbd:`Alt`:kbd:`1`."
":kbd:`Alt`:kbd:`2`", "Switch focus to document editor." ":kbd:`Alt`:kbd:`2`", "Switch focus to document editor. On Windows, use :kbd:`Ctrl`:kbd:`Alt`:kbd:`2`."
":kbd:`Alt`:kbd:`3`", "Switch focus to document viewer." ":kbd:`Alt`:kbd:`3`", "Switch focus to document viewer. On Windows, use :kbd:`Ctrl`:kbd:`Alt`:kbd:`3`."
":kbd:`Alt`:kbd:`4`", "Switch focus to outline view." ":kbd:`Alt`:kbd:`4`", "Switch focus to outline view. On Windows, use :kbd:`Ctrl`:kbd:`Alt`:kbd:`4`."
":kbd:`Alt`:kbd:`Left`", "Move backward in the view history of the document viewer." ":kbd:`Alt`:kbd:`Left`", "Move backward in the view history of the document viewer."
":kbd:`Alt`:kbd:`Right`", "Move forward in the view history of the document viewer." ":kbd:`Alt`:kbd:`Right`", "Move forward in the view history of the document viewer."
":kbd:`Ctrl`:kbd:`.`", "Open menu to correct word under cursor." ":kbd:`Ctrl`:kbd:`.`", "Open menu to correct word under cursor."
-1
View File
@@ -296,7 +296,6 @@ class NWIndex():
nTitle = 0 nTitle = 0
theLines = theText.splitlines() theLines = theText.splitlines()
for aLine in theLines: for aLine in theLines:
aLine = aLine
nLine += 1 nLine += 1
nChar = len(aLine.strip()) nChar = len(aLine.strip())
if nChar == 0: if nChar == 0:
+92 -109
View File
@@ -120,7 +120,7 @@ class NWProject():
CUSTOM, and always have parent handle set to None. CUSTOM, and always have parent handle set to None.
""" """
if not self.projTree.checkRootUnique(rootClass): if not self.projTree.checkRootUnique(rootClass):
self.makeAlert("Duplicate root item detected.", nwAlert.ERROR) self.makeAlert(self.tr("Duplicate root item detected."), nwAlert.ERROR)
return None return None
newItem = NWItem(self) newItem = NWItem(self)
newItem.setName(rootName) newItem.setName(rootName)
@@ -362,7 +362,9 @@ class NWProject():
if not os.path.isfile(fileName): if not os.path.isfile(fileName):
fileName = os.path.join(fileName, nwFiles.PROJ_FILE) fileName = os.path.join(fileName, nwFiles.PROJ_FILE)
if not os.path.isfile(fileName): if not os.path.isfile(fileName):
self.makeAlert(self.tr("File not found: {0}").format(fileName), nwAlert.ERROR) self.makeAlert(self.tr(
"File not found: {0}"
).format(fileName), nwAlert.ERROR)
return False return False
self.clearProject() self.clearProject()
@@ -411,20 +413,22 @@ class NWProject():
try: try:
nwXML = etree.parse(fileName) nwXML = etree.parse(fileName)
except Exception as e: except Exception as e:
self.makeAlert([self.tr("Failed to parse project xml."), str(e)], nwAlert.ERROR) self.makeAlert([
self.tr("Failed to parse project xml."), str(e)
], nwAlert.ERROR)
# Trying to open backup file instead # Trying to open backup file instead
backFile = fileName[:-3]+"bak" backFile = fileName[:-3]+"bak"
if os.path.isfile(backFile): if os.path.isfile(backFile):
self.makeAlert( self.makeAlert(self.tr(
self.tr("Attempting to open backup project file instead."), nwAlert.INFO "Attempting to open backup project file instead."
) ), nwAlert.INFO)
try: try:
nwXML = etree.parse(backFile) nwXML = etree.parse(backFile)
except Exception as e: except Exception as e:
self.makeAlert( self.makeAlert([
[self.tr("Failed to parse project xml."), str(e)], nwAlert.ERROR self.tr("Failed to parse project xml."), str(e)
) ], nwAlert.ERROR)
self.clearProject() self.clearProject()
return False return False
else: else:
@@ -445,10 +449,9 @@ class NWProject():
# =============== # ===============
if not nwxRoot == "novelWriterXML": if not nwxRoot == "novelWriterXML":
self.makeAlert( self.makeAlert(self.tr(
self.tr("Project file does not appear to be a novelWriterXML file."), "Project file does not appear to be a novelWriterXML file."
nwAlert.ERROR ), nwAlert.ERROR)
)
self.clearProject() self.clearProject()
return False return False
@@ -465,13 +468,11 @@ class NWProject():
# read the file. Introduced in version 0.10. # read the file. Introduced in version 0.10.
if fileVersion not in ("1.0", "1.1", "1.2"): if fileVersion not in ("1.0", "1.1", "1.2"):
self.makeAlert(( self.makeAlert(self.tr(
self.tr( "Unknown or unsupported novelWriter project file format. "
"Unknown or unsupported novelWriter project file format. " "The project cannot be opened by this version of novelWriter. "
"The project cannot be opened by this version of novelWriter. " "The file was saved with novelWriter version {0}."
"The file was saved with novelWriter version {0}." ).format(appVersion), nwAlert.ERROR)
).format(appVersion)
), nwAlert.ERROR)
self.clearProject() self.clearProject()
return False return False
@@ -600,9 +601,9 @@ class NWProject():
file. file.
""" """
if self.projPath is None: if self.projPath is None:
self.makeAlert( self.makeAlert(self.tr(
self.tr("Project path not set, cannot save project."), nwAlert.ERROR "Project path not set, cannot save project."
) ), nwAlert.ERROR)
return False return False
saveTime = time() saveTime = time()
@@ -681,7 +682,9 @@ class NWProject():
xml_declaration = True xml_declaration = True
)) ))
except Exception as e: except Exception as e:
self.makeAlert([self.tr("Failed to save project."), str(e)], nwAlert.ERROR) self.makeAlert([
self.tr("Failed to save project."), str(e)
], nwAlert.ERROR)
return False return False
# If we're here, the file was successfully saved, # If we're here, the file was successfully saved,
@@ -755,30 +758,24 @@ class NWProject():
self.theParent.setStatus(self.tr("Backing up project ...")) self.theParent.setStatus(self.tr("Backing up project ..."))
if self.mainConf.backupPath is None or self.mainConf.backupPath == "": if self.mainConf.backupPath is None or self.mainConf.backupPath == "":
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "Cannot backup project because no backup path is set. "
"Cannot backup project because no backup path is set. " "Please set a valid backup location in Tools > Preferences."
"Please set a valid backup location in Tools > Preferences." ), nwAlert.ERROR)
), nwAlert.ERROR
)
return False return False
if self.projName is None or self.projName == "": if self.projName is None or self.projName == "":
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "Cannot backup project because no project name is set. "
"Cannot backup project because no project name is set. " "Please set a Working Title in Project > Project Settings."
"Please set a Working Title in Project > Project Settings." ), nwAlert.ERROR)
), nwAlert.ERROR
)
return False return False
if not os.path.isdir(self.mainConf.backupPath): if not os.path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "Cannot backup project because the backup path does not exist. "
"Cannot backup project because the backup path does not exist. " "Please set a valid backup location in Tools > Preferences."
"Please set a valid backup location in Tools > Preferences." ), nwAlert.ERROR)
), nwAlert.ERROR
)
return False return False
cleanName = makeFileNameSafe(self.projName) cleanName = makeFileNameSafe(self.projName)
@@ -788,20 +785,17 @@ class NWProject():
os.mkdir(baseDir) os.mkdir(baseDir)
logger.debug("Created folder %s" % baseDir) logger.debug("Created folder %s" % baseDir)
except Exception as e: except Exception as e:
self.theParent.makeAlert( self.theParent.makeAlert([
[self.tr("Could not create backup folder."), str(e)], self.tr("Could not create backup folder."), str(e)
nwAlert.ERROR ], nwAlert.ERROR)
)
return False return False
if os.path.commonpath([self.projPath, baseDir]) == self.projPath: if os.path.commonpath([self.projPath, baseDir]) == self.projPath:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "Cannot backup project because the backup path is within the "
"Cannot backup project because the backup path is within the " "project folder to be backed up. Please choose a different "
"project folder to be backed up. Please choose a different " "backup path in Tools > Preferences."
"backup path in Tools > Preferences." ), nwAlert.ERROR)
), nwAlert.ERROR
)
return False return False
archName = self.tr("Backup from {0}").format(formatTimeStamp(time(), fileSafe=True)) archName = self.tr("Backup from {0}").format(formatTimeStamp(time(), fileSafe=True))
@@ -813,22 +807,19 @@ class NWProject():
self._writeLockFile() self._writeLockFile()
logger.info("Backup written to: %s" % archName) logger.info("Backup written to: %s" % archName)
if doNotify: if doNotify:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "Backup archive file written to: {0}"
"Backup archive file written to: {0}" ).format(f"{os.path.join(cleanName, archName)}.zip"), nwAlert.INFO)
).format(
f"{os.path.join(cleanName, archName)}.zip"
), nwAlert.INFO
)
except Exception as e: except Exception as e:
self.theParent.makeAlert( self.theParent.makeAlert([
[self.tr("Could not write backup archive."), str(e)], self.tr("Could not write backup archive."), str(e)
nwAlert.ERROR ], nwAlert.ERROR)
)
return False return False
self.theParent.setStatus(self.tr("Project backed up to '{0}'").format(f"{baseName}.zip")) self.theParent.setStatus(self.tr(
"Project backed up to '{0}'"
).format(f"{baseName}.zip"))
return True return True
@@ -854,9 +845,9 @@ class NWProject():
shutil.unpack_archive(pkgSample, projPath) shutil.unpack_archive(pkgSample, projPath)
isSuccess = True isSuccess = True
except Exception as e: except Exception as e:
self.makeAlert( self.makeAlert([
[self.tr("Failed to create a new example project."), str(e)], nwAlert.ERROR self.tr("Failed to create a new example project."), str(e)
) ], nwAlert.ERROR)
elif os.path.isdir(srcSample): elif os.path.isdir(srcSample):
@@ -876,17 +867,16 @@ class NWProject():
isSuccess = True isSuccess = True
except Exception as e: except Exception as e:
self.makeAlert( self.makeAlert([
[self.tr("Failed to create a new example project."), str(e)], nwAlert.ERROR self.tr("Failed to create a new example project."), str(e)
) ], nwAlert.ERROR)
else: else:
self.makeAlert( self.makeAlert(self.tr(
self.tr( "Failed to create a new example project. "
"Failed to create a new example project. Could not find the " "Could not find the necessary files. "
"necessary files. They seem to be missing from this installation." "They seem to be missing from this installation."
), nwAlert.ERROR ), nwAlert.ERROR)
)
if isSuccess: if isSuccess:
self.clearProject() self.clearProject()
@@ -916,19 +906,17 @@ class NWProject():
os.mkdir(projPath) os.mkdir(projPath)
logger.debug("Created folder %s" % projPath) logger.debug("Created folder %s" % projPath)
except Exception as e: except Exception as e:
self.theParent.makeAlert(( self.theParent.makeAlert([
[self.tr("Could not create new project folder."), str(e)] self.tr("Could not create new project folder."), str(e)
), nwAlert.ERROR) ], nwAlert.ERROR)
return False return False
if os.path.isdir(projPath): if os.path.isdir(projPath):
if os.listdir(self.projPath): if os.listdir(self.projPath):
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "New project folder is not empty. "
"New project folder is not empty. " "Each project requires a dedicated project folder."
"Each project requires a dedicated project folder." ), nwAlert.ERROR)
), nwAlert.ERROR
)
return False return False
self.ensureFolderStructure() self.ensureFolderStructure()
@@ -975,21 +963,17 @@ class NWProject():
self.doBackup = doBackup self.doBackup = doBackup
if doBackup: if doBackup:
if not os.path.isdir(self.mainConf.backupPath): if not os.path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "You must set a valid backup path in Preferences to use "
"You must set a valid backup path in Preferences to use " "the automatic project backup feature."
"the automatic project backup feature." ), nwAlert.WARN)
), nwAlert.WARN
)
return False return False
if self.projName == "": if self.projName == "":
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "You must set a valid project name in Project Settings to "
"You must set a valid project name in Project Settings to " "use the automatic project backup feature."
"use the automatic project backup feature." ), nwAlert.WARN)
), nwAlert.WARN
)
return False return False
return True return True
@@ -1317,7 +1301,9 @@ class NWProject():
os.mkdir(thePath) os.mkdir(thePath)
logger.debug("Created folder %s" % thePath) logger.debug("Created folder %s" % thePath)
except Exception as e: except Exception as e:
self.makeAlert(["Could not create folder.", str(e)], nwAlert.ERROR) self.makeAlert([
self.tr("Could not create folder."), str(e)
], nwAlert.ERROR)
return False return False
return True return True
@@ -1374,10 +1360,9 @@ class NWProject():
# Report status # Report status
if len(orphanFiles) > 0: if len(orphanFiles) > 0:
self.makeAlert( self.makeAlert(self.tr(
self.tr("Found {0} orphaned file(s) in project folder.").format(len(orphanFiles)), "Found {0} orphaned file(s) in project folder."
nwAlert.WARN ).format(len(orphanFiles)), nwAlert.WARN)
)
else: else:
logger.debug("File check OK") logger.debug("File check OK")
return return
@@ -1431,12 +1416,10 @@ class NWProject():
self.projTree.append(oHandle, oParent, orphItem) self.projTree.append(oHandle, oParent, orphItem)
if noWhere: if noWhere:
self.makeAlert( self.makeAlert(self.tr(
self.tr( "One or more orphaned files could not be added back into the project. "
"One or more orphaned files could not be added back into the " "Make sure at least a Novel root folder exists."
"project. Make sure at least a Novel root folder exists." ), nwAlert.WARN)
), nwAlert.WARN
)
return True return True
+15 -15
View File
@@ -102,9 +102,9 @@ class GuiDocMerge(QDialog):
finalOrder.append(self.listBox.item(i).data(Qt.UserRole)) finalOrder.append(self.listBox.item(i).data(Qt.UserRole))
if len(finalOrder) == 0: if len(finalOrder) == 0:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("No source documents found. Nothing to do."), nwAlert.ERROR "No source documents found. Nothing to do."
) ), nwAlert.ERROR)
return False return False
theText = "" theText = ""
@@ -113,16 +113,16 @@ class GuiDocMerge(QDialog):
docText = inDoc.readDocument() docText = inDoc.readDocument()
docErr = inDoc.getError() docErr = inDoc.getError()
if docText is None and docErr: if docText is None and docErr:
self.theParent.makeAlert( self.theParent.makeAlert([
[self.tr("Failed to open document file."), docErr], nwAlert.ERROR self.tr("Failed to open document file."), docErr
) ], nwAlert.ERROR)
if docText: if docText:
theText += docText.rstrip("\n")+"\n\n" theText += docText.rstrip("\n")+"\n\n"
if self.sourceItem is None: if self.sourceItem is None:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("No source folder selected. Nothing to do."), nwAlert.ERROR "No source folder selected. Nothing to do."
) ), nwAlert.ERROR)
return False return False
srcItem = self.theProject.projTree[self.sourceItem] srcItem = self.theProject.projTree[self.sourceItem]
@@ -136,9 +136,9 @@ class GuiDocMerge(QDialog):
outDoc = NWDoc(self.theProject, nHandle) outDoc = NWDoc(self.theProject, nHandle)
if not outDoc.writeDocument(theText): if not outDoc.writeDocument(theText):
self.theParent.makeAlert( self.theParent.makeAlert([
[self.tr("Could not save document."), outDoc.getError()], nwAlert.ERROR self.tr("Could not save document."), outDoc.getError()
) ], nwAlert.ERROR)
return False return False
self.theParent.treeView.revealNewTreeItem(nHandle) self.theParent.treeView.revealNewTreeItem(nHandle)
@@ -174,9 +174,9 @@ class GuiDocMerge(QDialog):
return False return False
if nwItem.itemType is not nwItemType.FOLDER: if nwItem.itemType is not nwItemType.FOLDER:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("Element selected in the project tree must be a folder."), nwAlert.ERROR "Element selected in the project tree must be a folder."
) ), nwAlert.ERROR)
return False return False
for sHandle in self.theParent.treeView.getTreeFromHandle(tHandle): for sHandle in self.theParent.treeView.getTreeFromHandle(tHandle):
+23 -25
View File
@@ -117,16 +117,16 @@ class GuiDocSplit(QDialog):
logger.verbose("GuiDocSplit split button clicked") logger.verbose("GuiDocSplit split button clicked")
if self.sourceItem is None: if self.sourceItem is None:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("No source document selected. Nothing to do."), nwAlert.ERROR "No source document selected. Nothing to do."
) ), nwAlert.ERROR)
return False return False
srcItem = self.theProject.projTree[self.sourceItem] srcItem = self.theProject.projTree[self.sourceItem]
if srcItem is None: if srcItem is None:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("Could not parse source document."), nwAlert.ERROR "Could not parse source document."
) ), nwAlert.ERROR)
return False return False
inDoc = NWDoc(self.theProject, self.sourceItem) inDoc = NWDoc(self.theProject, self.sourceItem)
@@ -134,9 +134,9 @@ class GuiDocSplit(QDialog):
docErr = inDoc.getError() docErr = inDoc.getError()
if theText is None and docErr: if theText is None and docErr:
self.theParent.makeAlert( self.theParent.makeAlert([
[self.tr("Failed to open document file."), docErr], nwAlert.ERROR self.tr("Failed to open document file."), docErr
) ], nwAlert.ERROR)
if theText is None: if theText is None:
theText = "" theText = ""
@@ -157,21 +157,19 @@ class GuiDocSplit(QDialog):
nFiles = len(finalOrder) nFiles = len(finalOrder)
if nFiles == 0: if nFiles == 0:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("No headers found. Nothing to do."), nwAlert.ERROR "No headers found. Nothing to do."
) ), nwAlert.ERROR)
return False return False
# Check that another folder can be created # Check that another folder can be created
parTree = self.theProject.projTree.getItemPath(srcItem.itemParent) parTree = self.theProject.projTree.getItemPath(srcItem.itemParent)
if len(parTree) >= nwConst.MAX_DEPTH - 1: if len(parTree) >= nwConst.MAX_DEPTH - 1:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "Cannot add new folder for the document split. "
"Cannot add new folder for the document split. " "Maximum folder depth has been reached. "
"Maximum folder depth has been reached. " "Please move the file to another level in the project tree."
"Please move the file to another level in the project tree." ), nwAlert.ERROR)
), nwAlert.ERROR
)
return False return False
msgYes = self.theParent.askQuestion( msgYes = self.theParent.askQuestion(
@@ -227,9 +225,9 @@ class GuiDocSplit(QDialog):
outDoc = NWDoc(self.theProject, nHandle) outDoc = NWDoc(self.theProject, nHandle)
if not outDoc.writeDocument(theText): if not outDoc.writeDocument(theText):
self.theParent.makeAlert( self.theParent.makeAlert([
[self.tr("Could not save document."), outDoc.getError()], nwAlert.ERROR self.tr("Could not save document."), outDoc.getError()
) ], nwAlert.ERROR)
return False return False
self.theParent.treeView.revealNewTreeItem(nHandle) self.theParent.treeView.revealNewTreeItem(nHandle)
@@ -267,9 +265,9 @@ class GuiDocSplit(QDialog):
return False return False
if nwItem.itemType is not nwItemType.FILE: if nwItem.itemType is not nwItemType.FILE:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("Element selected in the project tree must be a file."), nwAlert.ERROR "Element selected in the project tree must be a file."
) ), nwAlert.ERROR)
return False return False
inDoc = NWDoc(self.theProject, self.sourceItem) inDoc = NWDoc(self.theProject, self.sourceItem)
+3 -4
View File
@@ -104,10 +104,9 @@ class GuiPreferences(PagedDialog):
self.tabQuote.saveValues() self.tabQuote.saveValues()
if needsRestart: if needsRestart:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("Some changes will not be applied until novelWriter has been restarted."), "Some changes will not be applied until novelWriter has been restarted."
nwAlert.INFO ), nwAlert.INFO)
)
self._saveWindowSize() self._saveWindowSize()
self.accept() self.accept()
+3 -3
View File
@@ -397,9 +397,9 @@ class GuiProjectEditStatus(QWidget):
self.listBox.takeTopLevelItem(iRow) self.listBox.takeTopLevelItem(iRow)
self.colChanged = True self.colChanged = True
else: else:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("Cannot delete a status item that is in use."), nwAlert.ERROR "Cannot delete a status item that is in use."
) ), nwAlert.ERROR)
return return
def _saveItem(self): def _saveItem(self):
+6 -5
View File
@@ -122,14 +122,15 @@ class GuiWordList(QDialog):
""" """
newWord = self.newEntry.text().strip() newWord = self.newEntry.text().strip()
if newWord == "": if newWord == "":
self.theParent.makeAlert(self.tr("Cannot add a blank word."), nwAlert.ERROR) self.theParent.makeAlert(self.tr(
"Cannot add a blank word."
), nwAlert.ERROR)
return False return False
if self.listBox.findItems(newWord, Qt.MatchExactly): if self.listBox.findItems(newWord, Qt.MatchExactly):
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("The word '{0}' is already in the word list.").format(newWord), "The word '{0}' is already in the word list."
nwAlert.ERROR ).format(newWord), nwAlert.ERROR)
)
return False return False
self.listBox.addItem(newWord) self.listBox.addItem(newWord)
+25 -35
View File
@@ -315,17 +315,14 @@ class GuiDocEditor(QTextEdit):
docSize = len(theDoc) docSize = len(theDoc)
if docSize > nwConst.MAX_DOCSIZE: if docSize > nwConst.MAX_DOCSIZE:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "The document you are trying to open is too big. "
"The document you are trying to open is too big. " "The document size is {0} MB. "
"The document size is {0} MB. " "The maximum size allowed is {1} MB."
"The maximum size allowed is {1} MB." ).format(
).format( f"{docSize/1.0e6:.2f}",
f"{docSize/1.0e6:.2f}", f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}"
f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}" ), nwAlert.ERROR)
),
nwAlert.ERROR
)
self.clearEditor() self.clearEditor()
return False return False
@@ -413,17 +410,14 @@ class GuiDocEditor(QTextEdit):
""" """
docSize = len(theText) docSize = len(theText)
if docSize > nwConst.MAX_DOCSIZE: if docSize > nwConst.MAX_DOCSIZE:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "The text you are trying to add is too big. "
"The text you are trying to add is too big. " "The text size is {0} MB. "
"The text size is {0} MB. " "The maximum size allowed is {1} MB."
"The maximum size allowed is {1} MB." ).format(
).format( f"{docSize/1.0e6:.2f}",
f"{docSize/1.0e6:.2f}", f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}"
f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}" ), nwAlert.ERROR)
),
nwAlert.ERROR
)
return False return False
qApp.setOverrideCursor(QCursor(Qt.WaitCursor)) qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
@@ -1009,15 +1003,12 @@ class GuiDocEditor(QTextEdit):
self._lastFind = None self._lastFind = None
if self._qDocument.characterCount() > nwConst.MAX_DOCSIZE: if self._qDocument.characterCount() > nwConst.MAX_DOCSIZE:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "The document has grown too big and you cannot add more text to it. "
"The document has grown too big and you cannot add more text to it. " "The maximum size of a single novelWriter document is {0} MB."
"The maximum size of a single novelWriter document is {0} MB." ).format(
).format( f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}"
f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}" ), nwAlert.ERROR)
),
nwAlert.ERROR
)
self.undo() self.undo()
return return
@@ -1552,10 +1543,9 @@ class GuiDocEditor(QTextEdit):
self._allowAutoReplace(True) self._allowAutoReplace(True)
else: else:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("Please select some text before calling replace quotes."), "Please select some text before calling replace quotes."
nwAlert.ERROR ), nwAlert.ERROR)
)
return return
+7 -8
View File
@@ -246,14 +246,13 @@ class GuiDocViewer(QTextBrowser):
logger.debug("Loading document from tag '%s'" % theTag) logger.debug("Loading document from tag '%s'" % theTag)
tHandle, _, sTitle = self.theParent.theIndex.getTagSource(theTag) tHandle, _, sTitle = self.theParent.theIndex.getTagSource(theTag)
if tHandle is None: if tHandle is None:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr( "Could not find the reference for tag '{0}'. It either doesn't "
"Could not find the reference for tag '{0}'. It either doesn't " "exist, or the index is out of date. The index can be updated "
"exist, or the index is out of date. The index can be updated " "from the Tools menu, or by pressing {1}."
"from the Tools menu, or by pressing {1}." ).format(
).format(theTag, "F9"), theTag, "F9"
nwAlert.ERROR ), nwAlert.ERROR)
)
return False return False
else: else:
# Let the parent handle the opening as it also ensures that # Let the parent handle the opening as it also ensures that
+16 -4
View File
@@ -468,28 +468,40 @@ class GuiMainMenu(QMenuBar):
# View > TreeView # View > TreeView
self.aFocusTree = QAction(self.tr("Focus Project Tree"), self) self.aFocusTree = QAction(self.tr("Focus Project Tree"), self)
self.aFocusTree.setStatusTip(self.tr("Move focus to project tree")) self.aFocusTree.setStatusTip(self.tr("Move focus to project tree"))
self.aFocusTree.setShortcut("Alt+1") if self.mainConf.osWindows:
self.aFocusTree.setShortcut("Ctrl+Alt+1")
else:
self.aFocusTree.setShortcut("Alt+1")
self.aFocusTree.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.TREE)) self.aFocusTree.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.TREE))
self.viewMenu.addAction(self.aFocusTree) self.viewMenu.addAction(self.aFocusTree)
# View > Document Pane 1 # View > Document Pane 1
self.aFocusEditor = QAction(self.tr("Focus Document Editor"), self) self.aFocusEditor = QAction(self.tr("Focus Document Editor"), self)
self.aFocusEditor.setStatusTip(self.tr("Move focus to left document pane")) self.aFocusEditor.setStatusTip(self.tr("Move focus to left document pane"))
self.aFocusEditor.setShortcut("Alt+2") if self.mainConf.osWindows:
self.aFocusEditor.setShortcut("Ctrl+Alt+2")
else:
self.aFocusEditor.setShortcut("Alt+2")
self.aFocusEditor.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.EDITOR)) self.aFocusEditor.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.EDITOR))
self.viewMenu.addAction(self.aFocusEditor) self.viewMenu.addAction(self.aFocusEditor)
# View > Document Pane 2 # View > Document Pane 2
self.aFocusView = QAction(self.tr("Focus Document Viewer"), self) self.aFocusView = QAction(self.tr("Focus Document Viewer"), self)
self.aFocusView.setStatusTip(self.tr("Move focus to right document pane")) self.aFocusView.setStatusTip(self.tr("Move focus to right document pane"))
self.aFocusView.setShortcut("Alt+3") if self.mainConf.osWindows:
self.aFocusView.setShortcut("Ctrl+Alt+3")
else:
self.aFocusView.setShortcut("Alt+3")
self.aFocusView.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.VIEWER)) self.aFocusView.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.VIEWER))
self.viewMenu.addAction(self.aFocusView) self.viewMenu.addAction(self.aFocusView)
# View > Outline # View > Outline
self.aFocusOutline = QAction(self.tr("Focus Outline"), self) self.aFocusOutline = QAction(self.tr("Focus Outline"), self)
self.aFocusOutline.setStatusTip(self.tr("Move focus to outline")) self.aFocusOutline.setStatusTip(self.tr("Move focus to outline"))
self.aFocusOutline.setShortcut("Alt+4") if self.mainConf.osWindows:
self.aFocusOutline.setShortcut("Ctrl+Alt+4")
else:
self.aFocusOutline.setShortcut("Alt+4")
self.aFocusOutline.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.OUTLINE)) self.aFocusOutline.triggered.connect(lambda: self.theParent.switchFocus(nwWidget.OUTLINE))
self.viewMenu.addAction(self.aFocusOutline) self.viewMenu.addAction(self.aFocusOutline)
-3
View File
@@ -99,9 +99,6 @@ class GuiNovelTree(QTreeWidget):
logger.debug("GuiNovelTree initialisation complete") logger.debug("GuiNovelTree initialisation complete")
# Internal Mapping
self.makeAlert = self.theParent.makeAlert
return return
def initTree(self): def initTree(self):
+33 -31
View File
@@ -197,15 +197,13 @@ class GuiProjectTree(QTreeWidget):
# If class is still not set, alert the user and exit # If class is still not set, alert the user and exit
if itemClass is None: if itemClass is None:
if itemType == nwItemType.FILE: if itemType == nwItemType.FILE:
self.makeAlert( self.makeAlert(self.tr(
self.tr("Please select a valid location in the tree to add the document."), "Please select a valid location in the tree to add the document."
nwAlert.ERROR ), nwAlert.ERROR)
)
else: else:
self.makeAlert( self.makeAlert(self.tr(
self.tr("Please select a valid location in the tree to add the folder."), "Please select a valid location in the tree to add the folder."
nwAlert.ERROR ), nwAlert.ERROR)
)
return False return False
# Everything is fine, we have what we need, so we proceed # Everything is fine, we have what we need, so we proceed
@@ -227,9 +225,9 @@ class GuiProjectTree(QTreeWidget):
# If still nothing, give up # If still nothing, give up
if pHandle is None: if pHandle is None:
self.makeAlert( self.makeAlert(self.tr(
self.tr("Did not find anywhere to add the file or folder!"), nwAlert.ERROR "Did not find anywhere to add the file or folder!"
) ), nwAlert.ERROR)
return False return False
# Now check if the selected item is a file, in which case # Now check if the selected item is a file, in which case
@@ -241,15 +239,15 @@ class GuiProjectTree(QTreeWidget):
# If we again have no home, give up # If we again have no home, give up
if pHandle is None: if pHandle is None:
self.makeAlert( self.makeAlert(self.tr(
self.tr("Did not find anywhere to add the file or folder!"), nwAlert.ERROR "Did not find anywhere to add the file or folder!"
) ), nwAlert.ERROR)
return False return False
if self.theProject.projTree.isTrashRoot(pHandle): if self.theProject.projTree.isTrashRoot(pHandle):
self.makeAlert( self.makeAlert(self.tr(
self.tr("Cannot add new files or folders to the Trash folder."), nwAlert.ERROR "Cannot add new files or folders to the Trash folder."
) ), nwAlert.ERROR)
return False return False
parTree = self.theProject.projTree.getItemPath(pHandle) parTree = self.theProject.projTree.getItemPath(pHandle)
@@ -262,9 +260,9 @@ class GuiProjectTree(QTreeWidget):
if len(parTree) >= nwConst.MAX_DEPTH - 1: if len(parTree) >= nwConst.MAX_DEPTH - 1:
# Folders cannot be deeper than MAX_DEPTH - 1, leaving room # Folders cannot be deeper than MAX_DEPTH - 1, leaving room
# for one more level of files. # for one more level of files.
self.makeAlert(( self.makeAlert(self.tr(
self.tr("Cannot add new folder to this item."), "Cannot add new folder to this item. "
self.tr("Maximum folder depth has been reached.") "Maximum folder depth has been reached."
), nwAlert.ERROR) ), nwAlert.ERROR)
return False return False
tHandle = self.theProject.newFolder(self.tr("New Folder"), itemClass, pHandle) tHandle = self.theProject.newFolder(self.tr("New Folder"), itemClass, pHandle)
@@ -433,9 +431,9 @@ class GuiProjectTree(QTreeWidget):
logger.debug("Emptying Trash folder") logger.debug("Emptying Trash folder")
if trashHandle is None: if trashHandle is None:
self.makeAlert( self.makeAlert(self.tr(
self.tr("There is currently no Trash folder in this project."), nwAlert.INFO "There is currently no Trash folder in this project."
) ), nwAlert.INFO)
return False return False
theTrash = self.getTreeFromHandle(trashHandle) theTrash = self.getTreeFromHandle(trashHandle)
@@ -444,7 +442,9 @@ class GuiProjectTree(QTreeWidget):
nTrash = len(theTrash) nTrash = len(theTrash)
if nTrash == 0: if nTrash == 0:
self.makeAlert(self.tr("The Trash folder is already empty."), nwAlert.INFO) self.makeAlert(self.tr(
"The Trash folder is already empty."
), nwAlert.INFO)
return False return False
msgYes = self.askQuestion( msgYes = self.askQuestion(
@@ -857,7 +857,9 @@ class GuiProjectTree(QTreeWidget):
snItem = self.theProject.projTree[sHandle] snItem = self.theProject.projTree[sHandle]
dnItem = self.theProject.projTree[dHandle] dnItem = self.theProject.projTree[dHandle]
if dnItem is None: if dnItem is None:
self.makeAlert(self.tr("The item cannot be moved to that location."), nwAlert.ERROR) self.makeAlert(self.tr(
"The item cannot be moved to that location."
), nwAlert.ERROR)
return return
pItem = sItem.parent() pItem = sItem.parent()
@@ -888,7 +890,9 @@ class GuiProjectTree(QTreeWidget):
else: else:
theEvent.ignore() theEvent.ignore()
logger.debug("Drag'n'drop of item %s not accepted" % sHandle) logger.debug("Drag'n'drop of item %s not accepted" % sHandle)
self.makeAlert(self.tr("The item cannot be moved to that location."), nwAlert.ERROR) self.makeAlert(self.tr(
"The item cannot be moved to that location."
), nwAlert.ERROR)
return return
@@ -985,11 +989,9 @@ class GuiProjectTree(QTreeWidget):
elif nwItem.itemType == nwItemType.TRASH: elif nwItem.itemType == nwItemType.TRASH:
self.addTopLevelItem(newItem) self.addTopLevelItem(newItem)
else: else:
self.makeAlert( self.makeAlert(self.tr(
self.tr( "There is nowhere to add item with name '{0}'."
"There is nowhere to add item with name '{0}'." ).format(nwItem.itemName), nwAlert.ERROR)
).format(nwItem.itemName), nwAlert.ERROR
)
del self._treeMap[tHandle] del self._treeMap[tHandle]
return None return None
+9 -9
View File
@@ -397,9 +397,9 @@ class GuiTheme:
with open(themeConf, mode="r", encoding="utf8") as inFile: with open(themeConf, mode="r", encoding="utf8") as inFile:
confParser.read_file(inFile) confParser.read_file(inFile)
except Exception as e: except Exception as e:
self.makeAlert( self.makeAlert([
[self.tr("Could not load theme config file."), str(e)], nwAlert.ERROR self.tr("Could not load theme config file."), str(e)
) ], nwAlert.ERROR)
continue continue
themeName = "" themeName = ""
if confParser.has_section("Main"): if confParser.has_section("Main"):
@@ -430,9 +430,9 @@ class GuiTheme:
with open(syntaxPath, mode="r", encoding="utf8") as inFile: with open(syntaxPath, mode="r", encoding="utf8") as inFile:
confParser.read_file(inFile) confParser.read_file(inFile)
except Exception as e: except Exception as e:
self.makeAlert( self.makeAlert([
[self.tr("Could not load syntax file."), str(e)], nwAlert.ERROR self.tr("Could not load syntax file."), str(e)
) ], nwAlert.ERROR)
return [] return []
syntaxName = "" syntaxName = ""
if confParser.has_section("Main"): if confParser.has_section("Main"):
@@ -745,9 +745,9 @@ class GuiIcons:
with open(themeConf, mode="r", encoding="utf8") as inFile: with open(themeConf, mode="r", encoding="utf8") as inFile:
confParser.read_file(inFile) confParser.read_file(inFile)
except Exception as e: except Exception as e:
self.makeAlert( self.makeAlert([
[self.tr("Could not load theme config file."), str(e)], nwAlert.ERROR self.tr("Could not load theme config file."), str(e)
) ], nwAlert.ERROR)
continue continue
themeName = "" themeName = ""
if confParser.has_section("Main"): if confParser.has_section("Main"):
+16 -21
View File
@@ -350,10 +350,9 @@ class GuiMain(QMainWindow):
""" """
if self.hasProject: if self.hasProject:
if not self.closeProject(): if not self.closeProject():
self.makeAlert( self.makeAlert(self.tr(
self.tr("Cannot create new project when another project is open."), "Cannot create new project when another project is open."
nwAlert.ERROR ), nwAlert.ERROR)
)
return False return False
if projData is None: if projData is None:
@@ -368,12 +367,10 @@ class GuiMain(QMainWindow):
return False return False
if os.path.isfile(os.path.join(projPath, self.theProject.projFile)): if os.path.isfile(os.path.join(projPath, self.theProject.projFile)):
self.makeAlert( self.makeAlert(self.tr(
self.tr( "A project already exists in that location. "
"A project already exists in that location. " "Please choose another folder."
"Please choose another folder." ), nwAlert.ERROR)
), nwAlert.ERROR
)
return False return False
logger.info("Creating new project") logger.info("Creating new project")
@@ -538,10 +535,9 @@ class GuiMain(QMainWindow):
# Check if we need to rebuild the index # Check if we need to rebuild the index
if self.theIndex.indexBroken: if self.theIndex.indexBroken:
self.makeAlert( self.makeAlert(self.tr(
self.tr("The project index is outdated or broken. Rebuilding index."), "The project index is outdated or broken. Rebuilding index."
nwAlert.WARN ), nwAlert.WARN)
)
self.rebuildIndex() self.rebuildIndex()
# Make sure the changed status is set to false on all that was # Make sure the changed status is set to false on all that was
@@ -735,10 +731,9 @@ class GuiMain(QMainWindow):
return False return False
if self.docEditor.docHandle() is None: if self.docEditor.docHandle() is None:
self.makeAlert( self.makeAlert(self.tr(
self.tr("Please open a document to import the text file into."), "Please open a document to import the text file into."
nwAlert.ERROR ), nwAlert.ERROR)
)
return False return False
if not self.docEditor.isEmpty(): if not self.docEditor.isEmpty():
@@ -912,9 +907,9 @@ class GuiMain(QMainWindow):
qApp.restoreOverrideCursor() qApp.restoreOverrideCursor()
if not beQuiet: if not beQuiet:
self.makeAlert( self.makeAlert(self.tr(
self.tr("The project index has been successfully rebuilt."), nwAlert.INFO "The project index has been successfully rebuilt."
) ), nwAlert.INFO)
return True return True
+9 -14
View File
@@ -748,10 +748,9 @@ class GuiBuildNovel(QDialog):
logger.debug("Built project in %.3f ms" % (1000*(tEnd - tStart))) logger.debug("Built project in %.3f ms" % (1000*(tEnd - tStart)))
if bldObj.errData: if bldObj.errData:
self.theParent.makeAlert("%s:<br>-&nbsp;%s" % ( self.theParent.makeAlert([
self.tr("There were problems when building the project"), self.tr("There were problems when building the project:")
"<br>-&nbsp;".join(bldObj.errData)), nwAlert.ERROR ] + bldObj.errData, nwAlert.ERROR)
)
return return
@@ -998,17 +997,13 @@ class GuiBuildNovel(QDialog):
# ============== # ==============
if wSuccess: if wSuccess:
self.theParent.makeAlert( self.theParent.makeAlert([
"%s<br>%s" % ( self.tr("{0} file successfully written to:").format(textFmt), savePath
self.tr("{0} file successfully written to:").format(textFmt), savePath ], nwAlert.INFO)
),
nwAlert.INFO
)
else: else:
self.theParent.makeAlert( self.theParent.makeAlert(self.tr(
self.tr("Failed to write {0} file. {1}").format(textFmt, errMsg), "Failed to write {0} file. {1}"
nwAlert.ERROR ).format(textFmt, errMsg), nwAlert.ERROR)
)
return wSuccess return wSuccess
+10 -14
View File
@@ -412,17 +412,13 @@ class GuiWritingStats(QDialog):
# Report to user # Report to user
if wSuccess: if wSuccess:
self.theParent.makeAlert( self.theParent.makeAlert([
"%s file successfully written to:<br>%s" % ( self.tr("{0} file successfully written to:").format(textFmt), savePath
textFmt, savePath ], nwAlert.INFO)
), nwAlert.INFO
)
else: else:
self.theParent.makeAlert( self.theParent.makeAlert([
"Failed to write %s file.<br>%s" % ( self.tr("Failed to write {0} file.").format(textFmt), errMsg
textFmt, errMsg ], nwAlert.ERROR)
), nwAlert.ERROR
)
return wSuccess return wSuccess
@@ -487,9 +483,9 @@ class GuiWritingStats(QDialog):
self.logData.append((dStart, sDiff, wcNovel, wcNotes, sIdle)) self.logData.append((dStart, sDiff, wcNovel, wcNotes, sIdle))
except Exception as e: except Exception as e:
self.theParent.makeAlert( self.theParent.makeAlert([
[self.tr("Failed to read session log file."), str(e)], nwAlert.ERROR self.tr("Failed to read session log file."), str(e)
) ], nwAlert.ERROR)
return False return False
ttWords = ttNovel + ttNotes ttWords = ttNovel + ttNotes
@@ -505,7 +501,7 @@ class GuiWritingStats(QDialog):
# Slots # Slots
## ##
def _updateListBox(self, dummyVar=None): def _updateListBox(self):
"""Load/reload the content of the list box. The dummyVar """Load/reload the content of the list box. The dummyVar
variable captures the variable sent from the widgets connecting variable captures the variable sent from the widgets connecting
to it and discards it. to it and discards it.
+13 -6
View File
@@ -50,12 +50,19 @@ def extractVersion():
numVers = "Unknown" numVers = "Unknown"
hexVers = "Unknown" hexVers = "Unknown"
initFile = os.path.join("nw", "__init__.py") initFile = os.path.join("nw", "__init__.py")
with open(initFile, mode="r") as inFile: try:
for aLine in inFile: with open(initFile, mode="r", encoding="utf-8") as inFile:
if aLine.startswith("__version__"): for aLine in inFile:
numVers = getValue((aLine)) if aLine.startswith("__version__"):
if aLine.startswith("__hexversion__"): numVers = getValue((aLine))
hexVers = getValue((aLine)) if aLine.startswith("__hexversion__"):
hexVers = getValue((aLine))
except Exception as e:
print("Could not read file: %s" % initFile)
print(str(e))
print("novelWriter version is: %s (%s)" % (numVers, hexVers))
print("")
return numVers, hexVers return numVers, hexVers
+1
View File
@@ -43,6 +43,7 @@ class MockGuiMain():
return return
def makeAlert(self, theMessage, theLevel): def makeAlert(self, theMessage, theLevel):
assert isinstance(theMessage, str) or isinstance(theMessage, list)
print("%s: %s" % (str(theLevel), theMessage)) print("%s: %s" % (str(theLevel), theMessage))
self.lastAlert = str(theMessage) self.lastAlert = str(theMessage)
return return