# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: nrm1977@gmail.com-20120411171754-p3ubjukfpf6qpoup
# target_branch: http://bzr.nvaccess.org/nvda/main/
# testament_sha1: 8063c5e7444434c29a1c0afda086c596a3609347
# timestamp: 2012-04-11 19:18:39 +0200
# base_revision_id: mhameed@src.gnome.org-20120410054749-\
#   cjmrhbc2786q4e81
# 
# Begin patch
=== modified file 'source/config/__init__.py'
--- source/config/__init__.py	2012-04-03 18:06:49 +0000
+++ source/config/__init__.py	2012-04-05 19:28:27 +0000
@@ -276,7 +276,7 @@
 		configPath=globalVars.appArgs.configPath
 	if not os.path.isdir(configPath):
 		os.makedirs(configPath)
-	for subdir in ("appModules","brailleDisplayDrivers","speechDicts","synthDrivers","globalPlugins"):
+	for subdir in ("appModules","brailleDisplayDrivers","speechDicts","synthDrivers","globalPlugins","search"):
 		subdir=os.path.join(configPath,subdir)
 		if not os.path.isdir(subdir):
 			os.makedirs(subdir)

=== modified file 'source/cursorManager.py'
--- source/cursorManager.py	2012-01-04 07:53:24 +0000
+++ source/cursorManager.py	2012-04-11 17:17:54 +0000
@@ -18,6 +18,9 @@
 import config
 import braille
 import controlTypes
+import os
+import re
+import ui
 
 class CursorManager(baseObject.ScriptableObject):
 	"""
@@ -34,6 +37,10 @@
 
 	_lastFindText=""
 
+	# For specific search
+
+	_lastSpecificFindText=""
+
 	def __init__(self, *args, **kwargs):
 		super(CursorManager, self).__init__(*args, **kwargs)
 		self.initCursorManager()
@@ -85,6 +92,7 @@
 				wx.CallLater(100, self.doFindText, d.GetValue())
 		gui.runScriptModalDialog(d, callback)
 
+
 	def doFindText(self,text,reverse=False):
 		if not text:
 			return
@@ -117,6 +125,79 @@
 		self.doFindText(self._lastFindText,reverse=True)
 	script_findPrevious.__doc__ = _("find the previous occurrence of the previously entered text string from the current cursor's position")
 
+
+	# For specific search
+
+	def standarFileName(self, fileName):
+		notAllowed = re.compile("\?|:|\*|\t|<|>|\"|\/|\\||") # Invalid characters
+		allowed = re.sub(notAllowed, "", unicode(fileName))
+		return allowed
+
+	def getFile(self):
+		obj=api.getForegroundObject()
+		file = obj.name
+		file = file.rsplit(" - ", 1)[0]
+		file = self.standarFileName(file)
+		file = file+".txt"
+		path=config.getUserDefaultConfigPath()
+		config.initConfigPath(None)
+		path=path+"\\search\\"+file
+		abspath=os.path.abspath(path)
+		return abspath
+
+	def getLastSpecificFindText(self):
+		f = open(self.getFile(), "r")
+		self._lastSpecificFindText = f.read()
+		f.close()
+
+	def saveSpecificFindTextDialog(self):
+		try:
+			self.getLastSpecificFindText()
+		except IOError:
+			self._lastSpecificFindText = ""
+		d = wx.TextEntryDialog(gui.mainFrame, _("Type the text you wish to save, or delete text if you want to remove the previous saved search"), _("Save text for specific search"), defaultValue=self._lastSpecificFindText)
+		def callback(result):
+			if result == wx.ID_OK:
+				# Make sure this happens after focus returns to the document.
+				wx.CallLater(100, self.saveSpecificFindText, d.GetValue())
+		gui.runScriptModalDialog(d, callback)
+
+	def saveSpecificFindText(self, text):
+		if not text:
+			try:
+				os.remove(self.getFile())
+			except WindowsError:
+				pass
+			return
+		f = open (self.getFile(), "w")
+		f.write(text.encode("latin-1"))
+		f.close
+
+	def script_specificSave(self,gesture): 
+		self.saveSpecificFindTextDialog()
+	script_specificSave.__doc__ = _("Save a text string for a specific search")
+
+	def doSpecificFindTextDialog(self):
+		try:
+			self.getLastSpecificFindText()
+		except IOError:
+			ui.message(_("File for specific search not found"))
+			return
+		d = wx.TextEntryDialog(gui.mainFrame, _("Type the text you wish to find"), _("Specific search"), defaultValue=self._lastSpecificFindText)
+		def callback(result):
+			if result == wx.ID_OK:
+				# Make sure this happens after focus returns to the document.
+				wx.CallLater(100, self.doFindText, d.GetValue())
+		gui.runScriptModalDialog(d, callback)
+
+	def script_specificFind(self,gesture): 
+		self.doSpecificFindTextDialog()
+	script_specificFind.__doc__ = _("find a text string from the current cursor position for a specific page")
+
+
	# End for specific search
+
+
+
 	def script_moveByPage_back(self,gesture):
 		self._caretMovementScriptHelper(textInfos.UNIT_LINE,-config.conf["virtualBuffers"]["linesPerPage"],extraDetail=False)
 
@@ -281,6 +362,8 @@
 		"kb:NVDA+Control+f": "find",
 		"kb:NVDA+f3": "findNext",
 		"kb:NVDA+shift+f3": "findPrevious",
+		"kb:control+shift+NVDA+s": "specificSave",
+		"kb:control+shift+NVDA+f": "specificFind",
 	}
 
 class _ReviewCursorManagerTextInfo(textInfos.TextInfo):

# Begin bundle
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
