|
From: Kevin A. <al...@se...> - 2001-10-07 17:59:20
|
I want to have some generic Find and Find/Replace dialogs and find/replace
classes in PythonCard, so as the first step I added a Find/Find Next field
and buttons to the bottom of the textIndexer layout. The actual code that
does the work is shown below. There is quite a bit of code in common with
the three methods, but I didn't try and refactor the code, except where
on_doFind_command and on_doFindNext_command both use method findNext to
search the remaining cards in the stack if a match isn't found on the
current card. This is a brute force search, which is case-insensitive and
matches partial words. If someone with more search experience would like to
optimize the code, I encourage them to do so.
Because of the way textIndexer storage is organized via a separate ZODB
storage class, when a match is not made on the current card, the next card
in the stack is loaded and then the text from field1 is searched. This
additional i/o slows down the search, but since a refresh of field1 is not
done until after the search completes there isn't much feedback about what
was going on. Consequently, I added a StaticText field to display the
current card number, which does update as the card number changes.
You'll need to create at least a few cards and enter text on each to see the
find do its work.
I'm going to add a similar find to the addresses sample which will be
generalized a bit more, probably use a separate Find dialog window and
support searching of multiple fields. It will also search the dictionary
that holds the actual addresses data directly, which will make it closer to
the general find classes later on. I don't have a timeframe for the
addresses find code, I only finished up the code in textIndexer today
because of a post I made to the wx-users mailing list yesterday regarding a
problem with selections in wxTextCtrl.
ka
---
def findNext(self, searchText):
startCard = self.wstack._v_current_card
numCards = len(self.wstack.card_list)-1
# move to the next card and repeat the search until a match
# or we come back to the card we started on
doneSearching = 0
while not doneSearching:
if self.wstack._v_current_card == numCards:
self.wstack.GoFirst()
else:
self.wstack.GoNext()
if self.wstack._v_current_card == startCard:
doneSearching = 1
fieldText = self.components.field1.text.lower()
offset = fieldText.find(searchText)
if offset != -1:
offset += fieldText.count('\n', 0, offset)
self.components.field1.setSelection(offset, offset +
len(searchText))
self.components.field1.setFocus()
doneSearching = 1
def on_doFind_command(self, target, event):
searchText = self.components.fldFind.text.lower()
fieldText = self.components.field1.text.lower()
offset = fieldText.find(searchText)
if offset != -1:
# find apparently doesn't count newlines in its total
offset += fieldText.count('\n', 0, offset)
self.components.field1.setSelection(offset, offset +
len(searchText))
self.components.field1.setFocus()
else:
self.findNext(searchText)
def on_doFindNext_command(self, target, event):
searchText = self.components.fldFind.text.lower()
fieldText = self.components.field1.text.lower()
selOffset = self.components.field1.getSelection()[1]
offset = fieldText[selOffset:].find(searchText)
if offset != -1:
offset += selOffset
offset += fieldText.count('\n', 0, offset)
self.components.field1.setSelection(offset, offset +
len(searchText))
self.components.field1.setFocus()
else:
self.findNext(searchText)
|