Merge branch 'dev' into tree_context

This commit is contained in:
Veronica K. B. Olsen
2020-06-04 17:58:39 +02:00
13 changed files with 408 additions and 70 deletions
+16 -6
View File
@@ -95,6 +95,7 @@ class Config:
self.projColWidth = [140, 55, 140] self.projColWidth = [140, 55, 140]
self.mainPanePos = [300, 800] self.mainPanePos = [300, 800]
self.docPanePos = [400, 400] self.docPanePos = [400, 400]
self.outlnPanePos = [500, 150]
self.isFullScreen = False self.isFullScreen = False
## Project ## Project
@@ -342,6 +343,9 @@ class Config:
self.docPanePos = self._parseLine( self.docPanePos = self._parseLine(
cnfParse, cnfSec, "docpane", self.CNF_LIST, self.docPanePos cnfParse, cnfSec, "docpane", self.CNF_LIST, self.docPanePos
) )
self.outlnPanePos = self._parseLine(
cnfParse, cnfSec, "outlinepane", self.CNF_LIST, self.outlnPanePos
)
self.isFullScreen = self._parseLine( self.isFullScreen = self._parseLine(
cnfParse, cnfSec, "fullscreen", self.CNF_BOOL, self.isFullScreen cnfParse, cnfSec, "fullscreen", self.CNF_BOOL, self.isFullScreen
) )
@@ -481,12 +485,13 @@ class Config:
## Sizes ## Sizes
cnfSec = "Sizes" cnfSec = "Sizes"
cnfParse.add_section(cnfSec) cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"geometry", self._packList(self.winGeometry)) cnfParse.set(cnfSec,"geometry", self._packList(self.winGeometry))
cnfParse.set(cnfSec,"treecols", self._packList(self.treeColWidth)) cnfParse.set(cnfSec,"treecols", self._packList(self.treeColWidth))
cnfParse.set(cnfSec,"projcols", self._packList(self.projColWidth)) cnfParse.set(cnfSec,"projcols", self._packList(self.projColWidth))
cnfParse.set(cnfSec,"mainpane", self._packList(self.mainPanePos)) cnfParse.set(cnfSec,"mainpane", self._packList(self.mainPanePos))
cnfParse.set(cnfSec,"docpane", self._packList(self.docPanePos)) cnfParse.set(cnfSec,"docpane", self._packList(self.docPanePos))
cnfParse.set(cnfSec,"fullscreen", str(self.isFullScreen)) cnfParse.set(cnfSec,"outlinepane", self._packList(self.outlnPanePos))
cnfParse.set(cnfSec,"fullscreen", str(self.isFullScreen))
## Project ## Project
cnfSec = "Project" cnfSec = "Project"
@@ -700,6 +705,11 @@ class Config:
self.confChanged = True self.confChanged = True
return True return True
def setOutlinePanePos(self, panePos):
self.outlnPanePos = panePos
self.confChanged = True
return True
def setShowRefPanel(self, checkState): def setShowRefPanel(self, checkState):
self.showRefPanel = checkState self.showRefPanel = checkState
self.confChanged = True self.confChanged = True
+4 -2
View File
@@ -13,7 +13,8 @@ from nw.gui.docviewer import GuiDocViewer
from nw.gui.itemdetails import GuiItemDetails from nw.gui.itemdetails import GuiItemDetails
from nw.gui.itemeditor import GuiItemEditor from nw.gui.itemeditor import GuiItemEditor
from nw.gui.mainmenu import GuiMainMenu from nw.gui.mainmenu import GuiMainMenu
from nw.gui.outline import GuiProjectOutline from nw.gui.outline import GuiOutline
from nw.gui.outlinedetails import GuiOutlineDetails
from nw.gui.preferences import GuiPreferences from nw.gui.preferences import GuiPreferences
from nw.gui.projload import GuiProjectLoad from nw.gui.projload import GuiProjectLoad
from nw.gui.projsettings import GuiProjectSettings from nw.gui.projsettings import GuiProjectSettings
@@ -37,7 +38,8 @@ __all__ = [
"GuiItemDetails", "GuiItemDetails",
"GuiItemEditor", "GuiItemEditor",
"GuiMainMenu", "GuiMainMenu",
"GuiProjectOutline", "GuiOutline",
"GuiOutlineDetails",
"GuiPreferences", "GuiPreferences",
"GuiProjectLoad", "GuiProjectLoad",
"GuiProjectSettings", "GuiProjectSettings",
+2 -2
View File
@@ -37,13 +37,13 @@ logger = logging.getLogger(__name__)
class GuiDocViewDetails(QWidget): class GuiDocViewDetails(QWidget):
def __init__(self, theParent, theProject): def __init__(self, theParent):
QWidget.__init__(self, theParent) QWidget.__init__(self, theParent)
logger.debug("Initialising DocViewDetails ...") logger.debug("Initialising DocViewDetails ...")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
self.theProject = theProject self.theProject = theParent.theProject
self.currHandle = None self.currHandle = None
self.outerBox = QGridLayout(self) self.outerBox = QGridLayout(self)
+3 -3
View File
@@ -50,16 +50,16 @@ logger = logging.getLogger(__name__)
class GuiDocEditor(QTextEdit): class GuiDocEditor(QTextEdit):
def __init__(self, theParent, theProject): def __init__(self, theParent):
QTextEdit.__init__(self) QTextEdit.__init__(self, theParent)
logger.debug("Initialising GuiDocEditor ...") logger.debug("Initialising GuiDocEditor ...")
# Class Variables # Class Variables
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theProject = theProject
self.theParent = theParent self.theParent = theParent
self.theTheme = theParent.theTheme self.theTheme = theParent.theTheme
self.theProject = theParent.theProject
self.docChanged = False self.docChanged = False
self.spellCheck = False self.spellCheck = False
self.nwDocument = NWDoc(self.theProject, self.theParent) self.nwDocument = NWDoc(self.theProject, self.theParent)
+20 -16
View File
@@ -40,16 +40,16 @@ logger = logging.getLogger(__name__)
class GuiDocViewer(QTextBrowser): class GuiDocViewer(QTextBrowser):
def __init__(self, theParent, theProject): def __init__(self, theParent):
QTextBrowser.__init__(self) QTextBrowser.__init__(self, theParent)
logger.debug("Initialising DocViewer ...") logger.debug("Initialising GuiDocViewer ...")
# Class Variables # Class Variables
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theProject = theProject
self.theParent = theParent self.theParent = theParent
self.theTheme = theParent.theTheme self.theTheme = theParent.theTheme
self.theProject = theParent.theProject
self.theHandle = None self.theHandle = None
self.qDocument = self.document() self.qDocument = self.document()
@@ -70,7 +70,7 @@ class GuiDocViewer(QTextBrowser):
self.anchorClicked.connect(self._linkClicked) self.anchorClicked.connect(self._linkClicked)
self.setFocusPolicy(Qt.StrongFocus) self.setFocusPolicy(Qt.StrongFocus)
logger.debug("DocViewer initialisation complete") logger.debug("GuiDocViewer initialisation complete")
# Connect Functions # Connect Functions
self.setSelectedHandle = self.theParent.treeView.setSelectedHandle self.setSelectedHandle = self.theParent.treeView.setSelectedHandle
@@ -268,6 +268,21 @@ class GuiDocViewer(QTextBrowser):
logger.verbose("Cursor moved to line %d" % theLine) logger.verbose("Cursor moved to line %d" % theLine)
return True return True
##
# Slots
##
def _linkClicked(self, theURL):
"""Slot for a link in the document being clicked.
"""
theLink = theURL.url()
logger.verbose("Clicked link: '%s'" % theLink)
if len(theLink) > 0:
theBits = theLink.split("=")
if len(theBits) == 2:
self.loadFromTag(theBits[1])
return
## ##
# Events # Events
## ##
@@ -293,17 +308,6 @@ class GuiDocViewer(QTextBrowser):
self.setTextCursor(theCursor) self.setTextCursor(theCursor)
return return
def _linkClicked(self, theURL):
"""Slot for a link in the document being clicked.
"""
theLink = theURL.url()
logger.verbose("Clicked link: '%s'" % theLink)
if len(theLink) > 0:
theBits = theLink.split("=")
if len(theBits) == 2:
self.loadFromTag(theBits[1])
return
def _makeStyleSheet(self): def _makeStyleSheet(self):
"""Generate an appropriate style sheet for the document viewer, """Generate an appropriate style sheet for the document viewer,
based on the current syntax highlighter theme, based on the current syntax highlighter theme,
+5 -5
View File
@@ -30,7 +30,7 @@ import nw
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QIcon, QPixmap from PyQt5.QtGui import QFont, QIcon, QPixmap
from PyQt5.QtWidgets import QFrame, QGridLayout, QLabel from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel
from nw.constants import ( from nw.constants import (
nwLabels, nwItemClass, nwItemType, nwItemLayout, nwUnicode nwLabels, nwItemClass, nwItemType, nwItemLayout, nwUnicode
@@ -38,15 +38,15 @@ from nw.constants import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiItemDetails(QFrame): class GuiItemDetails(QWidget):
def __init__(self, theParent, theProject): def __init__(self, theParent):
QFrame.__init__(self, theParent) QWidget.__init__(self, theParent)
logger.debug("Initialising GuiItemDetails ...") logger.debug("Initialising GuiItemDetails ...")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
self.theProject = theProject self.theProject = theParent.theProject
self.theTheme = theParent.theTheme self.theTheme = theParent.theTheme
self.theHandle = None self.theHandle = None
+4 -4
View File
@@ -39,13 +39,13 @@ logger = logging.getLogger(__name__)
class GuiMainMenu(QMenuBar): class GuiMainMenu(QMenuBar):
def __init__(self, theParent, theProject): def __init__(self, theParent):
QMenuBar.__init__(self, theParent) QMenuBar.__init__(self, theParent)
logger.debug("Initialising Main Menu ...") logger.debug("Initialising GuiMainMenu ...")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
self.theProject = theProject self.theProject = theParent.theProject
self._buildProjectMenu() self._buildProjectMenu()
self._buildDocumentMenu() self._buildDocumentMenu()
@@ -60,7 +60,7 @@ class GuiMainMenu(QMenuBar):
self._moveTreeItem = self.theParent.treeView.moveTreeItem self._moveTreeItem = self.theParent.treeView.moveTreeItem
self._newTreeItem = self.theParent.treeView.newTreeItem self._newTreeItem = self.theParent.treeView.newTreeItem
logger.debug("Main Menu initialisation complete") logger.debug("GuiMainMenu initialisation complete")
return return
+27 -13
View File
@@ -39,7 +39,7 @@ from nw.constants import nwKeyWords, nwLabels, nwOutline
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiProjectOutline(QTreeWidget): class GuiOutline(QTreeWidget):
DEF_WIDTH = { DEF_WIDTH = {
nwOutline.TITLE : 200, nwOutline.TITLE : 200,
@@ -79,17 +79,17 @@ class GuiProjectOutline(QTreeWidget):
nwOutline.SYNOP : False, nwOutline.SYNOP : False,
} }
def __init__(self, theParent, theProject): def __init__(self, theParent):
QTreeWidget.__init__(self, theParent) QTreeWidget.__init__(self, theParent)
logger.debug("Initialising ProjectOutline ...") logger.debug("Initialising GuiOutline ...")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
self.theProject = theProject self.theProject = theParent.theProject
self.theTheme = theParent.theTheme self.theTheme = theParent.theTheme
self.theIndex = theParent.theIndex self.theIndex = theParent.theIndex
self.optState = theProject.optState self.optState = theParent.theProject.optState
self.headerMenu = GuiOutlineHeaderMenu(self) self.headerMenu = GuiOutlineHeaderMenu(self)
self.firstView = True self.firstView = True
@@ -100,6 +100,7 @@ class GuiProjectOutline(QTreeWidget):
self.setExpandsOnDoubleClick(False) self.setExpandsOnDoubleClick(False)
self.setDragEnabled(False) self.setDragEnabled(False)
self.itemDoubleClicked.connect(self._treeDoubleClick) self.itemDoubleClicked.connect(self._treeDoubleClick)
self.itemSelectionChanged.connect(self._itemSelected)
iPx = self.theTheme.textIconSize iPx = self.theTheme.textIconSize
self.setIconSize(QSize(iPx, iPx)) self.setIconSize(QSize(iPx, iPx))
@@ -120,7 +121,7 @@ class GuiProjectOutline(QTreeWidget):
self.clearOutline() self.clearOutline()
self.headerMenu.setHiddenState(self.colHidden) self.headerMenu.setHiddenState(self.colHidden)
logger.debug("ProjectOutline initialisation complete") logger.debug("GuiOutline initialisation complete")
return return
@@ -198,6 +199,18 @@ class GuiProjectOutline(QTreeWidget):
self.theParent.openDocument(tHandle, tLine - 1) self.theParent.openDocument(tHandle, tLine - 1)
return return
def _itemSelected(self):
"""Extract the handle and line number of the currently selected
title, and send it to the details panel.
"""
selItems = self.selectedItems()
if selItems:
tHandle = selItems[0].data(self.colIndex[nwOutline.TITLE], Qt.UserRole)
sTitle = selItems[0].data(self.colIndex[nwOutline.LINE], Qt.UserRole)
logger.verbose("User selected entry %s:%s" % (tHandle, sTitle))
self.theParent.projMeta.showItem(tHandle, sTitle)
return
def _headerRightClick(self, clickPos): def _headerRightClick(self, clickPos):
"""Show the header column menu. """Show the header column menu.
""" """
@@ -233,7 +246,7 @@ class GuiProjectOutline(QTreeWidget):
# Load whatever we saved last time, regardless of wether it # Load whatever we saved last time, regardless of wether it
# contains the correct names or number of columns. The names # contains the correct names or number of columns. The names
# must be valid though. # must be valid though.
tempOrder = self.optState.getValue("GuiProjectOutline", "headerOrder", []) tempOrder = self.optState.getValue("GuiOutline", "headerOrder", [])
treeOrder = [] treeOrder = []
for hName in tempOrder: for hName in tempOrder:
try: try:
@@ -256,14 +269,14 @@ class GuiProjectOutline(QTreeWidget):
# We load whatever column widths and hidden states we find in # We load whatever column widths and hidden states we find in
# the file, and leave the rest in their default state. # the file, and leave the rest in their default state.
tmpWidth = self.optState.getValue("GuiProjectOutline", "columnWidth", {}) tmpWidth = self.optState.getValue("GuiOutline", "columnWidth", {})
for hName in tmpWidth: for hName in tmpWidth:
try: try:
self.colWidth[nwOutline[hName]] = tmpWidth[hName] self.colWidth[nwOutline[hName]] = tmpWidth[hName]
except: except:
logger.warning("Ignored unknown outline column '%s'" % str(hName)) logger.warning("Ignored unknown outline column '%s'" % str(hName))
tmpHidden = self.optState.getValue("GuiProjectOutline", "columnHidden", {}) tmpHidden = self.optState.getValue("GuiOutline", "columnHidden", {})
for hName in tmpHidden: for hName in tmpHidden:
try: try:
self.colHidden[nwOutline[hName]] = tmpHidden[hName] self.colHidden[nwOutline[hName]] = tmpHidden[hName]
@@ -304,9 +317,9 @@ class GuiProjectOutline(QTreeWidget):
if not logHidden and logWidth > 0: if not logHidden and logWidth > 0:
colWidth[hName] = logWidth colWidth[hName] = logWidth
self.optState.setValue("GuiProjectOutline", "headerOrder", treeOrder) self.optState.setValue("GuiOutline", "headerOrder", treeOrder)
self.optState.setValue("GuiProjectOutline", "columnWidth", colWidth) self.optState.setValue("GuiOutline", "columnWidth", colWidth)
self.optState.setValue("GuiProjectOutline", "columnHidden", colHidden) self.optState.setValue("GuiOutline", "columnHidden", colHidden)
self.optState.saveSettings() self.optState.saveSettings()
return return
@@ -415,6 +428,7 @@ class GuiProjectOutline(QTreeWidget):
newItem.setText(self.colIndex[nwOutline.LABEL], nwItem.itemName) newItem.setText(self.colIndex[nwOutline.LABEL], nwItem.itemName)
newItem.setIcon(self.colIndex[nwOutline.LABEL], self.theTheme.getIcon("proj_document")) newItem.setIcon(self.colIndex[nwOutline.LABEL], self.theTheme.getIcon("proj_document"))
newItem.setText(self.colIndex[nwOutline.LINE], sTitle[1:].lstrip("0")) newItem.setText(self.colIndex[nwOutline.LINE], sTitle[1:].lstrip("0"))
newItem.setData(self.colIndex[nwOutline.LINE], Qt.UserRole, sTitle)
newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"]) newItem.setText(self.colIndex[nwOutline.SYNOP], novIdx["synopsis"])
newItem.setText(self.colIndex[nwOutline.CCOUNT], str(novIdx["cCount"])) newItem.setText(self.colIndex[nwOutline.CCOUNT], str(novIdx["cCount"]))
newItem.setText(self.colIndex[nwOutline.WCOUNT], str(novIdx["wCount"])) newItem.setText(self.colIndex[nwOutline.WCOUNT], str(novIdx["wCount"]))
@@ -438,7 +452,7 @@ class GuiProjectOutline(QTreeWidget):
return newItem return newItem
# END Class GuiProjectOutline # END Class GuiOutline
class GuiOutlineHeaderMenu(QMenu): class GuiOutlineHeaderMenu(QMenu):
+301
View File
@@ -0,0 +1,301 @@
# -*- coding: utf-8 -*-
"""novelWriter GUI Project Outline
novelWriter GUI Project Outline
===================================
Class holding the project outline view
File History:
Created: 2020-06-02 [0.7.0]
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging
import nw
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QScrollArea, QWidget, QGridLayout, QHBoxLayout, QGroupBox, QLabel, QSizePolicy
)
from nw.constants import nwLabels, nwKeyWords
from nw.common import checkInt
logger = logging.getLogger(__name__)
class GuiOutlineDetails(QScrollArea):
LVL_MAP = {
"H1" : "Title",
"H2" : "Chapter",
"H3" : "Scene",
"H4" : "Section"
}
def __init__(self, theParent):
QScrollArea.__init__(self, theParent)
logger.debug("Initialising GuiOutlineDetails ...")
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theParent.theProject
self.theTheme = theParent.theTheme
self.theIndex = theParent.theIndex
self.optState = theParent.theProject.optState
# Sizes
minTitle = 30*self.theTheme.textNWidth
maxTitle = 40*self.theTheme.textNWidth
wCount = self.theTheme.getTextWidth("999,999")
hSpace = int(0.8*self.theTheme.textNWidth)
vSpace = int(0.2*self.theTheme.textNHeight)
# Details Area
self.titleLabel = QLabel("<b>Title</b>")
self.fileLabel = QLabel("<b>Document</b>")
self.itemLabel = QLabel("<b>Status</b>")
self.titleValue = QLabel("")
self.fileValue = QLabel("")
self.itemValue = QLabel("")
self.titleValue.setMinimumWidth(minTitle)
self.titleValue.setMaximumWidth(maxTitle)
self.fileValue.setMinimumWidth(minTitle)
self.fileValue.setMaximumWidth(maxTitle)
self.itemValue.setMinimumWidth(minTitle)
self.itemValue.setMaximumWidth(maxTitle)
# Stats Area
self.cCLabel = QLabel("<b>Characters</b>")
self.wCLabel = QLabel("<b>Words</b>")
self.pCLabel = QLabel("<b>Paragraphs</b>")
self.cCValue = QLabel("")
self.wCValue = QLabel("")
self.pCValue = QLabel("")
self.cCValue.setMinimumWidth(wCount)
self.wCValue.setMinimumWidth(wCount)
self.pCValue.setMinimumWidth(wCount)
self.cCValue.setAlignment(Qt.AlignRight)
self.wCValue.setAlignment(Qt.AlignRight)
self.pCValue.setAlignment(Qt.AlignRight)
# Synopsis
self.synopLabel = QLabel("<b>Synopsis</b>")
self.synopValue = QLabel("")
self.synopLWrap = QHBoxLayout()
self.synopValue.setWordWrap(True)
self.synopValue.setAlignment(Qt.AlignTop | Qt.AlignLeft)
self.synopLWrap.addWidget(self.synopValue, 1)
# Tags
self.povKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
self.chrKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.CHAR_KEY])
self.pltKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.PLOT_KEY])
self.timKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.TIME_KEY])
self.wldKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.WORLD_KEY])
self.objKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.OBJECT_KEY])
self.entKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.ENTITY_KEY])
self.cstKeyLabel = QLabel("<b>%s</b>" % nwLabels.KEY_NAME[nwKeyWords.CUSTOM_KEY])
self.povKeyLWrap = QHBoxLayout()
self.chrKeyLWrap = QHBoxLayout()
self.pltKeyLWrap = QHBoxLayout()
self.timKeyLWrap = QHBoxLayout()
self.wldKeyLWrap = QHBoxLayout()
self.objKeyLWrap = QHBoxLayout()
self.entKeyLWrap = QHBoxLayout()
self.cstKeyLWrap = QHBoxLayout()
self.povKeyValue = QLabel("")
self.chrKeyValue = QLabel("")
self.pltKeyValue = QLabel("")
self.timKeyValue = QLabel("")
self.wldKeyValue = QLabel("")
self.objKeyValue = QLabel("")
self.entKeyValue = QLabel("")
self.cstKeyValue = QLabel("")
self.povKeyValue.setWordWrap(True)
self.chrKeyValue.setWordWrap(True)
self.pltKeyValue.setWordWrap(True)
self.timKeyValue.setWordWrap(True)
self.wldKeyValue.setWordWrap(True)
self.objKeyValue.setWordWrap(True)
self.entKeyValue.setWordWrap(True)
self.cstKeyValue.setWordWrap(True)
self.povKeyValue.linkActivated.connect(self._tagClicked)
self.chrKeyValue.linkActivated.connect(self._tagClicked)
self.pltKeyValue.linkActivated.connect(self._tagClicked)
self.timKeyValue.linkActivated.connect(self._tagClicked)
self.wldKeyValue.linkActivated.connect(self._tagClicked)
self.objKeyValue.linkActivated.connect(self._tagClicked)
self.entKeyValue.linkActivated.connect(self._tagClicked)
self.cstKeyValue.linkActivated.connect(self._tagClicked)
self.povKeyLWrap.addWidget(self.povKeyValue, 1)
self.chrKeyLWrap.addWidget(self.chrKeyValue, 1)
self.pltKeyLWrap.addWidget(self.pltKeyValue, 1)
self.timKeyLWrap.addWidget(self.timKeyValue, 1)
self.wldKeyLWrap.addWidget(self.wldKeyValue, 1)
self.objKeyLWrap.addWidget(self.objKeyValue, 1)
self.entKeyLWrap.addWidget(self.entKeyValue, 1)
self.cstKeyLWrap.addWidget(self.cstKeyValue, 1)
# Selected Item Details
self.mainGroup = QGroupBox("Title Details", self)
self.mainForm = QGridLayout()
self.mainGroup.setLayout(self.mainForm)
self.mainForm.addWidget(self.titleLabel, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.titleValue, 0, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.cCLabel, 0, 2, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.cCValue, 0, 3, 1, 1, Qt.AlignTop | Qt.AlignRight)
self.mainForm.addWidget(self.fileLabel, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.fileValue, 1, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.wCLabel, 1, 2, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.wCValue, 1, 3, 1, 1, Qt.AlignTop | Qt.AlignRight)
self.mainForm.addWidget(self.itemLabel, 2, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.itemValue, 2, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.pCLabel, 2, 2, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addWidget(self.pCValue, 2, 3, 1, 1, Qt.AlignTop | Qt.AlignRight)
self.mainForm.addWidget(self.synopLabel, 3, 0, 1, 4, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.addLayout(self.synopLWrap, 4, 0, 1, 4, Qt.AlignTop | Qt.AlignLeft)
self.mainForm.setColumnStretch(1, 1)
self.mainForm.setRowStretch(4, 1)
self.mainForm.setHorizontalSpacing(hSpace)
self.mainForm.setVerticalSpacing(vSpace)
# Selected Item Tags
self.tagsGroup = QGroupBox("Reference Tags", self)
self.tagsForm = QGridLayout()
self.tagsGroup.setLayout(self.tagsForm)
self.tagsForm.addWidget(self.povKeyLabel, 0, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.povKeyLWrap, 0, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addWidget(self.chrKeyLabel, 1, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.chrKeyLWrap, 1, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addWidget(self.pltKeyLabel, 2, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.pltKeyLWrap, 2, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addWidget(self.timKeyLabel, 3, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.timKeyLWrap, 3, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addWidget(self.wldKeyLabel, 4, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.wldKeyLWrap, 4, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addWidget(self.objKeyLabel, 5, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.objKeyLWrap, 5, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addWidget(self.entKeyLabel, 6, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.entKeyLWrap, 6, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addWidget(self.cstKeyLabel, 7, 0, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.addLayout(self.cstKeyLWrap, 7, 1, 1, 1, Qt.AlignTop | Qt.AlignLeft)
self.tagsForm.setColumnStretch(1, 1)
self.tagsForm.setRowStretch(7, 1)
self.tagsForm.setHorizontalSpacing(hSpace)
self.tagsForm.setVerticalSpacing(vSpace)
# Assemble
self.outerWidget = QWidget()
self.outerBox = QHBoxLayout()
self.outerBox.addWidget(self.mainGroup, 0)
self.outerBox.addWidget(self.tagsGroup, 1)
# self.outerBox.addStretch(1)
self.outerWidget.setLayout(self.outerBox)
self.setWidget(self.outerWidget)
self.show()
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.setWidgetResizable(True)
logger.debug("GuiOutlineDetails initialisation complete")
return
def showItem(self, tHandle, sTitle):
"""Update the content of the tree with the given handle and line
number pointing to a header.
"""
try:
nwItem = self.theProject.projTree[tHandle]
novIdx = self.theIndex.novelIndex[tHandle][sTitle]
theRefs = self.theIndex.getReferences(tHandle, sTitle)
except:
return False
if novIdx["level"] in self.LVL_MAP:
self.titleLabel.setText("<b>%s</b>" % self.LVL_MAP[novIdx["level"]])
else:
self.titleLabel.setText("<b>Title</b>")
self.titleValue.setText(novIdx["title"])
self.fileValue.setText(nwItem.itemName)
self.itemValue.setText(nwItem.itemStatus)
self.cCValue.setText("{:n}".format(checkInt(novIdx["cCount"], 0)))
self.wCValue.setText("{:n}".format(checkInt(novIdx["pCount"], 0)))
self.pCValue.setText("{:n}".format(checkInt(novIdx["wCount"], 0)))
self.synopValue.setText(novIdx["synopsis"])
self.povKeyValue.setText(self._formatTags(theRefs, nwKeyWords.POV_KEY))
self.chrKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CHAR_KEY))
self.pltKeyValue.setText(self._formatTags(theRefs, nwKeyWords.PLOT_KEY))
self.timKeyValue.setText(self._formatTags(theRefs, nwKeyWords.TIME_KEY))
self.wldKeyValue.setText(self._formatTags(theRefs, nwKeyWords.WORLD_KEY))
self.objKeyValue.setText(self._formatTags(theRefs, nwKeyWords.OBJECT_KEY))
self.entKeyValue.setText(self._formatTags(theRefs, nwKeyWords.ENTITY_KEY))
self.cstKeyValue.setText(self._formatTags(theRefs, nwKeyWords.CUSTOM_KEY))
return True
##
# Slots
##
def _tagClicked(self, theLink):
"""Capture the click of a tag in the right-most column.
"""
logger.verbose("Clicked link: '%s'" % theLink)
if len(theLink) > 0:
theBits = theLink.split("=")
if len(theBits) == 2:
self.theParent.docViewer.loadFromTag(theBits[1])
self.theParent.tabWidget.setCurrentWidget(self.theParent.splitView)
return
##
# Internal Functions
##
def _formatTags(self, theRefs, theKey):
"""Format the tags as clickable links.
"""
if theKey not in theKey:
return ""
refTags = []
for tTag in theRefs[theKey]:
refTags.append("<a href='#%s=%s'>%s</a>" % (
theKey[1:], tTag, tTag
))
return ", ".join(refTags)
# END Class GuiOutlineDetails
+3 -3
View File
@@ -50,20 +50,20 @@ class GuiProjectTree(QTreeWidget):
C_EXPORT = 2 C_EXPORT = 2
C_FLAGS = 3 C_FLAGS = 3
def __init__(self, theParent, theProject): def __init__(self, theParent):
QTreeWidget.__init__(self, theParent) QTreeWidget.__init__(self, theParent)
logger.debug("Initialising GuiProjectTree ...") logger.debug("Initialising GuiProjectTree ...")
self.mainConf = nw.CONFIG self.mainConf = nw.CONFIG
self.theParent = theParent self.theParent = theParent
self.theTheme = theParent.theTheme self.theTheme = theParent.theTheme
self.theProject = theProject self.theProject = theParent.theProject
self.ctxMenu = GuiProjectTreeMenu(self)
# Tree Settings # Tree Settings
self.theMap = None self.theMap = None
self.orphRoot = None self.orphRoot = None
self.ctxMenu = GuiProjectTreeMenu(self)
self.clearTree() self.clearTree()
# Build GUI # Build GUI
+2
View File
@@ -140,6 +140,8 @@ class GuiTheme:
self.fontPixelSize = int(round(qMetric.height())) self.fontPixelSize = int(round(qMetric.height()))
self.baseIconSize = int(round(qMetric.ascent())) self.baseIconSize = int(round(qMetric.ascent()))
self.textIconSize = int(round(qMetric.ascent() + qMetric.leading())) self.textIconSize = int(round(qMetric.ascent() + qMetric.leading()))
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 Family: %s" % self.guiFont.family())
logger.verbose("GUI Font Point Size: %.2f" % self.fontPointSize) logger.verbose("GUI Font Point Size: %.2f" % self.fontPointSize)
+19 -15
View File
@@ -35,15 +35,15 @@ from time import time
from PyQt5.QtCore import Qt, QTimer from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QIcon, QPixmap, QColor, QKeySequence, QCursor from PyQt5.QtGui import QIcon, QPixmap, QColor, QKeySequence, QCursor
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
qApp, QMainWindow, QVBoxLayout, QFrame, QSplitter, QFileDialog, QShortcut, qApp, QMainWindow, QVBoxLayout, QWidget, QSplitter, QFileDialog, QShortcut,
QMessageBox, QDialog, QTabWidget QMessageBox, QDialog, QTabWidget
) )
from nw.gui import ( from nw.gui import (
GuiMainMenu, GuiMainStatus, GuiTheme, GuiProjectTree, GuiDocEditor, GuiBuildNovel, GuiDocEditor, GuiDocMerge, GuiDocSplit, GuiDocViewDetails,
GuiDocViewer, GuiItemDetails, GuiSearchBar, GuiNoticeBar, GuiDocViewDetails, GuiDocViewer, GuiItemDetails, GuiItemEditor, GuiMainMenu, GuiMainStatus,
GuiPreferences, GuiProjectSettings, GuiItemEditor, GuiProjectOutline, GuiNoticeBar, GuiOutline, GuiOutlineDetails, GuiPreferences, GuiProjectLoad,
GuiSessionLogView, GuiDocMerge, GuiDocSplit, GuiProjectLoad, GuiBuildNovel GuiProjectSettings, GuiProjectTree, GuiSearchBar, GuiSessionLogView, GuiTheme
) )
from nw.core import NWProject, NWDoc, NWIndex from nw.core import NWProject, NWDoc, NWIndex
from nw.constants import nwFiles, nwItemType, nwAlert from nw.constants import nwFiles, nwItemType, nwAlert
@@ -91,28 +91,29 @@ class GuiMain(QMainWindow):
# Main GUI Elements # Main GUI Elements
self.statusBar = GuiMainStatus(self) self.statusBar = GuiMainStatus(self)
self.noticeBar = GuiNoticeBar(self) self.noticeBar = GuiNoticeBar(self)
self.treeView = GuiProjectTree(self, self.theProject) self.treeView = GuiProjectTree(self)
self.docEditor = GuiDocEditor(self, self.theProject) self.docEditor = GuiDocEditor(self)
self.docViewer = GuiDocViewer(self, self.theProject) self.docViewer = GuiDocViewer(self)
self.viewMeta = GuiDocViewDetails(self, self.theProject) self.viewMeta = GuiDocViewDetails(self)
self.searchBar = GuiSearchBar(self) self.searchBar = GuiSearchBar(self)
self.treeMeta = GuiItemDetails(self, self.theProject) self.treeMeta = GuiItemDetails(self)
self.projView = GuiProjectOutline(self, self.theProject) self.projView = GuiOutline(self)
self.mainMenu = GuiMainMenu(self, self.theProject) self.projMeta = GuiOutlineDetails(self)
self.mainMenu = GuiMainMenu(self)
# Minor Gui Elements # Minor Gui Elements
self.statusIcons = [] self.statusIcons = []
self.importIcons = [] self.importIcons = []
# Assemble Main Window # Assemble Main Window
self.treePane = QFrame() self.treePane = QWidget()
self.treeBox = QVBoxLayout() self.treeBox = QVBoxLayout()
self.treeBox.setContentsMargins(0,0,0,0) self.treeBox.setContentsMargins(0,0,0,0)
self.treeBox.addWidget(self.treeView) self.treeBox.addWidget(self.treeView)
self.treeBox.addWidget(self.treeMeta) self.treeBox.addWidget(self.treeMeta)
self.treePane.setLayout(self.treeBox) self.treePane.setLayout(self.treeBox)
self.editPane = QFrame() self.editPane = QWidget()
self.docEdit = QVBoxLayout() self.docEdit = QVBoxLayout()
self.docEdit.setContentsMargins(0,0,0,0) self.docEdit.setContentsMargins(0,0,0,0)
self.docEdit.setSpacing(2) self.docEdit.setSpacing(2)
@@ -121,7 +122,7 @@ class GuiMain(QMainWindow):
self.docEdit.addWidget(self.docEditor) self.docEdit.addWidget(self.docEditor)
self.editPane.setLayout(self.docEdit) self.editPane.setLayout(self.docEdit)
self.viewPane = QFrame() self.viewPane = QWidget()
self.docView = QVBoxLayout() self.docView = QVBoxLayout()
self.docView.setContentsMargins(0,0,0,0) self.docView.setContentsMargins(0,0,0,0)
self.docView.setSpacing(2) self.docView.setSpacing(2)
@@ -137,6 +138,8 @@ class GuiMain(QMainWindow):
self.splitOutline = QSplitter(Qt.Vertical) self.splitOutline = QSplitter(Qt.Vertical)
self.splitOutline.addWidget(self.projView) self.splitOutline.addWidget(self.projView)
self.splitOutline.addWidget(self.projMeta)
self.splitOutline.setSizes(self.mainConf.outlnPanePos)
self.tabWidget = QTabWidget() self.tabWidget = QTabWidget()
self.tabWidget.setTabPosition(QTabWidget.East) self.tabWidget.setTabPosition(QTabWidget.East)
@@ -847,6 +850,7 @@ class GuiMain(QMainWindow):
if not self.isZenMode: if not self.isZenMode:
self.mainConf.setMainPanePos(self.splitMain.sizes()) self.mainConf.setMainPanePos(self.splitMain.sizes())
self.mainConf.setDocPanePos(self.splitView.sizes()) self.mainConf.setDocPanePos(self.splitView.sizes())
self.mainConf.setOutlinePanePos(self.splitOutline.sizes())
self.mainConf.saveConfig() self.mainConf.saveConfig()
self.reportConfErr() self.reportConfErr()
+2 -1
View File
@@ -1,5 +1,5 @@
[Main] [Main]
timestamp = 2020-05-21 14:52:36 timestamp = 2020-06-03 20:42:03
theme = default theme = default
syntax = default_light syntax = default_light
icons = typicons_grey_light icons = typicons_grey_light
@@ -13,6 +13,7 @@ treecols = 120, 30, 50
projcols = 140, 55, 140 projcols = 140, 55, 140
mainpane = 300, 800 mainpane = 300, 800
docpane = 400, 400 docpane = 400, 400
outlinepane = 500, 150
fullscreen = False fullscreen = False
[Project] [Project]