Skip to content

Commit

Permalink
Update global search (#1936)
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo authored Jun 16, 2024
2 parents e9e7fae + 59c9783 commit 45ad0f8
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 27 deletions.
4 changes: 3 additions & 1 deletion novelwriter/core/coretools.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,9 @@ def searchText(self, text: str) -> tuple[list[tuple[int, int, str]], bool]:
rxMatch = rxItt.next()
pos = rxMatch.capturedStart()
num = rxMatch.capturedLength()
context = text[pos:pos+100].partition("\n")[0]
lim = text[:pos].rfind("\n") + 1
cut = text[lim:pos].rfind(" ") + lim + 1
context = text[cut:cut+100].partition("\n")[0]
if context:
results.append((pos, num, context))
count += 1
Expand Down
6 changes: 3 additions & 3 deletions novelwriter/gui/projtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ def permDeleteItem(self, tHandle: str, askFirst: bool = True, flush: bool = True
trItemP.takeChild(tIndex)

for dHandle in reversed(self.getTreeFromHandle(tHandle)):
SHARED.closeDocument(dHandle)
SHARED.closeEditor(dHandle)
SHARED.project.removeItem(dHandle)
self._treeMap.pop(dHandle, None)

Expand Down Expand Up @@ -1404,7 +1404,7 @@ def _mergeDocuments(self, tHandle: str, newFile: bool) -> bool:
return False

# Save the open document first, in case it's part of merge
SHARED.saveDocument()
SHARED.saveEditor()

# Create merge object, and append docs
docMerger = DocMerger(SHARED.project)
Expand Down Expand Up @@ -1805,7 +1805,7 @@ def _itemCreation(self) -> None:

def _itemHeader(self) -> None:
"""Check if there is a header that can be used for rename."""
SHARED.ensureEditorSaved(self._handle)
SHARED.saveEditor()
if hItem := SHARED.project.index.getItemHeading(self._handle, "T0001"):
action = self.addAction(self.tr("Rename to Heading"))
action.triggered.connect(
Expand Down
11 changes: 10 additions & 1 deletion novelwriter/gui/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ def closeProjectTasks(self) -> None:
self.searchResult.clear()
return

def refreshCurrentSearch(self) -> None:
"""Refresh the search if there is one."""
if self.searchResult.topLevelItemCount() > 0:
self._processSearch()
return

##
# Events
##
Expand Down Expand Up @@ -259,7 +265,7 @@ def _processSearch(self) -> None:
if not self._blocked:
QApplication.setOverrideCursor(QCursor(Qt.CursorShape.WaitCursor))
start = time()
SHARED.saveDocument()
SHARED.saveEditor()
self._blocked = True
self._map = {}
self.searchResult.clear()
Expand Down Expand Up @@ -298,18 +304,21 @@ def _searchResultDoubleClicked(self, item: QTreeWidgetItem, column: int) -> None
def _toggleCase(self, state: bool) -> None:
"""Enable/disable case sensitive mode."""
CONFIG.searchProjCase = state
self.refreshCurrentSearch()
return

@pyqtSlot(bool)
def _toggleWord(self, state: bool) -> None:
"""Enable/disable whole word search mode."""
CONFIG.searchProjWord = state
self.refreshCurrentSearch()
return

@pyqtSlot(bool)
def _toggleRegEx(self, state: bool) -> None:
"""Enable/disable regular expression search mode."""
CONFIG.searchProjRegEx = state
self.refreshCurrentSearch()
return

##
Expand Down
27 changes: 10 additions & 17 deletions novelwriter/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,21 @@ def initSharedData(self, gui: GuiMain, theme: GuiTheme) -> None:
logger.debug("Thread Pool Max Count: %d", QThreadPool.globalInstance().maxThreadCount())
return

def closeDocument(self, tHandle: str | None = None) -> None:
def closeEditor(self, tHandle: str | None = None) -> None:
"""Close the document editor, optionally a specific document."""
if tHandle is None or tHandle == self.mainGui.docEditor.docHandle:
self.mainGui.closeDocument()
return

def saveDocument(self) -> None:
"""Forward save document call to main GUI."""
self.mainGui.saveDocument()
def saveEditor(self, tHandle: str | None = None) -> None:
"""Save the editor content, optionally a specific document."""
docEditor = self.mainGui.docEditor
if (
self.hasProject and docEditor.docHandle
and (tHandle is None or tHandle == docEditor.docHandle)
):
logger.debug("Saving editor document before action")
docEditor.saveText()
return

def openProject(self, path: str | Path, clearLock: bool = False) -> bool:
Expand Down Expand Up @@ -216,19 +222,6 @@ def closeProject(self) -> None:
self._resetIdleTimer()
return

def ensureEditorSaved(self, tHandle: str | None) -> None:
"""Ensure that the editor content is saved. Optionally, only if
it is a specific handle.
"""
docEditor = self.mainGui.docEditor
if (
self.hasProject and docEditor.docHandle
and (tHandle is None or tHandle == docEditor.docHandle)
):
logger.debug("Saving editor document before action")
docEditor.saveText()
return

def updateSpellCheckLanguage(self, reload: bool = False) -> None:
"""Update the active spell check language from settings."""
from novelwriter import CONFIG
Expand Down
2 changes: 1 addition & 1 deletion novelwriter/tools/manusbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ def _runBuild(self) -> bool:
return False

# Make sure editor content is saved before we start
SHARED.saveDocument()
SHARED.saveEditor()

docBuild = NWBuildDocument(SHARED.project, self._build)
docBuild.queueAll()
Expand Down
2 changes: 1 addition & 1 deletion novelwriter/tools/manuscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def _generatePreview(self) -> None:
start = time()

# Make sure editor content is saved before we start
SHARED.ensureEditorSaved(None)
SHARED.saveEditor()

docBuild = NWBuildDocument(SHARED.project, build)
docBuild.queueAll()
Expand Down
6 changes: 3 additions & 3 deletions tests/test_core/test_core_coretools.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,16 +449,16 @@ def pruneResult(result, index):
assert pruneResult(search.iterSearch(project, "Lor"), 2) == []
search.setWholeWords(False)
assert pruneResult(search.iterSearch(project, "Lor"), 2) == [
(15, 3, "Lorem"), (29, 3, "lor"), (754, 3, "lorem"), (2056, 3, "lorem,"),
(2209, 3, "lorem"), (2425, 3, "lorem"), (2840, 3, "lorem."), (3328, 3, "lor."),
(15, 3, "Lorem"), (29, 3, "dolor"), (754, 3, "lorem"), (2056, 3, "lorem,"),
(2209, 3, "lorem"), (2425, 3, "lorem"), (2840, 3, "lorem."), (3328, 3, "dolor."),
(3399, 3, "lorem"),
]

# As RegEx
search.setWholeWords(False)
search.setUserRegEx(True)
assert pruneResult(search.iterSearch(project, r"Lor\b"), 2) == [
(29, 3, "lor"), (3328, 3, "lor."),
(29, 3, "dolor"), (3328, 3, "dolor."),
]

# Max Results
Expand Down

0 comments on commit 45ad0f8

Please sign in to comment.