Index: dogtail/path.py
===================================================================
--- dogtail/path.py	(revision 339)
+++ dogtail/path.py	(working copy)
@@ -86,10 +86,10 @@
 
             if False:
                 print "...................."
-                print "from %s"%self
-                print "to %s"%other
-                print "i=%s"%i
-                print "relative path %s"%result
+                print _("from %s")%self
+                print _("to %s")%other
+                print _("i=%s")%i
+                print _("relative path %s")%result
                 print "...................."
 
             return result
Index: dogtail/tree.py
===================================================================
--- dogtail/tree.py	(revision 339)
+++ dogtail/tree.py	(working copy)
@@ -60,6 +60,9 @@
 David Malcolm <dmalcolm@redhat.com>
 """
 
+import gettext
+gettext.install('dogtail')
+
 from utils import checkForA11y
 checkForA11y()
 
@@ -79,7 +82,7 @@
     import atspi
 except ImportError:
     # If atspi can't be imported, fail.
-    raise ImportError, "Error importing the AT-SPI bindings"
+    raise ImportError, _("Error importing the AT-SPI bindings")
 
 # We optionally import the bindings for libwnck.
 try:
@@ -99,7 +102,7 @@
     """
     This attribute is not writeable.
     """
-    message = "Cannot set %s. It is read-only."
+    message = _("Cannot set %s. It is read-only.")
     def __init__(self, attr):
         self.attr = attr
 
@@ -110,7 +113,7 @@
     """
     The widget is not sensitive.
     """
-    message = "Cannot %s %s. It is not sensitive."
+    message = _("Cannot %s %s. It is not sensitive.")
     def __init__(self, action):
         self.action = action
 
@@ -121,7 +124,7 @@
     """
     The widget does not support the requested action.
     """
-    message = "Cannot do '%s' action on %s"
+    message = _("Cannot do '%s' action on %s")
     def __init__(self, actionName, node):
         self.actionName = actionName
         self.node = node
@@ -163,7 +166,7 @@
         """
         Plain-text representation of the Action.
         """
-        string = "Action node='%s' name='%s' description='%s' keybinding='%s'" % (self.node, self.name, self.description, self.keyBinding)
+        string = _("Action node='%s' name='%s' description='%s' keybinding='%s'") % (self.node, self.name, self.description, self.keyBinding)
         return string
 
     def do (self):
@@ -171,13 +174,13 @@
         Performs the given tree.Action, with appropriate delays and logging.
         """
         assert isinstance(self, Action)
-        logger.log("%s on %s"%(self.name, self.node.getLogString()))
+        logger.log(_("%s on %s")%(self.name, self.node.getLogString()))
         if not self.node.sensitive:
             if config.ensureSensitivity:
                 raise NotSensitiveError, self
             else:
                 nSE = NotSensitiveError(self)
-                logger.log("Warning: " + str(nSE))
+                logger.log(_("Warning: ") + str(nSE))
         if config.blinkOnActions: self.node.blink()
         result = self.__action.doAction (self.__index)
         doDelay()
@@ -320,7 +323,7 @@
             self.__accessible = initializer.__accessible
             self.debugName = getattr(initializer, 'debugName', None)
         else:
-            raise "Unknown Node initializer"
+            raise _("Unknown Node initializer")
         assert self.__accessible
 
         # Swallow the Action object, if it exists
@@ -360,7 +363,7 @@
                 clickX = position[0] + 0.5 * size[0]
                 clickY = position[1] + 0.5 * size[1]
                 if config.debugSearching:
-                    logger.log("raw click on %s %s at (%s,%s)"%(self.name, self.getLogString(), str(clickX), str(clickY)))
+                    logger.log(_("raw click on %s %s at (%s,%s)")%(self.name, self.getLogString(), str(clickX), str(clickY)))
                 rawinput.click(clickX, clickY, button)
             self.rawClick = rawClick
 
@@ -468,7 +471,7 @@
             if childCount > config.childrenLimit:
                 global haveWarnedAboutChildrenLimit
                 if not haveWarnedAboutChildrenLimit:
-                    logger.log("Only returning %s children. You may change config.childrenLimit if you wish. This message will only be printed once." % str(config.childrenLimit))
+                    logger.log(_("Only returning %s children. You may change config.childrenLimit if you wish. This message will only be printed once.") % str(config.childrenLimit))
                     haveWarnedAboutChildrenLimit = True
                 childCount = config.childrenLimit
             for i in xrange (childCount):
@@ -609,7 +612,7 @@
             """
             if not self.__editableText:
                 raise ReadOnlyError, attr
-            if config.debugSearching: logger.log("Setting text of %s to '%s'"%(self.getLogString(), value))
+            if config.debugSearching: logger.log(_("Setting text of %s to '%s'")%(self.getLogString(), value))
             self.__editableText.setTextContents (value)
             doDelay()
 
@@ -625,7 +628,7 @@
             """
             if not self.__editableText:
                 raise ReadOnlyError, attr
-            logger.log("Setting text %s to password '%s'"%(self.getLogString(), value))
+            logger.log(_("Setting text %s to password '%s'")%(self.getLogString(), value))
             self.__editableText.setTextContents (value)
             doDelay()
 
@@ -634,7 +637,7 @@
             Set the combobox to the given value, with appropriate delays and
             logging.
             """
-            logger.log("Setting combobox %s to '%s'"%(self.getLogString(), value))
+            logger.log(_("Setting combobox %s to '%s'")%(self.getLogString(), value))
             self.childNamed(childName=value).click()
             doDelay()
         else:
@@ -646,33 +649,33 @@
         Type the given text into the node, with appropriate delays and
         logging.
         """
-        logger.log("Typing text into %s: '%s'"%(self.getLogString(), string))
+        logger.log(_("Typing text into %s: '%s'")%(self.getLogString(), string))
 
         # Non-working implementation
         # Unfortunately, the call to AccessibleText_setCaretOffset fails for Evolution's gtkhtml composer for some reason
         if False:
-            logger.log("caret offset: %s" % self.caretOffset)
+            logger.log(_("caret offset: %s") % self.caretOffset)
             self.__editableText.insertText (self.caretOffset, text)
             self.caretOffset+=len(string) # FIXME: is this correct?
-            logger.log("new caret offset: %s" % self.caretOffset)
+            logger.log(_("new caret offset: %s") % self.caretOffset)
 
         if self.focusable:
             if not self.focused:
                 try: self.grabFocus()
-                except Exception: logger.log("Node is focusable but I can't grabFocus!")
+                except Exception: logger.log(_("Node is focusable but I can't grabFocus!"))
             rawinput.typeText(string)
         else:
-            logger.log("Node is not focusable; falling back to setting text")
+            logger.log(_("Node is not focusable; falling back to setting text"))
             node.text += string
             doDelay()
 
     def keyCombo(self, comboString):
-        if config.debugSearching: logger.log("Pressing keys '%s' into %s"%(combo, self.getLogString()))
+        if config.debugSearching: logger.log(_("Pressing keys '%s' into %s")%(combo, self.getLogString()))
         if self.focusable:
             if not self.focused:
                 try: self.grabFocus()
-                except Exception: logger.log("Node is focusable but I can't grabFocus!")
-        else: logger.log("Node is not focusable; trying key combo anyway")
+                except Exception: logger.log(_("Node is focusable but I can't grabFocus!"))
+        else: logger.log(_("Node is not focusable; trying key combo anyway"))
         rawinput.keyCombo(comboString)
 
     def __str__ (self):
@@ -685,11 +688,11 @@
         if self.debugName:
             return "{" + self.debugName + "}"
         else:
-            string = "Node"
-            string = string + " roleName='%s'" % self.roleName
-            string = string + " name='%s' description='%s'" % (self.name, self.description)
+            string = _("Node")
+            string = string + _(" roleName='%s'") % self.roleName
+            string = string + _(" name='%s' description='%s'") % (self.name, self.description)
             if self.text is not None:
-                string = string + " text='%s'" % self.text
+                string = string + _(" text='%s'") % self.text
             return string
 
     def getLogString(self):
@@ -745,7 +748,7 @@
             if self.parent:
                 (ancestor, pred, isRecursive) = self.getRelativeSearch()
                 if config.debugSearchPaths:
-                    logger.log("got ancestor: %s" % ancestor)
+                    logger.log(_("got ancestor: %s") % ancestor)
 
                 ancestorPath = ancestor.getAbsoluteSearchPath()
                 ancestorPath.append(pred, isRecursive)
@@ -850,9 +853,9 @@
             Internal helper function
             """
             if recursive:
-                noun = "descendent"
+                noun = _("descendent")
             else:
-                noun = "child"
+                noun = _("child")
 
             if debugName == None:
                 debugName = pred.describeSearchResult()
@@ -863,7 +866,7 @@
         numAttempts = 0
         while numAttempts<config.searchCutoffCount:
             if numAttempts>=config.searchWarningThreshold or config.debugSearching:
-                logger.log("searching for %s (attempt %i)" % (describeSearch(self, pred, recursive, debugName), numAttempts))
+                logger.log(_("searching for %s (attempt %i)") % (describeSearch(self, pred, recursive, debugName), numAttempts))
 
             result = findFirstChildSatisfying(self, pred, recursive)
             if result:
@@ -877,7 +880,7 @@
                 if not retry: break
                 numAttempts+=1
                 if config.debugSearching or config.debugSleep:
-                    logger.log("sleeping for %f" % config.searchBackoffDuration)
+                    logger.log(_("sleeping for %f") % config.searchBackoffDuration)
                 sleep(config.searchBackoffDuration)
         if requireResult:
             raise SearchError(describeSearch(self, pred, recursive, debugName))
@@ -1195,7 +1198,7 @@
         Node.__init__(self, node)
         if debugName:
             self.debugName = debugName
-        logger.log("%s is on '%s' page"%(self, self.getPageTitle()))
+        logger.log(_("%s is on '%s' page")%(self, self.getPageTitle()))
 
     def currentPage(self):
         """
@@ -1210,7 +1213,7 @@
             #print child.showing
             if child.showing:
                 return child
-        raise "Unable to determine current page of %s"%self
+        raise _("Unable to determine current page of %s")%self
 
     def getPageTitle(self):
         """
@@ -1236,7 +1239,7 @@
         fwd.click()
 
         # Log the new wizard page; it's helpful when debugging scripts
-        logger.log("%s is now on '%s' page"%(self, self.getPageTitle()))
+        logger.log(_("%s is now on '%s' page")%(self, self.getPageTitle()))
         # FIXME disabled for now (can't get valid page titles)
 
     def clickApply(self):
@@ -1257,12 +1260,12 @@
     root.debugName= 'root'
 except AssertionError:
     # Warn if AT-SPI's desktop object doesn't show up.
-    logger.log("Error: AT-SPI's desktop is not visible. Do you have accessibility enabled?")
+    logger.log(_("Error: AT-SPI's desktop is not visible. Do you have accessibility enabled?"))
 
 # Check that there are applications running. Warn if none are.
 children = root.children
 if not children:
-    logger.log("Warning: AT-SPI's desktop is visible but it has no children. Are you running any AT-SPI-aware applications?")
+    logger.log(_("Warning: AT-SPI's desktop is visible but it has no children. Are you running any AT-SPI-aware applications?"))
 del children
 
 # Convenient place to set some debug variables:
Index: dogtail/utils.py
===================================================================
--- dogtail/utils.py	(revision 339)
+++ dogtail/utils.py	(working copy)
@@ -29,7 +29,7 @@
     The timeStamp argument may be set to False to name the file foo.png.
     """
     if not isinstance(timeStamp, bool):
-        raise TypeError, "timeStampt must be True or False"
+        raise TypeError, _("timeStampt must be True or False")
     # config is supposed to create this for us. If it's not there, bail.
     assert os.path.isdir(config.scratchDir)
 
@@ -59,9 +59,9 @@
     if fileExt == 'jpg': fileExt = 'jpeg'
     try: pixbuf.save(path, fileExt)
     except gobject.GError:
-        raise ValueError, "Failed to save screenshot in %s format" % fileExt
+        raise ValueError, _("Failed to save screenshot in %s format") % fileExt
     assert os.path.exists(path)
-    logger.log("Screenshot taken: " + path)
+    logger.log(_("Screenshot taken: ") + path)
     return path
 
 def run(string, timeout=config.runTimeout, interval=config.runInterval, desktop=None, dumb=False, appName=''):
@@ -110,7 +110,7 @@
     if delay is None:
         delay = config.defaultDelay
     if config.debugSleep:
-        logger.log("sleeping for %f" % delay)
+        logger.log(_("sleeping for %f") % delay)
     sleep(delay)
 
 class Blinker:
@@ -164,7 +164,7 @@
     return (gconfEnabled or envEnabled)
 
 def bailBecauseA11yIsDisabled():
-    logger.log("Dogtail requires that Assistive Technology support be enabled. Aborting...")
+    logger.log(_("Dogtail requires that Assistive Technology support be enabled. Aborting..."))
     sys.exit(1)
 
 def enableA11y():
@@ -186,15 +186,15 @@
     """
     if isA11yEnabled(): return
     import gtk
-    dialog = gtk.Dialog('Enable Assistive Technology Support?',
+    dialog = gtk.Dialog(_('Enable Assistive Technology Support?'),
                      None,
                      gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                      (gtk.STOCK_QUIT, gtk.RESPONSE_CLOSE, 
                          "_Enable", gtk.RESPONSE_ACCEPT))
-    question = """Dogtail requires that Assistive Technology Support be enabled for it to function. Would you like to enable Assistive Technology support now?
+    question = _("""Dogtail requires that Assistive Technology Support be enabled for it to function. Would you like to enable Assistive Technology support now?
 
 Note that you will have to log out for the change to fully take effect.
-    """.strip()
+    """).strip()
     dialog.set_default_response(gtk.RESPONSE_ACCEPT)
     questionLabel = gtk.Label(question)
     questionLabel.set_line_wrap(True)
@@ -202,7 +202,7 @@
     dialog.show_all()
     result = dialog.run()
     if result == gtk.RESPONSE_ACCEPT:
-        logger.log("Enabling accessibility...")
+        logger.log(_("Enabling accessibility..."))
         enableA11y()
     elif result == gtk.RESPONSE_CLOSE:
        bailBecauseA11yIsDisabled()
Index: dogtail/procedural.py
===================================================================
--- dogtail/procedural.py	(revision 339)
+++ dogtail/procedural.py	(working copy)
@@ -28,10 +28,10 @@
 import errors
 def focusFailed(type, name):
     if type is None or type == '':
-        type = "widget"
-    errors.warn('The requested %s \'%s\' could not be focused.' % (type, name))
+        type = _("widget")
+    errors.warn(_('The requested %s \'%s\' could not be focused.') % (type, name))
 
-ENOARGS = "At least one argument is needed"
+ENOARGS = _("At least one argument is needed")
 
 class FocusBase:
     """
@@ -69,7 +69,7 @@
         except tree.SearchError, desc:
             if config.fatalErrors: raise FocusError, name
             else:
-                focusFailed('Application', name)
+                focusFailed(_('Application'), name)
                 return False
         if app: 
             FocusApplication.node = app
@@ -102,7 +102,7 @@
         else: 
             if config.fatalErrors: raise FocusError, predicate.debugName
             else:
-                focusFailed('Dialog', name)
+                focusFailed(_('Dialog'), name)
                 return False
         return True
 
Index: dogtail/predicate.py
===================================================================
--- dogtail/predicate.py	(revision 339)
+++ dogtail/predicate.py	(working copy)
@@ -16,7 +16,7 @@
     if isRecursive==defaultValue:
         return ""
     else:
-        return ", recursive=%s"%isRecursive
+        return _(", recursive=%s")%isRecursive
 
 def makeCamel(string):
     """
@@ -96,7 +96,7 @@
         return node.roleName=='application' and stringMatches(self.appName, node.name)
 
     def describeSearchResult(self):
-        return '%s application'%self.appName
+        return _("%s application")%self.appName
 
     def makeScriptMethodCall(self, isRecursive):
         # ignores the isRecursive parameter
@@ -124,15 +124,15 @@
             self.debugName = debugName
         else:
             if label:
-                self.debugName = "labelled '%s'"%self.label
+                self.debugName = _("labelled '%s'")%self.label
             else:
-                self.debugName = "child with"
+                self.debugName = _("child with")
             if name:
-                self.debugName += " name=%s" % self.name
+                self.debugName += _(" name=%s") % self.name
             if roleName:
-                self.debugName += " roleName='%s'"%roleName
+                self.debugName += _(" roleName='%s'")%roleName
             if description:
-                self.debugName += " description='%s'"%description
+                self.debugName += _(" description='%s'")%description
         assert self.debugName
 
 
@@ -193,7 +193,7 @@
         return stringMatches(self.name, node.name)
 
     def describeSearchResult(self):
-        return "named %s"%self.name
+        return _("named %s")%self.name
 
     def makeScriptMethodCall(self, isRecursive):
         return "child(name=%s%s)"%(self.name, makeScriptRecursiveArgument(isRecursive, True))
@@ -210,7 +210,7 @@
         return node.roleName=='frame' and stringMatches(self.windowName, node.name)
 
     def describeSearchResult(self):
-        return "%s window"%self.windowName
+        return _("%s window")%self.windowName
 
     def makeScriptMethodCall(self, isRecursive):
         return "window(%s%s)"%(self.windowName, makeScriptRecursiveArgument(isRecursive, False))
@@ -224,7 +224,7 @@
         return node.roleName=='frame'
 
     def describeSearchResult(self):
-        return "window"
+        return _("window")
 
 class IsADialogNamed(Predicate):
     """Predicate subclass that looks for a top-level dialog by name"""
@@ -236,7 +236,7 @@
         return node.roleName=='dialog' and stringMatches(self.dialogName, node.name)
 
     def describeSearchResult(self):
-        return '%s dialog'%self.dialogName
+        return _("%s dialog")%self.dialogName
 
     def makeScriptMethodCall(self, isRecursive):
         return "dialog(%s%s)"%(self.dialogName, makeScriptRecursiveArgument(isRecursive, False))
@@ -261,7 +261,7 @@
         else: return False
 
     def describeSearchResult(self):
-        return 'labelled %s'%self.labelText
+        return _("labelled %s")%self.labelText
 
     def makeScriptMethodCall(self, isRecursive):
         return "child(label=%s%s)"%(self.labelText, makeScriptRecursiveArgument(isRecursive, True))
@@ -279,7 +279,7 @@
         return node.roleName=='menu' and stringMatches(self.menuName, node.name)
 
     def describeSearchResult(self):
-        return '%s menu'%(self.menuName)
+        return _("%s menu")%(self.menuName)
 
     def makeScriptMethodCall(self, isRecursive):
         return "menu(%s%s)"%(self.menuName, makeScriptRecursiveArgument(isRecursive, True))
@@ -298,7 +298,7 @@
         return (roleName=='menu item' or roleName=='check menu item' or roleName=='radio menu item') and stringMatches(self.menuItemName, node.name)
 
     def describeSearchResult(self):
-        return '%s menuitem'%(self.menuItemName)
+        return _('%s menuitem')%(self.menuItemName)
 
     def makeScriptMethodCall(self, isRecursive):
         return "menuItem(%s%s)"%(self.menuItemName, makeScriptRecursiveArgument(isRecursive, True))
@@ -316,7 +316,7 @@
         return node.roleName=='text' and stringMatches(self.textEntryName, node.name)
 
     def describeSearchResult(self):
-        return '%s textentry'%(self.textEntryName)
+        return _('%s textentry')%(self.textEntryName)
 
     def makeScriptMethodCall(self, isRecursive):
         return "textentry(%s%s)"%(self.textEntryName, makeScriptRecursiveArgument(isRecursive, True))
@@ -334,7 +334,7 @@
         return node.roleName=='push button' and stringMatches(self.buttonName, node.name)
 
     def describeSearchResult(self):
-        return '%s button'%(self.buttonName)
+        return _('%s button')%(self.buttonName)
 
     def makeScriptMethodCall(self, isRecursive):
         return "button(%s%s)"%(self.buttonName, makeScriptRecursiveArgument(isRecursive, True))
@@ -352,7 +352,7 @@
         return node.roleName=='page tab' and stringMatches(self.tabName, node.name)
 
     def describeSearchResult(self):
-        return '%s tab'%(self.tabName)
+        return _('%s tab')%(self.tabName)
 
     def makeScriptMethodCall(self, isRecursive):
         return "tab(%s%s)"%(self.tabName, makeScriptRecursiveArgument(isRecursive, True))
Index: dogtail/distro.py
===================================================================
--- dogtail/distro.py	(revision 339)
+++ dogtail/distro.py	(working copy)
@@ -15,7 +15,7 @@
     Arguments:
             distro: the distribution that is not supported.
     """
-    PATCH_MESSAGE = "Please send patches to dogtail-devel-list@gnome.org"
+    PATCH_MESSAGE = _("Please send patches to ") + 'dogtail-devel-list@gnome.org'
 
     def __init__(self, distro):
         self.distro = distro
@@ -297,40 +297,40 @@
     def __init__(self):
         self.packageDb = JhBuildPackageDb()
 
-message = "Detecting distribution: "
+message = _("Detecting distribution: ")
 if os.environ.get("CERTIFIED_GNOMIE", "no") == "yes":
-    logger.log(message + "JHBuild environment")
+    logger.log(message + _("JHBuild environment"))
     distro = JHBuild()
 elif os.path.exists ("/etc/SuSE-release"):
-    logger.log(message + "SuSE (or derived distribution)")
+    logger.log(message + _("SuSE (or derived distribution)"))
     distro = Suse()
 elif os.path.exists ("/etc/fedora-release"):
-    logger.log(message + "Fedora (or derived distribution)")
+    logger.log(message + _("Fedora (or derived distribution)"))
     distro = RedHatOrFedora()
 elif os.path.exists ("/etc/redhat-release"):
-    logger.log(message + "Red Hat/Fedora/derived distribution")
+    logger.log(message + _("Red Hat/Fedora/derived distribution"))
     distro = RedHatOrFedora()
 elif os.path.exists ("/usr/share/doc/ubuntu-minimal"):
-    logger.log(message + "Ubuntu (or derived distribution)")
+    logger.log(message + _("Ubuntu (or derived distribution)"))
     distro = Ubuntu()
 elif os.path.exists ("/etc/debian_version"):
-    logger.log(message + "Debian (or derived distribution)")
+    logger.log(message + _("Debian (or derived distribution)"))
     distro = Debian()
 elif os.path.exists ("/etc/gentoo-release"):
-    logger.log(message + "Gentoo (or derived distribution)")
+    logger.log(message + _("Gentoo (or derived distribution)"))
     distro = Gentoo()
 elif os.path.exists ("/etc/slackware-version"):
-    logger.log(message + "Slackware")
+    logger.log(message + _("Slackware"))
     raise DistributionNotSupportedError("Slackware")
 elif os.path.exists ("/var/lib/conarydb/conarydb"):
-    logger.log(message + "Conary-based distribution")
+    logger.log(message + _("Conary-based distribution"))
     distro = Conary()
 elif os.path.exists ("/etc/release") and \
         re.match (".*Solaris", open ("/etc/release").readline()):
-    print "Solaris distribution"
+    print _("Solaris distribution")
     distro = Solaris()
 else:
-    logger.log(message + "Unknown")
-    raise DistributionNotSupportedError("Unknown")
+    logger.log(message + _("Unknown"))
+    raise DistributionNotSupportedError(_("Unknown"))
 
 packageDb = distro.packageDb
Index: dogtail/config.py
===================================================================
--- dogtail/config.py	(revision 339)
+++ dogtail/config.py	(working copy)
@@ -158,7 +158,7 @@
 
     def __setattr__(self, name, value):
         if not config.defaults.has_key(name):
-            raise AttributeError, name + " is not a valid option."
+            raise AttributeError, name + _(" is not a valid option.")
 
         elif _Config.defaults[name] != value or \
                 _Config.options.get(name, _Config.invalidValue) != value:
@@ -182,7 +182,7 @@
         try: return _Config.options[name]
         except KeyError:
             try: return _Config.defaults[name]
-            except KeyError: raise AttributeError, name + " is not a valid option."
+            except KeyError: raise AttributeError, name + _(" is not a valid option.")
 
     def __createDir(cls, dirName, perms = None):
         """
@@ -200,12 +200,12 @@
                 #print "Not found."
                 #print "Parent %s ..." % parentDirName
                 _Config.__createDir(parentDirName, perms)
-                print "Creating %s ..." % dirName
+                print _("Creating %s ...") % dirName
                 os.mkdir(dirName)
                 if perms: os.chmod(dirName, perms)
             else:
                 #print "Found."
-                print "Creating %s ..." % dirName
+                print _("Creating %s ...") % dirName
                 os.mkdir(dirName)
                 if perms: os.chmod(dirName, perms)
         #else: print "Found."
@@ -231,8 +231,8 @@
     def failOrPass(failure, description):
         if failure:
             anyFailed = True
-            print "FAILED: " + description
-        else: print "PASSED: " + description
+            print _("FAILED: ") + description
+        else: print _("PASSED: ") + description
 
     # BEGIN tests
 
@@ -240,7 +240,7 @@
     for option in config.defaults.keys():
         print failure, getattr(config, option), config.defaults[option]
         failure = failure or not (getattr(config, option) == config.defaults[option])
-    failOrPass(failure, "Reading all default values")
+    failOrPass(failure, _("Reading all default values"))
 
     failure = True
     failure = config.ensureSensitivity != config.defaults['ensureSensitivity']
@@ -248,13 +248,13 @@
     failure = failure or config.ensureSensitivity == True
     config.ensureSensitivity = True
     failure = failure or config.ensureSensitivity != True
-    failOrPass(failure, "Setting ensureSensitivity")
+    failOrPass(failure, _("Setting ensureSensitivity"))
 
     failure = True
     failure = not os.path.isdir(config.defaults['scratchDir'])
     failure = failure or not os.path.isdir(config.defaults['logDir'])
     failure = failure or not os.path.isdir(config.defaults['dataDir'])
-    failOrPass(failure, "Looking for default directories")
+    failOrPass(failure, _("Looking for default directories"))
 
     failure = True
     config.scratchDir = '/tmp/dt'
@@ -263,7 +263,7 @@
     failure = failure or not os.path.isdir('/tmp/dt_log/')
     config.dataDir = '/tmp/dt_data'
     failure = failure or not os.path.isdir('/tmp/dt_data')
-    failOrPass(failure, "Changing default directories")
+    failOrPass(failure, _("Changing default directories"))
 
     failure = True
     config.useIconLogger = True
@@ -272,7 +272,7 @@
         if isinstance(logging.debugLogger.iconLogger, logging.IconLogger):
             failure = False
     except AttributeError: pass
-    failOrPass(failure, "Setting useIconLogger")
+    failOrPass(failure, _("Setting useIconLogger"))
 
     # END tests
 
Index: dogtail/tc.py
===================================================================
--- dogtail/tc.py	(revision 339)
+++ dogtail/tc.py	(working copy)
@@ -54,16 +54,16 @@
             self.undertest = (self.undertest).encode(self.encoding)
             # Compare the strings
             if self.baseline == self.undertest:
-                self.result = {self.label: "Passed"}
+                self.result = {self.label: _("Passed")}
             else:
-                self.result = {self.label: "Failed - " + self.encoding + " strings do not match. " + self.baseline + " expected: Got " + self.undertest}
+                self.result = {self.label: _("Failed - ") + self.encoding + _(" strings do not match. ") + self.baseline + _(" expected; Got ") + self.undertest}
             # Pass the test result to the ResultsLogger for writing
             TC.logger.log(self.result)
             return self.result
 
         else:
             # We should probably raise an exception here
-            self.result = {self.label: "ERROR - " + self.encoding + " is not a supported encoding type"}
+            self.result = {self.label: _("ERROR - ") + self.encoding + _(" is not a supported encoding type")}
             TC.logger.log(self.result)
             return self.result
 
@@ -138,10 +138,10 @@
                 # os.popen returns a list; if it is empty then we have passed
                 answer = os.popen(cmd).readlines()
                 if answer == []:
-                    self.result = {self.label: "Passed - Images are the same size"}
+                    self.result = {self.label: _("Passed - Images are the same size")}
                 else:
                     fanswer = answer[0].strip()
-                    self.result = {self.label: "Failed - " + fanswer}
+                    self.result = {self.label: _("Failed - ") + fanswer}
                 TC.logger.log(self.result)
                 return self.result
             else: # otherwise run the metric code
@@ -159,7 +159,7 @@
                 if IMVersion >= '6.2.4' and len(answer) != 1: metricFailed = False
                 if metricFailed:
                     fanswer = answer[0]
-                    self.result = {self.label: "Failed - " + fanswer}
+                    self.result = {self.label: _("Failed - ") + fanswer}
                 else: # grab the metric from answer and convert it to a number
                     fanswer = answer[0].strip()
                     fanswer = fanswer.split(" ")
@@ -167,13 +167,13 @@
                     fanswer = float(fanswer)
 
                     if fanswer == float("inf"): #same under PSNR returns inf dB:
-                        self.result = {self.label: "Passed - " + "compare results: " + str(fanswer) + " dB"}
+                        self.result = {self.label: _("Passed - ") + _("compare results: ") + str(fanswer) + _(" dB")}
                     elif fanswer > self.threshold:
                         excess = fanswer - self.threshold
-                        self.result = {self.label: "Failed - " + "compare result exceeds threshold by: " + str(excess) + " dB"}
+                        self.result = {self.label: _("Failed - ") + _("compare result exceeds threshold by: ") + str(excess) + _(" dB")}
                     else:
                         under = self.threshold - fanswer
-                        self.result = {self.label: "Passed - " + "compare results under threshold by: " + str(under) + " dB"}
+                        self.result = {self.label: _("Passed - ") + _("compare results under threshold by: ") + str(under) + _(" dB")}
                 TC.logger.log(self.result)
                 return self.result
 
@@ -182,10 +182,10 @@
                 try:
                     os.remove(self.dfile)
                 except IOError:
-                    debugLogger.log("Could not delete tempfile " + self.dfile)
+                    debugLogger.log(_("Could not delete tempfile ") + self.dfile)
 
         else: # unsupported metric given
-            self.result = {self.label: "Failed - " + self.metric + " is not in the list of supported metrics"}
+            self.result = {self.label: _("Failed - ") + self.metric + _(" is not in the list of supported metrics")}
             TC.logger.log(self.result)
             return self.result
 
@@ -228,13 +228,13 @@
 
             #compare
             if self.baseline == self.undertest:
-                self.result = {self.label: "Passed - numbers are the same"}
+                self.result = {self.label: _("Passed - numbers are the same")}
             else:
-                self.result = {self.label: "Failed - " + str(self.baseline) + " expected: Got " + str(self.undertest)}
+                self.result = {self.label: _("Failed - ") + str(self.baseline) + _(" expected; Got ") + str(self.undertest)}
             TC.logger.log(self.result)
             return self.result
         else:
-            self.result = {self.label: "Failed - " + self.type + " is not in list of supported types"}
+            self.result = {self.label: _("Failed - ") + self.type + _(" is not in list of supported types")}
             TC.logger.log(self.result)
             return self.result
 
Index: dogtail/rawinput.py
===================================================================
--- dogtail/rawinput.py	(revision 339)
+++ dogtail/rawinput.py	(working copy)
@@ -25,7 +25,7 @@
     """
     Synthesize a mouse button click at (x,y)
     """
-    logger.log("Mouse button %s click at (%s,%s)"%(button,x,y))
+    logger.log(_("Mouse button %s click at (%s,%s)")%(button,x,y))
     ev.click(x, y, button)
     doDelay()
 
@@ -33,7 +33,7 @@
     """
     Synthesize a mouse button double-click at (x,y)
     """
-    logger.log("Mouse button %s doubleclick at (%s,%s)"%(button,x,y))
+    logger.log(_("Mouse button %s doubleclick at (%s,%s)")%(button,x,y))
     ev.doubleClick(x,y,button)
     doDelay()
 
@@ -41,7 +41,7 @@
     """
     Synthesize a mouse button press at (x,y)
     """
-    logger.log("Mouse button %s press at (%s,%s)"%(button,x,y))
+    logger.log(_("Mouse button %s press at (%s,%s)")%(button,x,y))
     ev.press(x,y, button)
     doDelay()
 
@@ -49,7 +49,7 @@
     """
     Synthesize a mouse button release at (x,y)
     """
-    logger.log("Mouse button %s release at (%s,%s)"%(button,x,y))
+    logger.log(_("Mouse button %s release at (%s,%s)")%(button,x,y))
     ev.release(x,y,button)
     doDelay()
 
@@ -57,12 +57,12 @@
     """
     Synthesize mouse absolute motion to (x,y)
     """
-    logger.log("Mouse absolute motion to (%s,%s)"%(x,y))
+    logger.log(_("Mouse absolute motion to (%s,%s)")%(x,y))
     ev.absoluteMotion(x,y)
     doDelay()
 
 def relativeMotion (x, y):
-    logger.log("Mouse relative motion of (%s,%s)"%(x,y))
+    logger.log(_("Mouse relative motion of (%s,%s)")%(x,y))
     ev.relativeMotion(x,y)
     doDelay()
 
@@ -71,7 +71,7 @@
     Synthesize a mouse press, drag, and release on the screen.
     Wraps atspi.EventGenerator.drag, but with logging and delays.
     """
-    logger.log("Mouse button %s drag from %s to %s"%(button, fromXY, toXY))
+    logger.log(_("Mouse button %s drag from %s to %s")%(button, fromXY, toXY))
 
     # A direct call to ev.drag doesn't work, delays seem to be needed
     # for nautilus icon view to work, at least:
@@ -181,7 +181,7 @@
                     strings.append(S)
     for s in strings:
         if not keySyms.has_key(s):
-            raise ValueError, "Cannot find key %s" % s
+            raise ValueError, _("Cannot find key %s") % s
 
     ev.generateKeyCombo(strings)
     doDelay()
Index: dogtail/errors.py
===================================================================
--- dogtail/errors.py	(revision 339)
+++ dogtail/errors.py	(working copy)
@@ -11,7 +11,7 @@
     Generate a warning, and pass it to the debug logger.
     """
     frameRec = inspect.stack()[-1]
-    message = "Warning: %s:%s: %s" % (frameRec[1], frameRec[2], message)
+    message = _("Warning: %s:%s: %s") % (frameRec[1], frameRec[2], message)
     if caller and frameRec[1] != '<stdin>' and frameRec[1] != '<string>': 
         message = message + ':\n  ' + frameRec[4][0]
     del frameRec
Index: dogtail/i18n.py
===================================================================
--- dogtail/i18n.py	(revision 339)
+++ dogtail/i18n.py	(working copy)
@@ -109,7 +109,7 @@
     # No translations found:
     if len(results)==0:
         if config.config.debugTranslation:
-            logger.log('Translation not found for "%s"'%srcString)
+            logger.log(_("Translation not found for '%s'") % srcString)
     return results.keys()
 
 class TranslatableString:
@@ -246,7 +246,7 @@
                     if config.config.debugTranslation:
                         #import traceback
                         #logger.log(traceback.format_exc())
-                        logger.log("Warning: Failed to load mo-file for translation: " + moFile)
+                        logger.log(_("Warning: Failed to load mo-file for translation: ") + moFile)
 
     # Hack alert:
     #
Index: dogtail/logging.py
===================================================================
--- dogtail/logging.py	(revision 339)
+++ dogtail/logging.py	(working copy)
@@ -96,7 +96,7 @@
             iconPath = '/usr/share/icons/hicolor/48x48/apps/' + iconName
             if os.path.exists(iconPath):
                 IconLogger.trayicon.set_icon(iconPath)
-            self.message('dogtail running...')
+            self.message(_("dogtail running..."))
 
     def message(self, msg):
         """
@@ -151,17 +151,17 @@
                 i += 1
         else:
             # If path doesn't exist, raise an exception
-            raise IOError, "Log path %s does not exist or is not a directory" % logDir
+            raise IOError, _("Log path %s does not exist or is not a directory") % logDir
 
         # Try to create the file and write the header info
         try:
-            print "Creating logfile at %s ..." % self.fileName
+            print _("Creating logfile at %s ...") % self.fileName
             self.file = codecs.open(self.fileName, mode = 'wb', encoding = 'utf-8')
             self.file.write("##### " + os.path.basename(self.fileName) + '\n')
             self.file.flush()
             #self.file.close()
         except IOError:
-            print "Could not create and write to " + self.fileName
+            print _("Could not create and write to ") + self.fileName
             self.file = False
 
     def log(self, message):
@@ -186,7 +186,7 @@
             self.file.flush()
             #self.file.close()
         except IOError:
-            print "Could not write to file " + self.fileName
+            print _("Could not write to file ") + self.fileName
 
 class ResultsLogger(Logger):
     """
@@ -213,7 +213,7 @@
             entry = str(key) + ":      " + str(value)
         else:
             raise ValueError, entry
-            print "Method argument requires a 1 {key: value} dict. Supplied argument not one {key: value}"
+            print _("Method argument requires a 1 {key: value} dict. Supplied argument not one {key: value}")
 
         Logger.log(self, self.stamper.entryStamp() + "      " + entry)
 
Index: sniff/sniff.glade
===================================================================
--- sniff/sniff.glade	(revision 339)
+++ sniff/sniff.glade	(working copy)
@@ -273,7 +273,7 @@
 		<widget class="GtkLabel" id="nameTextLabel">
 		  <property name="visible">True</property>
 		  <property name="can_focus">True</property>
-		  <property name="label" translatable="yes">name</property>
+		  <property name="label" translatable="yes">None</property>
 		  <property name="use_underline">False</property>
 		  <property name="use_markup">False</property>
 		  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -302,7 +302,7 @@
 		<widget class="GtkLabel" id="roleNameTextLabel">
 		  <property name="visible">True</property>
 		  <property name="can_focus">True</property>
-		  <property name="label" translatable="yes">roleName</property>
+		  <property name="label" translatable="yes">None</property>
 		  <property name="use_underline">False</property>
 		  <property name="use_markup">False</property>
 		  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -331,7 +331,7 @@
 		<widget class="GtkLabel" id="descTextLabel">
 		  <property name="visible">True</property>
 		  <property name="can_focus">True</property>
-		  <property name="label" translatable="yes">description</property>
+		  <property name="label" translatable="yes">None</property>
 		  <property name="use_underline">False</property>
 		  <property name="use_markup">False</property>
 		  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -415,7 +415,7 @@
 	      <child>
 		<widget class="GtkLabel" id="actionsTextLabel">
 		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">actions</property>
+		  <property name="label" translatable="yes">None</property>
 		  <property name="use_underline">False</property>
 		  <property name="use_markup">False</property>
 		  <property name="justify">GTK_JUSTIFY_LEFT</property>
Index: sniff/sniff
===================================================================
--- sniff/sniff	(revision 339)
+++ sniff/sniff	(working copy)
@@ -4,6 +4,9 @@
 appName = 'Sniff'
 appAuthors = ['Zack Cerza <zcerza@redhat.com>', 'David Malcolm <dmalcolm@redhat.com']
 
+import gettext
+gettext.install('dogtail')
+
 from dogtail.utils import checkForA11yInteractively
 checkForA11yInteractively()
 
@@ -15,6 +18,9 @@
 program = gnome.program_init(appName, '0.1')
 import gtk.glade
 
+# note : if you want this to pick up your lang, you *must* have LANGUAGE env var set, LANG is not enough !
+gtk.glade.textdomain('dogtail')
+
 import os
 if os.path.exists('sniff.glade'):
     x = gtk.glade.XML('sniff.glade')
@@ -60,7 +66,7 @@
     about = gtk.AboutDialog()
     about.set_name(appName)
     about.set_authors(appAuthors)
-    about.set_comments('Explore your desktop with Dogtail')
+    about.set_comments(_('Explore your desktop with Dogtail'))
     about.set_website('http://people.redhat.com/zcerza/dogtail/')
     about.show_all()
 
@@ -352,7 +358,7 @@
     try:
         text = getattr(node, attr)
     except atspi.SpiException:
-        text = "(broken node)"
+        text = _("(broken node)")
     cell.set_property('text', text)
 
 def getCellPixbufForNode(column, cell, model, iter):
@@ -381,7 +387,7 @@
     col.pack_end(cellRenderer, expand = False)
     col.set_cell_data_func(cellRenderer, getNodeAttr, 'name')
 
-    col.set_title('Name')
+    col.set_title(_('Name'))
 
     view.insert_column(col, -1)
     #view.insert_column_with_data_func(-1, "Role Name", \
Index: po/dogtail.pot
===================================================================
--- po/dogtail.pot	(revision 0)
+++ po/dogtail.pot	(revision 0)
@@ -0,0 +1,571 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR ORGANIZATION
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2007-11-26 07:47+CET\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+"Generated-By: pygettext.py 1.5\n"
+
+
+#: dogtail_upstream/dogtail/config.py:161
+#: dogtail_upstream/dogtail/config.py:185
+msgid " is not a valid option."
+msgstr ""
+
+#: dogtail_upstream/dogtail/config.py:203
+#: dogtail_upstream/dogtail/config.py:208
+msgid "Creating %s ..."
+msgstr ""
+
+#: dogtail_upstream/dogtail/config.py:234
+msgid "FAILED: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/config.py:235
+msgid "PASSED: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/config.py:243
+msgid "Reading all default values"
+msgstr ""
+
+#: dogtail_upstream/dogtail/config.py:251
+msgid "Setting ensureSensitivity"
+msgstr ""
+
+#: dogtail_upstream/dogtail/config.py:257
+msgid "Looking for default directories"
+msgstr ""
+
+#: dogtail_upstream/dogtail/config.py:266
+msgid "Changing default directories"
+msgstr ""
+
+#: dogtail_upstream/dogtail/config.py:275
+msgid "Setting useIconLogger"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:18
+msgid "Please send patches to "
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:300
+msgid "Detecting distribution: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:302
+msgid "JHBuild environment"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:305
+msgid "SuSE (or derived distribution)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:308
+msgid "Fedora (or derived distribution)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:311
+msgid "Red Hat/Fedora/derived distribution"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:314
+msgid "Ubuntu (or derived distribution)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:317
+msgid "Debian (or derived distribution)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:320
+msgid "Gentoo (or derived distribution)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:323
+msgid "Slackware"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:326
+msgid "Conary-based distribution"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:330
+msgid "Solaris distribution"
+msgstr ""
+
+#: dogtail_upstream/dogtail/distro.py:333
+#: dogtail_upstream/dogtail/distro.py:334
+msgid "Unknown"
+msgstr ""
+
+#: dogtail_upstream/dogtail/errors.py:14
+msgid "Warning: %s:%s: %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/i18n.py:112
+msgid "Translation not found for '%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/i18n.py:249
+msgid "Warning: Failed to load mo-file for translation: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/logging.py:99
+msgid "dogtail running..."
+msgstr ""
+
+#: dogtail_upstream/dogtail/logging.py:154
+msgid "Log path %s does not exist or is not a directory"
+msgstr ""
+
+#: dogtail_upstream/dogtail/logging.py:158
+msgid "Creating logfile at %s ..."
+msgstr ""
+
+#: dogtail_upstream/dogtail/logging.py:164
+msgid "Could not create and write to "
+msgstr ""
+
+#: dogtail_upstream/dogtail/logging.py:189
+msgid "Could not write to file "
+msgstr ""
+
+#: dogtail_upstream/dogtail/logging.py:216
+msgid "Method argument requires a 1 {key: value} dict. Supplied argument not one {key: value}"
+msgstr ""
+
+#: dogtail_upstream/dogtail/path.py:89
+msgid "from %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/path.py:90
+msgid "to %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/path.py:91
+msgid "i=%s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/path.py:92
+msgid "relative path %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:19
+msgid ", recursive=%s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:99
+msgid "%s application"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:127
+msgid "labelled '%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:129
+msgid "child with"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:131
+msgid " name=%s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:133
+#: dogtail_upstream/dogtail/tree.py:689
+msgid " roleName='%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:135
+msgid " description='%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:196
+msgid "named %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:213
+msgid "%s window"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:227
+msgid "window"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:239
+msgid "%s dialog"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:264
+msgid "labelled %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:282
+msgid "%s menu"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:301
+msgid "%s menuitem"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:319
+msgid "%s textentry"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:337
+msgid "%s button"
+msgstr ""
+
+#: dogtail_upstream/dogtail/predicate.py:355
+msgid "%s tab"
+msgstr ""
+
+#: dogtail_upstream/dogtail/procedural.py:31
+msgid "widget"
+msgstr ""
+
+#: dogtail_upstream/dogtail/procedural.py:32
+msgid "The requested %s '%s' could not be focused."
+msgstr ""
+
+#: dogtail_upstream/dogtail/procedural.py:34
+msgid "At least one argument is needed"
+msgstr ""
+
+#: dogtail_upstream/dogtail/procedural.py:72
+msgid "Application"
+msgstr ""
+
+#: dogtail_upstream/dogtail/procedural.py:105
+msgid "Dialog"
+msgstr ""
+
+#: dogtail_upstream/dogtail/rawinput.py:28
+msgid "Mouse button %s click at (%s,%s)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/rawinput.py:36
+msgid "Mouse button %s doubleclick at (%s,%s)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/rawinput.py:44
+msgid "Mouse button %s press at (%s,%s)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/rawinput.py:52
+msgid "Mouse button %s release at (%s,%s)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/rawinput.py:60
+msgid "Mouse absolute motion to (%s,%s)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/rawinput.py:65
+msgid "Mouse relative motion of (%s,%s)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/rawinput.py:74
+msgid "Mouse button %s drag from %s to %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/rawinput.py:184
+msgid "Cannot find key %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:57
+msgid "Passed"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:59
+msgid " strings do not match. "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:59 dogtail_upstream/dogtail/tc.py:144
+#: dogtail_upstream/dogtail/tc.py:162 dogtail_upstream/dogtail/tc.py:173
+#: dogtail_upstream/dogtail/tc.py:188 dogtail_upstream/dogtail/tc.py:233
+#: dogtail_upstream/dogtail/tc.py:237
+msgid "Failed - "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:59 dogtail_upstream/dogtail/tc.py:233
+msgid " expected; Got "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:66
+msgid " is not a supported encoding type"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:66
+msgid "ERROR - "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:141
+msgid "Passed - Images are the same size"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:170
+msgid "compare results: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:170 dogtail_upstream/dogtail/tc.py:173
+#: dogtail_upstream/dogtail/tc.py:176
+msgid " dB"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:170 dogtail_upstream/dogtail/tc.py:176
+msgid "Passed - "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:173
+msgid "compare result exceeds threshold by: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:176
+msgid "compare results under threshold by: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:185
+msgid "Could not delete tempfile "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:188
+msgid " is not in the list of supported metrics"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:231
+msgid "Passed - numbers are the same"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tc.py:237
+msgid " is not in list of supported types"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:82
+msgid "Error importing the AT-SPI bindings"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:102
+msgid "Cannot set %s. It is read-only."
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:113
+msgid "Cannot %s %s. It is not sensitive."
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:124
+msgid "Cannot do '%s' action on %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:166
+msgid "Action node='%s' name='%s' description='%s' keybinding='%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:174
+msgid "%s on %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:180
+msgid "Warning: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:323
+msgid "Unknown Node initializer"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:363
+msgid "raw click on %s %s at (%s,%s)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:471
+msgid "Only returning %s children. You may change config.childrenLimit if you wish. This message will only be printed once."
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:612
+msgid "Setting text of %s to '%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:628
+msgid "Setting text %s to password '%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:637
+msgid "Setting combobox %s to '%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:649
+msgid "Typing text into %s: '%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:654
+msgid "caret offset: %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:657
+msgid "new caret offset: %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:662 dogtail_upstream/dogtail/tree.py:674
+msgid "Node is focusable but I can't grabFocus!"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:665
+msgid "Node is not focusable; falling back to setting text"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:670
+msgid "Pressing keys '%s' into %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:675
+msgid "Node is not focusable; trying key combo anyway"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:688
+msgid "Node"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:690
+msgid " name='%s' description='%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:692
+msgid " text='%s'"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:748
+msgid "got ancestor: %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:853
+msgid "descendent"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:855
+msgid "child"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:866
+msgid "searching for %s (attempt %i)"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:880 dogtail_upstream/dogtail/utils.py:113
+msgid "sleeping for %f"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:1198
+msgid "%s is on '%s' page"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:1213
+msgid "Unable to determine current page of %s"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:1239
+msgid "%s is now on '%s' page"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:1260
+msgid "Error: AT-SPI's desktop is not visible. Do you have accessibility enabled?"
+msgstr ""
+
+#: dogtail_upstream/dogtail/tree.py:1265
+msgid "Warning: AT-SPI's desktop is visible but it has no children. Are you running any AT-SPI-aware applications?"
+msgstr ""
+
+#: dogtail_upstream/dogtail/utils.py:32
+msgid "timeStampt must be True or False"
+msgstr ""
+
+#: dogtail_upstream/dogtail/utils.py:62
+msgid "Failed to save screenshot in %s format"
+msgstr ""
+
+#: dogtail_upstream/dogtail/utils.py:64
+msgid "Screenshot taken: "
+msgstr ""
+
+#: dogtail_upstream/dogtail/utils.py:167
+msgid "Dogtail requires that Assistive Technology support be enabled. Aborting..."
+msgstr ""
+
+#: dogtail_upstream/dogtail/utils.py:189
+msgid "Enable Assistive Technology Support?"
+msgstr ""
+
+#: dogtail_upstream/dogtail/utils.py:194
+msgid ""
+"Dogtail requires that Assistive Technology Support be enabled for it to function. Would you like to enable Assistive Technology support now?\n"
+"\n"
+"Note that you will have to log out for the change to fully take effect.\n"
+"    "
+msgstr ""
+
+#: dogtail_upstream/dogtail/utils.py:205
+msgid "Enabling accessibility..."
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff:63
+msgid "Explore your desktop with Dogtail"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff:355
+msgid "(broken node)"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff:384
+msgid "Name"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:11
+msgid "AT-SPI Browser"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:40
+msgid "_Sniff"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:69
+msgid "_Refresh"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:97
+msgid "_Expand All"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:106
+msgid "_Collapse All"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:191
+msgid "Name:"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:219
+msgid "Role Name:"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:247
+msgid "Description:"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:276
+#: dogtail_upstream/sniff/sniff.glade:305
+#: dogtail_upstream/sniff/sniff.glade:334
+#: dogtail_upstream/sniff/sniff.glade:418
+msgid "None"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:362
+msgid "Text:"
+msgstr ""
+
+#: dogtail_upstream/sniff/sniff.glade:390
+msgid "Actions:"
+msgstr ""
