Remove timeline view so we can clean up the indexing class
This commit is contained in:
@@ -12,7 +12,6 @@ from nw.gui.dialogs.export import GuiExport
|
|||||||
from nw.gui.dialogs.itemeditor import GuiItemEditor
|
from nw.gui.dialogs.itemeditor import GuiItemEditor
|
||||||
from nw.gui.dialogs.projecteditor import GuiProjectEditor
|
from nw.gui.dialogs.projecteditor import GuiProjectEditor
|
||||||
from nw.gui.dialogs.sessionlog import GuiSessionLogView
|
from nw.gui.dialogs.sessionlog import GuiSessionLogView
|
||||||
from nw.gui.dialogs.timelineview import GuiTimeLineView
|
|
||||||
|
|
||||||
# GUI Elements
|
# GUI Elements
|
||||||
from nw.gui.elements.docdetails import GuiDocDetails
|
from nw.gui.elements.docdetails import GuiDocDetails
|
||||||
@@ -38,7 +37,6 @@ __all__ = [
|
|||||||
"GuiItemEditor",
|
"GuiItemEditor",
|
||||||
"GuiProjectEditor",
|
"GuiProjectEditor",
|
||||||
"GuiSessionLogView",
|
"GuiSessionLogView",
|
||||||
"GuiTimeLineView",
|
|
||||||
"GuiDocDetails",
|
"GuiDocDetails",
|
||||||
"GuiDocEditor",
|
"GuiDocEditor",
|
||||||
"GuiDocTree",
|
"GuiDocTree",
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from nw.gui.dialogs.export import GuiExport
|
|||||||
from nw.gui.dialogs.itemeditor import GuiItemEditor
|
from nw.gui.dialogs.itemeditor import GuiItemEditor
|
||||||
from nw.gui.dialogs.projecteditor import GuiProjectEditor
|
from nw.gui.dialogs.projecteditor import GuiProjectEditor
|
||||||
from nw.gui.dialogs.sessionlog import GuiSessionLogView
|
from nw.gui.dialogs.sessionlog import GuiSessionLogView
|
||||||
from nw.gui.dialogs.timelineview import GuiTimeLineView
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"GuiConfigEditor",
|
"GuiConfigEditor",
|
||||||
@@ -13,5 +12,4 @@ __all__ = [
|
|||||||
"GuiItemEditor",
|
"GuiItemEditor",
|
||||||
"GuiProjectEditor",
|
"GuiProjectEditor",
|
||||||
"GuiSessionLogView",
|
"GuiSessionLogView",
|
||||||
"GuiTimeLineView",
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,273 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""novelWriter GUI Timeline View
|
|
||||||
|
|
||||||
novelWriter – GUI Timeline View
|
|
||||||
=================================
|
|
||||||
Class holding the timeline view window
|
|
||||||
|
|
||||||
File History:
|
|
||||||
Created: 2019-05-30 [0.1.4]
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import nw
|
|
||||||
|
|
||||||
from os import path
|
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt
|
|
||||||
from PyQt5.QtGui import QColor, QPixmap
|
|
||||||
from PyQt5.QtWidgets import (
|
|
||||||
QDialog, QVBoxLayout, QHBoxLayout, QTableWidget, QTableWidgetItem, QLabel,
|
|
||||||
QDialogButtonBox, QPushButton, QHeaderView, QGridLayout, QGroupBox,
|
|
||||||
QCheckBox
|
|
||||||
)
|
|
||||||
|
|
||||||
from nw.constants import nwFiles, nwItemClass
|
|
||||||
from nw.tools import OptLastState
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class GuiTimeLineView(QDialog):
|
|
||||||
|
|
||||||
def __init__(self, theParent, theProject, theIndex):
|
|
||||||
QDialog.__init__(self, theParent)
|
|
||||||
|
|
||||||
logger.debug("Initialising TimeLineView ...")
|
|
||||||
|
|
||||||
self.mainConf = nw.CONFIG
|
|
||||||
self.theProject = theProject
|
|
||||||
self.theParent = theParent
|
|
||||||
self.theIndex = theIndex
|
|
||||||
self.optState = TimeLineLastState(self.theProject,nwFiles.TLINE_OPT)
|
|
||||||
self.optState.loadSettings()
|
|
||||||
|
|
||||||
self.theMatrix = {}
|
|
||||||
self.numRows = 0
|
|
||||||
self.numCols = 0
|
|
||||||
|
|
||||||
self.outerBox = QVBoxLayout()
|
|
||||||
self.filterBox = QVBoxLayout()
|
|
||||||
self.centreBox = QHBoxLayout()
|
|
||||||
self.bottomBox = QHBoxLayout()
|
|
||||||
|
|
||||||
self.setWindowTitle("Timeline View")
|
|
||||||
self.setMinimumWidth(700)
|
|
||||||
self.setMinimumHeight(400)
|
|
||||||
|
|
||||||
winWidth = self.optState.validIntRange(
|
|
||||||
self.optState.getSetting("winWidth"), 700, 10000, 700
|
|
||||||
)
|
|
||||||
winHeight = self.optState.validIntRange(
|
|
||||||
self.optState.getSetting("winHeight"), 400, 10000, 400
|
|
||||||
)
|
|
||||||
self.resize(winWidth,winHeight)
|
|
||||||
|
|
||||||
# TimeLine Table
|
|
||||||
self.mainTable = QTableWidget()
|
|
||||||
self.mainTable.setGridStyle(Qt.NoPen)
|
|
||||||
|
|
||||||
self.hHeader = self.mainTable.horizontalHeader()
|
|
||||||
self.hHeader.setSectionResizeMode(QHeaderView.ResizeToContents)
|
|
||||||
self.mainTable.setHorizontalHeader(self.hHeader)
|
|
||||||
|
|
||||||
self.vHeader = self.mainTable.verticalHeader()
|
|
||||||
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.filterPlot.stateChanged.connect(self._filterChange)
|
|
||||||
|
|
||||||
self.filterChar = QCheckBox("Character tags", self)
|
|
||||||
self.filterChar.setChecked(self.optState.getSetting("fChar"))
|
|
||||||
self.filterChar.stateChanged.connect(self._filterChange)
|
|
||||||
|
|
||||||
self.filterWorld = QCheckBox("Location tags", self)
|
|
||||||
self.filterWorld.setChecked(self.optState.getSetting("fWorld"))
|
|
||||||
self.filterWorld.stateChanged.connect(self._filterChange)
|
|
||||||
|
|
||||||
self.filterTime = QCheckBox("Timeline tags", self)
|
|
||||||
self.filterTime.setChecked(self.optState.getSetting("fTime"))
|
|
||||||
self.filterTime.stateChanged.connect(self._filterChange)
|
|
||||||
|
|
||||||
self.filterObject = QCheckBox("Object tags", self)
|
|
||||||
self.filterObject.setChecked(self.optState.getSetting("fObject"))
|
|
||||||
self.filterObject.stateChanged.connect(self._filterChange)
|
|
||||||
|
|
||||||
self.filterCustom = QCheckBox("Custom tags", self)
|
|
||||||
self.filterCustom.setChecked(self.optState.getSetting("fCustom"))
|
|
||||||
self.filterCustom.stateChanged.connect(self._filterChange)
|
|
||||||
|
|
||||||
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.hideUnused.stateChanged.connect(self._filterChange)
|
|
||||||
|
|
||||||
self.optHideGrid.addWidget(self.hideUnused, 0, 1)
|
|
||||||
|
|
||||||
# Button Box
|
|
||||||
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Close)
|
|
||||||
self.buttonBox.rejected.connect(self._doClose)
|
|
||||||
|
|
||||||
self.btnRebuild = QPushButton("Rebuild Index")
|
|
||||||
self.btnRebuild.clicked.connect(self.theParent.rebuildIndex)
|
|
||||||
|
|
||||||
self.btnRefresh = QPushButton("Refresh Table")
|
|
||||||
self.btnRefresh.clicked.connect(self._buildNovelList)
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
logger.debug("TimeLineView initialisation complete")
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _buildNovelList(self):
|
|
||||||
|
|
||||||
self.mainTable.clear()
|
|
||||||
self.theIndex.buildNovelList()
|
|
||||||
|
|
||||||
self.numRows = len(self.theIndex.novelList)
|
|
||||||
self.mainTable.setRowCount(self.numRows)
|
|
||||||
|
|
||||||
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]
|
|
||||||
iTitle = self.theIndex.novelList[n][2]
|
|
||||||
newItem = QTableWidgetItem("%s%s " % (" "*iDepth,iTitle))
|
|
||||||
self.mainTable.setVerticalHeaderItem(n, newItem)
|
|
||||||
|
|
||||||
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.fill(QColor(0,120,0))
|
|
||||||
lblNew = QLabel()
|
|
||||||
lblNew.setPixmap(pxNew)
|
|
||||||
lblNew.setAlignment(Qt.AlignCenter)
|
|
||||||
lblNew.setAttribute(Qt.WA_TranslucentBackground)
|
|
||||||
self.mainTable.setCellWidget(n, nCol, lblNew)
|
|
||||||
elif theCols[n] == 2:
|
|
||||||
pxNew = QPixmap(10,10)
|
|
||||||
pxNew.fill(QColor(0,0,120))
|
|
||||||
lblNew = QLabel()
|
|
||||||
lblNew.setPixmap(pxNew)
|
|
||||||
lblNew.setAlignment(Qt.AlignCenter)
|
|
||||||
lblNew.setAttribute(Qt.WA_TranslucentBackground)
|
|
||||||
self.mainTable.setCellWidget(n, nCol, lblNew)
|
|
||||||
nCol += 1
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _doClose(self):
|
|
||||||
|
|
||||||
logger.verbose("GuiTimeLineView close button clicked")
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _filterChange(self, checkState):
|
|
||||||
self._buildNovelList()
|
|
||||||
return
|
|
||||||
|
|
||||||
# END Class GuiTimeLineView
|
|
||||||
|
|
||||||
class TimeLineLastState(OptLastState):
|
|
||||||
|
|
||||||
def __init__(self, theProject, theFile):
|
|
||||||
OptLastState.__init__(self, theProject, theFile)
|
|
||||||
self.theState = {
|
|
||||||
"winWidth" : 700,
|
|
||||||
"winHeight" : 400,
|
|
||||||
"fPlot" : True,
|
|
||||||
"fChar" : True,
|
|
||||||
"fWorld" : True,
|
|
||||||
"fTime" : True,
|
|
||||||
"fObject" : True,
|
|
||||||
"fCustom" : True,
|
|
||||||
"hUnused" : True,
|
|
||||||
}
|
|
||||||
self.stringOpt = ()
|
|
||||||
self.boolOpt = ("fPlot","fChar","fWorld","fTime","fObject","fCustom","hUnused")
|
|
||||||
self.intOpt = ("winWidth","winHeight")
|
|
||||||
return
|
|
||||||
|
|
||||||
# END Class TimeLineLastState
|
|
||||||
@@ -87,7 +87,7 @@ class GuiDocViewDetails(QWidget):
|
|||||||
if self.isSticky.isChecked():
|
if self.isSticky.isChecked():
|
||||||
return
|
return
|
||||||
|
|
||||||
theRefs = self.theParent.theIndex.buildReferenceList(tHandle)
|
theRefs = self.theParent.theIndex.getBackReferenceList(tHandle)
|
||||||
theList = []
|
theList = []
|
||||||
for tHandle in theRefs:
|
for tHandle in theRefs:
|
||||||
tItem = self.theProject.getItem(tHandle)
|
tItem = self.theProject.getItem(tHandle)
|
||||||
|
|||||||
@@ -416,16 +416,6 @@ class GuiMainMenu(QMenuBar):
|
|||||||
self.aFullScreen.triggered.connect(self.theParent.toggleFullScreenMode)
|
self.aFullScreen.triggered.connect(self.theParent.toggleFullScreenMode)
|
||||||
self.viewMenu.addAction(self.aFullScreen)
|
self.viewMenu.addAction(self.aFullScreen)
|
||||||
|
|
||||||
# View > Separator
|
|
||||||
self.viewMenu.addSeparator()
|
|
||||||
|
|
||||||
# View > Project Timeline
|
|
||||||
self.aViewTimeLine = QAction("Show Project Timeline", self)
|
|
||||||
self.aViewTimeLine.setStatusTip("Open the project timeline window")
|
|
||||||
self.aViewTimeLine.setShortcut("Ctrl+T")
|
|
||||||
self.aViewTimeLine.triggered.connect(self.theParent.showTimeLineDialog)
|
|
||||||
self.viewMenu.addAction(self.aViewTimeLine)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def _buildEditMenu(self):
|
def _buildEditMenu(self):
|
||||||
|
|||||||
+1
-8
@@ -27,7 +27,7 @@ from nw.gui import (
|
|||||||
GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor,
|
GuiMainMenu, GuiMainStatus, GuiTheme, GuiDocTree, GuiDocEditor,
|
||||||
GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar,
|
GuiDocViewer, GuiDocDetails, GuiSearchBar, GuiNoticeBar,
|
||||||
GuiDocViewDetails, GuiConfigEditor, GuiProjectEditor, GuiExport,
|
GuiDocViewDetails, GuiConfigEditor, GuiProjectEditor, GuiExport,
|
||||||
GuiItemEditor, GuiTimeLineView, GuiSessionLogView, GuiProjectOutline
|
GuiItemEditor, GuiSessionLogView, GuiProjectOutline
|
||||||
)
|
)
|
||||||
from nw.project import NWProject, NWDoc, NWItem, NWIndex, NWBackup
|
from nw.project import NWProject, NWDoc, NWItem, NWIndex, NWBackup
|
||||||
from nw.tools import countWords
|
from nw.tools import countWords
|
||||||
@@ -619,12 +619,6 @@ class GuiMain(QMainWindow):
|
|||||||
dlgExport.exec_()
|
dlgExport.exec_()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def showTimeLineDialog(self):
|
|
||||||
if self.hasProject:
|
|
||||||
dlgTLine = GuiTimeLineView(self, self.theProject, self.theIndex)
|
|
||||||
dlgTLine.exec_()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def showSessionLogDialog(self):
|
def showSessionLogDialog(self):
|
||||||
if self.hasProject:
|
if self.hasProject:
|
||||||
dlgTLine = GuiSessionLogView(self, self.theProject)
|
dlgTLine = GuiSessionLogView(self, self.theProject)
|
||||||
@@ -778,7 +772,6 @@ class GuiMain(QMainWindow):
|
|||||||
self.addAction(self.mainMenu.aFileDetails)
|
self.addAction(self.mainMenu.aFileDetails)
|
||||||
self.addAction(self.mainMenu.aZenMode)
|
self.addAction(self.mainMenu.aZenMode)
|
||||||
self.addAction(self.mainMenu.aFullScreen)
|
self.addAction(self.mainMenu.aFullScreen)
|
||||||
self.addAction(self.mainMenu.aViewTimeLine)
|
|
||||||
self.addAction(self.mainMenu.aEditUndo)
|
self.addAction(self.mainMenu.aEditUndo)
|
||||||
self.addAction(self.mainMenu.aEditRedo)
|
self.addAction(self.mainMenu.aEditRedo)
|
||||||
self.addAction(self.mainMenu.aEditCut)
|
self.addAction(self.mainMenu.aEditCut)
|
||||||
|
|||||||
+18
-70
@@ -17,7 +17,7 @@ import nw
|
|||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
from nw.constants import (
|
from nw.constants import (
|
||||||
nwFiles, nwKeyWords, nwItemType, nwItemClass, nwAlert
|
nwFiles, nwKeyWords, nwItemType, nwItemClass, nwItemLayout, nwAlert
|
||||||
)
|
)
|
||||||
from nw.tools import countWords
|
from nw.tools import countWords
|
||||||
|
|
||||||
@@ -66,9 +66,6 @@ class NWIndex():
|
|||||||
self.textCounts = {}
|
self.textCounts = {}
|
||||||
self.textSynopsis = {}
|
self.textSynopsis = {}
|
||||||
|
|
||||||
# Lists
|
|
||||||
self.novelList = []
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -261,23 +258,28 @@ class NWIndex():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
theItem = self.theProject.getItem(tHandle)
|
theItem = self.theProject.getItem(tHandle)
|
||||||
if theItem is None: return False
|
if theItem is None:
|
||||||
if theItem.itemType != nwItemType.FILE: return False
|
return False
|
||||||
if theItem.parHandle == self.theProject.trashRoot: return False
|
if theItem.itemType != nwItemType.FILE:
|
||||||
|
return False
|
||||||
|
if theItem.parHandle == self.theProject.trashRoot:
|
||||||
|
return False
|
||||||
|
if theItem.itemLayout == nwItemLayout.NO_LAYOUT:
|
||||||
|
return False
|
||||||
|
|
||||||
itemClass = theItem.itemClass
|
itemClass = theItem.itemClass
|
||||||
itemLayout = theItem.itemLayout
|
itemLayout = theItem.itemLayout
|
||||||
|
|
||||||
logger.debug("Indexing item with handle %s" % tHandle)
|
logger.debug("Indexing item with handle %s" % tHandle)
|
||||||
|
|
||||||
# Check file type, and reset its old index
|
# Check file type, and reset its old index
|
||||||
if itemClass == nwItemClass.NOVEL:
|
self.refIndex[tHandle] = []
|
||||||
self.novelIndex[tHandle] = []
|
if itemLayout == nwItemLayout.NOTE:
|
||||||
self.refIndex[tHandle] = []
|
|
||||||
isNovel = True
|
|
||||||
else:
|
|
||||||
self.noteIndex[tHandle] = []
|
self.noteIndex[tHandle] = []
|
||||||
self.refIndex[tHandle] = []
|
|
||||||
isNovel = False
|
isNovel = False
|
||||||
|
else:
|
||||||
|
self.novelIndex[tHandle] = []
|
||||||
|
isNovel = True
|
||||||
|
|
||||||
# Also clear references to file in tag index
|
# Also clear references to file in tag index
|
||||||
clearTags = []
|
clearTags = []
|
||||||
@@ -296,7 +298,8 @@ class NWIndex():
|
|||||||
aLine = aLine
|
aLine = aLine
|
||||||
nLine += 1
|
nLine += 1
|
||||||
nChar = len(aLine.strip())
|
nChar = len(aLine.strip())
|
||||||
if nChar == 0: continue
|
if nChar == 0:
|
||||||
|
continue
|
||||||
|
|
||||||
if aLine.startswith(r"#"):
|
if aLine.startswith(r"#"):
|
||||||
isTitle = self.indexTitle(tHandle, isNovel, aLine, nLine, itemLayout)
|
isTitle = self.indexTitle(tHandle, isNovel, aLine, nLine, itemLayout)
|
||||||
@@ -513,20 +516,7 @@ class NWIndex():
|
|||||||
|
|
||||||
return theRefs
|
return theRefs
|
||||||
|
|
||||||
def buildNovelList(self):
|
def getBackReferenceList(self, tHandle):
|
||||||
"""Build a list of the content of the novel.
|
|
||||||
"""
|
|
||||||
self.novelList = []
|
|
||||||
self.novelOrder = []
|
|
||||||
for tHandle in self.theProject.treeOrder:
|
|
||||||
if tHandle not in self.novelIndex:
|
|
||||||
continue
|
|
||||||
for tEntry in self.novelIndex[tHandle]:
|
|
||||||
self.novelList.append(tEntry)
|
|
||||||
self.novelOrder.append("%s:%d" % (tHandle,tEntry[0]))
|
|
||||||
return True
|
|
||||||
|
|
||||||
def buildReferenceList(self, tHandle):
|
|
||||||
"""Build a list of files referring back to our file, specified
|
"""Build a list of files referring back to our file, specified
|
||||||
by tHandle.
|
by tHandle.
|
||||||
"""
|
"""
|
||||||
@@ -560,46 +550,4 @@ class NWIndex():
|
|||||||
return theRef[1], theRef[0]
|
return theRef[1], theRef[0]
|
||||||
return None, 0
|
return None, 0
|
||||||
|
|
||||||
def buildTagNovelMap(self, theTags, theFilters=None):
|
|
||||||
"""Build a two-dimensional map of all titles of the novel and
|
|
||||||
which tags they link to from the various meta tags. This map is
|
|
||||||
used to display the timeline view.
|
|
||||||
"""
|
|
||||||
|
|
||||||
tagMap = {}
|
|
||||||
tagClass = {}
|
|
||||||
exClass = []
|
|
||||||
|
|
||||||
if theFilters is not None:
|
|
||||||
if "exClass" in theFilters.keys():
|
|
||||||
exClass = theFilters["exClass"]
|
|
||||||
|
|
||||||
for theTag in theTags:
|
|
||||||
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]:
|
|
||||||
if tTag in tagMap.keys() and tKey in self.TAG_CLASS:
|
|
||||||
try:
|
|
||||||
nPos = self.novelOrder.index("%s:%d" % (tHandle, nTitle))
|
|
||||||
if self.TAG_CLASS[tKey][0] == tagClass[tTag]:
|
|
||||||
tagMap[tTag][nPos] = self.TAG_CLASS[tKey][1]
|
|
||||||
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
|
# END Class NWIndex
|
||||||
|
|||||||
@@ -95,25 +95,3 @@ def testIndexScanThis(nwTempProj):
|
|||||||
assert isValid
|
assert isValid
|
||||||
assert str(theBits) == "['@tag', 'this', 'and this']"
|
assert str(theBits) == "['@tag', 'this', 'and this']"
|
||||||
assert str(thePos) == "[0, 6, 12]"
|
assert str(thePos) == "[0, 6, 12]"
|
||||||
|
|
||||||
@pytest.mark.project
|
|
||||||
def testBuildIndex(nwTempProj):
|
|
||||||
projFile = path.join(nwTempProj,"nwProject.nwx")
|
|
||||||
assert theProject.openProject(projFile)
|
|
||||||
|
|
||||||
theIndex = NWIndex(theProject,theMain)
|
|
||||||
tHandle = "31489056e0916"
|
|
||||||
|
|
||||||
theIndex.scanText(tHandle, (
|
|
||||||
"# Novel\n\n"
|
|
||||||
"## Chapter\n\n"
|
|
||||||
"### Scene\n\n"
|
|
||||||
"#### Section\n\n"
|
|
||||||
"@pov: John\n"
|
|
||||||
"@char: Jane\n"
|
|
||||||
"@location: Somewhere\n"
|
|
||||||
))
|
|
||||||
|
|
||||||
assert theIndex.buildNovelList()
|
|
||||||
assert str(theIndex.novelList) == "[[1, 1, 'Novel', 'SCENE'], [3, 2, 'Chapter', 'SCENE'], [5, 3, 'Scene', 'SCENE'], [7, 4, 'Section', 'SCENE']]"
|
|
||||||
assert str(theIndex.novelOrder) == "['31489056e0916:1', '31489056e0916:3', '31489056e0916:5', '31489056e0916:7']"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user