Added item status, and added icons and flags to the main treeview

This commit is contained in:
Veronica K. B. Olsen
2019-04-24 22:42:57 +02:00
parent b180971548
commit 2f0f39b53e
8 changed files with 198 additions and 18 deletions
+1
View File
@@ -43,6 +43,7 @@ class nwItemLayout(Enum):
PARTITION = 3
CHAPTER = 4
SCENE = 5
NOTE = 6
# END Enum nwItemLayout
+86
View File
@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
"""novelWriter GUI Document Details
novelWriter GUI Document Details
====================================
Class holding the left side document details panel
File History:
Created: 2019-04-24 [0.0.1]
"""
import logging
import nw
from os import path
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QFrame, QGridLayout, QLabel
from nw.enum import nwItemType, nwItemClass, nwItemLayout
from nw.project.item import NWItem
logger = logging.getLogger(__name__)
class GuiDocDetails(QFrame):
C_NAME = 0
C_COUNT = 1
C_FLAGS = 2
C_HANDLE = 3
def __init__(self, theProject):
QFrame.__init__(self)
logger.debug("Initialising DocDetails ...")
self.mainConf = nw.CONFIG
self.debugGUI = self.mainConf.debugGUI
self.theProject = theProject
self.mainBox = QGridLayout(self)
self.mainBox.setVerticalSpacing(1)
self.mainBox.setHorizontalSpacing(15)
self.setLayout(self.mainBox)
self.fntOne = QFont()
self.fntOne.setPointSize(10)
self.fntOne.setBold(True)
self.fntTwo = QFont()
self.fntTwo.setPointSize(10)
colOne = ["Name","Status","Class","Layout"]
for nRow in range(4):
lblOne = QLabel(colOne[nRow])
lblOne.setFont(self.fntOne)
self.mainBox.addWidget(lblOne,nRow+1,0)
self.mainBox.setColumnStretch(0,0)
self.mainBox.setColumnStretch(1,1)
logger.debug("DocDetails initialisation complete")
return
def buildViewBox(self, tHandle):
nwItem = self.theProject.getItem(tHandle)
itemStatus = nwItem.itemStatus
if itemStatus < 0 or itemStatus >= len(self.theProject.statusLabels):
itemStatus = 0
colTwo = [
nwItem.itemName,
self.theProject.statusLabels[itemStatus],
NWItem.CLASS_NAME[nwItem.itemClass],
NWItem.LAYOUT_NAME[nwItem.itemLayout],
]
for nRow in range(4):
lblTwo = QLabel(colTwo[nRow])
lblTwo.setFont(self.fntTwo)
self.mainBox.addWidget(lblTwo,nRow+1,1)
return
# END Class GuiDocDetails
+35 -10
View File
@@ -14,8 +14,8 @@ import logging
import nw
from os import path
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QIcon, QFont, QColor
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView, QInputDialog, QLineEdit
from nw.enum import nwItemType, nwItemClass
@@ -43,10 +43,13 @@ class GuiDocTree(QTreeWidget):
self.setExpandsOnDoubleClick(True)
self.setIndentation(13)
self.setColumnCount(4)
self.setHeaderLabels(["Name","S","#","Handle"])
self.setHeaderLabels(["Name","Count","Flags","Handle"])
if not self.debugGUI:
self.hideColumn(self.C_HANDLE)
treeHead = self.headerItem()
treeHead.setTextAlignment(self.C_COUNT,Qt.AlignRight)
# Allow Move by Drag & Drop
self.setDragEnabled(True)
self.setDragDropMode(QAbstractItemView.InternalMove)
@@ -54,6 +57,9 @@ class GuiDocTree(QTreeWidget):
for colN in range(len(self.mainConf.treeColWidth)):
self.setColumnWidth(colN,self.mainConf.treeColWidth[colN])
self.fontFlags = QFont("Monospace",10)
self.fontCount = QFont("Monospace",10)
logger.debug("DocTree initialisation complete")
return
@@ -139,34 +145,53 @@ class GuiDocTree(QTreeWidget):
return theItem, theCount+1
def _addTreeItem(self, nwItem):
tName = nwItem.itemName
tHandle = nwItem.itemHandle
pHandle = nwItem.parHandle
tStatus = 0
tStatus = NWItem.CLASS_FLAG[nwItem.itemClass]
if nwItem.itemType == nwItemType.FILE:
tStatus += "."+NWItem.LAYOUT_FLAG[nwItem.itemLayout]
nStatus = nwItem.itemStatus
if nStatus < 0 or nStatus >= len(self.theProject.statusIcons):
nStatus = 0
newItem = QTreeWidgetItem([""]*4)
newItem.setText(self.C_NAME, tName)
newItem.setText(self.C_FLAGS, str(tStatus))
newItem.setText(self.C_COUNT, "0")
newItem.setText(self.C_NAME,tName)
newItem.setText(self.C_COUNT,"0")
# newItem.setFont(self.C_COUNT,self.fontCount)
newItem.setForeground(self.C_COUNT,QColor(0,105,135))
newItem.setTextAlignment(self.C_COUNT,Qt.AlignRight)
newItem.setText(self.C_FLAGS,tStatus)
newItem.setIcon(self.C_FLAGS,self.theProject.statusIcons[nStatus])
newItem.setFont(self.C_FLAGS,self.fontFlags)
newItem.setText(self.C_HANDLE, tHandle)
self.theMap[tHandle] = newItem
if pHandle is None:
self.addTopLevelItem(newItem)
else:
self.theMap[pHandle].addChild(newItem)
self.propagateCount(tHandle, nwItem.wordCount)
newItem.setTextAlignment(self.C_COUNT,Qt.AlignRight)
newItem.setExpanded(nwItem.isExpanded)
if nwItem.itemType == nwItemType.ROOT:
newItem.setIcon(self.C_NAME, QIcon.fromTheme("drive-harddisk"))
elif nwItem.itemType == nwItemType.FOLDER:
newItem.setIcon(self.C_NAME, QIcon.fromTheme("folder"))
elif nwItem.itemType == nwItemType.FILE:
newItem.setIcon(self.C_NAME, QIcon.fromTheme("x-office-document"))
return True
def propagateCount(self, tHandle, theCount, nDepth=0):
tItem = self.theMap[tHandle]
tItem.setText(self.C_COUNT,str(theCount))
tItem.setText(self.C_COUNT,"{:n}".format(theCount))
pItem = tItem.parent()
if pItem is not None:
pCount = 0
@@ -184,7 +209,7 @@ class GuiDocTree(QTreeWidget):
self._addTreeItem(nwItem)
return True
def _getSelectedHandle(self):
def getSelectedHandle(self):
selItem = self.selectedItems()
if len(selItem) == 0:
return None
@@ -210,7 +235,7 @@ class GuiDocTree(QTreeWidget):
"""Overload the drop of dragged item event to check whether the drop is allowed
or not. Disallowed drops are cancelled.
"""
sHandle = self._getSelectedHandle()
sHandle = self.getSelectedHandle()
if sHandle is None:
return
+1 -1
View File
@@ -192,7 +192,7 @@ class GuiDocTreeCtx(QMenu):
return
def _buildSubMenuAddRoot(self, itemClass):
mnuSub = QAction("Add "+NWItem.CLASS_NAME[itemClass], self)
mnuSub = QAction("Add %s Root" % NWItem.CLASS_NAME[itemClass], self)
mnuSub.triggered.connect(lambda: self._ctxSignal(
nwItemAction.ADD_ROOT,
itemClass,
+18 -3
View File
@@ -21,6 +21,7 @@ from PyQt5.QtGui import QIcon
from nw.gui.doctree import GuiDocTree
from nw.gui.doctreectx import GuiDocTreeCtx
from nw.gui.doceditor import GuiDocEditor
from nw.gui.docdetails import GuiDocDetails
from nw.gui.projecteditor import GuiProjectEditor
from nw.gui.statusbar import GuiMainStatus
from nw.project.project import NWProject
@@ -44,8 +45,9 @@ class GuiMain(QMainWindow):
self.setWindowIcon(QIcon(path.join(self.mainConf.appPath,"..","novelWriter.svg")))
# Main GUI Elements
self.docEditor = GuiDocEditor(self)
self.treeView = GuiDocTree(self.theProject)
self.docEditor = GuiDocEditor(self)
self.docDetails = GuiDocDetails(self.theProject)
self.treeView = GuiDocTree(self.theProject)
# Assemble Main Window
self.stackPane = QStackedWidget()
@@ -53,8 +55,14 @@ class GuiMain(QMainWindow):
self.stackDoc = self.stackPane.addWidget(self.docEditor)
self.stackPane.setCurrentIndex(self.stackNone)
self.treePane = QFrame()
self.treeBox = QVBoxLayout()
self.treeBox.addWidget(self.treeView)
self.treeBox.addWidget(self.docDetails)
self.treePane.setLayout(self.treeBox)
self.splitMain = QSplitter(Qt.Horizontal)
self.splitMain.addWidget(self.treeView)
self.splitMain.addWidget(self.treePane)
self.splitMain.addWidget(self.stackPane)
self.splitMain.setSizes(self.mainConf.mainPanePos)
self.splitMain.splitterMoved.connect(self._splitMainMove)
@@ -65,6 +73,7 @@ class GuiMain(QMainWindow):
self._buildMenu()
self.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
self.treeView.customContextMenuRequested.connect(self._openDocTreeContextMenu)
self.treeView.itemSelectionChanged.connect(self._treeSingleClick)
self.treeView.itemDoubleClicked.connect(self._treeDoubleClick)
self.treeView.buildTree()
@@ -159,6 +168,12 @@ class GuiMain(QMainWindow):
# Internal Functions
##
def _treeSingleClick(self):
sHandle = self.treeView.getSelectedHandle()
if sHandle is not None:
self.docDetails.buildViewBox(sHandle)
return
def _treeDoubleClick(self, tItem, colNo):
tHandle = tItem.text(3)
logger.verbose("User double clicked tree item with handle %s" % tHandle)
+20 -3
View File
@@ -25,7 +25,7 @@ class NWItem():
MAX_DEPTH = 8
CLASS_NAME = {
nwItemClass.NO_CLASS : "Folder",
nwItemClass.NO_CLASS : "Custom",
nwItemClass.NOVEL : "Novel",
nwItemClass.PLOT : "Plot",
nwItemClass.CHARACTER : "Characters",
@@ -42,6 +42,15 @@ class NWItem():
nwItemClass.TIMELINE : "T",
nwItemClass.OBJECT : "O",
}
LAYOUT_NAME = {
nwItemLayout.NO_LAYOUT : "None",
nwItemLayout.TITLE_PAGE : "Title Page",
nwItemLayout.SIMPLE_PAGE : "Simple Page",
nwItemLayout.PARTITION : "Partition",
nwItemLayout.CHAPTER : "Chapter",
nwItemLayout.SCENE : "Scene",
nwItemLayout.NOTE : "Note",
}
LAYOUT_FLAG = {
nwItemLayout.NO_LAYOUT : "Xo",
nwItemLayout.TITLE_PAGE : "Tt",
@@ -49,6 +58,7 @@ class NWItem():
nwItemLayout.PARTITION : "Pt",
nwItemLayout.CHAPTER : "Ch",
nwItemLayout.SCENE : "Sc",
nwItemLayout.NOTE : "Nt",
}
def __init__(self):
@@ -60,6 +70,7 @@ class NWItem():
self.itemType = nwItemType.NO_TYPE
self.itemClass = nwItemClass.NO_CLASS
self.itemLayout = nwItemLayout.NO_LAYOUT
self.itemStatus = 0
self.itemDepth = None
self.hasChildren = False
self.isExpanded = False
@@ -83,12 +94,12 @@ class NWItem():
xSub = self._subPack(xPack,"name", text=str(self.itemName))
xSub = self._subPack(xPack,"type", text=str(self.itemType.name))
xSub = self._subPack(xPack,"class", text=str(self.itemClass.name))
xSub = self._subPack(xPack,"status", text=str(self.itemStatus))
xSub = self._subPack(xPack,"depth", text=str(self.itemDepth))
xSub = self._subPack(xPack,"children", text=str(self.hasChildren))
xSub = self._subPack(xPack,"expanded", text=str(self.isExpanded))
if self.itemClass == nwItemClass.NOVEL and self.itemLayout is not nwItemLayout.NO_LAYOUT:
xSub = self._subPack(xPack,"layout", text=str(self.itemLayout.name))
if self.itemType == nwItemType.FILE:
xSub = self._subPack(xPack,"layout", text=str(self.itemLayout.name))
xSub = self._subPack(xPack,"charCount", text=str(self.charCount), none=False)
xSub = self._subPack(xPack,"wordCount", text=str(self.wordCount), none=False)
xSub = self._subPack(xPack,"paraCount", text=str(self.paraCount), none=False)
@@ -113,6 +124,7 @@ class NWItem():
elif tagName == "type": self.setType(tagValue)
elif tagName == "class": self.setClass(tagValue)
elif tagName == "layout": self.setLayout(tagValue)
elif tagName == "status": self.setStatus(tagValue)
elif tagName == "depth": self.setDepth(tagValue)
elif tagName == "children": self.setChildren(tagValue)
elif tagName == "expanded": self.setExpanded(tagValue)
@@ -182,6 +194,11 @@ class NWItem():
self.itemLayout = nwItemLayout.NO_LAYOUT
return
def setStatus(self, theStatus):
theStatus = self._checkInt(theStatus,0)
self.itemStatus = theStatus
return
def setDepth(self, theDepth):
theDepth = self._checkInt(theDepth,-1)
if theDepth >= 0 and theDepth <= self.MAX_DEPTH:
+24
View File
@@ -19,6 +19,8 @@ from hashlib import sha256
from datetime import datetime
from time import time
from PyQt5.QtGui import QIcon, QPixmap, QColor
from nw.enum import nwItemType, nwItemClass, nwItemAction
from nw.project.item import NWItem
@@ -41,6 +43,16 @@ class NWProject():
self.bookTitle = ""
self.bookAuthors = []
self.statusCols = [
("New", 100,100,100),
("Note", 200, 50, 0),
("Draft", 200,150, 0),
("Finished", 50,200, 0),
]
self.statusIcons = []
self.statusLabels = []
self._makeStatusIcons()
return
##
@@ -79,6 +91,7 @@ class NWProject():
self.projName = ""
self.bookTitle = ""
self.bookAuthors = []
self._makeStatusIcons()
hNovel = self.newRoot("Novel", nwItemClass.NOVEL)
hChars = self.newRoot("Characters", nwItemClass.CHARACTER)
hWorld = self.newRoot("World", nwItemClass.WORLD)
@@ -147,6 +160,7 @@ class NWProject():
nwItem.setFromTag(xValue.tag,xValue.text)
self._appendItem(tHandle,pHandle,nwItem)
self._makeStatusIcons()
self.mainConf.setRecent(self.projPath)
return True
@@ -365,6 +379,16 @@ class NWProject():
return
def _makeStatusIcons(self):
self.statusIcons = []
self.statusLabels = []
for sLabel, sR, sG, sB in self.statusCols:
theIcon = QPixmap(32,32)
theIcon.fill(QColor(sR,sG,sB))
self.statusIcons.append(QIcon(theIcon))
self.statusLabels.append(sLabel)
return
def _makeHandle(self, addSeed=""):
newSeed = str(time()) + addSeed
logger.verbose("Generating handle with seed '%s'" % newSeed)
+13 -1
View File
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-04-24 18:07:47">
<novelWriterXML appVersion="0.0.1" fileVersion="1.0" timeStamp="2019-04-24 22:34:36">
<project>
<name>Sample Project</name>
<title>Sample Project</title>
@@ -11,6 +11,7 @@
<name>Novel</name>
<type>ROOT</type>
<class>NOVEL</class>
<status>0</status>
<depth>0</depth>
<children>True</children>
<expanded>True</expanded>
@@ -19,6 +20,7 @@
<name>New Chapter</name>
<type>FOLDER</type>
<class>NOVEL</class>
<status>1</status>
<depth>1</depth>
<children>True</children>
<expanded>True</expanded>
@@ -27,9 +29,11 @@
<name>New Scene</name>
<type>FILE</type>
<class>NOVEL</class>
<status>2</status>
<depth>2</depth>
<children>False</children>
<expanded>False</expanded>
<layout>SCENE</layout>
<charCount>2575</charCount>
<wordCount>377</wordCount>
<paraCount>5</paraCount>
@@ -38,9 +42,11 @@
<name>Test File</name>
<type>FILE</type>
<class>NOVEL</class>
<status>1</status>
<depth>2</depth>
<children>False</children>
<expanded>False</expanded>
<layout>SCENE</layout>
<charCount>125</charCount>
<wordCount>24</wordCount>
<paraCount>2</paraCount>
@@ -49,6 +55,7 @@
<name>Characters</name>
<type>ROOT</type>
<class>CHARACTER</class>
<status>0</status>
<depth>0</depth>
<children>True</children>
<expanded>True</expanded>
@@ -57,9 +64,11 @@
<name>Jon Smith</name>
<type>FILE</type>
<class>CHARACTER</class>
<status>0</status>
<depth>1</depth>
<children>False</children>
<expanded>False</expanded>
<layout>NOTE</layout>
<charCount>0</charCount>
<wordCount>0</wordCount>
<paraCount>0</paraCount>
@@ -68,9 +77,11 @@
<name>Jane Smith</name>
<type>FILE</type>
<class>CHARACTER</class>
<status>0</status>
<depth>1</depth>
<children>False</children>
<expanded>False</expanded>
<layout>NOTE</layout>
<charCount>0</charCount>
<wordCount>0</wordCount>
<paraCount>0</paraCount>
@@ -79,6 +90,7 @@
<name>World</name>
<type>ROOT</type>
<class>WORLD</class>
<status>0</status>
<depth>0</depth>
<children>False</children>
<expanded>False</expanded>