Visible columns and column width in outline is now saved and loaded
This commit is contained in:
@@ -20,15 +20,15 @@ class nwConst():
|
|||||||
|
|
||||||
class nwFiles():
|
class nwFiles():
|
||||||
|
|
||||||
APP_ICON = "novelWriter.svg"
|
APP_ICON = "novelWriter.svg"
|
||||||
PROJ_FILE = "nwProject.nwx"
|
PROJ_FILE = "nwProject.nwx"
|
||||||
PROJ_COUNT = "projCount.txt"
|
PROJ_COUNT = "projCount.txt"
|
||||||
PROJ_DICT = "wordlist.txt"
|
PROJ_DICT = "wordlist.txt"
|
||||||
SESS_INFO = "sessionInfo.log"
|
SESS_INFO = "sessionInfo.log"
|
||||||
INDEX_FILE = "tagsIndex.json"
|
INDEX_FILE = "tagsIndex.json"
|
||||||
EXPORT_OPT = "exportOptions.json"
|
EXPORT_OPT = "exportOptions.json"
|
||||||
TLINE_OPT = "timelineOptions.json"
|
OUTLINE_OPT = "outlineOptions.json"
|
||||||
SLOG_OPT = "sessionLogOptions.json"
|
SLOG_OPT = "sessionLogOptions.json"
|
||||||
|
|
||||||
# END Class nwFiles
|
# END Class nwFiles
|
||||||
|
|
||||||
|
|||||||
@@ -683,7 +683,7 @@ class ExportLastState(OptLastState):
|
|||||||
|
|
||||||
def __init__(self, theProject, theFile):
|
def __init__(self, theProject, theFile):
|
||||||
OptLastState.__init__(self, theProject, theFile)
|
OptLastState.__init__(self, theProject, theFile)
|
||||||
self.theState = {
|
self.theState = {
|
||||||
"wNovel" : True,
|
"wNovel" : True,
|
||||||
"wNotes" : False,
|
"wNotes" : False,
|
||||||
"eFormat" : 1,
|
"eFormat" : 1,
|
||||||
|
|||||||
+92
-32
@@ -16,12 +16,13 @@ import nw
|
|||||||
from os import path
|
from os import path
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt, QByteArray
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QWidget, QVBoxLayout, QTreeWidget, QTreeWidgetItem
|
QWidget, QVBoxLayout, QTreeWidget, QTreeWidgetItem
|
||||||
)
|
)
|
||||||
|
|
||||||
from nw.constants import nwItemLayout, nwKeyWords, nwLabels
|
from nw.tools import OptLastState
|
||||||
|
from nw.constants import nwItemLayout, nwKeyWords, nwLabels, nwFiles
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -44,12 +45,7 @@ class GuiProjectOutline(QWidget):
|
|||||||
I_ENTITY = 14
|
I_ENTITY = 14
|
||||||
I_CUSTOM = 15
|
I_CUSTOM = 15
|
||||||
|
|
||||||
COL_ORDER = [
|
COL_MAX = 15
|
||||||
I_TITLE, I_LEVEL, I_LABEL, I_LINE,
|
|
||||||
I_WCOUNT, I_CCOUNT, I_PCOUNT, I_SYNOP,
|
|
||||||
I_POV, I_CHAR, I_PLOT, I_TIME,
|
|
||||||
I_WORLD, I_OBJECT, I_ENTITY, I_CUSTOM,
|
|
||||||
]
|
|
||||||
|
|
||||||
COL_LABELS = {
|
COL_LABELS = {
|
||||||
I_TITLE : "Title",
|
I_TITLE : "Title",
|
||||||
@@ -79,6 +75,7 @@ class GuiProjectOutline(QWidget):
|
|||||||
self.theParent = theParent
|
self.theParent = theParent
|
||||||
self.theProject = theProject
|
self.theProject = theProject
|
||||||
self.theIndex = self.theParent.theIndex
|
self.theIndex = self.theParent.theIndex
|
||||||
|
self.optState = OutlineLastState(self.theProject,nwFiles.OUTLINE_OPT)
|
||||||
|
|
||||||
self.showWords = True
|
self.showWords = True
|
||||||
self.showSynopsis = True
|
self.showSynopsis = True
|
||||||
@@ -86,9 +83,18 @@ class GuiProjectOutline(QWidget):
|
|||||||
|
|
||||||
self.outerBox = QVBoxLayout()
|
self.outerBox = QVBoxLayout()
|
||||||
self.mainTree = QTreeWidget()
|
self.mainTree = QTreeWidget()
|
||||||
self.treeCols = self.COL_ORDER
|
|
||||||
self.lastBuild = 0
|
self.lastBuild = 0
|
||||||
self.treeMap = {}
|
self.treeMap = {}
|
||||||
|
self.treeCols = {
|
||||||
|
"order" : [
|
||||||
|
self.I_TITLE, self.I_LABEL,
|
||||||
|
self.I_WCOUNT, self.I_POV,
|
||||||
|
self.I_CHAR, self.I_PLOT,
|
||||||
|
self.I_WORLD, self.I_SYNOP
|
||||||
|
],
|
||||||
|
"width" : [150, 100, 80, 100, 100, 100, 100, 300],
|
||||||
|
}
|
||||||
|
self.colIndex = {}
|
||||||
|
|
||||||
self.outerBox.addWidget(self.mainTree)
|
self.outerBox.addWidget(self.mainTree)
|
||||||
self.outerBox.setContentsMargins(0,0,0,0)
|
self.outerBox.setContentsMargins(0,0,0,0)
|
||||||
@@ -98,19 +104,57 @@ class GuiProjectOutline(QWidget):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def saveHeaderState(self):
|
||||||
|
|
||||||
|
colW = []
|
||||||
|
for iCol in range(self.mainTree.columnCount()):
|
||||||
|
colW.append(self.mainTree.columnWidth(iCol))
|
||||||
|
|
||||||
|
self.treeCols["width"] = colW
|
||||||
|
self.optState.setSetting("headState", self.treeCols)
|
||||||
|
self.optState.saveSettings()
|
||||||
|
return
|
||||||
|
|
||||||
|
def loadHeaderState(self):
|
||||||
|
self.optState.loadSettings()
|
||||||
|
treeCols = self.optState.getSetting("headState")
|
||||||
|
|
||||||
|
if "order" not in treeCols.keys(): return
|
||||||
|
if not isinstance(treeCols["order"], list): return
|
||||||
|
if len(treeCols["order"]) == 0: return
|
||||||
|
|
||||||
|
self.treeCols["order"] = []
|
||||||
|
for colID in treeCols["order"]:
|
||||||
|
if colID >= 0 and colID <= self.COL_MAX:
|
||||||
|
self.treeCols["order"].append(colID)
|
||||||
|
|
||||||
|
if "width" in treeCols.keys():
|
||||||
|
if isinstance(treeCols["width"],list):
|
||||||
|
self.treeCols["width"] = treeCols["width"]
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def populateTree(self):
|
def populateTree(self):
|
||||||
|
|
||||||
|
self.loadHeaderState()
|
||||||
|
|
||||||
theLabels = []
|
theLabels = []
|
||||||
for n in self.treeCols:
|
for i, n in enumerate(self.treeCols["order"]):
|
||||||
theLabels.append(self.COL_LABELS[n])
|
theLabels.append(self.COL_LABELS[n])
|
||||||
|
self.colIndex[n] = i
|
||||||
|
|
||||||
self.mainTree.clear()
|
self.mainTree.clear()
|
||||||
self.mainTree.setHeaderLabels(theLabels)
|
self.mainTree.setHeaderLabels(theLabels)
|
||||||
|
for n, colW in enumerate(self.treeCols["width"]):
|
||||||
|
self.mainTree.setColumnWidth(n,colW)
|
||||||
|
|
||||||
treeHead = self.mainTree.headerItem()
|
treeHead = self.mainTree.headerItem()
|
||||||
treeHead.setTextAlignment(self.I_CCOUNT,Qt.AlignRight)
|
if self.I_CCOUNT in self.colIndex:
|
||||||
treeHead.setTextAlignment(self.I_WCOUNT,Qt.AlignRight)
|
treeHead.setTextAlignment(self.colIndex[self.I_CCOUNT],Qt.AlignRight)
|
||||||
treeHead.setTextAlignment(self.I_PCOUNT,Qt.AlignRight)
|
if self.I_WCOUNT in self.colIndex:
|
||||||
|
treeHead.setTextAlignment(self.colIndex[self.I_WCOUNT],Qt.AlignRight)
|
||||||
|
if self.I_PCOUNT in self.colIndex:
|
||||||
|
treeHead.setTextAlignment(self.colIndex[self.I_PCOUNT],Qt.AlignRight)
|
||||||
|
|
||||||
currTitle = None
|
currTitle = None
|
||||||
currChapter = None
|
currChapter = None
|
||||||
@@ -180,28 +224,44 @@ class GuiProjectOutline(QWidget):
|
|||||||
novIdx = self.theIndex.novelIndex[tHandle][sTitle]
|
novIdx = self.theIndex.novelIndex[tHandle][sTitle]
|
||||||
|
|
||||||
newItem = QTreeWidgetItem()
|
newItem = QTreeWidgetItem()
|
||||||
newItem.setText(self.I_TITLE, novIdx["title"])
|
self._setItemText(newItem, self.I_TITLE, novIdx["title"])
|
||||||
newItem.setText(self.I_LEVEL, novIdx["level"])
|
self._setItemText(newItem, self.I_LEVEL, novIdx["level"])
|
||||||
newItem.setText(self.I_LABEL, nwItem.itemName)
|
self._setItemText(newItem, self.I_LABEL, nwItem.itemName)
|
||||||
newItem.setText(self.I_LINE, sTitle[1:])
|
self._setItemText(newItem, self.I_LINE, sTitle[1:])
|
||||||
|
self._setItemText(newItem, self.I_SYNOP, novIdx["synopsis"])
|
||||||
newItem.setText(self.I_CCOUNT, str(novIdx["cCount"]))
|
self._setItemText(newItem, self.I_CCOUNT, str(novIdx["cCount"]), True)
|
||||||
newItem.setText(self.I_WCOUNT, str(novIdx["wCount"]))
|
self._setItemText(newItem, self.I_WCOUNT, str(novIdx["wCount"]), True)
|
||||||
newItem.setText(self.I_PCOUNT, str(novIdx["pCount"]))
|
self._setItemText(newItem, self.I_PCOUNT, str(novIdx["pCount"]), True)
|
||||||
newItem.setTextAlignment(self.I_CCOUNT,Qt.AlignRight)
|
|
||||||
newItem.setTextAlignment(self.I_WCOUNT,Qt.AlignRight)
|
|
||||||
newItem.setTextAlignment(self.I_PCOUNT,Qt.AlignRight)
|
|
||||||
|
|
||||||
theRefs = self.theIndex.getReferences(tHandle, sTitle)
|
theRefs = self.theIndex.getReferences(tHandle, sTitle)
|
||||||
newItem.setText(self.I_POV, ", ".join(theRefs[nwKeyWords.POV_KEY]))
|
self._setItemText(newItem, self.I_POV, ", ".join(theRefs[nwKeyWords.POV_KEY]))
|
||||||
newItem.setText(self.I_CHAR, ", ".join(theRefs[nwKeyWords.CHAR_KEY]))
|
self._setItemText(newItem, self.I_CHAR, ", ".join(theRefs[nwKeyWords.CHAR_KEY]))
|
||||||
newItem.setText(self.I_PLOT, ", ".join(theRefs[nwKeyWords.PLOT_KEY]))
|
self._setItemText(newItem, self.I_PLOT, ", ".join(theRefs[nwKeyWords.PLOT_KEY]))
|
||||||
newItem.setText(self.I_TIME, ", ".join(theRefs[nwKeyWords.TIME_KEY]))
|
self._setItemText(newItem, self.I_TIME, ", ".join(theRefs[nwKeyWords.TIME_KEY]))
|
||||||
newItem.setText(self.I_WORLD, ", ".join(theRefs[nwKeyWords.WORLD_KEY]))
|
self._setItemText(newItem, self.I_WORLD, ", ".join(theRefs[nwKeyWords.WORLD_KEY]))
|
||||||
newItem.setText(self.I_OBJECT, ", ".join(theRefs[nwKeyWords.OBJECT_KEY]))
|
self._setItemText(newItem, self.I_OBJECT, ", ".join(theRefs[nwKeyWords.OBJECT_KEY]))
|
||||||
newItem.setText(self.I_ENTITY, ", ".join(theRefs[nwKeyWords.ENTITY_KEY]))
|
self._setItemText(newItem, self.I_ENTITY, ", ".join(theRefs[nwKeyWords.ENTITY_KEY]))
|
||||||
newItem.setText(self.I_CUSTOM, ", ".join(theRefs[nwKeyWords.CUSTOM_KEY]))
|
self._setItemText(newItem, self.I_CUSTOM, ", ".join(theRefs[nwKeyWords.CUSTOM_KEY]))
|
||||||
|
|
||||||
return newItem
|
return newItem
|
||||||
|
|
||||||
|
def _setItemText(self, tItem, colID, theText, rAlign=False):
|
||||||
|
if colID in self.colIndex:
|
||||||
|
tItem.setText(self.colIndex[colID], theText)
|
||||||
|
if rAlign:
|
||||||
|
tItem.setTextAlignment(self.colIndex[colID],Qt.AlignRight)
|
||||||
|
return
|
||||||
|
|
||||||
# END Class GuiProjectOutline
|
# END Class GuiProjectOutline
|
||||||
|
|
||||||
|
class OutlineLastState(OptLastState):
|
||||||
|
|
||||||
|
def __init__(self, theProject, theFile):
|
||||||
|
OptLastState.__init__(self, theProject, theFile)
|
||||||
|
self.theState = {
|
||||||
|
"headState" : {},
|
||||||
|
}
|
||||||
|
self.dictOpt = ("headState")
|
||||||
|
return
|
||||||
|
|
||||||
|
# END Class OutlineLastState
|
||||||
|
|||||||
@@ -679,6 +679,8 @@ class GuiMain(QMainWindow):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
logger.info("Exiting %s" % nw.__package__)
|
logger.info("Exiting %s" % nw.__package__)
|
||||||
|
self.projView.saveHeaderState()
|
||||||
|
|
||||||
self.closeProject(True)
|
self.closeProject(True)
|
||||||
|
|
||||||
self.mainConf.setTreeColWidths(self.treeView.getColumnSizes())
|
self.mainConf.setTreeColWidths(self.treeView.getColumnSizes())
|
||||||
|
|||||||
@@ -28,12 +28,21 @@ class OptLastState():
|
|||||||
self.theState = {}
|
self.theState = {}
|
||||||
self.stringOpt = ()
|
self.stringOpt = ()
|
||||||
self.boolOpt = ()
|
self.boolOpt = ()
|
||||||
|
self.dictOpt = ()
|
||||||
self.intOpt = ()
|
self.intOpt = ()
|
||||||
return
|
return
|
||||||
|
|
||||||
def loadSettings(self):
|
def loadSettings(self):
|
||||||
|
|
||||||
|
if self.theProject.projMeta is None or self.theFile is None:
|
||||||
|
logger.error("Cannot load file '%s' to path '%s'" % (
|
||||||
|
str(self.theFile), str(self.theProject.projMeta)
|
||||||
|
))
|
||||||
|
return False
|
||||||
|
|
||||||
stateFile = path.join(self.theProject.projMeta,self.theFile)
|
stateFile = path.join(self.theProject.projMeta,self.theFile)
|
||||||
theState = {}
|
theState = {}
|
||||||
|
|
||||||
if path.isfile(stateFile):
|
if path.isfile(stateFile):
|
||||||
logger.debug("Loading options file")
|
logger.debug("Loading options file")
|
||||||
try:
|
try:
|
||||||
@@ -44,11 +53,20 @@ class OptLastState():
|
|||||||
logger.error("Failed to load options file")
|
logger.error("Failed to load options file")
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
for anOpt in theState:
|
for anOpt in theState:
|
||||||
self.theState[anOpt] = theState[anOpt]
|
self.theState[anOpt] = theState[anOpt]
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def saveSettings(self):
|
def saveSettings(self):
|
||||||
|
|
||||||
|
if self.theProject.projMeta is None or self.theFile is None:
|
||||||
|
logger.error("Cannot save file '%s' to path '%s'" % (
|
||||||
|
str(self.theFile), str(self.theProject.projMeta)
|
||||||
|
))
|
||||||
|
return False
|
||||||
|
|
||||||
stateFile = path.join(self.theProject.projMeta,self.theFile)
|
stateFile = path.join(self.theProject.projMeta,self.theFile)
|
||||||
logger.debug("Saving options file")
|
logger.debug("Saving options file")
|
||||||
try:
|
try:
|
||||||
@@ -58,6 +76,7 @@ class OptLastState():
|
|||||||
logger.error("Failed to save options file")
|
logger.error("Failed to save options file")
|
||||||
logger.error(str(e))
|
logger.error(str(e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def setSetting(self, setName, setValue):
|
def setSetting(self, setName, setValue):
|
||||||
@@ -72,6 +91,11 @@ class OptLastState():
|
|||||||
return checkString(self.theState[setName],self.theState[setName],False)
|
return checkString(self.theState[setName],self.theState[setName],False)
|
||||||
elif setName in self.boolOpt:
|
elif setName in self.boolOpt:
|
||||||
return checkBool(self.theState[setName],self.theState[setName],False)
|
return checkBool(self.theState[setName],self.theState[setName],False)
|
||||||
|
elif setName in self.dictOpt:
|
||||||
|
if isinstance(self.theState[setName], dict):
|
||||||
|
return self.theState[setName]
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
elif setName in self.intOpt:
|
elif setName in self.intOpt:
|
||||||
return checkInt(self.theState[setName],self.theState[setName],False)
|
return checkInt(self.theState[setName],self.theState[setName],False)
|
||||||
return None
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user