Code cleanup and added comments
This commit is contained in:
+9
-3
@@ -35,6 +35,8 @@ from nw.constants import nwConst
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def checkString(checkValue, defaultValue, allowNone=False):
|
||||
"""Check if a variable is a string or a none.
|
||||
"""
|
||||
if allowNone:
|
||||
if checkValue == None:
|
||||
return None
|
||||
@@ -45,6 +47,8 @@ def checkString(checkValue, defaultValue, allowNone=False):
|
||||
return defaultValue
|
||||
|
||||
def checkInt(checkValue, defaultValue, allowNone=False):
|
||||
"""Check if a variable is an integer or a none.
|
||||
"""
|
||||
if allowNone:
|
||||
if checkValue == None:
|
||||
return None
|
||||
@@ -56,6 +60,8 @@ def checkInt(checkValue, defaultValue, allowNone=False):
|
||||
return defaultValue
|
||||
|
||||
def checkBool(checkValue, defaultValue, allowNone=False):
|
||||
"""Check if a variable is a boolean or a none.
|
||||
"""
|
||||
if allowNone:
|
||||
if checkValue == None:
|
||||
return None
|
||||
@@ -92,7 +98,8 @@ def isHandle(theString):
|
||||
return not invalidChar
|
||||
|
||||
def colRange(rgbStart, rgbEnd, nStep):
|
||||
|
||||
"""Generate a range of colours from one RGB value to another.
|
||||
"""
|
||||
if len(rgbStart) != 3 and len(rgbEnd) != 3 and nStep < 1:
|
||||
logger.error("Cannot create colour range from given parameters")
|
||||
return None
|
||||
@@ -124,7 +131,7 @@ def colRange(rgbStart, rgbEnd, nStep):
|
||||
def formatInt(theInt):
|
||||
"""Formats an integer with k, M, G etc.
|
||||
"""
|
||||
postFix = ["k","M","G","T","P","E"]
|
||||
postFix = ["k", "M", "G", "T", "P", "E"]
|
||||
theVal = float(theInt)
|
||||
|
||||
if theVal > 1000.0:
|
||||
@@ -153,7 +160,6 @@ def splitVersionNumber(vString):
|
||||
""" Splits a version string on the form aa.bb.cc into major, minor
|
||||
and patch, and computes an integer value aabbcc.
|
||||
"""
|
||||
|
||||
vMajor = 0
|
||||
vMinor = 0
|
||||
vPatch = 0
|
||||
|
||||
+11
-3
@@ -88,7 +88,7 @@ class Config:
|
||||
self.guiSyntax = "default_light"
|
||||
self.guiIcons = "typicons_colour_light"
|
||||
self.guiDark = False
|
||||
self.guiLang = "en" # Hardcoded for now
|
||||
self.guiLang = "en" # Hardcoded for now since the GUI is only in English
|
||||
self.guiFont = ""
|
||||
self.guiFontSize = 11
|
||||
self.guiScale = 1.0 # Set automatically by Theme class
|
||||
@@ -286,7 +286,7 @@ class Config:
|
||||
|
||||
# Check if config file exists
|
||||
if self.confPath is not None:
|
||||
if path.isfile(path.join(self.confPath,self.confFile)):
|
||||
if path.isfile(path.join(self.confPath, self.confFile)):
|
||||
# If it exists, load it
|
||||
self.loadConfig()
|
||||
else:
|
||||
@@ -855,7 +855,9 @@ class Config:
|
||||
##
|
||||
|
||||
def _unpackList(self, inStr, listLen, listDefault, castTo=int):
|
||||
inData = inStr.split(",")
|
||||
"""Unpack a comma separated string of items into a list.
|
||||
"""
|
||||
inData = inStr.split(",")
|
||||
outData = []
|
||||
for i in range(listLen):
|
||||
try:
|
||||
@@ -865,9 +867,13 @@ class Config:
|
||||
return outData
|
||||
|
||||
def _packList(self, inData):
|
||||
"""Pack a list of items into a comma separated string.
|
||||
"""
|
||||
return ", ".join(str(inVal) for inVal in inData)
|
||||
|
||||
def _parseLine(self, cnfParse, cnfSec, cnfName, cnfType, cnfDefault):
|
||||
"""Parse a line and return the correct datatype.
|
||||
"""
|
||||
if cnfParse.has_section(cnfSec):
|
||||
if cnfParse.has_option(cnfSec, cnfName):
|
||||
if cnfType == self.CNF_STR:
|
||||
@@ -883,6 +889,8 @@ class Config:
|
||||
return cnfDefault
|
||||
|
||||
def _checkNone(self, checkVal):
|
||||
"""Convert a string to a none type.
|
||||
"""
|
||||
if checkVal is None:
|
||||
return None
|
||||
if isinstance(checkVal, str):
|
||||
|
||||
+5
-4
@@ -44,10 +44,11 @@ class NWDoc():
|
||||
self.mainConf = nw.CONFIG
|
||||
self.theProject = theProject
|
||||
self.theParent = theParent
|
||||
self.theItem = None
|
||||
self.docHandle = None
|
||||
self.fileLoc = None
|
||||
self.docMeta = ""
|
||||
|
||||
self.theItem = None
|
||||
self.docHandle = None
|
||||
self.fileLoc = None
|
||||
self.docMeta = ""
|
||||
|
||||
# Internal Mapping
|
||||
self.makeAlert = self.theParent.makeAlert
|
||||
|
||||
@@ -195,7 +195,6 @@ class NWSpellEnchant(NWSpellCheck):
|
||||
class NWSpellEnchantDummy:
|
||||
"""Fallback for when Enchant is selected, but not installed.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
return
|
||||
|
||||
|
||||
@@ -227,7 +227,6 @@ class Tokenizer():
|
||||
"""Set the text for the tokenizer from a handle. If theText is
|
||||
not set, load it from the file.
|
||||
"""
|
||||
|
||||
self.theHandle = theHandle
|
||||
self.theItem = self.theProject.projTree[theHandle]
|
||||
if self.theItem is None:
|
||||
@@ -308,7 +307,6 @@ class Tokenizer():
|
||||
4: The internal formatting map of the text, self.FMT_*
|
||||
5: The style of the block, self.A_*
|
||||
"""
|
||||
|
||||
# RegExes for adding formatting tags within text lines
|
||||
rxFormats = [
|
||||
(QRegularExpression(nwRegEx.FMT_I), [None, self.FMT_I_B, None, self.FMT_I_E]),
|
||||
@@ -457,7 +455,6 @@ class Tokenizer():
|
||||
"""Apply formatting to the text headers according to document
|
||||
layout and user settings.
|
||||
"""
|
||||
|
||||
# No special header formatting for notes and no-layout files
|
||||
if self.isNone or self.isNote:
|
||||
return
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ def formatHtmlErrMsg(exType, exValue, exTrace):
|
||||
"<p>Please report this error by submitting an issue report on "
|
||||
"GitHub, providing a description and this error message. "
|
||||
"URL: <{issueUrl}>.</p>"
|
||||
"<p><b>Environment</b><br>Version: {nwVersion}, OS: {osType} ({osKernel}),"
|
||||
"<p><b>Environment</b><br>Version: {nwVersion}, OS: {osType} ({osKernel}), "
|
||||
"Python: {pyVersion} ({pyHexVer:#x}), Qt: {qtVers}, PyQt: {pyqtVers}</p>"
|
||||
"<p><b>Error Type</b><br>{exType}: {exMessage}</p>"
|
||||
"<p><b>Traceback</b><br>{exTrace}</p>"
|
||||
|
||||
@@ -95,7 +95,6 @@ class GuiDocMerge(QDialog):
|
||||
create a new file in the same parent folder. The old files are
|
||||
not removed in the merge process, and must be deleted manually.
|
||||
"""
|
||||
|
||||
logger.verbose("GuiDocMerge merge button clicked")
|
||||
|
||||
finalOrder = []
|
||||
@@ -142,7 +141,6 @@ class GuiDocMerge(QDialog):
|
||||
are then added to the list view in order. The list itself can be
|
||||
reordered by the user.
|
||||
"""
|
||||
|
||||
tHandle = self.theParent.treeView.getSelectedHandle()
|
||||
self.sourceItem = tHandle
|
||||
if tHandle is None:
|
||||
|
||||
+1
-3
@@ -110,7 +110,6 @@ class GuiDocSplit(QDialog):
|
||||
settings. The old file is not removed in the merge process, and
|
||||
must be deleted manually.
|
||||
"""
|
||||
|
||||
logger.verbose("GuiDocSplit split button clicked")
|
||||
|
||||
if self.sourceItem is None:
|
||||
@@ -132,7 +131,7 @@ class GuiDocSplit(QDialog):
|
||||
nLines = len(theLines)
|
||||
theLines.insert(0, "%Split Doc")
|
||||
logger.debug(
|
||||
"Splitting document %s with %d lines" % (self.sourceItem,nLines)
|
||||
"Splitting document %s with %d lines" % (self.sourceItem, nLines)
|
||||
)
|
||||
|
||||
finalOrder = []
|
||||
@@ -210,7 +209,6 @@ class GuiDocSplit(QDialog):
|
||||
are then added to the list view in order. The list itself can be
|
||||
reordered by the user.
|
||||
"""
|
||||
|
||||
if self.sourceItem is None:
|
||||
self.sourceItem = self.theParent.treeView.getSelectedHandle()
|
||||
|
||||
|
||||
@@ -150,7 +150,6 @@ class GuiItemEditor(QDialog):
|
||||
def _doSave(self):
|
||||
"""Save the setting to the item.
|
||||
"""
|
||||
|
||||
logger.verbose("ItemEditor save button clicked")
|
||||
|
||||
itemName = self.editName.text()
|
||||
@@ -171,6 +170,8 @@ class GuiItemEditor(QDialog):
|
||||
return
|
||||
|
||||
def _doClose(self):
|
||||
"""Close the dialog without saving the settings.
|
||||
"""
|
||||
logger.verbose("ItemEditor close button clicked")
|
||||
self.close()
|
||||
return
|
||||
|
||||
+18
-9
@@ -192,7 +192,8 @@ class GuiMainMenu(QMenuBar):
|
||||
##
|
||||
|
||||
def _buildProjectMenu(self):
|
||||
|
||||
"""Assemble the Project menu.
|
||||
"""
|
||||
# Project
|
||||
self.projMenu = self.addMenu("&Project")
|
||||
|
||||
@@ -295,7 +296,8 @@ class GuiMainMenu(QMenuBar):
|
||||
return
|
||||
|
||||
def _buildDocumentMenu(self):
|
||||
|
||||
"""Assemble the Document menu.
|
||||
"""
|
||||
# Document
|
||||
self.docuMenu = self.addMenu("&Document")
|
||||
|
||||
@@ -377,7 +379,8 @@ class GuiMainMenu(QMenuBar):
|
||||
return
|
||||
|
||||
def _buildEditMenu(self):
|
||||
|
||||
"""Assemble the Edit menu.
|
||||
"""
|
||||
# Edit
|
||||
self.editMenu = self.addMenu("&Edit")
|
||||
|
||||
@@ -439,7 +442,8 @@ class GuiMainMenu(QMenuBar):
|
||||
return
|
||||
|
||||
def _buildViewMenu(self):
|
||||
|
||||
"""Assemble the View menu.
|
||||
"""
|
||||
# View
|
||||
self.viewMenu = self.addMenu("&View")
|
||||
|
||||
@@ -486,7 +490,8 @@ class GuiMainMenu(QMenuBar):
|
||||
return
|
||||
|
||||
def _buildInsertMenu(self):
|
||||
|
||||
"""Assemble the Insert menu.
|
||||
"""
|
||||
# Insert
|
||||
self.insertMenu = self.addMenu("&Insert")
|
||||
|
||||
@@ -576,7 +581,8 @@ class GuiMainMenu(QMenuBar):
|
||||
return
|
||||
|
||||
def _buildSearchMenu(self):
|
||||
|
||||
"""Assemble the Search menu.
|
||||
"""
|
||||
# Search
|
||||
self.srcMenu = self.addMenu("&Search")
|
||||
|
||||
@@ -627,7 +633,8 @@ class GuiMainMenu(QMenuBar):
|
||||
return
|
||||
|
||||
def _buildFormatMenu(self):
|
||||
|
||||
"""Assemble the Format menu.
|
||||
"""
|
||||
# Format
|
||||
self.fmtMenu = self.addMenu("&Format")
|
||||
|
||||
@@ -732,7 +739,8 @@ class GuiMainMenu(QMenuBar):
|
||||
return
|
||||
|
||||
def _buildToolsMenu(self):
|
||||
|
||||
"""Assemble the Tools menu.
|
||||
"""
|
||||
# Tools
|
||||
self.toolsMenu = self.addMenu("&Tools")
|
||||
|
||||
@@ -828,7 +836,8 @@ class GuiMainMenu(QMenuBar):
|
||||
return
|
||||
|
||||
def _buildHelpMenu(self):
|
||||
|
||||
"""Assemble the Help menu.
|
||||
"""
|
||||
# Help
|
||||
self.helpMenu = self.addMenu("&Help")
|
||||
|
||||
|
||||
@@ -195,8 +195,10 @@ class GuiOutline(QTreeWidget):
|
||||
tLine = int(tItem.text(self.colIndex[nwOutline.LINE]))
|
||||
except:
|
||||
tLine = 1
|
||||
|
||||
logger.verbose("User selected entry with handle %s on line %s" % (tHandle, tLine))
|
||||
self.theParent.openDocument(tHandle, tLine=tLine-1, doScroll=True)
|
||||
|
||||
return
|
||||
|
||||
def _itemSelected(self):
|
||||
@@ -208,6 +210,7 @@ class GuiOutline(QTreeWidget):
|
||||
tHandle = selItems[0].data(self.colIndex[nwOutline.TITLE], Qt.UserRole)
|
||||
sTitle = selItems[0].data(self.colIndex[nwOutline.LINE], Qt.UserRole)
|
||||
self.theParent.projMeta.showItem(tHandle, sTitle)
|
||||
|
||||
return
|
||||
|
||||
def _headerRightClick(self, clickPos):
|
||||
@@ -232,6 +235,7 @@ class GuiOutline(QTreeWidget):
|
||||
if theItem in self.colIndex:
|
||||
self.setColumnHidden(self.colIndex[theItem], not isChecked)
|
||||
self._saveHeaderState()
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
|
||||
+17
-6
@@ -80,7 +80,9 @@ class GuiPreferences(PagedDialog):
|
||||
##
|
||||
|
||||
def _doSave(self):
|
||||
|
||||
"""Trigger all the save functions in the tabs, and collect the
|
||||
status of the saves.
|
||||
"""
|
||||
logger.verbose("ConfigEditor save button clicked")
|
||||
|
||||
validEntries = True
|
||||
@@ -115,6 +117,8 @@ class GuiPreferences(PagedDialog):
|
||||
return
|
||||
|
||||
def _doClose(self):
|
||||
"""Close the preferences without saving the changes.
|
||||
"""
|
||||
logger.verbose("ConfigEditor close button clicked")
|
||||
self.close()
|
||||
return
|
||||
@@ -284,7 +288,8 @@ class GuiConfigEditGeneralTab(QWidget):
|
||||
return
|
||||
|
||||
def saveValues(self):
|
||||
|
||||
"""Save the values set for this tab.
|
||||
"""
|
||||
validEntries = True
|
||||
needsRestart = False
|
||||
|
||||
@@ -329,7 +334,6 @@ class GuiConfigEditGeneralTab(QWidget):
|
||||
def _backupFolder(self):
|
||||
"""Open a dialog to select the backup folder.
|
||||
"""
|
||||
|
||||
currDir = self.backupPath
|
||||
if not path.isdir(currDir):
|
||||
currDir = ""
|
||||
@@ -515,7 +519,8 @@ class GuiConfigEditLayoutTab(QWidget):
|
||||
return
|
||||
|
||||
def saveValues(self):
|
||||
|
||||
"""Save the values set for this tab.
|
||||
"""
|
||||
validEntries = True
|
||||
needsRestart = False
|
||||
|
||||
@@ -681,7 +686,8 @@ class GuiConfigEditEditingTab(QWidget):
|
||||
return
|
||||
|
||||
def saveValues(self):
|
||||
|
||||
"""Save the values set for this tab.
|
||||
"""
|
||||
validEntries = True
|
||||
needsRestart = False
|
||||
|
||||
@@ -712,6 +718,8 @@ class GuiConfigEditEditingTab(QWidget):
|
||||
##
|
||||
|
||||
def _disableComboItem(self, theList, theValue):
|
||||
"""Disable a list item in the combo box.
|
||||
"""
|
||||
theIdx = theList.findData(theValue)
|
||||
theModel = theList.model()
|
||||
anItem = theModel.item(1)
|
||||
@@ -719,6 +727,8 @@ class GuiConfigEditEditingTab(QWidget):
|
||||
return theModel
|
||||
|
||||
def _doUpdateSpellTool(self, currIdx):
|
||||
"""Update the list of dictionaries based on spell tool selected.
|
||||
"""
|
||||
spellTool = self.spellToolList.currentData()
|
||||
self._updateLanguageList(spellTool)
|
||||
return
|
||||
@@ -903,7 +913,8 @@ class GuiConfigEditAutoReplaceTab(QWidget):
|
||||
return
|
||||
|
||||
def saveValues(self):
|
||||
|
||||
"""Save the values set for this tab.
|
||||
"""
|
||||
validEntries = True
|
||||
needsRestart = False
|
||||
|
||||
|
||||
@@ -152,6 +152,7 @@ class GuiProjectLoad(QDialog):
|
||||
"""
|
||||
logger.verbose("GuiProjectLoad open button clicked")
|
||||
self._saveDialogState()
|
||||
|
||||
selItems = self.listBox.selectedItems()
|
||||
if selItems:
|
||||
self.openPath = selItems[0].data(self.C_NAME, Qt.UserRole)
|
||||
@@ -160,6 +161,7 @@ class GuiProjectLoad(QDialog):
|
||||
else:
|
||||
self.openPath = None
|
||||
self.openState = self.NONE_STATE
|
||||
|
||||
return
|
||||
|
||||
def _doSelectRecent(self):
|
||||
@@ -189,6 +191,7 @@ class GuiProjectLoad(QDialog):
|
||||
self.openPath = thePath
|
||||
self.openState = self.OPEN_STATE
|
||||
self.accept()
|
||||
|
||||
return
|
||||
|
||||
def _doClose(self):
|
||||
|
||||
+44
-9
@@ -97,6 +97,7 @@ class GuiProjectSettings(PagedDialog):
|
||||
bookTitle = self.tabMain.editTitle.text()
|
||||
bookAuthors = self.tabMain.editAuthors.toPlainText()
|
||||
doBackup = not self.tabMain.doBackup.isChecked()
|
||||
|
||||
self.theProject.setProjectName(projName)
|
||||
self.theProject.setBookTitle(bookTitle)
|
||||
self.theProject.setBookAuthors(bookAuthors)
|
||||
@@ -105,11 +106,14 @@ class GuiProjectSettings(PagedDialog):
|
||||
if self.tabStatus.colChanged:
|
||||
statusCol = self.tabStatus.getNewList()
|
||||
self.theProject.setStatusColours(statusCol)
|
||||
|
||||
if self.tabImport.colChanged:
|
||||
importCol = self.tabImport.getNewList()
|
||||
self.theProject.setImportColours(importCol)
|
||||
|
||||
if self.tabStatus.colChanged or self.tabImport.colChanged:
|
||||
self.theParent.rebuildTree()
|
||||
|
||||
if self.tabReplace.arChanged:
|
||||
newList = self.tabReplace.getNewList()
|
||||
self.theProject.setAutoReplace(newList)
|
||||
@@ -119,7 +123,7 @@ class GuiProjectSettings(PagedDialog):
|
||||
return
|
||||
|
||||
def _doClose(self):
|
||||
"""Close the dialog.
|
||||
"""Save settings and close the dialog.
|
||||
"""
|
||||
winWidth = self.mainConf.rpxInt(self.width())
|
||||
winHeight = self.mainConf.rpxInt(self.height())
|
||||
@@ -372,6 +376,8 @@ class GuiProjectEditStatus(QWidget):
|
||||
##
|
||||
|
||||
def _selectColour(self):
|
||||
"""Open a dialog to select the status icon colour.
|
||||
"""
|
||||
logger.verbose("Item colour button clicked")
|
||||
if self.selColour is not None:
|
||||
newCol = QColorDialog.getColor(
|
||||
@@ -386,6 +392,8 @@ class GuiProjectEditStatus(QWidget):
|
||||
return
|
||||
|
||||
def _newItem(self):
|
||||
"""Create a new status item.
|
||||
"""
|
||||
logger.verbose("New item button clicked")
|
||||
newItem = self._addItem("New Item", (0, 0, 0), None, 0)
|
||||
newItem.setBackground(QBrush(QColor(0, 255, 0, 80)))
|
||||
@@ -393,6 +401,8 @@ class GuiProjectEditStatus(QWidget):
|
||||
return
|
||||
|
||||
def _delItem(self):
|
||||
"""Delete a status item.
|
||||
"""
|
||||
logger.verbose("Delete item button clicked")
|
||||
selItem = self._getSelectedItem()
|
||||
if selItem is not None:
|
||||
@@ -408,6 +418,8 @@ class GuiProjectEditStatus(QWidget):
|
||||
return
|
||||
|
||||
def _saveItem(self):
|
||||
"""Save changes made to a status item.
|
||||
"""
|
||||
logger.verbose("Save item button clicked")
|
||||
selItem = self._getSelectedItem()
|
||||
iRow = self.listBox.row(selItem)
|
||||
@@ -427,6 +439,8 @@ class GuiProjectEditStatus(QWidget):
|
||||
return
|
||||
|
||||
def _addItem(self, iName, iCol, oName, nUse):
|
||||
"""Add a status item to the list.
|
||||
"""
|
||||
newIcon = QPixmap(self.iPx, self.iPx)
|
||||
newIcon.fill(QColor(*iCol))
|
||||
newItem = QListWidgetItem()
|
||||
@@ -439,11 +453,14 @@ class GuiProjectEditStatus(QWidget):
|
||||
return newItem
|
||||
|
||||
def _selectedItem(self):
|
||||
"""Extract the info of a selected item and populate the settings
|
||||
boxes and button.
|
||||
"""
|
||||
logger.verbose("Item selected")
|
||||
selItem = self._getSelectedItem()
|
||||
if selItem is not None:
|
||||
selIdx = selItem.data(Qt.UserRole)
|
||||
selVal = self.colData[selIdx]
|
||||
selIdx = selItem.data(Qt.UserRole)
|
||||
selVal = self.colData[selIdx]
|
||||
self.selColour = QColor(selVal[1], selVal[2], selVal[3])
|
||||
newIcon = QPixmap(self.iPx, self.iPx)
|
||||
newIcon.fill(self.selColour)
|
||||
@@ -459,6 +476,8 @@ class GuiProjectEditStatus(QWidget):
|
||||
##
|
||||
|
||||
def _getSelectedItem(self):
|
||||
"""Get the currently selected item.
|
||||
"""
|
||||
selItem = self.listBox.selectedItems()
|
||||
if len(selItem) == 0:
|
||||
return None
|
||||
@@ -467,6 +486,8 @@ class GuiProjectEditStatus(QWidget):
|
||||
return None
|
||||
|
||||
def _rowsMoved(self):
|
||||
"""A row has been moved, so sett the changed flag.
|
||||
"""
|
||||
logger.verbose("A drag move event occurred")
|
||||
self.colChanged = True
|
||||
return
|
||||
@@ -506,9 +527,9 @@ class GuiProjectEditReplace(QWidget):
|
||||
|
||||
self.editKey = QLineEdit()
|
||||
self.editValue = QLineEdit()
|
||||
self.saveButton = QPushButton(self.theTheme.getIcon("done"),"")
|
||||
self.addButton = QPushButton(self.theTheme.getIcon("add"),"")
|
||||
self.delButton = QPushButton(self.theTheme.getIcon("remove"),"")
|
||||
self.saveButton = QPushButton(self.theTheme.getIcon("done"), "")
|
||||
self.addButton = QPushButton(self.theTheme.getIcon("add"), "")
|
||||
self.delButton = QPushButton(self.theTheme.getIcon("remove"), "")
|
||||
self.saveButton.setToolTip("Save entry")
|
||||
self.addButton.setToolTip("Add new entry")
|
||||
self.delButton.setToolTip("Delete selected entry")
|
||||
@@ -536,11 +557,13 @@ class GuiProjectEditReplace(QWidget):
|
||||
return
|
||||
|
||||
def getNewList(self):
|
||||
"""Extract the list from the widget.
|
||||
"""
|
||||
newList = {}
|
||||
for n in range(self.listBox.topLevelItemCount()):
|
||||
tItem = self.listBox.topLevelItem(n)
|
||||
aKey = self._stripNotAllowed(tItem.text(0))
|
||||
aVal = tItem.text(1)
|
||||
aKey = self._stripNotAllowed(tItem.text(0))
|
||||
aVal = tItem.text(1)
|
||||
if len(aKey) > 0:
|
||||
newList[aKey] = aVal
|
||||
return newList
|
||||
@@ -550,6 +573,9 @@ class GuiProjectEditReplace(QWidget):
|
||||
##
|
||||
|
||||
def _selectedItem(self):
|
||||
"""Extract the details from the selected item and populate the
|
||||
edit form.
|
||||
"""
|
||||
selItem = self._getSelectedItem()
|
||||
if selItem is None:
|
||||
return False
|
||||
@@ -564,7 +590,8 @@ class GuiProjectEditReplace(QWidget):
|
||||
return True
|
||||
|
||||
def _saveEntry(self):
|
||||
|
||||
"""Save the form data into the list widget.
|
||||
"""
|
||||
selItem = self._getSelectedItem()
|
||||
if selItem is None:
|
||||
return False
|
||||
@@ -586,6 +613,8 @@ class GuiProjectEditReplace(QWidget):
|
||||
return
|
||||
|
||||
def _addEntry(self):
|
||||
"""Add a new list entry.
|
||||
"""
|
||||
saveKey = "<keyword%d>" % (self.listBox.topLevelItemCount() + 1)
|
||||
newVal = ""
|
||||
newItem = QTreeWidgetItem([saveKey, newVal])
|
||||
@@ -593,6 +622,8 @@ class GuiProjectEditReplace(QWidget):
|
||||
return True
|
||||
|
||||
def _delEntry(self):
|
||||
"""Delete the selected entry.
|
||||
"""
|
||||
selItem = self._getSelectedItem()
|
||||
if selItem is None:
|
||||
return False
|
||||
@@ -601,12 +632,16 @@ class GuiProjectEditReplace(QWidget):
|
||||
return True
|
||||
|
||||
def _getSelectedItem(self):
|
||||
"""Extract the currently selected item.
|
||||
"""
|
||||
selItem = self.listBox.selectedItems()
|
||||
if len(selItem) == 0:
|
||||
return None
|
||||
return selItem[0]
|
||||
|
||||
def _stripNotAllowed(self, theKey):
|
||||
"""Clean up the replace key string.
|
||||
"""
|
||||
retKey = ""
|
||||
for c in theKey:
|
||||
if c.isalnum():
|
||||
|
||||
+27
-1
@@ -90,7 +90,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
# for some fonts like the Ubuntu font.
|
||||
treeHeader = self.header()
|
||||
treeHeader.setStretchLastSection(True)
|
||||
treeHeader.setMinimumSectionSize(iPx+6)
|
||||
treeHeader.setMinimumSectionSize(iPx + 6)
|
||||
|
||||
# Allow Move by Drag & Drop
|
||||
self.setDragEnabled(True)
|
||||
@@ -237,6 +237,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
has focus. This also applies when the menu is used.
|
||||
"""
|
||||
if qApp.focusWidget() == self and self.theParent.hasProject:
|
||||
|
||||
tHandle = self.getSelectedHandle()
|
||||
tItem = self._getTreeItem(tHandle)
|
||||
pItem = tItem.parent()
|
||||
@@ -248,6 +249,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
return False
|
||||
cItem = self.takeTopLevelItem(tIndex)
|
||||
self.insertTopLevelItem(nIndex, cItem)
|
||||
|
||||
else:
|
||||
tIndex = pItem.indexOfChild(tItem)
|
||||
nChild = pItem.childCount()
|
||||
@@ -256,11 +258,14 @@ class GuiProjectTree(QTreeWidget):
|
||||
return False
|
||||
cItem = pItem.takeChild(tIndex)
|
||||
pItem.insertChild(nIndex, cItem)
|
||||
|
||||
self.clearSelection()
|
||||
cItem.setSelected(True)
|
||||
self._setTreeChanged(True)
|
||||
|
||||
else:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def saveTreeOrder(self):
|
||||
@@ -516,8 +521,10 @@ class GuiProjectTree(QTreeWidget):
|
||||
for i in range(pItem.childCount()):
|
||||
pCount += int(pItem.child(i).text(self.C_COUNT))
|
||||
pHandle = pItem.data(self.C_NAME, Qt.UserRole)
|
||||
|
||||
if not nDepth > 200 and pHandle != "":
|
||||
self.propagateCount(pHandle, pCount, nDepth+1)
|
||||
|
||||
return
|
||||
|
||||
def projectWordCount(self):
|
||||
@@ -533,9 +540,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
if tItem == self.orphRoot:
|
||||
continue
|
||||
nWords += int(tItem.text(self.C_COUNT))
|
||||
|
||||
self.theProject.setProjectWordCount(nWords)
|
||||
sWords = self.theProject.getSessionWordCount()
|
||||
self.theParent.statusBar.setStats(nWords,sWords)
|
||||
|
||||
return
|
||||
|
||||
def buildTree(self):
|
||||
@@ -547,9 +556,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
logger.debug("Building project tree ...")
|
||||
self.clear()
|
||||
iCount = 0
|
||||
|
||||
for nwItem in self.theProject.getProjectItems():
|
||||
iCount += 1
|
||||
self._addTreeItem(nwItem)
|
||||
|
||||
logger.debug("%d items added to project tree" % iCount)
|
||||
return True
|
||||
|
||||
@@ -558,10 +569,13 @@ class GuiProjectTree(QTreeWidget):
|
||||
selected, return the first.
|
||||
"""
|
||||
selItem = self.selectedItems()
|
||||
|
||||
if len(selItem) == 0:
|
||||
return None
|
||||
|
||||
if isinstance(selItem[0], QTreeWidgetItem):
|
||||
return selItem[0].data(self.C_NAME, Qt.UserRole)
|
||||
|
||||
return None
|
||||
|
||||
def getSelectedHandles(self):
|
||||
@@ -572,6 +586,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
for n in range(len(selItems)):
|
||||
if isinstance(selItems[n], QTreeWidgetItem):
|
||||
selHandles.append(selItems[n].data(self.C_NAME, Qt.UserRole))
|
||||
|
||||
return selHandles
|
||||
|
||||
def setSelectedHandle(self, tHandle, doScroll=False):
|
||||
@@ -580,12 +595,14 @@ class GuiProjectTree(QTreeWidget):
|
||||
if tHandle in self.theMap:
|
||||
self.clearSelection()
|
||||
self.theMap[tHandle].setSelected(True)
|
||||
|
||||
selItems = self.selectedIndexes()
|
||||
if selItems and doScroll:
|
||||
self.scrollTo(
|
||||
selItems[0], QAbstractItemView.PositionAtCenter
|
||||
)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
##
|
||||
@@ -601,9 +618,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
tHandle = selItem.data(self.C_NAME, Qt.UserRole)
|
||||
tItem = self.theProject.projTree[tHandle]
|
||||
self.setSelectedHandle(tHandle) # Just to be safe
|
||||
|
||||
if self.ctxMenu.filterActions(tItem):
|
||||
# Only open menu if any actions remain after filter
|
||||
self.ctxMenu.exec_(self.viewport().mapToGlobal(clickPos))
|
||||
|
||||
return
|
||||
|
||||
##
|
||||
@@ -615,9 +634,11 @@ class GuiProjectTree(QTreeWidget):
|
||||
mouse in a blank area of the tree view.
|
||||
"""
|
||||
QTreeWidget.mousePressEvent(self, theEvent)
|
||||
|
||||
selItem = self.indexAt(theEvent.pos())
|
||||
if not selItem.isValid():
|
||||
self.clearSelection()
|
||||
|
||||
return
|
||||
|
||||
def dropEvent(self, theEvent):
|
||||
@@ -766,6 +787,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
trashHandle = self.theProject.trashFolder()
|
||||
if trashHandle is None:
|
||||
return None
|
||||
|
||||
trItem = self._getTreeItem(trashHandle)
|
||||
if trItem is None:
|
||||
trItem = self._addTreeItem(
|
||||
@@ -773,6 +795,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
)
|
||||
trItem.setExpanded(True)
|
||||
self._setTreeChanged(True)
|
||||
|
||||
return trItem
|
||||
|
||||
def _addOrphanedRoot(self):
|
||||
@@ -790,6 +813,7 @@ class GuiProjectTree(QTreeWidget):
|
||||
newItem.setExpanded(True)
|
||||
newItem.setData(self.C_NAME, Qt.UserRole, "")
|
||||
newItem.setIcon(self.C_NAME, self.theTheme.getIcon("proj_orphan"))
|
||||
|
||||
return
|
||||
|
||||
def _cleanOrphanedRoot(self):
|
||||
@@ -834,10 +858,12 @@ class GuiProjectTree(QTreeWidget):
|
||||
if trItemP is None:
|
||||
logger.error("Failed to find new parent item of %s" % tHandle)
|
||||
return
|
||||
|
||||
pHandle = trItemP.data(self.C_NAME, Qt.UserRole)
|
||||
nwItemS.setParent(pHandle)
|
||||
self.setTreeItemValues(tHandle)
|
||||
self._setTreeChanged(True)
|
||||
|
||||
return
|
||||
|
||||
def _setTreeChanged(self, theState):
|
||||
|
||||
+1
-1
@@ -264,7 +264,7 @@ class StatusLED(QAbstractButton):
|
||||
qPaint.setPen(qPalette.dark().color())
|
||||
qPaint.setBrush(self._theCol)
|
||||
qPaint.setOpacity(1.0)
|
||||
qPaint.drawEllipse(1, 1, self.width()-2, self.height()-2)
|
||||
qPaint.drawEllipse(1, 1, self.width() - 2, self.height() - 2)
|
||||
return
|
||||
|
||||
# END Class StatusLED
|
||||
|
||||
+56
-53
@@ -77,11 +77,11 @@ class GuiTheme:
|
||||
self.themeLicenseUrl = ""
|
||||
|
||||
## GUI
|
||||
self.treeWCount = [ 0, 0, 0]
|
||||
self.statNone = [120,120,120]
|
||||
self.statUnsaved = [120,120, 40]
|
||||
self.statSaved = [ 40,120, 0]
|
||||
self.helpText = [ 0, 0, 0]
|
||||
self.treeWCount = [ 0, 0, 0]
|
||||
self.statNone = [120, 120, 120]
|
||||
self.statUnsaved = [120, 120, 40]
|
||||
self.statSaved = [ 40, 120, 0]
|
||||
self.helpText = [ 0, 0, 0]
|
||||
|
||||
# Loaded Syntax Settings
|
||||
|
||||
@@ -95,22 +95,22 @@ class GuiTheme:
|
||||
self.syntaxLicenseUrl = ""
|
||||
|
||||
## Colours
|
||||
self.colBack = [255,255,255]
|
||||
self.colText = [ 0, 0, 0]
|
||||
self.colLink = [ 0, 0, 0]
|
||||
self.colHead = [ 0, 0, 0]
|
||||
self.colHeadH = [ 0, 0, 0]
|
||||
self.colEmph = [ 0, 0, 0]
|
||||
self.colDialN = [ 0, 0, 0]
|
||||
self.colDialD = [ 0, 0, 0]
|
||||
self.colDialS = [ 0, 0, 0]
|
||||
self.colComm = [ 0, 0, 0]
|
||||
self.colKey = [ 0, 0, 0]
|
||||
self.colVal = [ 0, 0, 0]
|
||||
self.colSpell = [ 0, 0, 0]
|
||||
self.colTagErr = [ 0, 0, 0]
|
||||
self.colRepTag = [ 0, 0, 0]
|
||||
self.colMod = [ 0, 0, 0]
|
||||
self.colBack = [255, 255, 255]
|
||||
self.colText = [ 0, 0, 0]
|
||||
self.colLink = [ 0, 0, 0]
|
||||
self.colHead = [ 0, 0, 0]
|
||||
self.colHeadH = [ 0, 0, 0]
|
||||
self.colEmph = [ 0, 0, 0]
|
||||
self.colDialN = [ 0, 0, 0]
|
||||
self.colDialD = [ 0, 0, 0]
|
||||
self.colDialS = [ 0, 0, 0]
|
||||
self.colComm = [ 0, 0, 0]
|
||||
self.colKey = [ 0, 0, 0]
|
||||
self.colVal = [ 0, 0, 0]
|
||||
self.colSpell = [ 0, 0, 0]
|
||||
self.colTagErr = [ 0, 0, 0]
|
||||
self.colRepTag = [ 0, 0, 0]
|
||||
self.colMod = [ 0, 0, 0]
|
||||
|
||||
# Changeable Settings
|
||||
self.guiTheme = None
|
||||
@@ -144,9 +144,9 @@ class GuiTheme:
|
||||
qMetric = QFontMetrics(self.guiFont)
|
||||
self.fontPointSize = self.guiFont.pointSizeF()
|
||||
self.fontPixelSize = int(round(qMetric.height()))
|
||||
self.baseIconSize = int(round(qMetric.ascent()))
|
||||
self.textNHeight = qMetric.boundingRect("N").height()
|
||||
self.textNWidth = qMetric.boundingRect("N").width()
|
||||
self.baseIconSize = int(round(qMetric.ascent()))
|
||||
self.textNHeight = qMetric.boundingRect("N").height()
|
||||
self.textNWidth= qMetric.boundingRect("N").width()
|
||||
|
||||
logger.verbose("GUI Font Family: %s" % self.guiFont.family())
|
||||
logger.verbose("GUI Font Point Size: %.2f" % self.fontPointSize)
|
||||
@@ -223,10 +223,10 @@ class GuiTheme:
|
||||
self.guiTheme = self.mainConf.guiTheme
|
||||
self.guiSyntax = self.mainConf.guiSyntax
|
||||
self.themeRoot = self.mainConf.themeRoot
|
||||
self.themePath = path.join(self.mainConf.themeRoot,self.guiPath,self.guiTheme)
|
||||
self.syntaxFile = path.join(self.themeRoot,self.syntaxPath,self.guiSyntax+".conf")
|
||||
self.confFile = path.join(self.themePath,self.confName)
|
||||
self.cssFile = path.join(self.themePath,self.cssName)
|
||||
self.themePath = path.join(self.mainConf.themeRoot, self.guiPath, self.guiTheme)
|
||||
self.syntaxFile = path.join(self.themeRoot, self.syntaxPath, self.guiSyntax+".conf")
|
||||
self.confFile = path.join(self.themePath, self.confName)
|
||||
self.cssFile = path.join(self.themePath, self.cssName)
|
||||
|
||||
self.loadTheme()
|
||||
self.loadSyntax()
|
||||
@@ -256,7 +256,7 @@ class GuiTheme:
|
||||
cssData = ""
|
||||
try:
|
||||
if path.isfile(self.cssFile):
|
||||
with open(self.cssFile,mode="r",encoding="utf8") as inFile:
|
||||
with open(self.cssFile, mode="r", encoding="utf8") as inFile:
|
||||
cssData = inFile.read()
|
||||
except Exception as e:
|
||||
logger.error("Could not load theme css file")
|
||||
@@ -329,13 +329,13 @@ class GuiTheme:
|
||||
## Main
|
||||
cnfSec = "Main"
|
||||
if confParser.has_section(cnfSec):
|
||||
self.syntaxName = self._parseLine( confParser, cnfSec, "name", "")
|
||||
self.syntaxDescription = self._parseLine( confParser, cnfSec, "description", "")
|
||||
self.syntaxAuthor = self._parseLine( confParser, cnfSec, "author", "")
|
||||
self.syntaxCredit = self._parseLine( confParser, cnfSec, "credit", "")
|
||||
self.syntaxUrl = self._parseLine( confParser, cnfSec, "url", "")
|
||||
self.syntaxLicense = self._parseLine( confParser, cnfSec, "license", "")
|
||||
self.syntaxLicenseUrl = self._parseLine( confParser, cnfSec, "licenseurl", "")
|
||||
self.syntaxName = self._parseLine(confParser, cnfSec, "name", "")
|
||||
self.syntaxDescription = self._parseLine(confParser, cnfSec, "description", "")
|
||||
self.syntaxAuthor = self._parseLine(confParser, cnfSec, "author", "")
|
||||
self.syntaxCredit = self._parseLine(confParser, cnfSec, "credit", "")
|
||||
self.syntaxUrl = self._parseLine(confParser, cnfSec, "url", "")
|
||||
self.syntaxLicense = self._parseLine(confParser, cnfSec, "license", "")
|
||||
self.syntaxLicenseUrl = self._parseLine(confParser, cnfSec, "licenseurl", "")
|
||||
|
||||
## Syntax
|
||||
cnfSec = "Syntax"
|
||||
@@ -376,7 +376,7 @@ class GuiTheme:
|
||||
confParser.read_file(inFile)
|
||||
except Exception as e:
|
||||
self.theParent.makeAlert(
|
||||
["Could not load theme config file.",str(e)], nwAlert.ERROR
|
||||
["Could not load theme config file.", str(e)], nwAlert.ERROR
|
||||
)
|
||||
continue
|
||||
themeName = ""
|
||||
@@ -409,7 +409,7 @@ class GuiTheme:
|
||||
confParser.read_file(inFile)
|
||||
except Exception as e:
|
||||
self.theParent.makeAlert(
|
||||
["Could not load syntax file.",str(e)], nwAlert.ERROR
|
||||
["Could not load syntax file.", str(e)], nwAlert.ERROR
|
||||
)
|
||||
return []
|
||||
syntaxName = ""
|
||||
@@ -429,8 +429,10 @@ class GuiTheme:
|
||||
##
|
||||
|
||||
def _loadColour(self, confParser, cnfSec, cnfName):
|
||||
"""Load a colour value from a config string.
|
||||
"""
|
||||
if confParser.has_option(cnfSec,cnfName):
|
||||
inData = confParser.get(cnfSec,cnfName).split(",")
|
||||
inData = confParser.get(cnfSec,cnfName).split(",")
|
||||
outData = []
|
||||
try:
|
||||
outData.append(int(inData[0]))
|
||||
@@ -438,16 +440,18 @@ class GuiTheme:
|
||||
outData.append(int(inData[2]))
|
||||
except:
|
||||
logger.error("Could not load theme colours for '%s' from config file" % cnfName)
|
||||
outData = [0,0,0]
|
||||
outData = [0, 0, 0]
|
||||
else:
|
||||
logger.warning("Could not find theme colours for '%s' in config file" % cnfName)
|
||||
outData = [0,0,0]
|
||||
outData = [0, 0, 0]
|
||||
return outData
|
||||
|
||||
def _setPalette(self, confParser, cnfSec, cnfName, paletteVal):
|
||||
"""Set a palette colour value from a config string.
|
||||
"""
|
||||
readCol = []
|
||||
if confParser.has_option(cnfSec,cnfName):
|
||||
inData = confParser.get(cnfSec,cnfName).split(",")
|
||||
inData = confParser.get(cnfSec,cnfName).split(",")
|
||||
try:
|
||||
readCol.append(int(inData[0]))
|
||||
readCol.append(int(inData[1]))
|
||||
@@ -547,8 +551,8 @@ class GuiIcons:
|
||||
"reference" : (None, None),
|
||||
|
||||
## Switches
|
||||
"sticky-on" : (None, None),
|
||||
"sticky-off" : (None, None),
|
||||
"sticky-on" : (None, None),
|
||||
"sticky-off" : (None, None),
|
||||
}
|
||||
|
||||
DECO_MAP = {
|
||||
@@ -615,13 +619,13 @@ class GuiIcons:
|
||||
## Main
|
||||
cnfSec = "Main"
|
||||
if confParser.has_section(cnfSec):
|
||||
self.themeName = self._parseLine( confParser, cnfSec, "name", "")
|
||||
self.themeDescription = self._parseLine( confParser, cnfSec, "description", "")
|
||||
self.themeAuthor = self._parseLine( confParser, cnfSec, "author", "")
|
||||
self.themeCredit = self._parseLine( confParser, cnfSec, "credit", "")
|
||||
self.themeUrl = self._parseLine( confParser, cnfSec, "url", "")
|
||||
self.themeLicense = self._parseLine( confParser, cnfSec, "license", "")
|
||||
self.themeLicenseUrl = self._parseLine( confParser, cnfSec, "licenseurl", "")
|
||||
self.themeName = self._parseLine(confParser, cnfSec, "name", "")
|
||||
self.themeDescription = self._parseLine(confParser, cnfSec, "description", "")
|
||||
self.themeAuthor = self._parseLine(confParser, cnfSec, "author", "")
|
||||
self.themeCredit = self._parseLine(confParser, cnfSec, "credit", "")
|
||||
self.themeUrl = self._parseLine(confParser, cnfSec, "url", "")
|
||||
self.themeLicense = self._parseLine(confParser, cnfSec, "license", "")
|
||||
self.themeLicenseUrl = self._parseLine(confParser, cnfSec, "licenseurl", "")
|
||||
|
||||
## Palette
|
||||
cnfSec = "Map"
|
||||
@@ -705,7 +709,7 @@ class GuiIcons:
|
||||
confParser.read_file(inFile)
|
||||
except Exception as e:
|
||||
self.theParent.makeAlert(
|
||||
["Could not load theme config file.",str(e)], nwAlert.ERROR
|
||||
["Could not load theme config file.", str(e)], nwAlert.ERROR
|
||||
)
|
||||
continue
|
||||
themeName = ""
|
||||
@@ -730,7 +734,6 @@ class GuiIcons:
|
||||
an icon exists. Prefer svg files over png files. Always returns
|
||||
a QIcon.
|
||||
"""
|
||||
|
||||
if iconKey not in self.ICON_MAP:
|
||||
logger.error("Requested unknown icon name '%s'" % iconKey)
|
||||
return QIcon()
|
||||
|
||||
@@ -90,7 +90,7 @@ class GuiWritingStats(QDialog):
|
||||
)
|
||||
|
||||
self.listBox = QTreeWidget()
|
||||
self.listBox.setHeaderLabels(["Session Start","Length","Words","Histogram"])
|
||||
self.listBox.setHeaderLabels(["Session Start", "Length", "Words", "Histogram"])
|
||||
self.listBox.setIndentation(0)
|
||||
self.listBox.setColumnWidth(self.C_TIME, wCol0)
|
||||
self.listBox.setColumnWidth(self.C_LENGTH, wCol1)
|
||||
|
||||
+70
-46
@@ -128,7 +128,7 @@ class GuiMain(QMainWindow):
|
||||
self.tabWidget = QTabWidget()
|
||||
self.tabWidget.setTabPosition(QTabWidget.East)
|
||||
self.tabWidget.setStyleSheet("QTabWidget::pane {border: 0;}")
|
||||
self.tabWidget.addTab(self.splitDocs, "Editor")
|
||||
self.tabWidget.addTab(self.splitDocs, "Editor")
|
||||
self.tabWidget.addTab(self.splitOutline, "Outline")
|
||||
self.tabWidget.currentChanged.connect(self._mainTabChanged)
|
||||
|
||||
@@ -139,8 +139,6 @@ class GuiMain(QMainWindow):
|
||||
self.splitMain.addWidget(self.tabWidget)
|
||||
self.splitMain.setSizes(self.mainConf.getMainPanePos())
|
||||
|
||||
self.setCentralWidget(self.splitMain)
|
||||
|
||||
self.idxTree = self.splitMain.indexOf(self.treePane)
|
||||
self.idxMain = self.splitMain.indexOf(self.tabWidget)
|
||||
self.idxEditor = self.splitDocs.indexOf(self.docEditor)
|
||||
@@ -167,8 +165,8 @@ class GuiMain(QMainWindow):
|
||||
|
||||
# Set Main Window Elements
|
||||
self.setMenuBar(self.mainMenu)
|
||||
self.setCentralWidget(self.splitMain)
|
||||
self.setStatusBar(self.statusBar)
|
||||
self.statusBar.setStatus("Ready")
|
||||
|
||||
# Finalise Initialisation
|
||||
##########################
|
||||
@@ -222,6 +220,7 @@ class GuiMain(QMainWindow):
|
||||
self.manageProjects()
|
||||
|
||||
logger.debug("novelWriter is ready ...")
|
||||
self.statusBar.setStatus("novelWriter is ready ...")
|
||||
|
||||
return
|
||||
|
||||
@@ -348,9 +347,7 @@ class GuiMain(QMainWindow):
|
||||
return saveOK
|
||||
|
||||
def openProject(self, projFile):
|
||||
"""Open a project. The parameter projFile is passed from the
|
||||
open recent projects menu, and must be set to be forwarded to
|
||||
the project class. Otherwise, we just return.
|
||||
"""Open a project from a projFile path.
|
||||
"""
|
||||
if projFile is None:
|
||||
return False
|
||||
@@ -365,43 +362,47 @@ class GuiMain(QMainWindow):
|
||||
|
||||
# Try to open the project
|
||||
if not self.theProject.openProject(projFile):
|
||||
if self.theProject.lockedBy is not None:
|
||||
if self.mainConf.showGUI:
|
||||
try:
|
||||
lockDetails = (
|
||||
"<br><br>The project was locked by the computer "
|
||||
"'%s' (%s %s), last active on %s"
|
||||
) % (
|
||||
self.theProject.lockedBy[0],
|
||||
self.theProject.lockedBy[1],
|
||||
self.theProject.lockedBy[2],
|
||||
datetime.fromtimestamp(
|
||||
int(self.theProject.lockedBy[3])
|
||||
).strftime("%x %X")
|
||||
)
|
||||
except:
|
||||
lockDetails = ""
|
||||
# The project open failed.
|
||||
|
||||
msgBox = QMessageBox()
|
||||
msgRes = msgBox.warning(
|
||||
self, "Project Locked", (
|
||||
"The project is already open by another instance of novelWriter, and "
|
||||
"is therefore locked. Override lock and continue anyway?<br><br>"
|
||||
"Note: If the program or the computer previously crashed, the lock "
|
||||
"can safely be overridden. If, however, another instance of "
|
||||
"novelWriter has the project open, overriding the lock may corrupt "
|
||||
"the project, and is not recommended.%s"
|
||||
) % lockDetails,
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.No
|
||||
)
|
||||
if msgRes == QMessageBox.Yes:
|
||||
if not self.theProject.openProject(projFile, overrideLock=True):
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
if self.theProject.lockedBy is None:
|
||||
# The project is not locked, so failed for some other
|
||||
# reason handled by the project class.
|
||||
return False
|
||||
|
||||
if self.mainConf.showGUI:
|
||||
try:
|
||||
lockDetails = (
|
||||
"<br><br>The project was locked by the computer "
|
||||
"'%s' (%s %s), last active on %s"
|
||||
) % (
|
||||
self.theProject.lockedBy[0],
|
||||
self.theProject.lockedBy[1],
|
||||
self.theProject.lockedBy[2],
|
||||
datetime.fromtimestamp(
|
||||
int(self.theProject.lockedBy[3])
|
||||
).strftime("%x %X")
|
||||
)
|
||||
except:
|
||||
lockDetails = ""
|
||||
|
||||
msgBox = QMessageBox()
|
||||
msgRes = msgBox.warning(
|
||||
self, "Project Locked", (
|
||||
"The project is already open by another instance of novelWriter, and "
|
||||
"is therefore locked. Override lock and continue anyway?<br><br>"
|
||||
"Note: If the program or the computer previously crashed, the lock "
|
||||
"can safely be overridden. If, however, another instance of "
|
||||
"novelWriter has the project open, overriding the lock may corrupt "
|
||||
"the project, and is not recommended.%s"
|
||||
) % lockDetails,
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.No
|
||||
)
|
||||
if msgRes == QMessageBox.Yes:
|
||||
if not self.theProject.openProject(projFile, overrideLock=True):
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
# Project is loaded
|
||||
self.hasProject = True
|
||||
|
||||
@@ -570,7 +571,7 @@ class GuiMain(QMainWindow):
|
||||
dlgOpt = QFileDialog.Options()
|
||||
dlgOpt |= QFileDialog.DontUseNativeDialog
|
||||
inPath = QFileDialog.getOpenFileName(
|
||||
self,"Import File",lastPath,options=dlgOpt,filter=";;".join(extFilter)
|
||||
self, "Import File", lastPath, options=dlgOpt, filter=";;".join(extFilter)
|
||||
)
|
||||
if inPath:
|
||||
loadFile = inPath[0]
|
||||
@@ -582,7 +583,7 @@ class GuiMain(QMainWindow):
|
||||
|
||||
theText = None
|
||||
try:
|
||||
with open(loadFile,mode="rt",encoding="utf8") as inFile:
|
||||
with open(loadFile, mode="rt", encoding="utf8") as inFile:
|
||||
theText = inFile.read()
|
||||
self.mainConf.setLastPath(loadFile)
|
||||
except Exception as e:
|
||||
@@ -602,7 +603,7 @@ class GuiMain(QMainWindow):
|
||||
if not self.docEditor.isEmpty():
|
||||
if self.mainConf.showGUI:
|
||||
msgBox = QMessageBox()
|
||||
msgRes = msgBox.question(self, "Import Document",(
|
||||
msgRes = msgBox.question(self, "Import Document", (
|
||||
"Importing the file will overwrite the current content of the document. "
|
||||
"Do you want to proceed?"
|
||||
))
|
||||
@@ -917,6 +918,8 @@ class GuiMain(QMainWindow):
|
||||
return True
|
||||
|
||||
def setFocus(self, paneNo):
|
||||
"""Switch focus to one of the three main gUi panes.
|
||||
"""
|
||||
if paneNo == 1:
|
||||
self.treeView.setFocus()
|
||||
elif paneNo == 2:
|
||||
@@ -926,6 +929,8 @@ class GuiMain(QMainWindow):
|
||||
return
|
||||
|
||||
def closeDocEditor(self):
|
||||
"""Close the document edit panel. This does not hide the editor.
|
||||
"""
|
||||
self.closeDocument()
|
||||
self.theProject.setLastEdited(None)
|
||||
return
|
||||
@@ -1059,6 +1064,8 @@ class GuiMain(QMainWindow):
|
||||
return True
|
||||
|
||||
def _setWindowTitle(self, projName=None):
|
||||
"""Set the window title and add the project's working title.
|
||||
"""
|
||||
winTitle = self.mainConf.appName
|
||||
if projName is not None:
|
||||
winTitle += " - %s" % projName
|
||||
@@ -1066,19 +1073,30 @@ class GuiMain(QMainWindow):
|
||||
return True
|
||||
|
||||
def _autoSaveProject(self):
|
||||
if (self.hasProject and self.theProject.projChanged and
|
||||
self.theProject.projPath is not None):
|
||||
"""Triggered by the auto-save project timer to save the project.
|
||||
"""
|
||||
doSave = self.hasProject
|
||||
doSave &= self.theProject.projChanged
|
||||
doSave &= self.theProject.projPath is not None
|
||||
|
||||
if doSave:
|
||||
logger.debug("Autosaving project")
|
||||
self.saveProject(autoSave=True)
|
||||
|
||||
return
|
||||
|
||||
def _autoSaveDocument(self):
|
||||
"""Triggered by the auto-save document timer to save the
|
||||
document.
|
||||
"""
|
||||
if self.hasProject and self.docEditor.docChanged:
|
||||
logger.debug("Autosaving document")
|
||||
self.saveDocument()
|
||||
return
|
||||
|
||||
def _makeStatusIcons(self):
|
||||
"""Generate all the item status icons based on project settings.
|
||||
"""
|
||||
self.statusIcons = {}
|
||||
iPx = self.mainConf.pxInt(32)
|
||||
for sLabel, sCol, _ in self.theProject.statusItems:
|
||||
@@ -1088,6 +1106,9 @@ class GuiMain(QMainWindow):
|
||||
return
|
||||
|
||||
def _makeImportIcons(self):
|
||||
"""Generate all the item importance icons based on project
|
||||
settings.
|
||||
"""
|
||||
self.importIcons = {}
|
||||
iPx = self.mainConf.pxInt(32)
|
||||
for sLabel, sCol, _ in self.theProject.importItems:
|
||||
@@ -1101,6 +1122,9 @@ class GuiMain(QMainWindow):
|
||||
##
|
||||
|
||||
def closeEvent(self, theEvent):
|
||||
"""Capture the closing event of the GUI and call the close
|
||||
function to handle all the close process steps.
|
||||
"""
|
||||
if self.closeMain():
|
||||
theEvent.accept()
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user