Added filters to timeline view GUI

This commit is contained in:
Veronica K. B. Olsen
2019-10-21 20:57:46 +02:00
parent 3aa07e9b33
commit 1434c2bdf3
5 changed files with 119 additions and 21 deletions
+100 -15
View File
@@ -17,12 +17,13 @@ from os import path
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QColor, QPixmap
from PyQt5.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem,
QDialogButtonBox, QLabel, QPushButton, QHeaderView
QDialog, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem, QDialogButtonBox, QLabel,
QPushButton, QHeaderView, QGridLayout, QGroupBox, QCheckBox
)
from nw.tools.optlaststate import OptLastState
from nw.constants import nwFiles
from nw.enum import nwItemClass
logger = logging.getLogger(__name__)
@@ -45,6 +46,8 @@ class GuiTimeLineView(QDialog):
self.numCols = 0
self.outerBox = QVBoxLayout()
self.filterBox = QVBoxLayout()
self.centreBox = QHBoxLayout()
self.bottomBox = QHBoxLayout()
self.setWindowTitle("Timeline View")
@@ -55,6 +58,7 @@ class GuiTimeLineView(QDialog):
self.optState.getSetting("winHeight")
)
# TimeLine Table
self.mainTable = QTableWidget()
self.mainTable.setGridStyle(Qt.NoPen)
@@ -66,6 +70,41 @@ class GuiTimeLineView(QDialog):
self.vHeader.setSectionResizeMode(QHeaderView.ResizeToContents)
self.mainTable.setVerticalHeader(self.vHeader)
# Option Box
self.optFilter = QGroupBox("Include Tags", self)
self.optFilterGrid = QGridLayout(self)
self.optFilter.setLayout(self.optFilterGrid)
self.filterPlot = QCheckBox("Plot tags", self)
self.filterPlot.setChecked(self.optState.getSetting("fPlot"))
self.filterChar = QCheckBox("Character tags", self)
self.filterChar.setChecked(self.optState.getSetting("fChar"))
self.filterWorld = QCheckBox("Location tags", self)
self.filterWorld.setChecked(self.optState.getSetting("fWorld"))
self.filterTime = QCheckBox("Timeline tags", self)
self.filterTime.setChecked(self.optState.getSetting("fTime"))
self.filterObject = QCheckBox("Object tags", self)
self.filterObject.setChecked(self.optState.getSetting("fObject"))
self.filterCustom = QCheckBox("Custom tags", self)
self.filterCustom.setChecked(self.optState.getSetting("fCustom"))
self.optFilterGrid.addWidget(self.filterPlot, 0, 1)
self.optFilterGrid.addWidget(self.filterChar, 1, 1)
self.optFilterGrid.addWidget(self.filterWorld, 2, 1)
self.optFilterGrid.addWidget(self.filterTime, 3, 1)
self.optFilterGrid.addWidget(self.filterObject, 4, 1)
self.optFilterGrid.addWidget(self.filterCustom, 5, 1)
self.optHide = QGroupBox("Filters", self)
self.optHideGrid = QGridLayout(self)
self.optHide.setLayout(self.optHideGrid)
self.hideUnused = QCheckBox("Hide unused", self)
self.hideUnused.setChecked(self.optState.getSetting("hUnused"))
self.optHideGrid.addWidget(self.hideUnused, 0, 1)
# Button Box
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
self.buttonBox.rejected.connect(self._doClose)
@@ -75,14 +114,21 @@ class GuiTimeLineView(QDialog):
self.btnRefresh = QPushButton("Refresh Table")
self.btnRefresh.clicked.connect(self._buildNovelList)
self.setLayout(self.outerBox)
self.outerBox.addWidget(self.mainTable)
self.outerBox.addLayout(self.bottomBox)
self.bottomBox.addWidget(self.btnRebuild)
self.bottomBox.addWidget(self.btnRefresh)
self.bottomBox.addStretch()
self.bottomBox.addWidget(self.buttonBox)
# Assemble
self.filterBox.addWidget(self.optFilter)
self.filterBox.addWidget(self.optHide)
self.filterBox.addStretch()
self.centreBox.addWidget(self.mainTable)
self.centreBox.addLayout(self.filterBox)
self.outerBox.addLayout(self.centreBox)
self.outerBox.addLayout(self.bottomBox)
self.setLayout(self.outerBox)
self._buildNovelList()
self.buttonBox.setFocus()
@@ -94,13 +140,28 @@ class GuiTimeLineView(QDialog):
def _buildNovelList(self):
self.theIndex.buildNovelList()
self.numRows = len(self.theIndex.novelList)
self.numCols = len(self.theIndex.tagIndex.keys())
self.mainTable.clear()
self.theIndex.buildNovelList()
self.numRows = len(self.theIndex.novelList)
self.mainTable.setRowCount(self.numRows)
self.mainTable.setColumnCount(self.numCols)
theFilters = {}
theFilters["exClass"] = []
theFilters["hUnused"] = self.hideUnused.isChecked()
if not self.filterPlot.isChecked():
theFilters["exClass"].append(nwItemClass.PLOT)
if not self.filterChar.isChecked():
theFilters["exClass"].append(nwItemClass.CHARACTER)
if not self.filterWorld.isChecked():
theFilters["exClass"].append(nwItemClass.WORLD)
if not self.filterTime.isChecked():
theFilters["exClass"].append(nwItemClass.TIMELINE)
if not self.filterObject.isChecked():
theFilters["exClass"].append(nwItemClass.OBJECT)
if not self.filterCustom.isChecked():
theFilters["exClass"].append(nwItemClass.CUSTOM)
for n in range(len(self.theIndex.novelList)):
iDepth = self.theIndex.novelList[n][1]
@@ -108,14 +169,17 @@ class GuiTimeLineView(QDialog):
newItem = QTableWidgetItem("%s%s " % (" "*iDepth,iTitle))
self.mainTable.setVerticalHeaderItem(n, newItem)
theMap = self.theIndex.buildTagNovelMap(self.theIndex.tagIndex.keys())
nCol = 0
theMap = self.theIndex.buildTagNovelMap(self.theIndex.tagIndex.keys(), theFilters)
self.numCols = len(theMap.keys())
self.mainTable.setColumnCount(self.numCols)
nCol = 0
for theTag, theCols in theMap.items():
newItem = QTableWidgetItem(" %s " % theTag)
self.mainTable.setHorizontalHeaderItem(nCol, newItem)
for n in range(len(theCols)):
if theCols[n] == 1:
pxNew = QPixmap(10,10)
pxNew = QPixmap(10,10)
pxNew.fill(QColor(0,120,0))
lblNew = QLabel()
lblNew.setPixmap(pxNew)
@@ -123,7 +187,7 @@ class GuiTimeLineView(QDialog):
lblNew.setAttribute(Qt.WA_TranslucentBackground)
self.mainTable.setCellWidget(n, nCol, lblNew)
elif theCols[n] == 2:
pxNew = QPixmap(10,10)
pxNew = QPixmap(10,10)
pxNew.fill(QColor(0,0,120))
lblNew = QLabel()
lblNew.setPixmap(pxNew)
@@ -140,9 +204,23 @@ class GuiTimeLineView(QDialog):
winWidth = self.width()
winHeight = self.height()
fPlot = self.filterPlot.isChecked()
fChar = self.filterChar.isChecked()
fWorld = self.filterWorld.isChecked()
fTime = self.filterTime.isChecked()
fObject = self.filterObject.isChecked()
fCustom = self.filterCustom.isChecked()
hUnused = self.hideUnused.isChecked()
self.optState.setSetting("winWidth", winWidth)
self.optState.setSetting("winHeight",winHeight)
self.optState.setSetting("fPlot", fPlot)
self.optState.setSetting("fChar", fChar)
self.optState.setSetting("fWorld", fWorld)
self.optState.setSetting("fTime", fTime)
self.optState.setSetting("fObject", fObject)
self.optState.setSetting("fCustom", fCustom)
self.optState.setSetting("hUnused", hUnused)
self.optState.saveSettings()
self.close()
@@ -158,9 +236,16 @@ class TimeLineLastState(OptLastState):
self.theState = {
"winWidth" : 700,
"winHeight" : 400,
"fPlot" : True,
"fChar" : True,
"fWorld" : True,
"fTime" : True,
"fObject" : True,
"fCustom" : True,
"hUnused" : True,
}
self.stringOpt = ()
self.boolOpt = ()
self.boolOpt = ("fPlot","fChar","fWorld","fTime","fObject","fCustom","hUnused")
self.intOpt = ("winWidth","winHeight")
return
+15 -2
View File
@@ -319,18 +319,24 @@ class NWIndex():
return True
def buildTagNovelMap(self, theTags):
def buildTagNovelMap(self, theTags, theFilters=None):
tagMap = {}
tagClass = {}
exClass = []
if theFilters is not None:
if "exClass" in theFilters.keys():
exClass = theFilters["exClass"]
for theTag in theTags:
tagMap[theTag] = [0]*len(self.novelOrder)
try:
tagClass[theTag] = nwItemClass[self.tagIndex[theTag][2]]
except:
logger.error("Could not map '%s' to nwItemClass" % self.tagIndex[theTag][2])
tagClass[theTag] = None
if tagClass[theTag] not in exClass:
tagMap[theTag] = [0]*len(self.novelOrder)
for tHandle in self.refIndex:
for nLine, tKey, tTag, nTitle in self.refIndex[tHandle]:
@@ -342,6 +348,13 @@ class NWIndex():
except:
logger.error("Could not find '%s:%d' in novelOrder" % (tHandle, nTitle))
if theFilters["hUnused"]:
tagMapFiltered = {}
for theTag in tagMap.keys():
if sum(tagMap[theTag]) > 0:
tagMapFiltered[theTag] = tagMap[theTag]
return tagMapFiltered
return tagMap
# END Class NWIndex
@@ -3,7 +3,7 @@
% Begin Meta
@pov: Jane
@char: John
@location: Earth
@location: Space
% End Meta
Some text here would look good as well, and maybe some "dialogue"?
@@ -1,7 +1,7 @@
### Another Scene
@pov: John
@location: Space
@location: Earth
This is the second scene in out story. We have no idea whats going on, so were just going to ramble on until we have a few lines of text so that the editor has something to work with.
+2 -2
View File
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.2.3" fileVersion="1.0" timeStamp="2019-10-19 13:37:25">
<novelWriterXML appVersion="0.3.1" fileVersion="1.0" timeStamp="2019-10-21 20:54:53">
<project>
<name>Sample Project</name>
<title>Sample Project</title>
@@ -82,7 +82,7 @@
<charCount>713</charCount>
<wordCount>132</wordCount>
<paraCount>6</paraCount>
<cursorPos>85</cursorPos>
<cursorPos>72</cursorPos>
</item>
<item handle="bc0cbd2a407f3" order="2" parent="e7ded148d6e4a">
<name>Another Scene</name>