Clean up code and tests
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
"""
|
||||
novelWriter – GUI Document Editor
|
||||
=================================
|
||||
GUI classes for the main document editor
|
||||
|
||||
File History:
|
||||
Created: 2018-09-29 [0.0.1] GuiDocEditor
|
||||
@@ -28,12 +27,14 @@ General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import bisect
|
||||
import logging
|
||||
|
||||
from enum import Enum
|
||||
from time import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5.QtCore import (
|
||||
Qt, QSize, QTimer, pyqtSlot, pyqtSignal, QRegExp, QRegularExpression,
|
||||
@@ -44,9 +45,8 @@ from PyQt5.QtGui import (
|
||||
QPalette, QTextDocument, QCursor, QPixmap
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
qApp, QTextEdit, QAction, QMenu, QShortcut, QMessageBox, QWidget, QLabel,
|
||||
QToolBar, QToolButton, QHBoxLayout, QGridLayout, QLineEdit, QPushButton,
|
||||
QFrame
|
||||
QAction, qApp, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu,
|
||||
QPushButton, QShortcut, QTextEdit, QToolBar, QToolButton, QWidget
|
||||
)
|
||||
|
||||
from novelwriter import CONFIG
|
||||
@@ -57,6 +57,9 @@ from novelwriter.core.index import countWords
|
||||
from novelwriter.core.spellcheck import NWSpellEnchant
|
||||
from novelwriter.gui.dochighlight import GuiDocHighlighter
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from novelwriter.guimain import GuiMain
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -75,7 +78,7 @@ class GuiDocEditor(QTextEdit):
|
||||
novelStructureChanged = pyqtSignal()
|
||||
novelItemMetaChanged = pyqtSignal(str)
|
||||
|
||||
def __init__(self, mainGui):
|
||||
def __init__(self, mainGui: GuiMain):
|
||||
super().__init__(parent=mainGui)
|
||||
|
||||
logger.debug("Create: GuiDocEditor")
|
||||
@@ -357,7 +360,7 @@ class GuiDocEditor(QTextEdit):
|
||||
).format(
|
||||
f"{docSize/1.0e6:.2f}",
|
||||
f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}"
|
||||
), nwAlert.ERROR)
|
||||
), level=nwAlert.ERROR)
|
||||
self.clearEditor()
|
||||
return False
|
||||
|
||||
@@ -457,7 +460,7 @@ class GuiDocEditor(QTextEdit):
|
||||
).format(
|
||||
f"{docSize/1.0e6:.2f}",
|
||||
f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}"
|
||||
), nwAlert.ERROR)
|
||||
), level=nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
|
||||
@@ -496,20 +499,19 @@ class GuiDocEditor(QTextEdit):
|
||||
if not self._nwDocument.writeDocument(docText):
|
||||
saveOk = False
|
||||
if self._nwDocument._currHash != self._nwDocument._prevHash:
|
||||
msgYes = self.mainGui.askQuestion(
|
||||
self.tr("File Changed on Disk"),
|
||||
self.tr(
|
||||
"This document has been changed outside of novelWriter "
|
||||
"while it was open. Overwrite the file on disk?"
|
||||
)
|
||||
)
|
||||
msgYes = self.mainGui.askQuestion(self.tr(
|
||||
"This document has been changed outside of novelWriter "
|
||||
"while it was open. Overwrite the file on disk?"
|
||||
))
|
||||
if msgYes:
|
||||
saveOk = self._nwDocument.writeDocument(docText, forceWrite=True)
|
||||
|
||||
if not saveOk:
|
||||
self.mainGui.makeAlert([
|
||||
self.tr("Could not save document."), self._nwDocument.getError()
|
||||
], nwAlert.ERROR)
|
||||
self.mainGui.makeAlert(
|
||||
self.tr("Could not save document."),
|
||||
info=self._nwDocument.getError(),
|
||||
level=nwAlert.ERROR
|
||||
)
|
||||
|
||||
return False
|
||||
|
||||
@@ -726,7 +728,7 @@ class GuiDocEditor(QTextEdit):
|
||||
self.mainGui.makeAlert(self.tr(
|
||||
"Spell checking requires the package PyEnchant. "
|
||||
"It does not appear to be installed."
|
||||
), nwAlert.INFO)
|
||||
))
|
||||
theMode = False
|
||||
|
||||
if self.spEnchant.spellLanguage is None:
|
||||
@@ -868,17 +870,10 @@ class GuiDocEditor(QTextEdit):
|
||||
if self._nwDocument is None:
|
||||
logger.error("No document open")
|
||||
return False
|
||||
|
||||
msgBox = QMessageBox()
|
||||
msgBox.information(
|
||||
self,
|
||||
self.tr("File Location"),
|
||||
"%s<br>%s" % (
|
||||
self.tr("The currently open file is saved in:"),
|
||||
self._nwDocument.getFileLocation()
|
||||
),
|
||||
self.mainGui.makeAlert(
|
||||
self.tr("The currently open file is saved in:"),
|
||||
info=self._nwDocument.getFileLocation()
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
def insertText(self, theInsert):
|
||||
@@ -1116,7 +1111,7 @@ class GuiDocEditor(QTextEdit):
|
||||
"The maximum size of a single novelWriter document is {0} MB."
|
||||
).format(
|
||||
f"{nwConst.MAX_DOCSIZE/1.0e6:.2f}"
|
||||
), nwAlert.ERROR)
|
||||
), level=nwAlert.ERROR)
|
||||
self.undo()
|
||||
return
|
||||
|
||||
@@ -1675,7 +1670,7 @@ class GuiDocEditor(QTextEdit):
|
||||
if not theCursor.hasSelection():
|
||||
self.mainGui.makeAlert(self.tr(
|
||||
"Please select some text before calling replace quotes."
|
||||
), nwAlert.ERROR)
|
||||
), level=nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
posS = theCursor.selectionStart()
|
||||
|
||||
+23
-31
@@ -589,7 +589,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
if sHandle is None or pItem is None:
|
||||
self.mainGui.makeAlert(self.tr(
|
||||
"Did not find anywhere to add the file or folder!"
|
||||
), nwAlert.ERROR)
|
||||
), level=nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
# Collect some information about the selected item
|
||||
@@ -600,7 +600,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
if self.theProject.tree.isTrash(sHandle):
|
||||
self.mainGui.makeAlert(self.tr(
|
||||
"Cannot add new files or folders to the Trash folder."
|
||||
), nwAlert.ERROR)
|
||||
), level=nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
# Set default label and determine if new item is to be added
|
||||
@@ -838,7 +838,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
if trashHandle is None:
|
||||
self.mainGui.makeAlert(self.tr(
|
||||
"There is currently no Trash folder in this project."
|
||||
), nwAlert.INFO)
|
||||
))
|
||||
return False
|
||||
|
||||
theTrash = self.getTreeFromHandle(trashHandle)
|
||||
@@ -849,11 +849,10 @@ class GuiProjectTree(QTreeWidget):
|
||||
if nTrash == 0:
|
||||
self.mainGui.makeAlert(self.tr(
|
||||
"The Trash folder is already empty."
|
||||
), nwAlert.INFO)
|
||||
))
|
||||
return False
|
||||
|
||||
msgYes = self.mainGui.askQuestion(
|
||||
self.tr("Empty Trash"),
|
||||
self.tr("Permanently delete {0} file(s) from Trash?").format(nTrash)
|
||||
)
|
||||
if not msgYes:
|
||||
@@ -900,7 +899,6 @@ class GuiProjectTree(QTreeWidget):
|
||||
|
||||
if askFirst:
|
||||
msgYes = self.mainGui.askQuestion(
|
||||
self.tr("Delete"),
|
||||
self.tr("Move '{0}' to Trash?").format(nwItemS.itemName),
|
||||
)
|
||||
if not msgYes:
|
||||
@@ -937,7 +935,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
if trItemS.childCount() > 0:
|
||||
self.mainGui.makeAlert(self.tr(
|
||||
"Root folders can only be deleted when they are empty."
|
||||
), nwAlert.ERROR)
|
||||
), level=nwAlert.ERROR)
|
||||
return False
|
||||
|
||||
logger.debug("Permanently deleting root folder '%s'", tHandle)
|
||||
@@ -956,7 +954,6 @@ class GuiProjectTree(QTreeWidget):
|
||||
else:
|
||||
if askFirst:
|
||||
msgYes = self.mainGui.askQuestion(
|
||||
self.tr("Delete"),
|
||||
self.tr("Permanently delete '{0}'?").format(nwItemS.itemName)
|
||||
)
|
||||
if not msgYes:
|
||||
@@ -1525,13 +1522,10 @@ class GuiProjectTree(QTreeWidget):
|
||||
"""Convert a folder to a note or document."""
|
||||
tItem = self.theProject.tree[tHandle]
|
||||
if tItem is not None and tItem.isFolderType():
|
||||
msgYes = self.mainGui.askQuestion(
|
||||
self.tr("Convert Folder"),
|
||||
self.tr(
|
||||
"Do you want to convert the folder to a {0}? "
|
||||
"This action cannot be reversed."
|
||||
).format(trConst(nwLabels.LAYOUT_NAME[itemLayout]))
|
||||
)
|
||||
msgYes = self.mainGui.askQuestion(self.tr(
|
||||
"Do you want to convert the folder to a {0}? "
|
||||
"This action cannot be reversed."
|
||||
).format(trConst(nwLabels.LAYOUT_NAME[itemLayout])))
|
||||
if msgYes and itemLayout == nwItemLayout.DOCUMENT and tItem.documentAllowed():
|
||||
tItem.setType(nwItemType.FILE)
|
||||
tItem.setLayout(nwItemLayout.DOCUMENT)
|
||||
@@ -1570,9 +1564,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
mrgData = dlgMerge.getData()
|
||||
mrgList = mrgData.get("finalItems", [])
|
||||
if not mrgList:
|
||||
self.mainGui.makeAlert([
|
||||
self.tr("No documents selected for merging.")
|
||||
], nwAlert.INFO)
|
||||
self.mainGui.makeAlert(self.tr("No documents selected for merging."))
|
||||
return False
|
||||
|
||||
# Save the open document first, in case it's part of merge
|
||||
@@ -1595,9 +1587,10 @@ class GuiProjectTree(QTreeWidget):
|
||||
docMerger.appendText(sHandle, True, mLabel)
|
||||
|
||||
if not docMerger.writeTargetDoc():
|
||||
self.mainGui.makeAlert([
|
||||
self.tr("Could not write document content."), docMerger.getError()
|
||||
], nwAlert.ERROR)
|
||||
self.mainGui.makeAlert(
|
||||
self.tr("Could not write document content."),
|
||||
info=docMerger.getError(), level=nwAlert.ERROR
|
||||
)
|
||||
return False
|
||||
|
||||
self.theProject.index.reIndexHandle(mHandle)
|
||||
@@ -1658,9 +1651,10 @@ class GuiProjectTree(QTreeWidget):
|
||||
self.revealNewTreeItem(dHandle, nHandle=nHandle, wordCount=True)
|
||||
self._alertTreeChange(dHandle, flush=False)
|
||||
if not writeOk:
|
||||
self.mainGui.makeAlert([
|
||||
self.tr("Could not write document content."), docSplit.getError()
|
||||
], nwAlert.ERROR)
|
||||
self.mainGui.makeAlert(
|
||||
self.tr("Could not write document content."),
|
||||
info=docSplit.getError(), level=nwAlert.ERROR
|
||||
)
|
||||
|
||||
if splitData.get("moveToTrash", False):
|
||||
self.moveItemToTrash(tHandle, askFirst=False, flush=True)
|
||||
@@ -1680,13 +1674,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
if nItems == 0:
|
||||
return False
|
||||
elif nItems == 1:
|
||||
qTitle = self.tr("Duplicate Document")
|
||||
qText = self.tr("Do you want to duplicate this document?")
|
||||
question = self.tr("Do you want to duplicate this document?")
|
||||
else:
|
||||
qTitle = self.tr("Duplicate from Here")
|
||||
qText = self.tr("Do you want to duplicate this item and all child items?")
|
||||
question = self.tr("Do you want to duplicate this item and all child items?")
|
||||
|
||||
if not self.mainGui.askQuestion(qTitle, qText):
|
||||
if not self.mainGui.askQuestion(question):
|
||||
return False
|
||||
|
||||
docDup = DocDuplicator(self.theProject)
|
||||
@@ -1698,7 +1690,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
dupCount += 1
|
||||
|
||||
if dupCount != nItems:
|
||||
self.mainGui.makeAlert(self.tr("Could not duplicate all items."), nwAlert.WARN)
|
||||
self.mainGui.makeAlert(self.tr("Could not duplicate all items."), level=nwAlert.WARN)
|
||||
|
||||
self.saveTreeOrder()
|
||||
|
||||
@@ -1757,7 +1749,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
else:
|
||||
self.mainGui.makeAlert(self.tr(
|
||||
"There is nowhere to add item with name '{0}'."
|
||||
).format(nwItem.itemName), nwAlert.ERROR)
|
||||
).format(nwItem.itemName), level=nwAlert.ERROR)
|
||||
return None
|
||||
|
||||
byIndex = -1
|
||||
|
||||
Reference in New Issue
Block a user