Merge branch 'main' into new_project_wizard

This commit is contained in:
Veronica K. B. Olsen
2020-08-09 16:17:40 +02:00
32 changed files with 446 additions and 249 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ from PyQt5.QtCore import (
Qt, QSize, QThread, QTimer, pyqtSlot, QRegExp, QRegularExpression
)
from PyQt5.QtGui import (
QTextCursor, QTextOption, QKeySequence, QFont, QColor, QPalette, QIcon,
QTextCursor, QTextOption, QKeySequence, QFont, QColor, QPalette,
QTextDocument, QCursor, QPixmap
)
from PyQt5.QtWidgets import (
-3
View File
@@ -79,7 +79,6 @@ class GuiDocMerge(QDialog):
self.setLayout(self.outerBox)
self.rejected.connect(self._doClose)
self.show()
self._populateList()
@@ -96,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 = []
@@ -143,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:
+2 -4
View File
@@ -33,6 +33,7 @@ from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QComboBox, QListWidget, QAbstractItemView,
QListWidgetItem, QDialogButtonBox, QLabel
)
from nw.constants import nwAlert, nwItemType, nwItemClass, nwItemLayout
from nw.gui.custom import QHelpLabel
from nw.core import NWDoc
@@ -92,7 +93,6 @@ class GuiDocSplit(QDialog):
self.setLayout(self.outerBox)
self.rejected.connect(self._doClose)
self.show()
self._populateList()
@@ -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()
+2 -2
View File
@@ -29,11 +29,11 @@ import logging
import nw
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QIcon, QPixmap
from PyQt5.QtGui import QFont, QPixmap
from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel
from nw.constants import (
nwLabels, nwItemClass, nwItemType, nwItemLayout, nwUnicode
nwLabels, nwItemClass, nwItemType, nwItemLayout
)
logger = logging.getLogger(__name__)
+2 -2
View File
@@ -28,7 +28,6 @@
import logging
import nw
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QGridLayout, QLineEdit, QComboBox, QLabel,
QDialogButtonBox
@@ -151,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()
@@ -172,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
+21 -30
View File
@@ -28,13 +28,10 @@
import logging
import nw
from os import path
from PyQt5.QtCore import QUrl, QProcess
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QMenuBar, QAction, QMessageBox
from PyQt5.QtWidgets import QMenuBar, QAction
from nw.gui.about import GuiAbout
from nw.constants import nwItemType, nwItemClass, nwDocAction, nwDocInsert
logger = logging.getLogger(__name__)
@@ -150,21 +147,6 @@ class GuiMainMenu(QMenuBar):
self.theProject.setAutoOutline(theMode)
return True
def _showAbout(self):
"""Show the about dialog.
"""
if self.mainConf.showGUI:
msgAbout = GuiAbout(self.theParent)
msgAbout.exec_()
return True
def _showAboutQt(self):
"""Show Qt's own About dialog.
"""
msgBox = QMessageBox()
msgBox.aboutQt(self.theParent,"About Qt")
return True
def _openAssistant(self):
"""Open the documentation in Qt Assistant.
"""
@@ -210,7 +192,8 @@ class GuiMainMenu(QMenuBar):
##
def _buildProjectMenu(self):
"""Assemble the Project menu.
"""
# Project
self.projMenu = self.addMenu("&Project")
@@ -313,7 +296,8 @@ class GuiMainMenu(QMenuBar):
return
def _buildDocumentMenu(self):
"""Assemble the Document menu.
"""
# Document
self.docuMenu = self.addMenu("&Document")
@@ -395,7 +379,8 @@ class GuiMainMenu(QMenuBar):
return
def _buildEditMenu(self):
"""Assemble the Edit menu.
"""
# Edit
self.editMenu = self.addMenu("&Edit")
@@ -457,7 +442,8 @@ class GuiMainMenu(QMenuBar):
return
def _buildViewMenu(self):
"""Assemble the View menu.
"""
# View
self.viewMenu = self.addMenu("&View")
@@ -504,7 +490,8 @@ class GuiMainMenu(QMenuBar):
return
def _buildInsertMenu(self):
"""Assemble the Insert menu.
"""
# Insert
self.insertMenu = self.addMenu("&Insert")
@@ -594,7 +581,8 @@ class GuiMainMenu(QMenuBar):
return
def _buildSearchMenu(self):
"""Assemble the Search menu.
"""
# Search
self.srcMenu = self.addMenu("&Search")
@@ -645,7 +633,8 @@ class GuiMainMenu(QMenuBar):
return
def _buildFormatMenu(self):
"""Assemble the Format menu.
"""
# Format
self.fmtMenu = self.addMenu("&Format")
@@ -750,7 +739,8 @@ class GuiMainMenu(QMenuBar):
return
def _buildToolsMenu(self):
"""Assemble the Tools menu.
"""
# Tools
self.toolsMenu = self.addMenu("&Tools")
@@ -846,20 +836,21 @@ class GuiMainMenu(QMenuBar):
return
def _buildHelpMenu(self):
"""Assemble the Help menu.
"""
# Help
self.helpMenu = self.addMenu("&Help")
# Help > About
self.aAboutNW = QAction("About %s" % self.mainConf.appName, self)
self.aAboutNW.setStatusTip("About %s" % self.mainConf.appName)
self.aAboutNW.triggered.connect(self._showAbout)
self.aAboutNW.triggered.connect(self.theParent.showAboutNWDialog)
self.helpMenu.addAction(self.aAboutNW)
# Help > About Qt5
self.aAboutQt = QAction("About Qt5", self)
self.aAboutQt.setStatusTip("About Qt5")
self.aAboutQt.triggered.connect(self._showAboutQt)
self.aAboutQt.triggered.connect(self.theParent.showAboutQtDialog)
self.helpMenu.addAction(self.aAboutQt)
# Help > Separator
+4
View File
@@ -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
##
+2 -1
View File
@@ -30,7 +30,8 @@ import nw
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QScrollArea, QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel, QSizePolicy
QScrollArea, QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel,
QSizePolicy
)
from nw.constants import nwLabels, nwKeyWords
+17 -7
View File
@@ -71,8 +71,6 @@ class GuiPreferences(PagedDialog):
self.buttonBox.rejected.connect(self._doClose)
self.addControls(self.buttonBox)
self.show()
logger.debug("GuiPreferences initialisation complete")
return
@@ -82,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
@@ -117,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
@@ -286,7 +288,8 @@ class GuiConfigEditGeneralTab(QWidget):
return
def saveValues(self):
"""Save the values set for this tab.
"""
validEntries = True
needsRestart = False
@@ -516,7 +519,8 @@ class GuiConfigEditLayoutTab(QWidget):
return
def saveValues(self):
"""Save the values set for this tab.
"""
validEntries = True
needsRestart = False
@@ -682,7 +686,8 @@ class GuiConfigEditEditingTab(QWidget):
return
def saveValues(self):
"""Save the values set for this tab.
"""
validEntries = True
needsRestart = False
@@ -713,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)
@@ -720,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
@@ -904,7 +913,8 @@ class GuiConfigEditAutoReplaceTab(QWidget):
return
def saveValues(self):
"""Save the values set for this tab.
"""
validEntries = True
needsRestart = False
+3
View File
@@ -153,6 +153,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)
@@ -161,6 +162,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
View File
@@ -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():
+30 -4
View File
@@ -30,15 +30,15 @@ import logging
import nw
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QFont, QColor, QIcon
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
qApp, QTreeWidget, QTreeWidgetItem, QAbstractItemView, QMessageBox,
QHeaderView, QMenu, QAction
QMenu, QAction
)
from nw.core import NWDoc
from nw.constants import (
nwLabels, nwItemType, nwItemClass, nwItemLayout, nwAlert, nwUnicode
nwLabels, nwItemType, nwItemClass, nwItemLayout, nwAlert
)
logger = logging.getLogger(__name__)
@@ -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):
+3 -3
View File
@@ -30,8 +30,8 @@ import nw
from time import time
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QColor, QPixmap, QFont, QPainter
from PyQt5.QtCore import QTimer
from PyQt5.QtGui import QColor, QPainter
from PyQt5.QtWidgets import qApp, QStatusBar, QLabel, QAbstractButton
from nw.core import NWSpellCheck
@@ -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 -52
View File
@@ -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]))
@@ -548,8 +552,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 = {
@@ -616,13 +620,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"
@@ -708,7 +712,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 = ""
+36 -10
View File
@@ -36,7 +36,7 @@ from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QPixmap
from PyQt5.QtWidgets import (
qApp, QDialog, QTreeWidget, QTreeWidgetItem, QDialogButtonBox, QGridLayout,
QLabel, QGroupBox, QMenu, QAction, QFileDialog
QLabel, QGroupBox, QMenu, QAction, QFileDialog, QSpinBox, QHBoxLayout
)
from nw.constants import nwConst, nwFiles, nwAlert
@@ -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)
@@ -207,11 +207,31 @@ class GuiWritingStats(QDialog):
self.filterForm.addWidget(self.groupByDay, 4, 1)
self.filterForm.setRowStretch(5, 1)
# Settings
self.histMax = QSpinBox(self)
self.histMax.setMinimum(100)
self.histMax.setMaximum(100000)
self.histMax.setSingleStep(100)
self.histMax.setValue(
self.optState.getInt("GuiWritingStats", "histMax", 2000)
)
self.histMax.valueChanged.connect(self._updateListBox)
self.optsBox = QHBoxLayout()
self.optsBox.addStretch(1)
self.optsBox.addWidget(QLabel("Word count cap for the histogram"), 0)
self.optsBox.addWidget(self.histMax, 0)
# Buttons
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
self.buttonBox = QDialogButtonBox()
self.buttonBox.rejected.connect(self._doClose)
self.btnClose = self.buttonBox.addButton(QDialogButtonBox.Close)
self.btnClose.setAutoDefault(False)
self.btnSave = self.buttonBox.addButton("Save As", QDialogButtonBox.ActionRole)
self.btnSave.setAutoDefault(False)
self.saveMenu = QMenu(self)
self.btnSave.setMenu(self.saveMenu)
@@ -226,9 +246,10 @@ class GuiWritingStats(QDialog):
# Assemble
self.outerBox = QGridLayout()
self.outerBox.addWidget(self.listBox, 0, 0, 1, 2)
self.outerBox.addWidget(self.infoBox, 1, 0)
self.outerBox.addWidget(self.filterBox, 1, 1)
self.outerBox.addWidget(self.buttonBox, 2, 0, 1, 2)
self.outerBox.addLayout(self.optsBox, 1, 0, 1, 2)
self.outerBox.addWidget(self.infoBox, 2, 0)
self.outerBox.addWidget(self.filterBox, 2, 1)
self.outerBox.addWidget(self.buttonBox, 3, 0, 1, 2)
self.outerBox.setRowStretch(0, 1)
self.setLayout(self.outerBox)
@@ -262,6 +283,7 @@ class GuiWritingStats(QDialog):
hideZeros = self.hideZeros.isChecked()
hideNegative = self.hideNegative.isChecked()
groupByDay = self.groupByDay.isChecked()
histMax = self.histMax.value()
self.optState.setValue("GuiWritingStats", "winWidth", winWidth)
self.optState.setValue("GuiWritingStats", "winHeight", winHeight)
@@ -275,6 +297,7 @@ class GuiWritingStats(QDialog):
self.optState.setValue("GuiWritingStats", "hideZeros", hideZeros)
self.optState.setValue("GuiWritingStats", "hideNegative", hideNegative)
self.optState.setValue("GuiWritingStats", "groupByDay", groupByDay)
self.optState.setValue("GuiWritingStats", "histMax", histMax)
self.optState.saveSettings()
self.close()
@@ -438,8 +461,10 @@ class GuiWritingStats(QDialog):
return True
def _updateListBox(self):
"""Load/reload the content of the list box.
def _updateListBox(self, dummyVar=None):
"""Load/reload the content of the list box. The dummyVar
variable captures the variable sent from the widgets connecting
to it and discards it.
"""
self.listBox.clear()
self.timeFilter = 0.0
@@ -449,6 +474,7 @@ class GuiWritingStats(QDialog):
hideZeros = self.hideZeros.isChecked()
hideNegative = self.hideNegative.isChecked()
groupByDay = self.groupByDay.isChecked()
histMax = self.histMax.value()
# Group the data
if groupByDay:
@@ -509,7 +535,7 @@ class GuiWritingStats(QDialog):
sStart = dStart.strftime(nwConst.tStampFmt)
self.filterData.append((dStart, sStart, sDiff, dwTotal, wcNovel, wcNotes))
listMax = max(listMax, dwTotal)
listMax = min(max(listMax, dwTotal), histMax)
pcTotal = wcTotal
# Populate the list
@@ -522,7 +548,7 @@ class GuiWritingStats(QDialog):
if nWords > 0 and listMax > 0:
theBar = self.barImage.scaled(
int(200*nWords/listMax),
int(200*min(nWords, histMax)/listMax),
self.barHeight,
Qt.IgnoreAspectRatio,
Qt.FastTransformation