Merge branch 'main' into testing
This commit is contained in:
@@ -152,6 +152,29 @@ convenient if you want to quickly look through all documents in the list in the
|
|||||||
pressing :kbd:`F9`.
|
pressing :kbd:`F9`.
|
||||||
|
|
||||||
|
|
||||||
|
.. _a_ui_edit_search:
|
||||||
|
|
||||||
|
Search & Replace
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The document editor has a search and replace bar that can be activated with :kbd:`Ctrl`:kbd:`F` for
|
||||||
|
search mode or :kbd:`Ctrl`:kbd:`H` for search/replace mode.
|
||||||
|
|
||||||
|
Pressing :kbd:`Return` while in the search box will search for the next occurrence of the word, and
|
||||||
|
:kbd:`Shift`:kbd:`Return` for the previous. Pressing :kbd:`Return` in the replace box, will replace
|
||||||
|
the highlighted text and move to the next word.
|
||||||
|
|
||||||
|
There are a number of settings for the search bar available as toggle switches above the search
|
||||||
|
box. They allows you to search for, in order:,: matched case only, whole word results only, search
|
||||||
|
using regular expressions, loop search when reaching the end of the document, and move to the next
|
||||||
|
document when reaching the end. There is also a switch that will try to match the case of the word
|
||||||
|
when the replacement is made. That is, it will try to keep the word upper, lower, or capitalised to
|
||||||
|
match the word being replaced.
|
||||||
|
|
||||||
|
The regular expression search is somewhat dependant on which version of Qt your system has. If you
|
||||||
|
have Qt 5.13 or higher, there is better support for unicode symbols in the search.
|
||||||
|
|
||||||
|
|
||||||
.. _a_ui_edit_auto:
|
.. _a_ui_edit_auto:
|
||||||
|
|
||||||
Auto-Replace as You Type
|
Auto-Replace as You Type
|
||||||
@@ -432,7 +455,7 @@ Most features are available as keyboard shortcuts. These are as follows:
|
|||||||
":kbd:`Ctrl`:kbd:`Backspace`", "Delete previous word in editor."
|
":kbd:`Ctrl`:kbd:`Backspace`", "Delete previous word in editor."
|
||||||
":kbd:`Ctrl`:kbd:`'`", "Wrap selected text, or word under cursor, in single quotes."
|
":kbd:`Ctrl`:kbd:`'`", "Wrap selected text, or word under cursor, in single quotes."
|
||||||
":kbd:`Ctrl`:kbd:`""`", "Wrap selected text, or word under cursor, in double quotes."
|
":kbd:`Ctrl`:kbd:`""`", "Wrap selected text, or word under cursor, in double quotes."
|
||||||
":kbd:`Ctrl`:kbd:`Enter`", "Open the tag or reference under the cursor in the Viewer."
|
":kbd:`Ctrl`:kbd:`Retrun`", "Open the tag or reference under the cursor in the Viewer."
|
||||||
":kbd:`Ctrl`:kbd:`Shift`:kbd:`,`", "Open the :guilabel:`Project Settings` dialog."
|
":kbd:`Ctrl`:kbd:`Shift`:kbd:`,`", "Open the :guilabel:`Project Settings` dialog."
|
||||||
":kbd:`Ctrl`:kbd:`Shift`:kbd:`/`", "Remove block formatting for block under cursor."
|
":kbd:`Ctrl`:kbd:`Shift`:kbd:`/`", "Remove block formatting for block under cursor."
|
||||||
":kbd:`Ctrl`:kbd:`Shift`:kbd:`1`", "Replace occurrence of search word in current document, and search for next occurrence."
|
":kbd:`Ctrl`:kbd:`Shift`:kbd:`1`", "Replace occurrence of search word in current document, and search for next occurrence."
|
||||||
|
|||||||
+8
-13
@@ -81,19 +81,14 @@ class nwDocAction(Enum):
|
|||||||
D_QUOTE = 10
|
D_QUOTE = 10
|
||||||
SEL_ALL = 11
|
SEL_ALL = 11
|
||||||
SEL_PARA = 12
|
SEL_PARA = 12
|
||||||
FIND = 13
|
BLOCK_H1 = 13
|
||||||
REPLACE = 14
|
BLOCK_H2 = 14
|
||||||
GO_NEXT = 15
|
BLOCK_H3 = 15
|
||||||
GO_PREV = 16
|
BLOCK_H4 = 16
|
||||||
REPL_NEXT = 17
|
BLOCK_COM = 17
|
||||||
BLOCK_H1 = 18
|
BLOCK_TXT = 18
|
||||||
BLOCK_H2 = 19
|
REPL_SNG = 19
|
||||||
BLOCK_H3 = 20
|
REPL_DBL = 20
|
||||||
BLOCK_H4 = 21
|
|
||||||
BLOCK_COM = 22
|
|
||||||
BLOCK_TXT = 23
|
|
||||||
REPL_SNG = 24
|
|
||||||
REPL_DBL = 25
|
|
||||||
|
|
||||||
# END Enum nwDocAction
|
# END Enum nwDocAction
|
||||||
|
|
||||||
|
|||||||
+151
-144
@@ -684,10 +684,6 @@ class GuiDocEditor(QTextEdit):
|
|||||||
this class when calling these actions from other classes.
|
this class when calling these actions from other classes.
|
||||||
"""
|
"""
|
||||||
logger.verbose("Requesting action: %s" % theAction.name)
|
logger.verbose("Requesting action: %s" % theAction.name)
|
||||||
if not self.hasFocus():
|
|
||||||
logger.verbose("Editor does not have focus")
|
|
||||||
return False
|
|
||||||
|
|
||||||
if self.theHandle is None:
|
if self.theHandle is None:
|
||||||
logger.error("No document open")
|
logger.error("No document open")
|
||||||
return False
|
return False
|
||||||
@@ -717,16 +713,6 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self._makeSelection(QTextCursor.Document)
|
self._makeSelection(QTextCursor.Document)
|
||||||
elif theAction == nwDocAction.SEL_PARA:
|
elif theAction == nwDocAction.SEL_PARA:
|
||||||
self._makeSelection(QTextCursor.BlockUnderCursor)
|
self._makeSelection(QTextCursor.BlockUnderCursor)
|
||||||
elif theAction == nwDocAction.FIND:
|
|
||||||
self._beginSearch()
|
|
||||||
elif theAction == nwDocAction.REPLACE:
|
|
||||||
self._beginReplace()
|
|
||||||
elif theAction == nwDocAction.GO_NEXT:
|
|
||||||
self._findNext()
|
|
||||||
elif theAction == nwDocAction.GO_PREV:
|
|
||||||
self._findNext(isBackward=True)
|
|
||||||
elif theAction == nwDocAction.REPL_NEXT:
|
|
||||||
self._replaceNext()
|
|
||||||
elif theAction == nwDocAction.BLOCK_H1:
|
elif theAction == nwDocAction.BLOCK_H1:
|
||||||
self._formatBlock(nwDocAction.BLOCK_H1)
|
self._formatBlock(nwDocAction.BLOCK_H1)
|
||||||
elif theAction == nwDocAction.BLOCK_H2:
|
elif theAction == nwDocAction.BLOCK_H2:
|
||||||
@@ -758,6 +744,15 @@ class GuiDocEditor(QTextEdit):
|
|||||||
"""
|
"""
|
||||||
return self.qDocument.isEmpty()
|
return self.qDocument.isEmpty()
|
||||||
|
|
||||||
|
def anyFocus(self):
|
||||||
|
"""Check if any widget or child widget has focus.
|
||||||
|
"""
|
||||||
|
if self.hasFocus():
|
||||||
|
return True
|
||||||
|
if self.isAncestorOf(qApp.focusWidget()):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def revealLocation(self):
|
def revealLocation(self):
|
||||||
"""Tell the user where on the file system the file in the editor
|
"""Tell the user where on the file system the file in the editor
|
||||||
is saved.
|
is saved.
|
||||||
@@ -851,7 +846,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
if self.docSearch.isVisible():
|
if self.docSearch.isVisible():
|
||||||
self.docSearch.closeSearch()
|
self.docSearch.closeSearch()
|
||||||
else:
|
else:
|
||||||
self._beginSearch()
|
self.beginSearch()
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
@@ -1169,6 +1164,144 @@ class GuiDocEditor(QTextEdit):
|
|||||||
logger.verbose("Denied cursor move to %d > %d" % (self.queuePos, thePos))
|
logger.verbose("Denied cursor move to %d > %d" % (self.queuePos, thePos))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
##
|
||||||
|
# Search & Replace
|
||||||
|
##
|
||||||
|
|
||||||
|
def beginSearch(self):
|
||||||
|
"""Sets the selected text as the search text for the search bar.
|
||||||
|
"""
|
||||||
|
theCursor = self.textCursor()
|
||||||
|
if theCursor.hasSelection():
|
||||||
|
self.docSearch.setSearchText(theCursor.selectedText())
|
||||||
|
else:
|
||||||
|
self.docSearch.setSearchText(None)
|
||||||
|
self.updateDocMargins()
|
||||||
|
return
|
||||||
|
|
||||||
|
def beginReplace(self):
|
||||||
|
"""Opens the replace line of the search bar and sets the find
|
||||||
|
text if a selection has been made, and resets the replace text.
|
||||||
|
"""
|
||||||
|
theCursor = self.textCursor()
|
||||||
|
if theCursor.hasSelection():
|
||||||
|
self.docSearch.setSearchText(theCursor.selectedText())
|
||||||
|
else:
|
||||||
|
self.docSearch.setSearchText(None)
|
||||||
|
self.docSearch.setReplaceText("")
|
||||||
|
self.updateDocMargins()
|
||||||
|
return
|
||||||
|
|
||||||
|
def findNext(self, goBack=False):
|
||||||
|
"""Searches for the next or previous occurrence of the search
|
||||||
|
bar text in the document. Wraps around if not found and loop is
|
||||||
|
enabled, or continues to next file if next file is enabled.
|
||||||
|
"""
|
||||||
|
if not self.anyFocus():
|
||||||
|
logger.debug("Editor does not have focus")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not self.docSearch.isVisible():
|
||||||
|
self.beginSearch()
|
||||||
|
return
|
||||||
|
|
||||||
|
findOpt = QTextDocument.FindFlag(0)
|
||||||
|
if goBack:
|
||||||
|
findOpt |= QTextDocument.FindBackward
|
||||||
|
if self.docSearch.isCaseSense:
|
||||||
|
findOpt |= QTextDocument.FindCaseSensitively
|
||||||
|
if self.docSearch.isWholeWord:
|
||||||
|
findOpt |= QTextDocument.FindWholeWords
|
||||||
|
|
||||||
|
searchFor = self.docSearch.getSearchObject()
|
||||||
|
wasFound = self.find(searchFor, findOpt)
|
||||||
|
if not wasFound:
|
||||||
|
if self.docSearch.doNextFile and not goBack:
|
||||||
|
self.theParent.openNextDocument(
|
||||||
|
self.theHandle, wrapAround=self.docSearch.doLoop
|
||||||
|
)
|
||||||
|
elif self.docSearch.doLoop:
|
||||||
|
theCursor = self.textCursor()
|
||||||
|
theCursor.movePosition(
|
||||||
|
QTextCursor.End if goBack else QTextCursor.Start
|
||||||
|
)
|
||||||
|
self.setTextCursor(theCursor)
|
||||||
|
wasFound = self.find(searchFor, findOpt)
|
||||||
|
|
||||||
|
if wasFound:
|
||||||
|
theCursor = self.textCursor()
|
||||||
|
self.lastFind = (theCursor.selectionStart(), theCursor.selectionEnd())
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def replaceNext(self):
|
||||||
|
"""Searches for the next occurrence of the search bar text in
|
||||||
|
the document and replaces it with the replace text. Calls search
|
||||||
|
next automatically when done.
|
||||||
|
"""
|
||||||
|
if not self.anyFocus():
|
||||||
|
logger.debug("Editor does not have focus")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not self.docSearch.isVisible():
|
||||||
|
# The search tool is not active, so we activate it.
|
||||||
|
self.beginSearch()
|
||||||
|
return
|
||||||
|
|
||||||
|
theCursor = self.textCursor()
|
||||||
|
if not theCursor.hasSelection():
|
||||||
|
# We have no text selected at all, so just make this a
|
||||||
|
# regular find next call.
|
||||||
|
self.findNext()
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.lastFind is None and theCursor.hasSelection():
|
||||||
|
# If we have a selection but no search, it may have been the
|
||||||
|
# text we triggered the search with, in which case we search
|
||||||
|
# again from the beginning of that selection to make sure we
|
||||||
|
# have a valid result.
|
||||||
|
sPos = theCursor.selectionStart()
|
||||||
|
theCursor.clearSelection()
|
||||||
|
theCursor.setPosition(sPos)
|
||||||
|
self.setTextCursor(theCursor)
|
||||||
|
self.findNext()
|
||||||
|
theCursor = self.textCursor()
|
||||||
|
|
||||||
|
if self.lastFind is None:
|
||||||
|
# In case the above didn't find a result, we give up here.
|
||||||
|
return
|
||||||
|
|
||||||
|
searchFor = self.docSearch.getSearchText()
|
||||||
|
replWith = self.docSearch.getReplaceText()
|
||||||
|
|
||||||
|
if self.docSearch.doMatchCap:
|
||||||
|
replWith = transferCase(theCursor.selectedText(), replWith)
|
||||||
|
|
||||||
|
# Make sure the selected text was selected by an actual find
|
||||||
|
# call, and not the user.
|
||||||
|
try:
|
||||||
|
isFind = self.lastFind[0] == theCursor.selectionStart()
|
||||||
|
isFind &= self.lastFind[1] == theCursor.selectionEnd()
|
||||||
|
except Exception:
|
||||||
|
isFind = False
|
||||||
|
|
||||||
|
if isFind:
|
||||||
|
theCursor.beginEditBlock()
|
||||||
|
theCursor.removeSelectedText()
|
||||||
|
theCursor.insertText(replWith)
|
||||||
|
theCursor.endEditBlock()
|
||||||
|
theCursor.setPosition(theCursor.selectionEnd())
|
||||||
|
self.setTextCursor(theCursor)
|
||||||
|
logger.verbose("Replaced occurrence of '%s' with '%s' on line %d" % (
|
||||||
|
searchFor, replWith, theCursor.blockNumber()
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
logger.error("The selected text is not a search result, skipping replace")
|
||||||
|
|
||||||
|
self.findNext()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Internal Functions
|
# Internal Functions
|
||||||
##
|
##
|
||||||
@@ -1630,132 +1763,6 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self._makeSelection(selMode)
|
self._makeSelection(selMode)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _beginSearch(self):
|
|
||||||
"""Sets the selected text as the search text for the search bar.
|
|
||||||
"""
|
|
||||||
theCursor = self.textCursor()
|
|
||||||
if theCursor.hasSelection():
|
|
||||||
self.docSearch.setSearchText(theCursor.selectedText())
|
|
||||||
else:
|
|
||||||
self.docSearch.setSearchText(None)
|
|
||||||
self.updateDocMargins()
|
|
||||||
return
|
|
||||||
|
|
||||||
def _beginReplace(self):
|
|
||||||
"""Opens the replace line of the search bar and sets the find
|
|
||||||
text if a selection has been made, and resets the replace text.
|
|
||||||
"""
|
|
||||||
theCursor = self.textCursor()
|
|
||||||
if theCursor.hasSelection():
|
|
||||||
self.docSearch.setSearchText(theCursor.selectedText())
|
|
||||||
else:
|
|
||||||
self.docSearch.setSearchText(None)
|
|
||||||
self.docSearch.setReplaceText("")
|
|
||||||
self.updateDocMargins()
|
|
||||||
return
|
|
||||||
|
|
||||||
def _findNext(self, isBackward=False):
|
|
||||||
"""Searches for the next or previous occurrence of the search
|
|
||||||
bar text in the document. Wraps around if not found and loop is
|
|
||||||
enabled, or continues to next file if next file is enabled.
|
|
||||||
"""
|
|
||||||
if not self.docSearch.isVisible():
|
|
||||||
self._beginSearch()
|
|
||||||
return
|
|
||||||
|
|
||||||
findOpt = QTextDocument.FindFlag(0)
|
|
||||||
if isBackward:
|
|
||||||
findOpt |= QTextDocument.FindBackward
|
|
||||||
if self.docSearch.isCaseSense:
|
|
||||||
findOpt |= QTextDocument.FindCaseSensitively
|
|
||||||
if self.docSearch.isWholeWord:
|
|
||||||
findOpt |= QTextDocument.FindWholeWords
|
|
||||||
|
|
||||||
searchFor = self.docSearch.getSearchObject()
|
|
||||||
wasFound = self.find(searchFor, findOpt)
|
|
||||||
if not wasFound:
|
|
||||||
if self.docSearch.doNextFile and not isBackward:
|
|
||||||
self.theParent.openNextDocument(
|
|
||||||
self.theHandle, wrapAround=self.docSearch.doLoop
|
|
||||||
)
|
|
||||||
elif self.docSearch.doLoop:
|
|
||||||
theCursor = self.textCursor()
|
|
||||||
theCursor.movePosition(
|
|
||||||
QTextCursor.End if isBackward else QTextCursor.Start
|
|
||||||
)
|
|
||||||
self.setTextCursor(theCursor)
|
|
||||||
wasFound = self.find(searchFor, findOpt)
|
|
||||||
|
|
||||||
if wasFound:
|
|
||||||
theCursor = self.textCursor()
|
|
||||||
self.lastFind = (theCursor.selectionStart(), theCursor.selectionEnd())
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _replaceNext(self):
|
|
||||||
"""Searches for the next occurrence of the search bar text in
|
|
||||||
the document and replaces it with the replace text. Calls search
|
|
||||||
next automatically when done.
|
|
||||||
"""
|
|
||||||
if not self.docSearch.isVisible():
|
|
||||||
# The search tool is not active, so we activate it.
|
|
||||||
self._beginSearch()
|
|
||||||
return
|
|
||||||
|
|
||||||
theCursor = self.textCursor()
|
|
||||||
if not theCursor.hasSelection():
|
|
||||||
# We have no text selected at all, so just make this a
|
|
||||||
# regular find next call.
|
|
||||||
self._findNext()
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.lastFind is None and theCursor.hasSelection():
|
|
||||||
# If we have a selection but no search, it may have been the
|
|
||||||
# text we triggered the search with, in which case we search
|
|
||||||
# again from the beginning of that selection to make sure we
|
|
||||||
# have a valid result.
|
|
||||||
sPos = theCursor.selectionStart()
|
|
||||||
theCursor.clearSelection()
|
|
||||||
theCursor.setPosition(sPos)
|
|
||||||
self.setTextCursor(theCursor)
|
|
||||||
self._findNext()
|
|
||||||
theCursor = self.textCursor()
|
|
||||||
|
|
||||||
if self.lastFind is None:
|
|
||||||
# In case the above didn't find a result, we give up here.
|
|
||||||
return
|
|
||||||
|
|
||||||
searchFor = self.docSearch.getSearchText()
|
|
||||||
replWith = self.docSearch.getReplaceText()
|
|
||||||
|
|
||||||
if self.docSearch.doMatchCap:
|
|
||||||
replWith = transferCase(theCursor.selectedText(), replWith)
|
|
||||||
|
|
||||||
# Make sure the selected text was selected by an actual find
|
|
||||||
# call, and not the user.
|
|
||||||
try:
|
|
||||||
isFind = self.lastFind[0] == theCursor.selectionStart()
|
|
||||||
isFind &= self.lastFind[1] == theCursor.selectionEnd()
|
|
||||||
except Exception:
|
|
||||||
isFind = False
|
|
||||||
|
|
||||||
if isFind:
|
|
||||||
theCursor.beginEditBlock()
|
|
||||||
theCursor.removeSelectedText()
|
|
||||||
theCursor.insertText(replWith)
|
|
||||||
theCursor.endEditBlock()
|
|
||||||
theCursor.setPosition(theCursor.selectionEnd())
|
|
||||||
self.setTextCursor(theCursor)
|
|
||||||
logger.verbose("Replaced occurrence of '%s' with '%s' on line %d" % (
|
|
||||||
searchFor, replWith, theCursor.blockNumber()
|
|
||||||
))
|
|
||||||
else:
|
|
||||||
logger.error("The selected text is not a search result, skipping replace")
|
|
||||||
|
|
||||||
self._findNext()
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def _setupSpellChecking(self):
|
def _setupSpellChecking(self):
|
||||||
"""Create the spell checking object based on the spellTool
|
"""Create the spell checking object based on the spellTool
|
||||||
setting in config.
|
setting in config.
|
||||||
@@ -2119,15 +2126,15 @@ class GuiDocEditSearch(QFrame):
|
|||||||
"""
|
"""
|
||||||
modKey = qApp.keyboardModifiers()
|
modKey = qApp.keyboardModifiers()
|
||||||
if modKey == Qt.ShiftModifier:
|
if modKey == Qt.ShiftModifier:
|
||||||
self.docEditor.docAction(nwDocAction.GO_PREV)
|
self.docEditor.findNext(goBack=True)
|
||||||
else:
|
else:
|
||||||
self.docEditor.docAction(nwDocAction.GO_NEXT)
|
self.docEditor.findNext()
|
||||||
return
|
return
|
||||||
|
|
||||||
def _doReplace(self):
|
def _doReplace(self):
|
||||||
"""Call the replace action function for the document editor.
|
"""Call the replace action function for the document editor.
|
||||||
"""
|
"""
|
||||||
self.docEditor.docAction(nwDocAction.REPL_NEXT)
|
self.docEditor.replaceNext()
|
||||||
return
|
return
|
||||||
|
|
||||||
def _doToggleReplace(self, theState):
|
def _doToggleReplace(self, theState):
|
||||||
|
|||||||
+5
-5
@@ -762,7 +762,7 @@ class GuiMainMenu(QMenuBar):
|
|||||||
self.aFind = QAction(self.tr("Find"), self)
|
self.aFind = QAction(self.tr("Find"), self)
|
||||||
self.aFind.setStatusTip(self.tr("Find text in document"))
|
self.aFind.setStatusTip(self.tr("Find text in document"))
|
||||||
self.aFind.setShortcut("Ctrl+F")
|
self.aFind.setShortcut("Ctrl+F")
|
||||||
self.aFind.triggered.connect(lambda: self._docAction(nwDocAction.FIND))
|
self.aFind.triggered.connect(lambda: self.theParent.docEditor.beginSearch())
|
||||||
self.srcMenu.addAction(self.aFind)
|
self.srcMenu.addAction(self.aFind)
|
||||||
|
|
||||||
# Search > Replace
|
# Search > Replace
|
||||||
@@ -772,7 +772,7 @@ class GuiMainMenu(QMenuBar):
|
|||||||
self.aReplace.setShortcut("Ctrl+=")
|
self.aReplace.setShortcut("Ctrl+=")
|
||||||
else:
|
else:
|
||||||
self.aReplace.setShortcut("Ctrl+H")
|
self.aReplace.setShortcut("Ctrl+H")
|
||||||
self.aReplace.triggered.connect(lambda: self._docAction(nwDocAction.REPLACE))
|
self.aReplace.triggered.connect(lambda: self.theParent.docEditor.beginReplace())
|
||||||
self.srcMenu.addAction(self.aReplace)
|
self.srcMenu.addAction(self.aReplace)
|
||||||
|
|
||||||
# Search > Find Next
|
# Search > Find Next
|
||||||
@@ -782,7 +782,7 @@ class GuiMainMenu(QMenuBar):
|
|||||||
self.aFindNext.setShortcuts(["Ctrl+G", "F3"])
|
self.aFindNext.setShortcuts(["Ctrl+G", "F3"])
|
||||||
else:
|
else:
|
||||||
self.aFindNext.setShortcuts(["F3", "Ctrl+G"])
|
self.aFindNext.setShortcuts(["F3", "Ctrl+G"])
|
||||||
self.aFindNext.triggered.connect(lambda: self._docAction(nwDocAction.GO_NEXT))
|
self.aFindNext.triggered.connect(lambda: self.theParent.docEditor.findNext())
|
||||||
self.srcMenu.addAction(self.aFindNext)
|
self.srcMenu.addAction(self.aFindNext)
|
||||||
|
|
||||||
# Search > Find Prev
|
# Search > Find Prev
|
||||||
@@ -792,7 +792,7 @@ class GuiMainMenu(QMenuBar):
|
|||||||
self.aFindPrev.setShortcuts(["Ctrl+Shift+G", "Shift+F3"])
|
self.aFindPrev.setShortcuts(["Ctrl+Shift+G", "Shift+F3"])
|
||||||
else:
|
else:
|
||||||
self.aFindPrev.setShortcuts(["Shift+F3", "Ctrl+Shift+G"])
|
self.aFindPrev.setShortcuts(["Shift+F3", "Ctrl+Shift+G"])
|
||||||
self.aFindPrev.triggered.connect(lambda: self._docAction(nwDocAction.GO_PREV))
|
self.aFindPrev.triggered.connect(lambda: self.theParent.docEditor.findNext(goBack=True))
|
||||||
self.srcMenu.addAction(self.aFindPrev)
|
self.srcMenu.addAction(self.aFindPrev)
|
||||||
|
|
||||||
# Search > Replace Next
|
# Search > Replace Next
|
||||||
@@ -801,7 +801,7 @@ class GuiMainMenu(QMenuBar):
|
|||||||
self.tr("Find and replace next occurrence of text in document")
|
self.tr("Find and replace next occurrence of text in document")
|
||||||
)
|
)
|
||||||
self.aReplaceNext.setShortcut("Ctrl+Shift+1")
|
self.aReplaceNext.setShortcut("Ctrl+Shift+1")
|
||||||
self.aReplaceNext.triggered.connect(lambda: self._docAction(nwDocAction.REPL_NEXT))
|
self.aReplaceNext.triggered.connect(lambda: self.theParent.docEditor.replaceNext())
|
||||||
self.srcMenu.addAction(self.aReplaceNext)
|
self.srcMenu.addAction(self.aReplaceNext)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
+8
-4
@@ -766,14 +766,18 @@ class GuiMain(QMainWindow):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def passDocumentAction(self, theAction):
|
def passDocumentAction(self, theAction):
|
||||||
"""Pass on document action theAction to the document viewer if
|
"""Pass on document action to the document viewer if it has
|
||||||
it has focus, otherwise pass it to the document editor.
|
focus, or pass it to the document editor if it or any of
|
||||||
|
its clid widgets have focus. If neither has focus, ignore the
|
||||||
|
action.
|
||||||
"""
|
"""
|
||||||
if self.docViewer.hasFocus():
|
if self.docViewer.hasFocus():
|
||||||
self.docViewer.docAction(theAction)
|
self.docViewer.docAction(theAction)
|
||||||
else:
|
elif self.docEditor.hasFocus():
|
||||||
self.docEditor.docAction(theAction)
|
self.docEditor.docAction(theAction)
|
||||||
return True
|
else:
|
||||||
|
logger.debug("Action cancelled as neither editor nor viewer has focus")
|
||||||
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Tree Item Actions
|
# Tree Item Actions
|
||||||
|
|||||||
@@ -510,7 +510,7 @@ def testGuiEditor_Search(qtbot, monkeypatch, nwGUI, nwLipsum):
|
|||||||
assert abs(nwGUI.docEditor.getCursorPosition() - 1127) < 3
|
assert abs(nwGUI.docEditor.getCursorPosition() - 1127) < 3
|
||||||
|
|
||||||
# Toggle Replace
|
# Toggle Replace
|
||||||
nwGUI.docEditor._beginReplace()
|
nwGUI.docEditor.beginReplace()
|
||||||
|
|
||||||
# MonkeyPatch the focus cycle. We can't really test this very well, other than
|
# MonkeyPatch the focus cycle. We can't really test this very well, other than
|
||||||
# check that the tabs aren't captured when the main editor has focus
|
# check that the tabs aren't captured when the main editor has focus
|
||||||
|
|||||||
Reference in New Issue
Block a user