find & replace

This commit is contained in:
Damien Elmes 2011-04-14 03:52:32 +09:00
parent 139048ad3f
commit 3855183213
4 changed files with 84 additions and 72 deletions

View file

@ -116,6 +116,7 @@ class DeckModel(QAbstractTableModel):
def beginReset(self): def beginReset(self):
self.browser.editor.saveNow() self.browser.editor.saveNow()
self.browser.editor.setFact(None, hide=False)
self.browser.mw.progress.start() self.browser.mw.progress.start()
self.saveSelection() self.saveSelection()
self.beginResetModel() self.beginResetModel()
@ -740,6 +741,7 @@ where id in %s""" % ids2str(sf))
ChangeModel(self, fids) ChangeModel(self, fids)
def cram(self): def cram(self):
return showInfo("not yet implemented")
self.close() self.close()
self.mw.onCram(self.selectedCards()) self.mw.onCram(self.selectedCards())
@ -822,6 +824,7 @@ where id in %s""" % ids2str(sf))
###################################################################### ######################################################################
def reschedule(self): def reschedule(self):
return showInfo("not yet implemented")
n = _("Reschedule") n = _("Reschedule")
d = QDialog(self) d = QDialog(self)
frm = aqt.forms.reschedule.Ui_Dialog() frm = aqt.forms.reschedule.Ui_Dialog()
@ -911,52 +914,46 @@ where id in %s""" % ids2str(sf))
sf = self.selectedFacts() sf = self.selectedFacts()
if not sf: if not sf:
return return
mods = self.deck.db.column0(""" import anki.find
select distinct modelId from facts fields = sorted(anki.find.fieldNames(self.deck, downcase=False))
where id in %s""" % ids2str(sf))
if not len(mods) == 1:
ui.utils.showInfo(
_("Can only operate on one model at a time."),
parent=self)
return
d = QDialog(self) d = QDialog(self)
frm = aqt.forms.findreplace.Ui_Dialog() frm = aqt.forms.findreplace.Ui_Dialog()
frm.setupUi(d) frm.setupUi(d)
fields = sorted(self.card.fact.model.fieldModels, key=attrgetter("name")) frm.field.addItems(QStringList([_("All Fields")] + fields))
frm.field.addItems(QStringList(
[_("All Fields")] + [f.name for f in fields]))
self.connect(frm.buttonBox, SIGNAL("helpRequested()"), self.connect(frm.buttonBox, SIGNAL("helpRequested()"),
self.onFindReplaceHelp) self.onFindReplaceHelp)
if not d.exec_(): if not d.exec_():
return return
n = _("Find and Replace") if frm.field.currentIndex() == 0:
self.deck.startProgress(2) field = None
self.deck.updateProgress(_("Replacing...")) else:
self.deck.setUndoStart(n) field = fields[frm.field.currentIndex()-1]
self.deck.updateProgress() self.mw.checkpoint(_("Find and Replace"))
changed = None self.mw.progress.start()
self.model.beginReset()
try: try:
if frm.field.currentIndex() == 0:
field = None
else:
field = fields[frm.field.currentIndex()-1].id
changed = self.deck.findReplace(sf, changed = self.deck.findReplace(sf,
unicode(frm.find.text()), unicode(frm.find.text()),
unicode(frm.replace.text()), unicode(frm.replace.text()),
frm.re.isChecked(), frm.re.isChecked(),
field) field,
frm.ignoreCase.isChecked())
except sre_constants.error: except sre_constants.error:
ui.utils.showInfo(_("Invalid regular expression."), ui.utils.showInfo(_("Invalid regular expression."),
parent=self) parent=self)
self.deck.setUndoEnd(n) return
self.deck.finishProgress() else:
self.mw.reset() self.onSearch()
self.onSearch() self.resetDeck()
if changed is not None: finally:
ui.utils.showInfo(ngettext("%(a)d of %(b)d fact updated", "%(a)d of %(b)d facts updated", len(sf)) % { self.model.endReset()
self.mw.progress.finish()
showInfo(ngettext(
"%(a)d of %(b)d fact updated",
"%(a)d of %(b)d facts updated", len(sf)) % {
'a': changed, 'a': changed,
'b': len(sf), 'b': len(sf),
}, parent=self) })
def onFindReplaceHelp(self): def onFindReplaceHelp(self):
aqt.openHelp("Browser#FindReplace") aqt.openHelp("Browser#FindReplace")

View file

@ -350,7 +350,7 @@ class Editor(object):
if self.fact: if self.fact:
self.loadFact() self.loadFact()
def setFact(self, fact): def setFact(self, fact, hide=True):
"Make FACT the current fact." "Make FACT the current fact."
self.fact = fact self.fact = fact
# change timer # change timer
@ -359,7 +359,7 @@ class Editor(object):
loadCB=self._loadFinished) loadCB=self._loadFinished)
self.updateTagsAndGroup() self.updateTagsAndGroup()
self.updateKeyboard() self.updateKeyboard()
else: elif hide:
self.widget.hide() self.widget.hide()
def loadFact(self, field=0): def loadFact(self, field=0):

View file

@ -457,6 +457,9 @@
<property name="text"> <property name="text">
<string>Find and Re&amp;place...</string> <string>Find and Re&amp;place...</string>
</property> </property>
<property name="shortcut">
<string>Ctrl+Alt+F</string>
</property>
</action> </action>
<action name="actionCram"> <action name="actionCram">
<property name="icon"> <property name="icon">

View file

@ -1,65 +1,76 @@
<ui version="4.0" > <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class> <class>Dialog</class>
<widget class="QDialog" name="Dialog" > <widget class="QDialog" name="Dialog">
<property name="geometry" > <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>322</width> <width>367</width>
<height>159</height> <height>209</height>
</rect> </rect>
</property> </property>
<property name="windowTitle" > <property name="windowTitle">
<string>Find and Replace</string> <string>Find and Replace</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout" > <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<layout class="QGridLayout" name="gridLayout" > <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" > <item row="0" column="0">
<widget class="QLabel" name="label" > <widget class="QLabel" name="label">
<property name="text" > <property name="text">
<string>&lt;b>Find&lt;/b>:</string> <string>&lt;b&gt;Find&lt;/b&gt;:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1" > <item row="0" column="1">
<widget class="QLineEdit" name="find" /> <widget class="QLineEdit" name="find"/>
</item> </item>
<item row="2" column="0" > <item row="1" column="0">
<widget class="QLabel" name="label_2" > <widget class="QLabel" name="label_2">
<property name="text" > <property name="text">
<string>&lt;b>Replace With&lt;/b>:</string> <string>&lt;b&gt;Replace With&lt;/b&gt;:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1" > <item row="1" column="1">
<widget class="QLineEdit" name="replace" /> <widget class="QLineEdit" name="replace"/>
</item> </item>
<item row="3" column="1" > <item row="2" column="0">
<widget class="QCheckBox" name="re" > <widget class="QLabel" name="label_3">
<property name="text" > <property name="text">
<string>&lt;b&gt;In&lt;/b&gt;:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="field"/>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="re">
<property name="text">
<string>Treat input as regular expression</string> <string>Treat input as regular expression</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" > <item row="3" column="1">
<widget class="QLabel" name="label_3" > <widget class="QCheckBox" name="ignoreCase">
<property name="text" > <property name="text">
<string>&lt;b>In&lt;/b>:</string> <string>Ignore case</string>
</property>
<property name="checked">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1" >
<widget class="QComboBox" name="field" />
</item>
</layout> </layout>
</item> </item>
<item> <item>
<spacer name="verticalSpacer" > <spacer name="verticalSpacer">
<property name="orientation" > <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" stdset="0" > <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>40</height> <height>40</height>
@ -68,11 +79,11 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox" > <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation" > <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="standardButtons" > <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
</property> </property>
</widget> </widget>
@ -81,8 +92,9 @@
</widget> </widget>
<tabstops> <tabstops>
<tabstop>find</tabstop> <tabstop>find</tabstop>
<tabstop>field</tabstop>
<tabstop>replace</tabstop> <tabstop>replace</tabstop>
<tabstop>field</tabstop>
<tabstop>ignoreCase</tabstop>
<tabstop>re</tabstop> <tabstop>re</tabstop>
<tabstop>buttonBox</tabstop> <tabstop>buttonBox</tabstop>
</tabstops> </tabstops>
@ -94,11 +106,11 @@
<receiver>Dialog</receiver> <receiver>Dialog</receiver>
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel" > <hint type="sourcelabel">
<x>256</x> <x>256</x>
<y>154</y> <y>154</y>
</hint> </hint>
<hint type="destinationlabel" > <hint type="destinationlabel">
<x>157</x> <x>157</x>
<y>274</y> <y>274</y>
</hint> </hint>
@ -110,11 +122,11 @@
<receiver>Dialog</receiver> <receiver>Dialog</receiver>
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel" > <hint type="sourcelabel">
<x>290</x> <x>290</x>
<y>154</y> <y>154</y>
</hint> </hint>
<hint type="destinationlabel" > <hint type="destinationlabel">
<x>286</x> <x>286</x>
<y>274</y> <y>274</y>
</hint> </hint>