Index: userdicts/default.dic
===================================================================
--- userdicts/default.dic	(revision 1821)
+++ userdicts/default.dic	(working copy)
@@ -1,15 +1,12 @@
-#General NVDA dictionary
-#syntax: record fields divided by tab character
-
-#Limit groups of the same character to 5 or less.
-([\W])\1{5,}	\1\1\1\1\1
+﻿#Limit groups of the same character to 5 or less.
+([\W])\1{5,}	\1\1\1\1\1	1	1
 #break up words that use a capital letter to denote another word
-([a-z])([A-Z])	\1 \2
+([a-z])([A-Z])	\1 \2	1	1
 #Break away a word starting with a capital from a fully uppercase word
-([A-Z])([A-Z][a-z])	\1 \2
+([A-Z])([A-Z][a-z])	\1 \2	1	1
 #telephone numbers
-\b(\d{3})\-(\d{2})(\d{2})\W	\1 \2 \3
+\b(\d{3})\-(\d{2})(\d{2})\W	\1 \2 \3	1	1
 #numbers beginning on the zero
-\b(0+)(\d+)	\1 \2
+\b(0+)(\d+)	\1 \2	1	1
 #Break words that have numbers at the end
-((?:(?=\D)\w)+)(\d+)	\1 \2
+((?:(?=\D)\w)+)(\d+)	\1 \2	1	1
Index: gui/settingsDialogs.py
===================================================================
--- gui/settingsDialogs.py	(revision 1821)
+++ gui/settingsDialogs.py	(working copy)
@@ -588,6 +588,32 @@
 		config.conf["documentFormatting"]["reportAlignment"]=self.alignmentCheckBox.IsChecked()
 		super(DocumentFormattingDialog, self).onOk(evt)
 
+class DictionaryEntryDialog(wx.Dialog):
+
+	def __init__(self,parent):
+		super(DictionaryEntryDialog,self).__init__(parent,title=_("Edit dictionary entry"))
+		mainSizer=wx.BoxSizer(wx.VERTICAL)
+		settingsSizer=wx.BoxSizer(wx.VERTICAL)
+		settingsSizer.Add(wx.StaticText(self,-1,label=_("&Pattern")))
+		self.patternTextCtrl=wx.TextCtrl(self,wx.NewId())
+		settingsSizer.Add(self.patternTextCtrl)
+		settingsSizer.Add(wx.StaticText(self,-1,label=_("&Replacement")))
+		self.replacementTextCtrl=wx.TextCtrl(self,wx.NewId())
+		settingsSizer.Add(self.replacementTextCtrl)
+		settingsSizer.Add(wx.StaticText(self,-1,label=_("&Comment")))
+		self.commentTextCtrl=wx.TextCtrl(self,wx.NewId())
+		settingsSizer.Add(self.commentTextCtrl)
+		self.caseSensitiveCheckBox=wx.CheckBox(self,wx.NewId(),label=_("Case &sensitive"))
+		settingsSizer.Add(self.caseSensitiveCheckBox)
+		self.regexpCheckBox=wx.CheckBox(self,wx.NewId(),label=_("Regular &expression"))
+		settingsSizer.Add(self.regexpCheckBox)
+		mainSizer.Add(settingsSizer,border=20,flag=wx.LEFT|wx.RIGHT|wx.TOP)
+		buttonSizer=self.CreateButtonSizer(wx.OK|wx.CANCEL)
+		mainSizer.Add(buttonSizer,border=20,flag=wx.LEFT|wx.RIGHT|wx.BOTTOM)
+		mainSizer.Fit(self)
+		self.SetSizer(mainSizer)
+		self.patternTextCtrl.SetFocus()
+
 class DictionaryDialog(SettingsDialog):
 
 	def __init__(self,parent,title,userDict):
@@ -607,8 +633,10 @@
 		self.dictList.InsertColumn(0,_("Comment"))
 		self.dictList.InsertColumn(1,_("Pattern"))
 		self.dictList.InsertColumn(2,_("Replacement"))
+		self.dictList.InsertColumn(3,_("case sensitive"))
+		self.dictList.InsertColumn(4,_("Regular expression"))
 		for entry in self.tempUserDict:
-			self.dictList.Append((entry.comment,entry.pattern,entry.replacement))
+			self.dictList.Append((entry.comment,entry.pattern,entry.replacement,str(entry.caseSensitive),str(entry.regexp)))
 		self.editingIndex=-1
 		entriesSizer.Add(self.dictList)
 		settingsSizer.Add(entriesSizer)
@@ -641,32 +669,50 @@
 		super(DictionaryDialog, self).onOk(evt)
 
 	def OnAddClick(self,evt):
-		if self.editingIndex==-1:
-			addEntryDialog=scriptUI.TextEntriesDialog((_("&Pattern"),_("&Replacement"),_("&Comment")),title=_("Add an entry"),callback=self.onDialog)
-			addEntryDialog.run()
+		entryDialog=DictionaryEntryDialog(self)
+		if entryDialog.ShowModal()==wx.ID_OK:
+			self.tempUserDict.append(userDictHandler.UserDictEntry(entryDialog.patternTextCtrl.GetValue(),entryDialog.replacementTextCtrl.GetValue(),entryDialog.commentTextCtrl.GetValue(),entryDialog.caseSensitiveCheckBox.GetValue(),entryDialog.regexpCheckBox.GetValue()))
+			self.dictList.Append((entryDialog.commentTextCtrl.GetValue(),entryDialog.patternTextCtrl.GetValue(),entryDialog.replacementTextCtrl.GetValue(),str(bool(entryDialog.caseSensitiveCheckBox.GetValue())),str(bool(entryDialog.regexpCheckBox.GetValue()))))
+			index=self.dictList.GetFirstSelected()
+			while index>=0:
+				self.dictList.Select(index,on=0)
+				index=self.dictList.GetNextSelected(index)
+			addedIndex=self.dictList.GetItemCount()-1
+			self.dictList.Select(addedIndex)
+			self.dictList.Focus(addedIndex)
+			self.dictList.SetFocus()
+		entryDialog.Destroy()
 
 	def OnEditClick(self,evt):
-		if (self.dictList.GetSelectedItemCount()==1) and (self.editingIndex==-1):
-			self.editingIndex=self.dictList.GetNextItem(-1,wx.LIST_NEXT_ALL,wx.LIST_STATE_SELECTED)
-			editEntryDialog=scriptUI.TextEntriesDialog((_("&Pattern"),_("&Replacement"),_("&Comment")),title=_("Edit an entry"),defaults=(self.tempUserDict[self.editingIndex].pattern,self.tempUserDict[self.editingIndex].replacement,self.tempUserDict[self.editingIndex].comment), callback=self.onDialog)
-			editEntryDialog.run()
+		if self.dictList.GetSelectedItemCount()!=1:
+			return
+		editIndex=self.dictList.GetFirstSelected()
+		if editIndex<0:
+			return
+		entryDialog=DictionaryEntryDialog(self)
+		entryDialog.patternTextCtrl.SetValue(self.tempUserDict[editIndex].pattern)
+		entryDialog.replacementTextCtrl.SetValue(self.tempUserDict[editIndex].replacement)
+		entryDialog.commentTextCtrl.SetValue(self.tempUserDict[editIndex].comment)
+		entryDialog.caseSensitiveCheckBox.SetValue(self.tempUserDict[editIndex].caseSensitive)
+		entryDialog.regexpCheckBox.SetValue(self.tempUserDict[editIndex].regexp)
+		if entryDialog.ShowModal()==wx.ID_OK:
+			self.tempUserDict[editIndex].comment=entryDialog.commentTextCtrl.GetValue()
+			self.dictList.SetStringItem(editIndex,0,entryDialog.commentTextCtrl.GetValue())
+			self.tempUserDict[editIndex].pattern=entryDialog.patternTextCtrl.GetValue()
+			self.dictList.SetStringItem(editIndex,1,entryDialog.patternTextCtrl.GetValue())
+			self.tempUserDict[editIndex].replacement=entryDialog.replacementTextCtrl.GetValue()
+			self.dictList.SetStringItem(editIndex,2,entryDialog.replacementTextCtrl.GetValue())
+			self.tempUserDict[editIndex].caseSensitive=bool(entryDialog.caseSensitiveCheckBox.GetValue())
+			self.dictList.SetStringItem(editIndex,3,str(bool(entryDialog.caseSensitiveCheckBox.GetValue())))
+			self.tempUserDict[editIndex].regexp=bool(entryDialog.regexpCheckBox.GetValue())
+			self.dictList.SetStringItem(editIndex,4,str(bool(entryDialog.regexpCheckBox.GetValue())))
+			self.dictList.SetFocus()
+		entryDialog.Destroy()
 
 	def OnRemoveClick(self,evt):
-		index=self.dictList.GetNextItem(-1,wx.LIST_NEXT_ALL,wx.LIST_STATE_SELECTED)
-		if (index!=self.editingIndex)and(self.dictList.GetSelectedItemCount()==1):
+		index=self.dictList.GetFirstSelected()
+		while index>=0:
 			self.dictList.DeleteItem(index)
 			del self.tempUserDict[index]
+			index=self.dictList.GetNextSelected(index)
 		self.dictList.SetFocus()
-
-	def onDialog(self,texts):
-		if texts is not None:
-			if self.editingIndex>=0:
-				self.tempUserDict[self.editingIndex]=userDictHandler.UserDictEntry(texts[0],texts[1],texts[2])
-				self.dictList.SetStringItem(self.editingIndex,1,texts[0])
-				self.dictList.SetStringItem(self.editingIndex,2,texts[1])
-				self.dictList.SetStringItem(self.editingIndex,0,texts[2])
-			else:
-				self.tempUserDict.append(userDictHandler.UserDictEntry(texts[0],texts[1],texts[2]))
-				self.dictList.Append((texts[2],texts[0],texts[1]))
-		self.editingIndex=-1
-		self.dictList.SetFocus()
Index: userDictHandler.py
===================================================================
--- userDictHandler.py	(revision 1821)
+++ userDictHandler.py	(working copy)
@@ -16,14 +16,19 @@
 
 class UserDictEntry:
 
-	def __init__(self, pattern, replacement,comment):
+	def __init__(self, pattern, replacement,comment,caseSensitive=True,regexp=False):
 		self.pattern = pattern
-		self.compiled = re.compile(pattern)
+		flags=re.IGNORECASE if not caseSensitive else 0
+		tempPattern=pattern if regexp else re.escape(pattern)
+		self.compiled = re.compile(tempPattern,flags)
 		self.replacement = replacement
 		self.comment=comment
+		self.caseSensitive=caseSensitive
+		self.regexp=regexp
 
 	def sub(self, text):
-		return self.compiled.sub(self.replacement, text)
+		replacement=self.replacement if self.regexp else re.escape(self.replacement)
+		return self.compiled.sub(replacement, text)
 
 class UserDict(list):
 
@@ -47,8 +52,8 @@
 				comment+=line[1:]
 			else:
 				temp=line.split("\t")
-				if len(temp) ==2:
-					self.append(UserDictEntry(temp[0],temp[1],comment))
+				if len(temp) ==4:
+					self.append(UserDictEntry(temp[0],temp[1],comment,bool(int(temp[2])),bool(int(temp[3]))))
 					comment=""
 				else:
 					globalVars.log.warning("can't parse line '%s'" % line)
@@ -64,7 +69,7 @@
 			for entry in self:
 				if entry.comment:
 					file.write("#%s\r\n"%entry.comment)
-				file.write("%s\t%s\r\n"%(entry.pattern,entry.replacement))
+				file.write("%s\t%s\t%s\t%s\r\n"%(entry.pattern,entry.replacement,int(entry.caseSensitive),int(entry.regexp)))
 			file.close()
 
 	def sub(self, text):

