Add basic string search

This commit is contained in:
Veronica Berglyd Olsen
2024-03-23 23:54:41 +01:00
parent 0feac3163f
commit 9153707075
2 changed files with 71 additions and 4 deletions
+28
View File
@@ -304,6 +304,34 @@ class DocDuplicator:
# END Class DocDuplicator
class DocSearch:
def __init__(self, project: NWProject) -> None:
self._project = project
return
def iterSearch(self, search: str) -> Iterable[tuple[NWItem, list[tuple[int, int, str]]]]:
"""Iteratively search through documents in the project."""
num = len(search)
cap = min(num+100, 100)
storage = self._project.storage
for item in self._project.tree:
if item.isFileType():
text = storage.getDocument(item.itemHandle).readDocument() or ""
prev = 0
results = []
count = 0
while (pos := text.find(search, prev)) >= 0 and count < 100:
count += 1
context = text[pos:pos+cap].partition("\n")[0]
results.append((pos, num, context))
prev = pos + num
yield item, results
return
# END Class DocSearch
class ProjectBuilder:
"""A class to build a new project from a set of user-defined
parameter provided by the New Project Wizard.
+43 -4
View File
@@ -25,10 +25,16 @@ from __future__ import annotations
import logging
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QPalette
from PyQt5.QtWidgets import QHBoxLayout, QLabel, QLineEdit, QTreeWidget, QVBoxLayout, QWidget
from PyQt5.QtWidgets import (
QHBoxLayout, QLabel, QLineEdit, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
QWidget
)
from novelwriter import CONFIG, SHARED
from novelwriter.core.coretools import DocSearch
from novelwriter.core.item import NWItem
from novelwriter.extensions.modified import NIconToolButton
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
@@ -51,13 +57,14 @@ class GuiProjectSearch(QWidget):
self.viewLabel.setContentsMargins(mPx, mPx, 0, mPx)
# Controls
self.searchBox = QLineEdit(self)
self.searchBox.setPlaceholderText(self.tr("Search text ..."))
self.searchText = QLineEdit(self)
self.searchText.setPlaceholderText(self.tr("Search text ..."))
self.searchButton = NIconToolButton(self, iPx)
self.searchButton.clicked.connect(self._processSearch)
self.searchBar = QHBoxLayout()
self.searchBar.addWidget(self.searchBox)
self.searchBar.addWidget(self.searchText)
self.searchBar.addWidget(self.searchButton)
# Search Result
@@ -96,4 +103,36 @@ class GuiProjectSearch(QWidget):
return
##
# Private Slots
##
@pyqtSlot()
def _processSearch(self) -> None:
"""Perform a search."""
self.searchResult.clear()
if text := self.searchText.text():
search = DocSearch(SHARED.project)
for item, results in search.iterSearch(text):
self._appendResultSet(item, results)
return
##
# Internal Functions
##
def _appendResultSet(self, item: NWItem, results: list[tuple[int, int, str]]) -> None:
"""Populate the result tree."""
if results:
tItem = QTreeWidgetItem()
tItem.setText(0, f"{item.itemName} ({len(results)})")
rItems = []
for start, end, context in results:
rItem = QTreeWidgetItem()
rItem.setText(0, context)
rItems.append(rItem)
tItem.addChildren(rItems)
self.searchResult.addTopLevelItem(tItem)
return
# END Class GuiProjectSearch