Skip to content

Commit

Permalink
Merge branch 'release'
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo committed Jul 25, 2024
2 parents f532857 + d4a0881 commit 7fe3a85
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 79 deletions.
5 changes: 4 additions & 1 deletion novelwriter/core/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def add(self, key: str | None, name: str, color: tuple[int, int, int],
return key

def update(self, update: list[tuple[str | None, StatusEntry]]) -> None:
"""Update the list of statuses, and from removed list."""
"""Update the list of statuses."""
self._store.clear()
for key, entry in update:
self._store[self._checkKey(key)] = entry
Expand All @@ -130,6 +130,9 @@ def update(self, update: list[tuple[str | None, StatusEntry]]) -> None:
if self._default not in self._store:
self._default = next(iter(self._store)) if self._store else None

# Emit the change signal
SHARED.projectSingalProxy({"event": "statusLabels", "kind": self._prefix})

return

def check(self, value: str) -> str:
Expand Down
16 changes: 6 additions & 10 deletions novelwriter/dialogs/projectsettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class GuiProjectSettings(NDialog):
PAGE_IMPORT = 2
PAGE_REPLACE = 3

newProjectSettingsReady = pyqtSignal(bool)
newProjectSettingsReady = pyqtSignal()

def __init__(self, parent: QWidget, gotoPage: int = PAGE_SETTINGS) -> None:
super().__init__(parent=parent)
Expand Down Expand Up @@ -175,31 +175,27 @@ def _doSave(self) -> None:
projAuthor = self.settingsPage.projAuthor.text()
projLang = self.settingsPage.projLang.currentData()
spellLang = self.settingsPage.spellLang.currentData()
doBackup = not self.settingsPage.doBackup.isChecked()
doBackup = not self.settingsPage.noBackup.isChecked()

project.data.setName(projName)
project.data.setAuthor(projAuthor)
project.data.setDoBackup(doBackup)
project.data.setSpellLang(spellLang)
project.setProjectLang(projLang)

rebuildTrees = False

if self.statusPage.changed:
logger.debug("Updating status labels")
project.data.itemStatus.update(self.statusPage.getNewList())
rebuildTrees = True

if self.importPage.changed:
logger.debug("Updating importance labels")
project.data.itemImport.update(self.importPage.getNewList())
rebuildTrees = True

if self.replacePage.changed:
logger.debug("Updating auto-replace settings")
project.data.setAutoReplace(self.replacePage.getNewList())

self.newProjectSettingsReady.emit(rebuildTrees)
self.newProjectSettingsReady.emit()
QApplication.processEvents()
self.close()

Expand Down Expand Up @@ -289,10 +285,10 @@ def __init__(self, parent: QWidget) -> None:
self.spellLang.setCurrentIndex(idx)

# Backup on Close
self.doBackup = NSwitch(self)
self.doBackup.setChecked(not data.doBackup)
self.noBackup = NSwitch(self)
self.noBackup.setChecked(not data.doBackup)
self.addRow(
self.tr("Disable backup on close"), self.doBackup,
self.tr("Disable backup on close"), self.noBackup,
self.tr("Overrides main preferences.")
)

Expand Down
7 changes: 7 additions & 0 deletions novelwriter/gui/docviewerpanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,13 @@ def updateChangedTags(self, updated: list[str], deleted: list[str]) -> None:
self._updateTabVisibility()
return

@pyqtSlot(str)
def updateStatusLabels(self, kind: str) -> None:
"""Update the importance labels."""
if kind == "i":
self._loadAllTags()
return

##
# Private Slots
##
Expand Down
115 changes: 66 additions & 49 deletions novelwriter/gui/projtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def closeProjectTasks(self) -> None:

def openProjectTasks(self) -> None:
"""Run open project tasks."""
self.populateTree()
self.projBar.buildQuickLinksMenu()
self.projBar.setEnabled(True)
return
Expand Down Expand Up @@ -213,7 +214,8 @@ def setSelectedHandle(self, tHandle: str, doScroll: bool = False) -> None:
@pyqtSlot(str)
def updateItemValues(self, tHandle: str) -> None:
"""Update tree item."""
self.projTree.setTreeItemValues(tHandle)
if nwItem := SHARED.project.tree[tHandle]:
self.projTree.setTreeItemValues(nwItem)
return

@pyqtSlot(str)
Expand Down Expand Up @@ -242,6 +244,12 @@ def createNewNote(self, tag: str, itemClass: nwItemClass) -> None:
self.projTree.createNewNote(tag, itemClass)
return

@pyqtSlot(str)
def refreshUserLabels(self, kind: str) -> None:
"""Refresh status or importance labels."""
self.projTree.refreshUserLabels(kind)
return


class GuiProjectToolBar(QWidget):

Expand Down Expand Up @@ -792,11 +800,11 @@ def moveToLevel(self, step: int) -> None:

def renameTreeItem(self, tHandle: str, name: str = "") -> None:
"""Open a dialog to edit the label of an item."""
if tItem := SHARED.project.tree[tHandle]:
newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or tItem.itemName)
if nwItem := SHARED.project.tree[tHandle]:
newLabel, dlgOk = GuiEditLabel.getLabel(self, text=name or nwItem.itemName)
if dlgOk:
tItem.setName(newLabel)
self.setTreeItemValues(tHandle)
nwItem.setName(newLabel)
self.setTreeItemValues(nwItem)
self._alertTreeChange(tHandle, flush=False)
return

Expand Down Expand Up @@ -1010,44 +1018,52 @@ def permDeleteItem(self, tHandle: str, askFirst: bool = True, flush: bool = True

return True

def setTreeItemValues(self, tHandle: str) -> None:
"""Set the name and flag values for a tree item from a handle in
the project tree. Does not trigger a tree change as the data is
already coming from the project tree.
def refreshUserLabels(self, kind: str) -> None:
"""Refresh status or importance labels."""
if kind == "s":
for nwItem in SHARED.project.tree:
if nwItem.isNovelLike():
self.setTreeItemValues(nwItem)
elif kind == "i":
for nwItem in SHARED.project.tree:
if not nwItem.isNovelLike():
self.setTreeItemValues(nwItem)
return

def setTreeItemValues(self, nwItem: NWItem | None) -> None:
"""Set the name and flag values for a tree item in the project
tree. Does not trigger a tree change as the data is already
coming from project data.
"""
trItem = self._getTreeItem(tHandle)
nwItem = SHARED.project.tree[tHandle]
if trItem is None or nwItem is None:
return

itemStatus, statusIcon = nwItem.getImportStatus()
hLevel = nwItem.mainHeading
itemIcon = SHARED.theme.getItemIcon(
nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, hLevel
)
if isinstance(nwItem, NWItem) and (trItem := self._getTreeItem(nwItem.itemHandle)):
itemStatus, statusIcon = nwItem.getImportStatus()
hLevel = nwItem.mainHeading
itemIcon = SHARED.theme.getItemIcon(
nwItem.itemType, nwItem.itemClass, nwItem.itemLayout, hLevel
)

trItem.setIcon(self.C_NAME, itemIcon)
trItem.setText(self.C_NAME, nwItem.itemName)
trItem.setIcon(self.C_STATUS, statusIcon)
trItem.setToolTip(self.C_STATUS, itemStatus)
trItem.setIcon(self.C_NAME, itemIcon)
trItem.setText(self.C_NAME, nwItem.itemName)
trItem.setIcon(self.C_STATUS, statusIcon)
trItem.setToolTip(self.C_STATUS, itemStatus)

if nwItem.isFileType():
iconName = "checked" if nwItem.isActive else "unchecked"
toolTip = self.trActive if nwItem.isActive else self.trInactive
trItem.setToolTip(self.C_ACTIVE, toolTip)
else:
iconName = "noncheckable"
if nwItem.isFileType():
iconName = "checked" if nwItem.isActive else "unchecked"
toolTip = self.trActive if nwItem.isActive else self.trInactive
trItem.setToolTip(self.C_ACTIVE, toolTip)
else:
iconName = "noncheckable"

trItem.setIcon(self.C_ACTIVE, SHARED.theme.getIcon(iconName))
trItem.setIcon(self.C_ACTIVE, SHARED.theme.getIcon(iconName))

if CONFIG.emphLabels and nwItem.isDocumentLayout():
trFont = trItem.font(self.C_NAME)
trFont.setBold(hLevel == "H1" or hLevel == "H2")
trFont.setUnderline(hLevel == "H1")
trItem.setFont(self.C_NAME, trFont)
if CONFIG.emphLabels and nwItem.isDocumentLayout():
trFont = trItem.font(self.C_NAME)
trFont.setBold(hLevel == "H1" or hLevel == "H2")
trFont.setUnderline(hLevel == "H1")
trItem.setFont(self.C_NAME, trFont)

# Emit Refresh Signal
self.itemRefreshed.emit(tHandle, nwItem, itemIcon)
# Emit Refresh Signal
self.itemRefreshed.emit(nwItem.itemHandle, nwItem, itemIcon)

return

Expand Down Expand Up @@ -1353,7 +1369,8 @@ def _postItemMove(self, tHandle: str) -> None:
SHARED.project.index.deleteHandle(mHandle)
else:
SHARED.project.index.reIndexHandle(mHandle)
self.setTreeItemValues(mHandle)
if mItem := SHARED.project.tree[mHandle]:
self.setTreeItemValues(mItem)

# Update word count
self.propagateCount(tHandle, nwItemS.wordCount, countChildren=True)
Expand Down Expand Up @@ -1594,7 +1611,7 @@ def _addTreeItem(self, nwItem: NWItem | None,

self._treeMap[tHandle] = newItem
self.propagateCount(tHandle, nwItem.wordCount, countChildren=True)
self.setTreeItemValues(tHandle)
self.setTreeItemValues(nwItem)
newItem.setExpanded(nwItem.isExpanded)

return newItem
Expand Down Expand Up @@ -1971,7 +1988,7 @@ def _iterPermDelete(self) -> None:
def _toggleItemActive(self) -> None:
"""Toggle the active status of an item."""
self._item.setActive(not self._item.isActive)
self.projTree.setTreeItemValues(self._handle)
self.projTree.setTreeItemValues(self._item)
self.projTree._alertTreeChange(self._handle, flush=False)
return

Expand All @@ -1984,14 +2001,14 @@ def _iterItemActive(self, isActive: bool) -> None:
for tItem in self._items:
if tItem and tItem.isFileType():
tItem.setActive(isActive)
self.projTree.setTreeItemValues(tItem.itemHandle)
self.projTree.setTreeItemValues(tItem)
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
return

def _changeItemStatus(self, key: str) -> None:
"""Set a new status value of an item."""
self._item.setStatus(key)
self.projTree.setTreeItemValues(self._handle)
self.projTree.setTreeItemValues(self._item)
self.projTree._alertTreeChange(self._handle, flush=False)
return

Expand All @@ -2000,14 +2017,14 @@ def _iterSetItemStatus(self, key: str) -> None:
for tItem in self._items:
if tItem and tItem.isNovelLike():
tItem.setStatus(key)
self.projTree.setTreeItemValues(tItem.itemHandle)
self.projTree.setTreeItemValues(tItem)
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
return

def _changeItemImport(self, key: str) -> None:
"""Set a new importance value of an item."""
self._item.setImport(key)
self.projTree.setTreeItemValues(self._handle)
self.projTree.setTreeItemValues(self._item)
self.projTree._alertTreeChange(self._handle, flush=False)
return

Expand All @@ -2016,19 +2033,19 @@ def _iterSetItemImport(self, key: str) -> None:
for tItem in self._items:
if tItem and not tItem.isNovelLike():
tItem.setImport(key)
self.projTree.setTreeItemValues(tItem.itemHandle)
self.projTree.setTreeItemValues(tItem)
self.projTree._alertTreeChange(tItem.itemHandle, flush=False)
return

def _changeItemLayout(self, itemLayout: nwItemLayout) -> None:
"""Set a new item layout value of an item."""
if itemLayout == nwItemLayout.DOCUMENT and self._item.documentAllowed():
self._item.setLayout(nwItemLayout.DOCUMENT)
self.projTree.setTreeItemValues(self._handle)
self.projTree.setTreeItemValues(self._item)
self.projTree._alertTreeChange(self._handle, flush=False)
elif itemLayout == nwItemLayout.NOTE:
self._item.setLayout(nwItemLayout.NOTE)
self.projTree.setTreeItemValues(self._handle)
self.projTree.setTreeItemValues(self._item)
self.projTree._alertTreeChange(self._handle, flush=False)
return

Expand All @@ -2042,12 +2059,12 @@ def _covertFolderToFile(self, itemLayout: nwItemLayout) -> None:
if msgYes and itemLayout == nwItemLayout.DOCUMENT and self._item.documentAllowed():
self._item.setType(nwItemType.FILE)
self._item.setLayout(nwItemLayout.DOCUMENT)
self.projTree.setTreeItemValues(self._handle)
self.projTree.setTreeItemValues(self._item)
self.projTree._alertTreeChange(self._handle, flush=False)
elif msgYes and itemLayout == nwItemLayout.NOTE:
self._item.setType(nwItemType.FILE)
self._item.setLayout(nwItemLayout.NOTE)
self.projTree.setTreeItemValues(self._handle)
self.projTree.setTreeItemValues(self._item)
self.projTree._alertTreeChange(self._handle, flush=False)
else:
logger.info("Folder conversion cancelled")
Expand Down
17 changes: 4 additions & 13 deletions novelwriter/guimain.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,6 @@ def __init__(self) -> None:
self.splitView.setVisible(False)
self.docEditor.closeSearch()

# Initialise the Project Tree
self.rebuildTrees()

# Assemble Main Window Elements
self.mainBox = QHBoxLayout()
self.mainBox.addWidget(self.sideBar)
Expand Down Expand Up @@ -222,6 +219,8 @@ def __init__(self) -> None:
SHARED.projectStatusChanged.connect(self.mainStatus.updateProjectStatus)
SHARED.projectStatusMessage.connect(self.mainStatus.setStatusMessage)
SHARED.spellLanguageChanged.connect(self.mainStatus.setLanguage)
SHARED.statusLabelsChanged.connect(self.docViewerPanel.updateStatusLabels)
SHARED.statusLabelsChanged.connect(self.projView.refreshUserLabels)

self.mainMenu.requestDocAction.connect(self._passDocumentAction)
self.mainMenu.requestDocInsert.connect(self._passDocumentInsert)
Expand Down Expand Up @@ -461,7 +460,6 @@ def openProject(self, projFile: str | Path | None) -> bool:

# Update GUI
self._updateWindowTitle(SHARED.project.data.name)
self.rebuildTrees()
self.docEditor.toggleSpellCheck(SHARED.project.data.spellCheck)
self.mainStatus.setRefTime(SHARED.project.projOpened)
self.projView.openProjectTasks()
Expand Down Expand Up @@ -735,11 +733,6 @@ def openSelectedItem(self) -> None:

return

def rebuildTrees(self) -> None:
"""Rebuild the project tree."""
self.projView.populateTree()
return

def rebuildIndex(self, beQuiet: bool = False) -> None:
"""Rebuild the entire index."""
if SHARED.hasProject:
Expand Down Expand Up @@ -1098,15 +1091,13 @@ def _processConfigChanges(self, restart: bool, tree: bool, theme: bool, syntax:

return

@pyqtSlot(bool)
def _processProjectSettingsChanges(self, rebuildTrees: bool) -> None:
@pyqtSlot()
def _processProjectSettingsChanges(self) -> None:
"""Refresh data dependent on project settings."""
logger.debug("Applying new project settings")
SHARED.updateSpellCheckLanguage()
self.itemDetails.refreshDetails()
self._updateWindowTitle(SHARED.project.data.name)
if rebuildTrees:
self.rebuildTrees()
return

@pyqtSlot()
Expand Down
Loading

0 comments on commit 7fe3a85

Please sign in to comment.