Merge pull request #256 from vkbo/gui_tweaks

Minor GUI Tweaks
This commit is contained in:
Veronica K. Berglyd Olsen
2020-05-28 23:11:27 +02:00
committed by GitHub
18 changed files with 142 additions and 89 deletions
+1
View File
@@ -6,6 +6,7 @@
* The back-references list now shows references to any tag in the open document, not just the first tag. Issue #227, PR #234. * The back-references list now shows references to any tag in the open document, not just the first tag. Issue #227, PR #234.
* Clicking a tag now tries to scroll to the header where the tag is set. The index needed a couple of minor changes for this feature, so this will invalidate the old index for a project, and require a new to be built. This is done automatically. PR #234. * Clicking a tag now tries to scroll to the header where the tag is set. The index needed a couple of minor changes for this feature, so this will invalidate the old index for a project, and require a new to be built. This is done automatically. PR #234.
* Moved the Close button on the "Build Novel project" dialog to the area with the other buttons since we anyway increased the size of that area. PR #256.
**Project Structure** **Project Structure**
+3 -1
View File
@@ -533,7 +533,9 @@ class Config:
# Write config file # Write config file
try: try:
cnfParse.write(open(path.join(self.confPath,self.confFile),mode="w",encoding="utf8")) cnfParse.write(
open(path.join(self.confPath, self.confFile), mode="w", encoding="utf8")
)
self.confChanged = False self.confChanged = False
except Exception as e: except Exception as e:
logger.error("Could not save config file") logger.error("Could not save config file")
+8 -8
View File
@@ -113,7 +113,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("Duplicate root item detected.", nwAlert.ERROR)
return None return None
newItem = NWItem(self) newItem = NWItem(self)
newItem.setName(rootName) newItem.setName(rootName)
@@ -995,7 +995,7 @@ class NWProject():
# Report status # Report status
if len(orphanFiles) > 0: if len(orphanFiles) > 0:
self.makeAlert( self.makeAlert(
"Found %d orphaned file(s) in project folder!" % len(orphanFiles), "Found %d orphaned file(s) in project folder." % len(orphanFiles),
nwAlert.WARN nwAlert.WARN
) )
else: else:
@@ -1097,10 +1097,10 @@ class NWProject():
# END Class NWProject # END Class NWProject
# ================================================================================================ # # =============================================================================================== #
# NWTree # NWTree
# Class holding the project tree for the NWProject # Class holding the project tree for the NWProject
# ================================================================================================ # # =============================================================================================== #
class NWTree(): class NWTree():
@@ -1435,10 +1435,10 @@ class NWTree():
# END Class NWTree # END Class NWTree
# ================================================================================================ # # =============================================================================================== #
# NWItem # NWItem
# Class holding the project items making up the NWProject # Class holding the project items making up the NWProject
# ================================================================================================ # # =============================================================================================== #
class NWItem(): class NWItem():
@@ -1680,10 +1680,10 @@ class NWItem():
# END Class NWItem # END Class NWItem
# ================================================================================================ # # =============================================================================================== #
# NWStatus # NWStatus
# Class holding the item status values stored in the NWProject # Class holding the item status values stored in the NWProject
# ================================================================================================ # # =============================================================================================== #
class NWStatus(): class NWStatus():
+6 -6
View File
@@ -35,9 +35,9 @@ from nw.constants import isoLanguage
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# ================================================================================================ # # =============================================================================================== #
# SpellChecking SuperClass # SpellChecking SuperClass
# ================================================================================================ # # =============================================================================================== #
class NWSpellCheck(): class NWSpellCheck():
@@ -129,9 +129,9 @@ class NWSpellCheck():
# END Class NWSpellCheck # END Class NWSpellCheck
# ================================================================================================ # # =============================================================================================== #
# Enchant Based SpellChecking # Enchant Based SpellChecking
# ================================================================================================ # # =============================================================================================== #
class NWSpellEnchant(NWSpellCheck): class NWSpellEnchant(NWSpellCheck):
@@ -211,9 +211,9 @@ class NWSpellEnchantDummy:
# END Class NWSpellEnchantDummy # END Class NWSpellEnchantDummy
# ================================================================================================ # # =============================================================================================== #
# Fallback SpellChecking Using difflib # Fallback SpellChecking Using difflib
# ================================================================================================ # # =============================================================================================== #
class NWSpellSimple(NWSpellCheck): class NWSpellSimple(NWSpellCheck):
"""Internal spell check tool that uses standard Python packages with """Internal spell check tool that uses standard Python packages with
+2 -2
View File
@@ -9,7 +9,7 @@ from nw.gui.theme import GuiTheme
# Dialogs # Dialogs
from nw.gui.dialogs.about import GuiAbout from nw.gui.dialogs.about import GuiAbout
from nw.gui.dialogs.configeditor import GuiConfigEditor from nw.gui.dialogs.preferences import GuiPreferences
from nw.gui.dialogs.docmerge import GuiDocMerge from nw.gui.dialogs.docmerge import GuiDocMerge
from nw.gui.dialogs.docsplit import GuiDocSplit from nw.gui.dialogs.docsplit import GuiDocSplit
from nw.gui.dialogs.itemeditor import GuiItemEditor from nw.gui.dialogs.itemeditor import GuiItemEditor
@@ -40,7 +40,7 @@ __all__ = [
"GuiMainStatus", "GuiMainStatus",
"GuiTheme", "GuiTheme",
"GuiAbout", "GuiAbout",
"GuiConfigEditor", "GuiPreferences",
"GuiDocMerge", "GuiDocMerge",
"GuiDocSplit", "GuiDocSplit",
"GuiItemEditor", "GuiItemEditor",
+33 -24
View File
@@ -34,12 +34,12 @@ from time import time
from PyQt5.QtCore import Qt, QByteArray from PyQt5.QtCore import Qt, QByteArray
from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog from PyQt5.QtPrintSupport import QPrinter, QPrintPreviewDialog
from PyQt5.QtGui import ( from PyQt5.QtGui import (
QTextOption, QPalette, QColor, QTextDocumentWriter, QFont QPalette, QColor, QTextDocumentWriter, QFont
) )
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QLabel, QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QLabel,
QLineEdit, QGroupBox, QGridLayout, QProgressBar, QMenu, QAction, QLineEdit, QGroupBox, QGridLayout, QProgressBar, QMenu, QAction,
QFileDialog, QFontComboBox, QSpinBox, QDialogButtonBox QFileDialog, QFontComboBox, QSpinBox
) )
from nw.gui.additions import QSwitch from nw.gui.additions import QSwitch
@@ -83,8 +83,7 @@ class GuiBuildNovel(QDialog):
self.optState.getInt("GuiBuildNovel", "winHeight", 800) self.optState.getInt("GuiBuildNovel", "winHeight", 800)
) )
self.outerBox = QVBoxLayout() self.outerBox = QHBoxLayout()
self.innerBox = QHBoxLayout()
self.toolsBox = QVBoxLayout() self.toolsBox = QVBoxLayout()
self.docView = GuiBuildNovelDocView(self, self.theProject) self.docView = GuiBuildNovelDocView(self, self.theProject)
@@ -173,7 +172,9 @@ class GuiBuildNovel(QDialog):
self.textFont = QFontComboBox() self.textFont = QFontComboBox()
self.textFont.setFixedWidth(220) self.textFont.setFixedWidth(220)
self.textFont.setToolTip("The font is used for PDF and printing. Other formats have no font set.") self.textFont.setToolTip(
"The font is used for PDF and printing. Other formats have no font set."
)
self.textFont.setCurrentFont( self.textFont.setCurrentFont(
QFont(self.optState.getString("GuiBuildNovel", "textFont", self.mainConf.textFont)) QFont(self.optState.getString("GuiBuildNovel", "textFont", self.mainConf.textFont))
) )
@@ -183,13 +184,17 @@ class GuiBuildNovel(QDialog):
self.textSize.setMinimum(5) self.textSize.setMinimum(5)
self.textSize.setMaximum(48) self.textSize.setMaximum(48)
self.textSize.setSingleStep(1) self.textSize.setSingleStep(1)
self.textSize.setToolTip("The size is used for PDF and printing. Other formats have no size set.") self.textSize.setToolTip(
"The size is used for PDF and printing. Other formats have no size set."
)
self.textSize.setValue( self.textSize.setValue(
self.optState.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize) self.optState.getInt("GuiBuildNovel", "textSize", self.mainConf.textSize)
) )
self.justifyText = QSwitch() self.justifyText = QSwitch()
self.justifyText.setToolTip("Applies to PDF, printing, HTML, and Open Document exports.") self.justifyText.setToolTip(
"Applies to PDF, printing, HTML, and Open Document exports."
)
self.justifyText.setChecked( self.justifyText.setChecked(
self.optState.getBool("GuiBuildNovel", "justifyText", False) self.optState.getBool("GuiBuildNovel", "justifyText", False)
) )
@@ -211,15 +216,21 @@ class GuiBuildNovel(QDialog):
self.includeGroup.setLayout(self.includeForm) self.includeGroup.setLayout(self.includeForm)
self.includeSynopsis = QSwitch() self.includeSynopsis = QSwitch()
self.includeSynopsis.setToolTip("Include synopsis type comments in the output.") self.includeSynopsis.setToolTip(
"Include synopsis type comments in the output."
)
self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"]) self.includeSynopsis.setChecked(self.theProject.titleFormat["withSynopsis"])
self.includeComments = QSwitch() self.includeComments = QSwitch()
self.includeComments.setToolTip("Include plain comments in the output.") self.includeComments.setToolTip(
"Include plain comments in the output."
)
self.includeComments.setChecked(self.theProject.titleFormat["withComments"]) self.includeComments.setChecked(self.theProject.titleFormat["withComments"])
self.includeKeywords = QSwitch() self.includeKeywords = QSwitch()
self.includeKeywords.setToolTip("Include meta keywords (tags, references) in the output.") self.includeKeywords.setToolTip(
"Include meta keywords (tags, references) in the output."
)
self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"]) self.includeKeywords.setChecked(self.theProject.titleFormat["withKeywords"])
self.includeForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft) self.includeForm.addWidget(QLabel("Include synopsis"), 0, 0, 1, 1, Qt.AlignLeft)
@@ -292,7 +303,7 @@ class GuiBuildNovel(QDialog):
# Action Buttons # Action Buttons
# ============== # ==============
self.buttonForm = QGridLayout() self.buttonBox = QHBoxLayout()
self.btnPrint = QPushButton("Print") self.btnPrint = QPushButton("Print")
self.btnPrint.clicked.connect(self._printDocument) self.btnPrint.clicked.connect(self._printDocument)
@@ -326,12 +337,13 @@ class GuiBuildNovel(QDialog):
self.saveTXT.triggered.connect(lambda: self._saveDocument(self.FMT_TXT)) self.saveTXT.triggered.connect(lambda: self._saveDocument(self.FMT_TXT))
self.saveMenu.addAction(self.saveTXT) self.saveMenu.addAction(self.saveTXT)
self.buttonForm.addWidget(self.btnSave, 0, 0) self.btnClose = QPushButton("Close")
self.buttonForm.addWidget(self.btnPrint, 0, 1) self.btnClose.clicked.connect(self._doClose)
# Buttons self.buttonBox.addWidget(self.btnSave)
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close) self.buttonBox.addWidget(self.btnPrint)
self.buttonBox.rejected.connect(self._doClose) self.buttonBox.addWidget(self.btnClose)
self.buttonBox.setSpacing(4)
# Assemble GUI # Assemble GUI
# ============ # ============
@@ -343,18 +355,15 @@ class GuiBuildNovel(QDialog):
self.toolsBox.addWidget(self.buildProgress) self.toolsBox.addWidget(self.buildProgress)
self.toolsBox.addWidget(self.buildNovel) self.toolsBox.addWidget(self.buildNovel)
self.toolsBox.addSpacing(8) self.toolsBox.addSpacing(8)
self.toolsBox.addLayout(self.buttonForm) self.toolsBox.addLayout(self.buttonBox)
self.innerBox.addLayout(self.toolsBox) self.outerBox.addLayout(self.toolsBox)
self.innerBox.addWidget(self.docView) self.outerBox.addWidget(self.docView)
self.outerBox.setStretch(0, 0)
self.outerBox.setStretch(1, 1)
self.outerBox.addLayout(self.innerBox)
self.outerBox.addWidget(self.buttonBox)
self.setLayout(self.outerBox) self.setLayout(self.outerBox)
self.innerBox.setStretch(0, 0)
self.innerBox.setStretch(1, 1)
self.show() self.show()
logger.debug("GuiBuildNovel initialisation complete") logger.debug("GuiBuildNovel initialisation complete")
+2 -2
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from nw.gui.dialogs.about import GuiAbout from nw.gui.dialogs.about import GuiAbout
from nw.gui.dialogs.configeditor import GuiConfigEditor from nw.gui.dialogs.preferences import GuiPreferences
from nw.gui.dialogs.docmerge import GuiDocMerge from nw.gui.dialogs.docmerge import GuiDocMerge
from nw.gui.dialogs.docsplit import GuiDocSplit from nw.gui.dialogs.docsplit import GuiDocSplit
from nw.gui.dialogs.itemeditor import GuiItemEditor from nw.gui.dialogs.itemeditor import GuiItemEditor
@@ -11,7 +11,7 @@ from nw.gui.dialogs.sessionlog import GuiSessionLogView
__all__ = [ __all__ = [
"GuiAbout", "GuiAbout",
"GuiConfigEditor", "GuiPreferences",
"GuiDocMerge", "GuiDocMerge",
"GuiDocSplit", "GuiDocSplit",
"GuiItemEditor", "GuiItemEditor",
+13 -10
View File
@@ -119,16 +119,19 @@ class GuiAbout(QDialog):
"<h2>About {name:s}</h2>" "<h2>About {name:s}</h2>"
"<p>{copyright:s}.</p>" "<p>{copyright:s}.</p>"
"<p>Website: <a href='{website:s}'>{domain:s}</a></p>" "<p>Website: <a href='{website:s}'>{domain:s}</a></p>"
"<p>{name:s} is a markdown-like text editor designed for organising and writing " "<p>{name:s} is a markdown-like text editor designed for "
"novels. It is written in Python 3 with a Qt5 GUI, using PyQt5.</p>" "organising and writing novels. It is written in Python 3 with a "
"<p>{name:s} is free software: you can redistribute it and/or modify it under the " "Qt5 GUI, using PyQt5.</p>"
"terms of the GNU General Public License as published by the Free Software Foundation, " "<p>{name:s} is free software: you can redistribute it and/or "
"either version 3 of the License, or (at your option) any later version.</p>" "modify it under the terms of the GNU General Public License as "
"<p>{name:s} is distributed in the hope that it will be useful, but WITHOUT ANY " "published by the Free Software Foundation, either version 3 of "
"WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A " "the License, or (at your option) any later version.</p>"
"PARTICULAR PURPOSE.</p>" "<p>{name:s} is distributed in the hope that it will be useful, "
"<p>See the License tab for the full text, or visit the GNU website at " "but WITHOUT ANY WARRANTY; without even the implied warranty of "
"<a href='https://www.gnu.org/licenses/gpl-3.0.html'>GPL v3.0</a> for more details.</p>" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p>"
"<p>See the License tab for the full text, or visit the GNU website "
"at <a href='https://www.gnu.org/licenses/gpl-3.0.html'>GPL v3.0</a> "
"for more details.</p>"
"<h3>Credits</h3>" "<h3>Credits</h3>"
"<p>{credits:s}</p>" "<p>{credits:s}</p>"
).format( ).format(
+9 -3
View File
@@ -150,7 +150,9 @@ class GuiDocSplit(QDialog):
), nwAlert.ERROR) ), nwAlert.ERROR)
return return
fHandle = self.theProject.newFolder(srcItem.itemName, srcItem.itemClass, srcItem.parHandle) fHandle = self.theProject.newFolder(
srcItem.itemName, srcItem.itemClass, srcItem.parHandle
)
self.theParent.treeView.revealTreeItem(fHandle) self.theParent.treeView.revealTreeItem(fHandle)
logger.verbose("Creating folder %s" % fHandle) logger.verbose("Creating folder %s" % fHandle)
@@ -174,7 +176,9 @@ class GuiDocSplit(QDialog):
newItem = self.theProject.projTree[nHandle] newItem = self.theProject.projTree[nHandle]
newItem.setLayout(itemLayout) newItem.setLayout(itemLayout)
logger.verbose( logger.verbose(
"Creating new document %s with text from line %d to %d" % (nHandle, iStart, iEnd-1) "Creating new document %s with text from line %d to %d" % (
nHandle, iStart, iEnd-1
)
) )
theText = "\n".join(theLines[iStart:iEnd]) theText = "\n".join(theLines[iStart:iEnd])
@@ -227,7 +231,9 @@ class GuiDocSplit(QDialog):
spLevel = self.splitLevel.currentData() spLevel = self.splitLevel.currentData()
self.optState.setValue("GuiDocSplit", "spLevel", spLevel) self.optState.setValue("GuiDocSplit", "spLevel", spLevel)
logger.debug("Scanning document %s for headings level <= %d" % (self.sourceItem, spLevel)) logger.debug(
"Scanning document %s for headings level <= %d" % (self.sourceItem, spLevel)
)
lineNo = 0 lineNo = 0
for aLine in theText.splitlines(): for aLine in theText.splitlines():
@@ -44,12 +44,12 @@ from nw.constants import nwAlert, nwQuotes
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiConfigEditor(PagedDialog): class GuiPreferences(PagedDialog):
def __init__(self, theParent, theProject): def __init__(self, theParent, theProject):
PagedDialog.__init__(self, theParent) PagedDialog.__init__(self, theParent)
logger.debug("Initialising ConfigEditor ...") logger.debug("Initialising GuiPreferences ...")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
@@ -74,7 +74,7 @@ class GuiConfigEditor(PagedDialog):
self.show() self.show()
logger.debug("ConfigEditor initialisation complete") logger.debug("GuiPreferences initialisation complete")
return return
@@ -122,7 +122,7 @@ class GuiConfigEditor(PagedDialog):
self.close() self.close()
return return
# END Class GuiConfigEditor # END Class GuiPreferences
class GuiConfigEditGeneralTab(QWidget): class GuiConfigEditGeneralTab(QWidget):
@@ -228,7 +228,7 @@ class GuiConfigEditGeneralTab(QWidget):
## Backup Path ## Backup Path
self.backupPath = self.mainConf.backupPath self.backupPath = self.mainConf.backupPath
self.backupGetPath = QPushButton(self.theTheme.getIcon("folder-open"),"Select Folder") self.backupGetPath = QPushButton("Browse")
self.backupGetPath.clicked.connect(self._backupFolder) self.backupGetPath.clicked.connect(self._backupFolder)
self.backupPathRow = self.mainForm.addRow( self.backupPathRow = self.mainForm.addRow(
"Backup storage location", "Backup storage location",
+3 -1
View File
@@ -362,7 +362,9 @@ class GuiProjectEditStatus(QWidget):
self.listBox.takeItem(iRow) self.listBox.takeItem(iRow)
self.colChanged = True self.colChanged = True
else: else:
self.theParent.makeAlert("Cannot delete status item that is in use.",nwAlert.ERROR) self.theParent.makeAlert(
"Cannot delete status item that is in use.", nwAlert.ERROR
)
return return
def _saveItem(self): def _saveItem(self):
+14 -6
View File
@@ -180,11 +180,15 @@ class GuiSessionLogView(QDialog):
inData = inLine.split() inData = inLine.split()
if len(inData) != 8: if len(inData) != 8:
continue continue
dStart = datetime.strptime("%s %s" % (inData[1],inData[2]), nwConst.tStampFmt) dStart = datetime.strptime(
dEnd = datetime.strptime("%s %s" % (inData[4],inData[5]), nwConst.tStampFmt) "%s %s" % (inData[1],inData[2]), nwConst.tStampFmt
)
dEnd = datetime.strptime(
"%s %s" % (inData[4],inData[5]), nwConst.tStampFmt
)
nWords = int(inData[7]) nWords = int(inData[7])
tDiff = dEnd - dStart tDiff = dEnd - dStart
sDiff = tDiff.total_seconds() sDiff = tDiff.total_seconds()
self.timeTotal += sDiff self.timeTotal += sDiff
if abs(nWords) > 0: if abs(nWords) > 0:
@@ -196,7 +200,9 @@ class GuiSessionLogView(QDialog):
if hideNegative and nWords < 0: if hideNegative and nWords < 0:
continue continue
newItem = QTreeWidgetItem([str(dStart),self._formatTime(sDiff),str(nWords),""]) newItem = QTreeWidgetItem(
[str(dStart), self._formatTime(sDiff), str(nWords), ""]
)
newItem.setTextAlignment(1,Qt.AlignRight) newItem.setTextAlignment(1,Qt.AlignRight)
newItem.setTextAlignment(2,Qt.AlignRight) newItem.setTextAlignment(2,Qt.AlignRight)
@@ -208,7 +214,9 @@ class GuiSessionLogView(QDialog):
self.listBox.addTopLevelItem(newItem) self.listBox.addTopLevelItem(newItem)
except Exception as e: except Exception as e:
self.theParent.makeAlert(["Failed to read session log file.",str(e)], nwAlert.ERROR) self.theParent.makeAlert(
["Failed to read session log file.",str(e)], nwAlert.ERROR
)
return False return False
self.labelFilter.setText(self._formatTime(self.timeFilter)) self.labelFilter.setText(self._formatTime(self.timeFilter))
+9 -3
View File
@@ -479,7 +479,9 @@ class GuiDocEditor(QTextEdit):
self.hLight.rehighlight() self.hLight.rehighlight()
qApp.restoreOverrideCursor() qApp.restoreOverrideCursor()
afTime = time() afTime = time()
logger.debug("Document re-highlighted in %.3f milliseconds" % (1000*(afTime-bfTime))) logger.debug(
"Document re-highlighted in %.3f milliseconds" % (1000*(afTime-bfTime))
)
return True return True
@@ -716,7 +718,9 @@ class GuiDocEditor(QTextEdit):
""" """
sinceActive = time()-self.lastEdit sinceActive = time()-self.lastEdit
if sinceActive > 5*self.wcInterval: if sinceActive > 5*self.wcInterval:
logger.debug("Stopping word count timer: no activity last %.1f seconds" % sinceActive) logger.debug(
"Stopping word count timer: no activity last %.1f seconds" % sinceActive
)
self.wcTimer.stop() self.wcTimer.stop()
elif self.wCounter.isRunning(): elif self.wCounter.isRunning():
logger.verbose("Word counter thread is busy") logger.verbose("Word counter thread is busy")
@@ -952,7 +956,9 @@ class GuiDocEditor(QTextEdit):
theText = newText theText = newText
cOffset -= 0 cOffset -= 0
else: else:
logger.error("Unknown or unsupported block format requested: %s" % str(docAction)) logger.error(
"Unknown or unsupported block format requested: %s" % str(docAction)
)
return return
# Replace the block text # Replace the block text
+2 -2
View File
@@ -396,7 +396,7 @@ class GuiDocTree(QTreeWidget):
trItemP.takeChild(tIndex) trItemP.takeChild(tIndex)
del self.theProject.projTree[tHandle] del self.theProject.projTree[tHandle]
else: else:
self.makeAlert(["Cannot delete folder.","It is not empty."], nwAlert.ERROR) self.makeAlert("Cannot delete folder. It is not empty.", nwAlert.ERROR)
return False return False
elif nwItemS.itemType == nwItemType.ROOT: elif nwItemS.itemType == nwItemType.ROOT:
@@ -407,7 +407,7 @@ class GuiDocTree(QTreeWidget):
self.theParent.mainMenu.setAvailableRoot() self.theParent.mainMenu.setAvailableRoot()
self.theProject.setProjectChanged(True) self.theProject.setProjectChanged(True)
else: else:
self.makeAlert(["Cannot delete root folder.","It is not empty."], nwAlert.ERROR) self.makeAlert("Cannot delete root folder. It is not empty.", nwAlert.ERROR)
return False return False
return True return True
+6 -2
View File
@@ -249,7 +249,9 @@ class GuiIcons:
try: try:
confParser.read_file(open(themeConf, mode="r", encoding="utf8")) confParser.read_file(open(themeConf, mode="r", encoding="utf8"))
except Exception as e: except Exception as e:
self.theParent.makeAlert(["Could not load theme config file.",str(e)],nwAlert.ERROR) self.theParent.makeAlert(
["Could not load theme config file.",str(e)], nwAlert.ERROR
)
continue continue
themeName = "" themeName = ""
if confParser.has_section("Main"): if confParser.has_section("Main"):
@@ -295,7 +297,9 @@ class GuiIcons:
# Finally. we check if we have a fallback icon # Finally. we check if we have a fallback icon
if self.mainConf.guiDark: if self.mainConf.guiDark:
fbackIcon = path.join(self.mainConf.iconPath, self.fbackName, "%s-dark.svg" % iconKey) fbackIcon = path.join(
self.mainConf.iconPath, self.fbackName, "%s-dark.svg" % iconKey
)
if path.isfile(fbackIcon): if path.isfile(fbackIcon):
logger.verbose("Loading icon '%s' from fallback theme" % iconKey) logger.verbose("Loading icon '%s' from fallback theme" % iconKey)
return QIcon(fbackIcon) return QIcon(fbackIcon)
+5 -1
View File
@@ -137,13 +137,17 @@ class GuiMainStatus(QStatusBar):
self._updateTime() self._updateTime()
return True return True
##
# Setters
##
def setRefTime(self, theTime): def setRefTime(self, theTime):
"""Set the reference time for the status bar clock. """Set the reference time for the status bar clock.
""" """
self.refTime = theTime self.refTime = theTime
return return
def setStatus(self, theMessage, timeOut=10.0): def setStatus(self, theMessage, timeOut=20.0):
"""Set the status bar message to display for 'timeOut' seconds. """Set the status bar message to display for 'timeOut' seconds.
""" """
self.showMessage(theMessage, int(timeOut*1000)) self.showMessage(theMessage, int(timeOut*1000))
+6 -2
View File
@@ -284,7 +284,9 @@ class GuiTheme:
try: try:
confParser.read_file(open(themeConf, mode="r", encoding="utf8")) confParser.read_file(open(themeConf, mode="r", encoding="utf8"))
except Exception as e: except Exception as e:
self.theParent.makeAlert(["Could not load theme config file.",str(e)],nwAlert.ERROR) self.theParent.makeAlert(
["Could not load theme config file.",str(e)], nwAlert.ERROR
)
continue continue
themeName = "" themeName = ""
if confParser.has_section("Main"): if confParser.has_section("Main"):
@@ -314,7 +316,9 @@ class GuiTheme:
try: try:
confParser.read_file(open(syntaxPath, mode="r", encoding="utf8")) confParser.read_file(open(syntaxPath, mode="r", encoding="utf8"))
except Exception as e: except Exception as e:
self.theParent.makeAlert(["Could not load syntax file.",str(e)],nwAlert.ERROR) self.theParent.makeAlert(
["Could not load syntax file.",str(e)], nwAlert.ERROR
)
return [] return []
syntaxName = "" syntaxName = ""
if confParser.has_section("Main"): if confParser.has_section("Main"):
+15 -11
View File
@@ -42,7 +42,7 @@ from PyQt5.QtWidgets import (
from nw.gui import ( from nw.gui import (
GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor, GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor,
GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails, GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails,
GuiConfigEditor, GuiProjectSettings, GuiItemEditor, GuiProjectOutline, GuiPreferences, GuiProjectSettings, GuiItemEditor, GuiProjectOutline,
GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel
) )
from nw.core import NWProject, NWDoc, NWIndex from nw.core import NWProject, NWDoc, NWIndex
@@ -553,7 +553,7 @@ class GuiMain(QMainWindow):
if self.docEditor.theHandle is None: if self.docEditor.theHandle is None:
self.makeAlert( self.makeAlert(
["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
@@ -668,6 +668,12 @@ class GuiMain(QMainWindow):
theDoc = NWDoc(self.theProject, self) theDoc = NWDoc(self.theProject, self)
for nDone, tItem in enumerate(self.theProject.projTree): for nDone, tItem in enumerate(self.theProject.projTree):
if tItem is not None:
self.statusBar.setStatus("Indexing: '%s'" % tItem.itemName)
else:
self.statusBar.setStatus("Indexing: Unknown item")
if tItem is not None and tItem.itemType == nwItemType.FILE: if tItem is not None and tItem.itemType == nwItemType.FILE:
logger.verbose("Scanning: %s" % tItem.itemName) logger.verbose("Scanning: %s" % tItem.itemName)
theText = theDoc.openDocument(tItem.itemHandle, showStatus=False) theText = theDoc.openDocument(tItem.itemHandle, showStatus=False)
@@ -683,16 +689,14 @@ class GuiMain(QMainWindow):
self.treeView.propagateCount(tItem.itemHandle, wC) self.treeView.propagateCount(tItem.itemHandle, wC)
self.treeView.projectWordCount() self.treeView.projectWordCount()
self.statusBar.setStatus("Building index: %.2f%%" % (100.0*(nDone + 1)/nItems))
self.docEditor.reloadText()
qApp.restoreOverrideCursor()
tEnd = time() tEnd = time()
self.statusBar.setStatus("Indexing completed in %.1f ms" % ((tEnd - tStart)*1000.0))
self.docEditor.reloadText()
qApp.restoreOverrideCursor()
if self.mainConf.showGUI: if self.mainConf.showGUI:
self.makeAlert( self.makeAlert("The project index has been successfully rebuilt.", nwAlert.INFO)
"Project index rebuilt in %.3f seconds." % (tEnd - tStart), nwAlert.INFO
)
return True return True
@@ -737,7 +741,7 @@ class GuiMain(QMainWindow):
def editConfigDialog(self): def editConfigDialog(self):
"""Open the preferences dialog. """Open the preferences dialog.
""" """
dlgConf = GuiConfigEditor(self, self.theProject) dlgConf = GuiPreferences(self, self.theProject)
if dlgConf.exec_() == QDialog.Accepted: if dlgConf.exec_() == QDialog.Accepted:
logger.debug("Applying new preferences") logger.debug("Applying new preferences")
self.initMain() self.initMain()
@@ -778,7 +782,7 @@ class GuiMain(QMainWindow):
0 = info, 1 = warning, and 2 = error. 0 = info, 1 = warning, and 2 = error.
""" """
if isinstance(theMessage, list): if isinstance(theMessage, list):
popMsg = " ".join(theMessage) popMsg = "<br>".join(theMessage)
logMsg = theMessage logMsg = theMessage
else: else:
popMsg = theMessage popMsg = theMessage