Merge pull request #115 from vkbo/tweaks

GUI Tweaks
This commit is contained in:
Veronica K. Berglyd Olsen
2019-11-03 01:09:32 +01:00
committed by GitHub
16 changed files with 228 additions and 110 deletions
+30 -3
View File
@@ -62,6 +62,8 @@ class Config:
## General
self.guiTheme = "default"
self.guiSyntax = "default_light"
## Sizes
self.winGeometry = [1100, 650]
self.treeColWidth = [120, 30, 50]
self.mainPanePos = [300, 800]
@@ -74,7 +76,7 @@ class Config:
## Text Editor
self.textFont = None
self.textSize = 12
self.textFixedW = False
self.textFixedW = True
self.textWidth = 600
self.textMargin = 40
self.tabWidth = 40
@@ -94,12 +96,16 @@ class Config:
self.spellLanguage = "en_GB"
# Backup
## Backup
self.backupPath = ""
self.backupOnClose = False
self.askBeforeBackup = True
# Path
## State
self.showRefPanel = True
self.viewComments = True
## Path
self.recentList = [""]*10
# Check Qt5 Versions
@@ -244,6 +250,11 @@ class Config:
self.backupOnClose = self._parseLine(cnfParse, cnfSec, "backuponclose", self.CNF_BOOL, self.backupOnClose)
self.askBeforeBackup = self._parseLine(cnfParse, cnfSec, "askbeforebackup", self.CNF_BOOL, self.askBeforeBackup)
## State
cnfSec = "State"
self.showRefPanel = self._parseLine(cnfParse, cnfSec, "showrefpanel", self.CNF_BOOL, self.showRefPanel)
self.viewComments = self._parseLine(cnfParse, cnfSec, "viewcomments", self.CNF_BOOL, self.viewComments)
## Path
cnfSec = "Path"
self.lastPath = self._parseLine(cnfParse, cnfSec, "lastpath", self.CNF_STR, self.lastPath)
@@ -312,6 +323,12 @@ class Config:
cnfParse.set(cnfSec,"backuponclose", str(self.backupOnClose))
cnfParse.set(cnfSec,"askbeforebackup",str(self.askBeforeBackup))
## State
cnfSec = "State"
cnfParse.add_section(cnfSec)
cnfParse.set(cnfSec,"showrefpanel",str(self.showRefPanel))
cnfParse.set(cnfSec,"viewcomments",str(self.viewComments))
## Path
cnfSec = "Path"
cnfParse.add_section(cnfSec)
@@ -385,6 +402,16 @@ class Config:
self.confChanged = True
return True
def setShowRefPanel(self, checkState):
self.showRefPanel = checkState
self.confChanged = True
return
def setViewComments(self, checkState):
self.viewComments = checkState
self.confChanged = True
return
##
# Internal Functions
##
+27
View File
@@ -32,6 +32,20 @@ class nwFiles():
# END Class nwFiles
class nwKeyWords:
TAG_KEY = "@tag"
POV_KEY = "@pov"
CHAR_KEY = "@char"
PLOT_KEY = "@plot"
TIME_KEY = "@time"
WORLD_KEY = "@location"
OBJECT_KEY = "@object"
ENTITY_KEY = "@entity"
CUSTOM_KEY = "@custom"
# END Class nwKeyWords
class nwLabels():
CLASS_NAME = {
@@ -42,6 +56,7 @@ class nwLabels():
nwItemClass.WORLD : "Locations",
nwItemClass.TIMELINE : "Timeline",
nwItemClass.OBJECT : "Objects",
nwItemClass.ENTITY : "Entity",
nwItemClass.CUSTOM : "Custom",
nwItemClass.TRASH : "Trash",
}
@@ -53,6 +68,7 @@ class nwLabels():
nwItemClass.WORLD : "L",
nwItemClass.TIMELINE : "T",
nwItemClass.OBJECT : "O",
nwItemClass.ENTITY : "E",
nwItemClass.CUSTOM : "X",
nwItemClass.TRASH : "R",
}
@@ -78,6 +94,17 @@ class nwLabels():
nwItemLayout.SCENE : "Sc",
nwItemLayout.NOTE : "Nt",
}
KEY_NAME = {
nwKeyWords.TAG_KEY : "Tag",
nwKeyWords.POV_KEY : "Point of View",
nwKeyWords.CHAR_KEY : "Characters",
nwKeyWords.PLOT_KEY : "Plot",
nwKeyWords.TIME_KEY : "Time",
nwKeyWords.WORLD_KEY : "Locations",
nwKeyWords.OBJECT_KEY : "Objects",
nwKeyWords.ENTITY_KEY : "Entities",
nwKeyWords.CUSTOM_KEY : "Custom",
}
# END Class nwLabels
+13 -16
View File
@@ -15,7 +15,7 @@ import re
import nw
from nw.convert.tokenizer import Tokenizer
from nw.constants import nwUnicode
from nw.constants import nwUnicode, nwLabels
logger = logging.getLogger(__name__)
@@ -26,7 +26,7 @@ class ToHtml(Tokenizer):
self.forPreview = False
return
def setPreview(self, forPreview):
def setPreview(self, forPreview, doComments):
"""If we're using this class to generate markdown preview, we need to make a few changes to
formatting, which is selected by this flag.
"""
@@ -34,6 +34,7 @@ class ToHtml(Tokenizer):
self.forPreview = forPreview
if forPreview:
self.doKeywords = True
self.doComments = doComments
return
@@ -118,7 +119,7 @@ class ToHtml(Tokenizer):
thisPar.append(tTemp.rstrip()+" ")
elif tType == self.T_COMMENT and self.doComments:
self.theResult += "<div class='comment'>%s</div>\n" % tText
self.theResult += self._formatComments(tText)
elif tType == self.T_KEYWORD and self.doKeywords:
self.theResult += self._formatTags(tText)
@@ -134,17 +135,6 @@ class ToHtml(Tokenizer):
if not self.forPreview:
return "<pre>@%s</pre>\n" % tText
theLabel = {
"@tag" : "Tag",
"@pov" : "Point of View",
"@char" : "Character(s)",
"@plot" : "Plot",
"@time" : "Time",
"@location" : "Location(s)",
"@object" : "Object(s)",
"@custom" : "Custom",
}
tText = "@"+tText
isValid, theBits, thePos = self.theParent.theIndex.scanThis(tText)
if not isValid or not theBits:
@@ -152,8 +142,8 @@ class ToHtml(Tokenizer):
retText = ""
refTags = []
if theBits[0] in theLabel:
retText += "<span class='tags'>%s:</span>&nbsp;" % theLabel[theBits[0]]
if theBits[0] in nwLabels.KEY_NAME:
retText += "<span class='tags'>%s:</span>&nbsp;" % nwLabels.KEY_NAME[theBits[0]]
for tTag in theBits[1:]:
refTags.append("<a href='#%s=%s'>%s</a>" % (
theBits[0][1:], tTag, tTag
@@ -162,4 +152,11 @@ class ToHtml(Tokenizer):
return "<div>%s</div>" % retText
def _formatComments(self, tText):
if not self.forPreview:
return "<div class='comment'>%s</div>\n" % tText
return "<p class='comment'>%s</p>\n" % tText
# END Class ToHtml
+3 -2
View File
@@ -31,8 +31,9 @@ class nwItemClass(Enum):
WORLD = 4
TIMELINE = 5
OBJECT = 6
CUSTOM = 7
TRASH = 8
ENTITY = 7
CUSTOM = 8
TRASH = 9
# END Enum nwItemClass
+9 -9
View File
@@ -322,17 +322,17 @@ class GuiConfigEditEditor(QWidget):
self.textFlowForm = QGridLayout(self)
self.textFlow.setLayout(self.textFlowForm)
self.textFlowFixed = QCheckBox("Fixed width",self)
self.textFlowFixed.setToolTip("Make text in editor fixed width and scale margins instead.")
self.textFlowFixed = QCheckBox("Max text width",self)
self.textFlowFixed.setToolTip("Maximum width of the text.")
if self.mainConf.textFixedW:
self.textFlowFixed.setCheckState(Qt.Checked)
else:
self.textFlowFixed.setCheckState(Qt.Unchecked)
self.textFlowWidth = QSpinBox(self)
self.textFlowWidth.setMinimum(300)
self.textFlowWidth.setMaximum(10000)
self.textFlowWidth.setSingleStep(10)
self.textFlowWidth.setValue(self.mainConf.textWidth)
self.textFlowMax = QSpinBox(self)
self.textFlowMax.setMinimum(300)
self.textFlowMax.setMaximum(10000)
self.textFlowMax.setSingleStep(10)
self.textFlowMax.setValue(self.mainConf.textWidth)
self.textFlowJustify = QCheckBox("Justify text",self)
self.textFlowJustify.setToolTip("Justify text in main document editor.")
@@ -342,7 +342,7 @@ class GuiConfigEditEditor(QWidget):
self.textFlowJustify.setCheckState(Qt.Unchecked)
self.textFlowForm.addWidget(self.textFlowFixed, 0, 0)
self.textFlowForm.addWidget(self.textFlowWidth, 0, 1)
self.textFlowForm.addWidget(self.textFlowMax, 0, 1)
self.textFlowForm.addWidget(QLabel("px"), 0, 2)
self.textFlowForm.addWidget(self.textFlowJustify, 1, 0)
self.textFlowForm.setColumnStretch(4, 1)
@@ -519,7 +519,7 @@ class GuiConfigEditEditor(QWidget):
self.mainConf.textFont = textFont
self.mainConf.textSize = textSize
textWidth = self.textFlowWidth.value()
textWidth = self.textFlowMax.value()
textFixedW = self.textFlowFixed.isChecked()
doJustify = self.textFlowJustify.isChecked()
+17 -4
View File
@@ -16,9 +16,9 @@ import nw
from time import time
from PyQt5.QtCore import Qt, QTimer, QSizeF
from PyQt5.QtWidgets import qApp, QTextEdit, QAction, QMenu, QShortcut
from PyQt5.QtWidgets import qApp, QTextEdit, QAction, QMenu, QShortcut, QMessageBox
from PyQt5.QtGui import (
QTextCursor, QTextOption, QIcon, QKeySequence, QFont, QColor, QPalette, QTextDocument
QTextCursor, QTextOption, QIcon, QKeySequence, QFont, QColor, QPalette, QTextDocument,
)
from nw.project.document import NWDoc
@@ -293,8 +293,8 @@ class GuiDocEditor(QTextEdit):
tW = self.mainConf.textWidth
wW = self.width()
tM = int((wW - sW - tW)/2)
if tM < 0:
tM = 0
if tM < self.mainConf.textMargin:
tM = self.mainConf.textMargin
docFormat = self.qDocument.rootFrame().frameFormat()
docFormat.setLeftMargin(tM)
docFormat.setRightMargin(tM)
@@ -332,6 +332,19 @@ class GuiDocEditor(QTextEdit):
def isEmpty(self):
return self.qDocument.isEmpty()
def revealLocation(self):
if self.theHandle is not None:
msgBox = QMessageBox()
msgBox.information(self, "File Location", (
"File details for the currently open file<br>"
"Handle: {handle:s}<br>"
"Location: {fileLoc:s}"
).format(
handle = self.theHandle,
fileLoc = str(self.nwDocument.fileLoc)
))
return
##
# Document Events and Maintenance
##
+36 -15
View File
@@ -18,7 +18,7 @@ from PyQt5.QtGui import QIcon, QFont, QColor
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem, QAbstractItemView, QApplication
from nw.project.item import NWItem
from nw.enum import nwItemType, nwItemClass, nwAlert
from nw.enum import nwItemType, nwItemClass, nwItemLayout, nwAlert
from nw.constants import nwLabels
logger = logging.getLogger(__name__)
@@ -62,9 +62,14 @@ class GuiDocTree(QTreeWidget):
self.setDragEnabled(True)
self.setDragDropMode(QAbstractItemView.InternalMove)
# But don't allow drop on root level
trRoot = self.invisibleRootItem()
trRoot.setFlags(trRoot.flags() ^ Qt.ItemIsDropEnabled)
# Set Multiple Selection by CTRL
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
# Disabled for now, until the merge files option has been added
# self.setSelectionMode(QAbstractItemView.ExtendedSelection)
# self.setSelectionBehavior(QAbstractItemView.SelectRows)
for colN in range(len(self.mainConf.treeColWidth)):
self.setColumnWidth(colN,self.mainConf.treeColWidth[colN])
@@ -183,7 +188,7 @@ class GuiDocTree(QTreeWidget):
nIndex = tIndex + nStep
if nIndex < 0 or nIndex >= nChild:
return False
cItem = self.takeTopLevelItem(tIndex)
cItem = self.takeTopLevelItem(tIndex)
self.insertTopLevelItem(nIndex, cItem)
else:
tIndex = pItem.indexOfChild(tItem)
@@ -191,7 +196,7 @@ class GuiDocTree(QTreeWidget):
nIndex = tIndex + nStep
if nIndex < 0 or nIndex >= nChild:
return False
cItem = pItem.takeChild(tIndex)
cItem = pItem.takeChild(tIndex)
pItem.insertChild(nIndex, cItem)
self.clearSelection()
cItem.setSelected(True)
@@ -446,17 +451,28 @@ class GuiDocTree(QTreeWidget):
return
def _updateItemParent(self, tHandle):
"""Update the parent handle of an item so that the information in the project is consistent
with the treeView. Also move the word count over to the new parent tree.
"""
trItemS = self._getTreeItem(tHandle)
nwItemS = self.theProject.getItem(tHandle)
trItemP = trItemS.parent()
if trItemP is None:
logger.error("Failed to find new parent item of %s" % tHandle)
return
return False
pHandle = trItemP.text(self.C_HANDLE)
wC = int(trItemS.text(self.C_COUNT))
self.propagateCount(tHandle, -wC)
nwItemS.setParent(pHandle)
self.propagateCount(tHandle, wC)
self.setTreeItemValues(tHandle)
self.theProject.setProjectChanged(True)
return
logger.debug("The parent of item %s has been changed to %s" % (tHandle,pHandle))
return True
def _moveOrphanedItem(self, tHandle, dHandle):
trItemS = self._getTreeItem(tHandle)
@@ -505,25 +521,30 @@ class GuiDocTree(QTreeWidget):
dnItem = self.theProject.getItem(dHandle)
isSame = snItem.itemClass == dnItem.itemClass
isNone = snItem.itemClass == nwItemClass.NO_CLASS
isNote = snItem.itemLayout == nwItemLayout.NOTE
onFile = dnItem.itemType == nwItemType.FILE
isRoot = snItem.itemType == nwItemType.ROOT
onRoot = dnItem.itemType == nwItemType.ROOT
isOnTop = self.dropIndicatorPosition() == QAbstractItemView.OnItem
isAbove = self.dropIndicatorPosition() == QAbstractItemView.AboveItem
isBelow = self.dropIndicatorPosition() == QAbstractItemView.BelowItem
if (isSame or isNone) and not (onFile and isOnTop) and not isRoot:
logger.verbose("Drag'n'drop of item %s accepted" % sHandle)
if (isSame or isNone or isNote) and not (onFile and isOnTop) and not isRoot:
logger.debug("Drag'n'drop of item %s accepted" % sHandle)
QTreeWidget.dropEvent(self, theEvent)
if isNone:
self._moveOrphanedItem(sHandle, dHandle)
self._cleanOrphanedRoot()
else:
self._updateItemParent(sHandle)
elif isRoot and (isAbove or isBelow) and onRoot:
logger.verbose("Drag'n'drop of item %s accepted" % sHandle)
QTreeWidget.dropEvent(self, theEvent)
if not isSame:
logger.debug("Item %s class has been changed from %s to %s" % (
sHandle,
snItem.itemClass.name,
dnItem.itemClass.name
))
snItem.setClass(dnItem.itemClass)
self.setTreeItemValues(sHandle)
else:
logger.verbose("Drag'n'drop of item %s not accepted" % sHandle)
logger.debug("Drag'n'drop of item %s not accepted" % sHandle)
self.makeAlert("The item cannot be moved to that location.", nwAlert.ERROR)
return
+14 -9
View File
@@ -105,7 +105,7 @@ class GuiDocViewer(QTextBrowser):
logger.debug("Generating preview for item %s" % tHandle)
sPos = self.verticalScrollBar().value()
aDoc = ToHtml(self.theProject, self.theParent)
aDoc.setPreview(True)
aDoc.setPreview(True, self.mainConf.viewComments)
aDoc.setText(tHandle)
aDoc.doAutoReplace()
aDoc.tokenizeText()
@@ -117,10 +117,14 @@ class GuiDocViewer(QTextBrowser):
self.theHandle = tHandle
self.theProject.setLastViewed(tHandle)
self.theParent.docMeta.refreshReferences(tHandle)
self.theParent.viewMeta.refreshReferences(tHandle)
return True
def reloadText(self):
self.loadText(self.theHandle)
return
def loadFromTag(self, theTag):
logger.debug("Loading document from tag '%s'" % theTag)
@@ -180,10 +184,6 @@ class GuiDocViewer(QTextBrowser):
"a {{"
" color: rgb({aColR},{aColG},{aColB});"
"}}\n"
"pre {{"
" color: rgb({cColR},{cColG},{cColB});"
" font-size: {preSize:.1f}pt;"
"}}\n"
"mark {{"
" color: rgb({eColR},{eColG},{eColB});"
"}}\n"
@@ -197,6 +197,11 @@ class GuiDocViewer(QTextBrowser):
" color: rgb({kColR},{kColG},{kColB});"
" font-wright: bold;"
"}}\n"
".comment {{"
" color: rgb({cColR},{cColG},{cColB});"
" margin-left: 1em;"
" margin-right: 1em;"
"}}\n"
).format(
textSize = self.mainConf.textSize,
preSize = self.mainConf.textSize*0.9,
@@ -212,9 +217,9 @@ class GuiDocViewer(QTextBrowser):
eColR = self.theTheme.colEmph[0],
eColG = self.theTheme.colEmph[1],
eColB = self.theTheme.colEmph[2],
aColR = self.theTheme.colLink[0],
aColG = self.theTheme.colLink[1],
aColB = self.theTheme.colLink[2],
aColR = self.theTheme.colVal[0],
aColG = self.theTheme.colVal[1],
aColB = self.theTheme.colVal[2],
kColR = self.theTheme.colKey[0],
kColG = self.theTheme.colKey[1],
kColB = self.theTheme.colKey[2],
+6 -11
View File
@@ -6,7 +6,7 @@
Class holding the document view details panel
File History:
Created: 2019-09-31 [0.3.2]
Created: 2019-10-31 [0.3.2]
"""
@@ -20,7 +20,7 @@ from PyQt5.QtWidgets import (
QSizePolicy, QCheckBox, QGridLayout
)
from nw.constants import nwLabels
from nw.constants import nwLabels
logger = logging.getLogger(__name__)
@@ -48,7 +48,6 @@ class GuiDocViewDetails(QWidget):
self.showHide.setToolButtonStyle(Qt.ToolButtonIconOnly)
self.showHide.setArrowType(Qt.DownArrow)
self.showHide.setCheckable(True)
self.showHide.setChecked(True)
self.showHide.setIconSize(QSize(16,16))
self.showHide.toggled.connect(self._doShowHide)
@@ -66,8 +65,7 @@ class GuiDocViewDetails(QWidget):
self.scrollBox.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scrollBox.setFrameStyle(QFrame.NoFrame)
self.scrollBox.setWidgetResizable(True)
self.scrollBox.setMaximumHeight(300)
self.scrollBox.setMinimumHeight(60)
self.scrollBox.setFixedHeight(80)
self.scrollBox.setWidget(self.refList)
self.outerBox.addWidget(self.showHide, 0, 0)
@@ -79,6 +77,8 @@ class GuiDocViewDetails(QWidget):
self.setLayout(self.outerBox)
self.setContentsMargins(0,0,0,0)
self._doShowHide(self.mainConf.showRefPanel)
logger.debug("DocViewDetails initialisation complete")
return
@@ -91,12 +91,6 @@ class GuiDocViewDetails(QWidget):
return
theRefs = self.theParent.theIndex.buildReferenceList(tHandle)
if theRefs:
self.setVisible(True)
else:
self.setVisible(False)
return
theList = []
for tHandle in theRefs:
tItem = self.theProject.getItem(tHandle)
@@ -120,6 +114,7 @@ class GuiDocViewDetails(QWidget):
def _doShowHide(self, chState):
self.scrollBox.setVisible(chState)
self.mainConf.setShowRefPanel(chState)
if chState:
self.showHide.setArrowType(Qt.DownArrow)
else:
+25 -1
View File
@@ -112,6 +112,11 @@ class GuiMainMenu(QMenuBar):
self.toolsSpellCheck.setChecked(False)
return True
def _toggleViewComments(self):
self.mainConf.setViewComments(self.docViewComments.isChecked())
self.theParent.docViewer.reloadText()
return True
def _showAbout(self):
listPrefix = "&nbsp;&nbsp;&bull;&nbsp;&nbsp;"
aboutMsg = (
@@ -163,6 +168,10 @@ class GuiMainMenu(QMenuBar):
self.updateRecentProjects()
return True
def _showDocumentLocation(self):
self.theParent.docEditor.revealLocation()
return True
##
# Menu Builders
##
@@ -235,6 +244,7 @@ class GuiMainMenu(QMenuBar):
self.rootItems[nwItemClass.WORLD] = QAction("Location Root", rootMenu)
self.rootItems[nwItemClass.TIMELINE] = QAction("Timeline Root", rootMenu)
self.rootItems[nwItemClass.OBJECT] = QAction("Object Root", rootMenu)
self.rootItems[nwItemClass.ENTITY] = QAction("Entity Root", rootMenu)
self.rootItems[nwItemClass.CUSTOM] = QAction("Custom Root", rootMenu)
nCount = 0
for itemClass in self.rootItems.keys():
@@ -330,10 +340,24 @@ class GuiMainMenu(QMenuBar):
menuItem.triggered.connect(self.theParent.closeDocViewer)
self.docuMenu.addAction(menuItem)
# Document > Toggle View Comments
self.docViewComments = QAction("View Comments", self)
self.docViewComments.setStatusTip("Show comments in view panel")
self.docViewComments.setCheckable(True)
self.docViewComments.setChecked(self.mainConf.viewComments)
self.docViewComments.toggled.connect(self._toggleViewComments)
self.docuMenu.addAction(self.docViewComments)
# Document > Separator
self.docuMenu.addSeparator()
# Document > Close Preview
# Document > Show File Details
menuItem = QAction("Show File Details", self)
menuItem.setStatusTip("Shows a message box with the document location in the project folder")
menuItem.triggered.connect(self._showDocumentLocation)
self.docuMenu.addAction(menuItem)
# Document > Import From File
menuItem = QAction("Import from File", self)
menuItem.setStatusTip("Import document from a text or markdown file")
menuItem.setShortcut("Ctrl+Shift+I")
+5 -5
View File
@@ -77,7 +77,7 @@ class GuiMain(QMainWindow):
self.noticeBar = GuiNoticeBar(self)
self.docEditor = GuiDocEditor(self, self.theProject)
self.docViewer = GuiDocViewer(self, self.theProject)
self.docMeta = GuiDocViewDetails(self, self.theProject)
self.viewMeta = GuiDocViewDetails(self, self.theProject)
self.searchBar = GuiSearchBar(self)
self.treeMeta = GuiDocDetails(self, self.theProject)
self.treeView = GuiDocTree(self, self.theProject)
@@ -107,7 +107,7 @@ class GuiMain(QMainWindow):
self.docView = QVBoxLayout()
self.docView.setContentsMargins(0,0,0,0)
self.docView.addWidget(self.docViewer)
self.docView.addWidget(self.docMeta)
self.docView.addWidget(self.viewMeta)
self.docView.setStretch(0, 1)
self.viewPane.setLayout(self.docView)
@@ -313,7 +313,7 @@ class GuiMain(QMainWindow):
return True
def saveProject(self):
def saveProject(self, isAuto=False):
"""Save the current project.
"""
if not self.hasProject:
@@ -327,7 +327,7 @@ class GuiMain(QMainWindow):
return False
self.treeView.saveTreeOrder()
self.theProject.saveProject()
self.theProject.saveProject(isAuto)
self.theIndex.saveIndex()
self.mainMenu.updateRecentProjects()
@@ -703,7 +703,7 @@ class GuiMain(QMainWindow):
def _autoSaveProject(self):
if self.hasProject and self.theProject.projChanged and self.theProject.projPath is not None:
logger.debug("Autosaving project")
self.saveProject()
self.saveProject(isAuto=True)
return
def _autoSaveDocument(self):
+1 -3
View File
@@ -17,18 +17,16 @@ from os import path, mkdir, listdir
from shutil import make_archive
from datetime import datetime
from nw.enum import nwAlert
from nw.enum import nwAlert
logger = logging.getLogger(__name__)
class NWBackup():
def __init__(self, theParent, theProject):
self.mainConf = nw.CONFIG
self.theParent = theParent
self.theProject = theProject
return
def zipIt(self):
+3 -1
View File
@@ -31,6 +31,7 @@ class NWDoc():
self.theItem = None
self.docHandle = None
self.docEditable = False
self.fileLoc = None
# Internal Mapping
self.makeAlert = self.theParent.makeAlert
@@ -58,7 +59,8 @@ class NWDoc():
self.docEditable = False
docDir, docFile = self._assemblePath(self.FILE_MN)
logger.debug("Opening document %s" % path.join(docDir,docFile))
self.fileLoc = path.join(docDir,docFile)
logger.debug("Opening document %s" % self.fileLoc)
dataDir = path.join(self.theProject.projPath, docDir)
docPath = path.join(dataDir, docFile)
+30 -27
View File
@@ -14,37 +14,37 @@ import logging
import json
import nw
from os import path
from os import path
from nw.project.document import NWDoc
from nw.enum import nwItemType, nwItemClass, nwItemLayout
from nw.constants import nwFiles
from nw.constants import nwFiles, nwKeyWords
from nw.enum import nwAlert
logger = logging.getLogger(__name__)
class NWIndex():
TAG_KEY = "@tag"
POV_KEY = "@pov"
CHAR_KEY = "@char"
PLOT_KEY = "@plot"
TIME_KEY = "@time"
WORLD_KEY = "@location"
OBJECT_KEY = "@object"
CUSTOM_KEY = "@custom"
NOTE_KEYS = [TAG_KEY]
NOVEL_KEYS = [PLOT_KEY, POV_KEY, CHAR_KEY, WORLD_KEY, TIME_KEY, OBJECT_KEY, CUSTOM_KEY]
VALID_KEYS = [TAG_KEY, PLOT_KEY, POV_KEY, CHAR_KEY, WORLD_KEY, TIME_KEY, OBJECT_KEY, CUSTOM_KEY]
VALID_KEYS = [
nwKeyWords.TAG_KEY,
nwKeyWords.PLOT_KEY,
nwKeyWords.POV_KEY,
nwKeyWords.CHAR_KEY,
nwKeyWords.WORLD_KEY,
nwKeyWords.TIME_KEY,
nwKeyWords.OBJECT_KEY,
nwKeyWords.ENTITY_KEY,
nwKeyWords.CUSTOM_KEY
]
TAG_CLASS = {
CHAR_KEY : [nwItemClass.CHARACTER, 1],
POV_KEY : [nwItemClass.CHARACTER, 2],
PLOT_KEY : [nwItemClass.PLOT, 1],
TIME_KEY : [nwItemClass.TIMELINE, 1],
WORLD_KEY : [nwItemClass.WORLD, 1],
OBJECT_KEY : [nwItemClass.OBJECT, 1],
CUSTOM_KEY : [nwItemClass.CUSTOM, 1],
nwKeyWords.CHAR_KEY : [nwItemClass.CHARACTER, 1],
nwKeyWords.POV_KEY : [nwItemClass.CHARACTER, 2],
nwKeyWords.PLOT_KEY : [nwItemClass.PLOT, 1],
nwKeyWords.TIME_KEY : [nwItemClass.TIMELINE, 1],
nwKeyWords.WORLD_KEY : [nwItemClass.WORLD, 1],
nwKeyWords.OBJECT_KEY : [nwItemClass.OBJECT, 1],
nwKeyWords.ENTITY_KEY : [nwItemClass.ENTITY, 1],
nwKeyWords.CUSTOM_KEY : [nwItemClass.CUSTOM, 1],
}
def __init__(self, theProject, theParent):
@@ -79,9 +79,13 @@ class NWIndex():
def deleteHandle(self, tHandle):
delTags = []
for tTag in self.tagIndex:
if self.tagIndex[tTag][1] == tHandle:
self.tagIndex.pop(tTag, None)
delTags.append(tTag)
for tTag in delTags:
self.tagIndex.pop(tTag, None)
self.refIndex.pop(tHandle, None)
self.novelIndex.pop(tHandle, None)
@@ -275,10 +279,9 @@ class NWIndex():
if not isValid or len(theBits) == 0:
return False
theKey = theBits[0]
if theKey in self.NOVEL_KEYS:
if theBits[0] != nwKeyWords.TAG_KEY:
for aVal in theBits[1:]:
self.refIndex[tHandle].append([nLine, theKey, aVal, nTitle])
self.refIndex[tHandle].append([nLine, theBits[0], aVal, nTitle])
return True
@@ -290,7 +293,7 @@ class NWIndex():
if not isValid or len(theBits) != 2:
return False
if theBits[0] == self.TAG_KEY:
if theBits[0] == nwKeyWords.TAG_KEY:
self.tagIndex[theBits[1]] = [nLine, tHandle, itemClass.name]
return True
@@ -355,7 +358,7 @@ class NWIndex():
return isGood
# If we have a tag, only the first value is accepted, the rest is ignored
if theBits[0] == self.TAG_KEY and nBits > 1:
if theBits[0] == nwKeyWords.TAG_KEY and nBits > 1:
isGood[0] = True
if theBits[1] in self.tagIndex.keys():
if self.tagIndex[theBits[1]][1] == tItem.itemHandle:
+3 -2
View File
@@ -280,7 +280,7 @@ class NWProject():
return True
def saveProject(self):
def saveProject(self, isAuto=False):
if self.projPath is None:
self.makeAlert("Project path not set, cannot save.", nwAlert.ERROR)
@@ -296,7 +296,8 @@ class NWProject():
logger.debug("Saving project: %s" % self.projPath)
# Save a copy of the current file, just in case
self._maintainPrevious()
if not isAuto:
self._maintainPrevious()
# Root element and project details
logger.debug("Writing project meta")
+6 -2
View File
@@ -1,5 +1,5 @@
[Main]
timestamp = 2019-10-29 19:20:27
timestamp = 2019-11-03 00:40:02
theme = default
syntax = default_light
@@ -16,7 +16,7 @@ autosavedoc = 30
[Editor]
textfont = None
textsize = 12
fixedwidth = False
fixedwidth = True
width = 600
margin = 40
tabwidth = 40
@@ -38,6 +38,10 @@ backuppath =
backuponclose = False
askbeforebackup = True
[State]
showrefpanel = True
viewcomments = True
[Path]
lastpath =
recent0 =