Rewrite how lipsum text is inserted
This commit is contained in:
@@ -86,6 +86,7 @@ class GuiEditLabel(QDialog):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def getLabel(cls, parent: QWidget, text: str) -> tuple[str, bool]:
|
def getLabel(cls, parent: QWidget, text: str) -> tuple[str, bool]:
|
||||||
|
"""Pop the dialog and return the result."""
|
||||||
cls = GuiEditLabel(parent, text=text)
|
cls = GuiEditLabel(parent, text=text)
|
||||||
cls.exec_()
|
cls.exec_()
|
||||||
label = cls.itemLabel
|
label = cls.itemLabel
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ class nwDocInsert(Enum):
|
|||||||
NEW_PAGE = 7
|
NEW_PAGE = 7
|
||||||
VSPACE_S = 8
|
VSPACE_S = 8
|
||||||
VSPACE_M = 9
|
VSPACE_M = 9
|
||||||
|
LIPSUM = 10
|
||||||
|
|
||||||
# END Enum nwDocInsert
|
# END Enum nwDocInsert
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ from novelwriter.common import minmax, transferCase
|
|||||||
from novelwriter.constants import nwKeyWords, nwLabels, nwShortcode, nwUnicode, trConst
|
from novelwriter.constants import nwKeyWords, nwLabels, nwShortcode, nwUnicode, trConst
|
||||||
from novelwriter.core.item import NWItem
|
from novelwriter.core.item import NWItem
|
||||||
from novelwriter.core.index import countWords
|
from novelwriter.core.index import countWords
|
||||||
|
from novelwriter.tools.lipsum import GuiLipsum
|
||||||
from novelwriter.core.document import NWDocument
|
from novelwriter.core.document import NWDocument
|
||||||
from novelwriter.gui.dochighlight import GuiDocHighlighter
|
from novelwriter.gui.dochighlight import GuiDocHighlighter
|
||||||
from novelwriter.gui.editordocument import GuiTextDocument
|
from novelwriter.gui.editordocument import GuiTextDocument
|
||||||
@@ -850,18 +851,23 @@ class GuiDocEditor(QPlainTextEdit):
|
|||||||
text = "[vspace:2]"
|
text = "[vspace:2]"
|
||||||
newBlock = True
|
newBlock = True
|
||||||
goAfter = False
|
goAfter = False
|
||||||
|
elif insert == nwDocInsert.LIPSUM:
|
||||||
|
text = GuiLipsum.getLipsum(self)
|
||||||
|
newBlock = True
|
||||||
|
goAfter = False
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if newBlock:
|
if text:
|
||||||
self.insertNewBlock(text, defaultAfter=goAfter)
|
if newBlock:
|
||||||
else:
|
self.insertNewBlock(text, defaultAfter=goAfter)
|
||||||
cursor = self.textCursor()
|
else:
|
||||||
cursor.beginEditBlock()
|
cursor = self.textCursor()
|
||||||
cursor.insertText(text)
|
cursor.beginEditBlock()
|
||||||
cursor.endEditBlock()
|
cursor.insertText(text)
|
||||||
|
cursor.endEditBlock()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -593,8 +593,10 @@ class GuiMainMenu(QMenuBar):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Insert > Placeholder Text
|
# Insert > Placeholder Text
|
||||||
self.aLipsumText = self.mInsBreaks.addAction(self.tr("Placeholder Text"))
|
self.aLipsumText = self.insMenu.addAction(self.tr("Placeholder Text"))
|
||||||
self.aLipsumText.triggered.connect(self.mainGui.showLoremIpsumDialog)
|
self.aLipsumText.triggered.connect(
|
||||||
|
lambda: self.requestDocInsert.emit(nwDocInsert.LIPSUM)
|
||||||
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ from novelwriter.dialogs.wordlist import GuiWordList
|
|||||||
from novelwriter.dialogs.preferences import GuiPreferences
|
from novelwriter.dialogs.preferences import GuiPreferences
|
||||||
from novelwriter.dialogs.projdetails import GuiProjectDetails
|
from novelwriter.dialogs.projdetails import GuiProjectDetails
|
||||||
from novelwriter.dialogs.projsettings import GuiProjectSettings
|
from novelwriter.dialogs.projsettings import GuiProjectSettings
|
||||||
from novelwriter.tools.lipsum import GuiLipsum
|
|
||||||
from novelwriter.tools.manuscript import GuiManuscript
|
from novelwriter.tools.manuscript import GuiManuscript
|
||||||
from novelwriter.tools.projwizard import GuiProjectWizard
|
from novelwriter.tools.projwizard import GuiProjectWizard
|
||||||
from novelwriter.tools.dictionaries import GuiDictionaries
|
from novelwriter.tools.dictionaries import GuiDictionaries
|
||||||
@@ -908,17 +907,6 @@ class GuiMain(QMainWindow):
|
|||||||
dialog.loadContent()
|
dialog.loadContent()
|
||||||
return
|
return
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def showLoremIpsumDialog(self) -> None:
|
|
||||||
"""Open the insert lorem ipsum text dialog."""
|
|
||||||
if SHARED.hasProject:
|
|
||||||
dialog = GuiLipsum(self)
|
|
||||||
dialog.setModal(False)
|
|
||||||
dialog.show()
|
|
||||||
dialog.raise_()
|
|
||||||
qApp.processEvents()
|
|
||||||
return
|
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def showProjectWordListDialog(self) -> None:
|
def showProjectWordListDialog(self) -> None:
|
||||||
"""Open the project word list dialog."""
|
"""Open the project word list dialog."""
|
||||||
|
|||||||
+29
-23
@@ -26,10 +26,10 @@ from __future__ import annotations
|
|||||||
import random
|
import random
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt, pyqtSlot
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QDialog, QGridLayout, QHBoxLayout, QVBoxLayout, QLabel, QDialogButtonBox,
|
QDialog, QDialogButtonBox, QGridLayout, QHBoxLayout, QLabel, QSpinBox,
|
||||||
QSpinBox
|
QVBoxLayout, QWidget
|
||||||
)
|
)
|
||||||
|
|
||||||
from novelwriter import CONFIG, SHARED
|
from novelwriter import CONFIG, SHARED
|
||||||
@@ -41,15 +41,15 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class GuiLipsum(QDialog):
|
class GuiLipsum(QDialog):
|
||||||
|
|
||||||
def __init__(self, mainGui):
|
def __init__(self, parent: QWidget) -> None:
|
||||||
super().__init__(parent=mainGui)
|
super().__init__(parent=parent)
|
||||||
|
|
||||||
logger.debug("Create: GuiLipsum")
|
logger.debug("Create: GuiLipsum")
|
||||||
self.setObjectName("GuiLipsum")
|
self.setObjectName("GuiLipsum")
|
||||||
if CONFIG.osDarwin:
|
if CONFIG.osDarwin:
|
||||||
self.setWindowFlag(Qt.WindowType.Tool)
|
self.setWindowFlag(Qt.WindowType.Tool)
|
||||||
|
|
||||||
self.mainGui = mainGui
|
self._lipsumText = ""
|
||||||
|
|
||||||
self.setWindowTitle(self.tr("Insert Placeholder Text"))
|
self.setWindowTitle(self.tr("Insert Placeholder Text"))
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ class GuiLipsum(QDialog):
|
|||||||
|
|
||||||
# Buttons
|
# Buttons
|
||||||
self.buttonBox = QDialogButtonBox()
|
self.buttonBox = QDialogButtonBox()
|
||||||
self.buttonBox.rejected.connect(self._doClose)
|
self.buttonBox.rejected.connect(self.close)
|
||||||
|
|
||||||
self.btnClose = self.buttonBox.addButton(QDialogButtonBox.Close)
|
self.btnClose = self.buttonBox.addButton(QDialogButtonBox.Close)
|
||||||
self.btnClose.setAutoDefault(False)
|
self.btnClose.setAutoDefault(False)
|
||||||
@@ -101,6 +101,8 @@ class GuiLipsum(QDialog):
|
|||||||
self.btnSave.clicked.connect(self._doInsert)
|
self.btnSave.clicked.connect(self._doInsert)
|
||||||
self.btnSave.setAutoDefault(False)
|
self.btnSave.setAutoDefault(False)
|
||||||
|
|
||||||
|
self.rejected.connect(self.close)
|
||||||
|
|
||||||
# Assemble
|
# Assemble
|
||||||
self.outerBox = QVBoxLayout()
|
self.outerBox = QVBoxLayout()
|
||||||
self.outerBox.addLayout(self.innerBox)
|
self.outerBox.addLayout(self.innerBox)
|
||||||
@@ -112,33 +114,37 @@ class GuiLipsum(QDialog):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def __del__(self): # pragma: no cover
|
def __del__(self) -> None: # pragma: no cover
|
||||||
logger.debug("Delete: GuiLipsum")
|
logger.debug("Delete: GuiLipsum")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lipsumText(self) -> str:
|
||||||
|
"""Return the generated text."""
|
||||||
|
return self._lipsumText
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getLipsum(cls, parent: QWidget) -> str:
|
||||||
|
"""Pop the dialog and return the lipsum text."""
|
||||||
|
cls = GuiLipsum(parent)
|
||||||
|
cls.exec_()
|
||||||
|
text = cls.lipsumText
|
||||||
|
cls.deleteLater()
|
||||||
|
return text
|
||||||
|
|
||||||
##
|
##
|
||||||
# Slots
|
# Private Slots
|
||||||
##
|
##
|
||||||
|
|
||||||
def _doInsert(self):
|
@pyqtSlot()
|
||||||
"""Load the text and insert it in the open document.
|
def _doInsert(self) -> None:
|
||||||
"""
|
"""Generate the text."""
|
||||||
lipsumFile = CONFIG.assetPath("text") / "lipsum.txt"
|
lipsumFile = CONFIG.assetPath("text") / "lipsum.txt"
|
||||||
lipsumText = readTextFile(lipsumFile).splitlines()
|
lipsumText = readTextFile(lipsumFile).splitlines()
|
||||||
|
|
||||||
if self.randSwitch.isChecked():
|
if self.randSwitch.isChecked():
|
||||||
random.shuffle(lipsumText)
|
random.shuffle(lipsumText)
|
||||||
|
|
||||||
pCount = self.paraCount.value()
|
pCount = self.paraCount.value()
|
||||||
inText = "\n\n".join(lipsumText[0:pCount]) + "\n\n"
|
self._lipsumText = "\n\n".join(lipsumText[0:pCount]) + "\n\n"
|
||||||
|
|
||||||
self.mainGui.docEditor.insertText(inText)
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _doClose(self):
|
|
||||||
"""Close the dialog window without doing anything.
|
|
||||||
"""
|
|
||||||
self.close()
|
self.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -30,43 +30,39 @@ from novelwriter.tools.lipsum import GuiLipsum
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.gui
|
@pytest.mark.gui
|
||||||
def testToolLipsum_Main(qtbot, nwGUI, projPath, mockRnd):
|
def testToolLipsum_Main(qtbot, monkeypatch, nwGUI, projPath, mockRnd):
|
||||||
"""Test the Lorem Ipsum tool.
|
"""Test the Lorem Ipsum tool."""
|
||||||
"""
|
|
||||||
# Check that we cannot open when there is no project
|
# Check that we cannot open when there is no project
|
||||||
nwGUI.mainMenu.aLipsumText.activate(QAction.Trigger)
|
nwGUI.mainMenu.aLipsumText.activate(QAction.Trigger)
|
||||||
assert getGuiItem("GuiLipsum") is None
|
assert getGuiItem("GuiLipsum") is None
|
||||||
|
|
||||||
# Create a new project
|
|
||||||
buildTestProject(nwGUI, projPath)
|
buildTestProject(nwGUI, projPath)
|
||||||
assert nwGUI.openDocument(C.hSceneDoc) is True
|
nwLipsum = GuiLipsum(nwGUI)
|
||||||
assert len(nwGUI.docEditor.getText()) == 15
|
|
||||||
|
|
||||||
# Open the tool
|
# Generate paragraphs
|
||||||
nwGUI.mainMenu.aLipsumText.activate(QAction.Trigger)
|
|
||||||
qtbot.waitUntil(lambda: getGuiItem("GuiLipsum") is not None, timeout=1000)
|
|
||||||
|
|
||||||
nwLipsum = getGuiItem("GuiLipsum")
|
|
||||||
assert isinstance(nwLipsum, GuiLipsum)
|
|
||||||
|
|
||||||
# Insert paragraphs
|
|
||||||
nwGUI.docEditor.setCursorPosition(100) # End of document
|
nwGUI.docEditor.setCursorPosition(100) # End of document
|
||||||
nwLipsum.paraCount.setValue(2)
|
nwLipsum.paraCount.setValue(2)
|
||||||
nwLipsum._doInsert()
|
nwLipsum._doInsert()
|
||||||
theText = nwGUI.docEditor.getText()
|
assert "Lorem ipsum" in nwLipsum.lipsumText
|
||||||
assert "Lorem ipsum" in theText
|
|
||||||
assert len(theText) == 965
|
|
||||||
|
|
||||||
# Insert random paragraph
|
# Generate random paragraph
|
||||||
nwGUI.docEditor.setCursorPosition(1000) # End of document
|
nwGUI.docEditor.setCursorPosition(1000) # End of document
|
||||||
nwLipsum.randSwitch.setChecked(True)
|
nwLipsum.randSwitch.setChecked(True)
|
||||||
nwLipsum.paraCount.setValue(1)
|
nwLipsum.paraCount.setValue(1)
|
||||||
nwLipsum._doInsert()
|
nwLipsum._doInsert()
|
||||||
theText = nwGUI.docEditor.getText()
|
assert len(nwLipsum.lipsumText) > 0
|
||||||
assert len(theText) > 965
|
|
||||||
|
|
||||||
# Close
|
nwLipsum.setObjectName("")
|
||||||
nwLipsum._doClose()
|
nwLipsum.close()
|
||||||
|
|
||||||
|
# Trigger insertion in document
|
||||||
|
assert nwGUI.openDocument(C.hSceneDoc) is True
|
||||||
|
nwGUI.docEditor.setCursorLine(3)
|
||||||
|
with monkeypatch.context() as mp:
|
||||||
|
mp.setattr(GuiLipsum, "exec_", lambda *a: None)
|
||||||
|
mp.setattr(GuiLipsum, "lipsumText", "FooBar")
|
||||||
|
nwGUI.mainMenu.aLipsumText.activate(QAction.Trigger)
|
||||||
|
assert nwGUI.docEditor.getText() == "### New Scene\n\nFooBar"
|
||||||
|
|
||||||
# qtbot.stop()
|
# qtbot.stop()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user