=== modified file 'common/Duplicity.vala'
--- common/Duplicity.vala	2011-10-20 16:31:27 +0000
+++ common/Duplicity.vala	2011-11-02 13:57:26 +0000
@@ -103,6 +103,7 @@
   static File slash_root;
   static File slash_home;
   static File slash_home_me;
+  static Regex gpg_regex;
   
   bool has_checked_contents = false;
   bool has_non_home_contents = false;
@@ -143,6 +144,15 @@
       slash_home = File.new_for_path("/home");
       slash_home_me = File.new_for_path(Environment.get_home_dir());
     }
+
+    if (gpg_regex == null) {
+      try {
+        gpg_regex = new Regex(".*\\[.*\\.(g|gpg)'.*]$");
+      }
+      catch (Error e) {
+        error("%s\n", e.message); // this is a programmer error, so use error()
+      }
+    }
   }
 
   ~Duplicity() {
@@ -1108,16 +1118,13 @@
     if (firstline.length > 1) {
       switch (int.parse(firstline[1])) {
       case DEBUG_GENERIC:
-        // In non-modern versions of duplicity, this list of files is the only
-        // way to tell whether the backup is encrypted or not.  This message
-        // was not translated in duplicity before switching to a better method
-        // of detecting, so we can safely check for it.
         if (mode == Operation.Mode.STATUS &&
             !DuplicityInfo.get_default().reports_encryption &&
-            !detected_encryption &&
-            text.has_prefix("Extracting backup chains from list of files:")) {
-          detected_encryption = true;
-          existing_encrypted = text.contains(".gpg'") || text.contains(".g'");
+            !detected_encryption) {
+          if (gpg_regex != null && gpg_regex.match(text)) {
+            detected_encryption = true;
+            existing_encrypted = true;
+          }
         }
         break;
       }

=== modified file 'preferences/Preferences.vala'
--- preferences/Preferences.vala	2011-10-19 15:32:50 +0000
+++ preferences/Preferences.vala	2011-11-02 13:57:26 +0000
@@ -360,6 +360,10 @@
     notebook.append_page(table, null);
     notebook.set_tab_label_text(table, _("Schedule"));
 
+    var accessible = notebook.get_accessible();
+    if (accessible != null)
+      accessible.set_name(_("Categories"));
+
     notebook.expand = true;
     settings_page.add(notebook);
 

=== modified file 'tests/backup/encrypt'
--- tests/backup/encrypt	2011-07-25 15:08:11 +0000
+++ tests/backup/encrypt	2011-11-02 13:57:26 +0000
@@ -20,7 +20,8 @@
 # Test whether we correctly ask or not for the encryption password
 
 import sys
-sys.path.insert(0, sys.path[0]+'/..')
+scriptdir=sys.path[0]
+sys.path.insert(0, scriptdir+'/..')
 import base
 import os
 import ldtp
@@ -34,6 +35,7 @@
 
 def encrypt():
   base.setup()
+  os.environ['PATH'] = os.path.join(scriptdir, 'encrypt-bin') + ":" + os.environ['PATH']
   base.backup_simple(backend='file', encrypt=True, includes=['data/simple'])
   basenum = len(os.listdir(base.get_temp_name('local')))
   base.backup_simple(encrypt=True, finish=False, includes=['/usr/bin'])

=== added directory 'tests/backup/encrypt-bin'
=== added file 'tests/backup/encrypt-bin/duplicity'
--- tests/backup/encrypt-bin/duplicity	1970-01-01 00:00:00 +0000
+++ tests/backup/encrypt-bin/duplicity	2011-11-02 13:57:26 +0000
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-
+#
+# This file is part of Déjà Dup.
+# For copyright information, see AUTHORS.
+#
+# Déjà Dup is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Déjà Dup is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Déjà Dup.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file acts like a duplicity wrapper.
+# It transforms any instances of "Extracting backup chains from list of files:"
+# to "Translation:" (to help catch things like bug
+# https://bugs.launchpad.net/deja-dup/+bug/877631)
+
+import os
+import sys
+import subprocess
+
+# Drop the PATH override that pointed to this script
+os.environ['PATH'] = os.environ['PATH'].split(':', 1)[-1]
+
+extra_args = []
+
+p1 = subprocess.Popen(['duplicity'] + sys.argv[1:], stdout=subprocess.PIPE)
+p2 = subprocess.Popen(["sed", "-s", "s/Extracting backup chains from list of files:/Translation:/g"], stdin=p1.stdout)
+p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
+p2.wait()

=== modified file 'tests/base.py'
--- tests/base.py	2011-08-30 18:57:19 +0000
+++ tests/base.py	2011-11-02 13:57:26 +0000
@@ -420,7 +420,7 @@
 
 def walk_prefs(backend, dest, includes, excludes):
   if backend == 'file':
-    ldtp.selectrow('frmBackup', 'tblCategories', 'Storage')
+    ldtp.selecttab('frmBackup', 'ptlCategories', 'Storage')
 
     if dest is None:
       dest = get_temp_name('local')
@@ -432,7 +432,7 @@
     ldtp.settextvalue('frmBackup', 'txt0', dest) # FIXME txt0 is bad name
     ldtp.wait(1) # without this, sometimes ldtp moves so fast, deja-dup doesn't notice dest
 
-  ldtp.selectrow('frmBackup', 'tblCategories', 'Folders')
+  ldtp.selecttab('frmBackup', 'ptlCategories', 'Folders')
   if includes is not None:
     set_file_list('frmBackup', 'tblIncludeList', 'btnIncludeListAdd', 'btnIncludeListRemove', includes)
   if excludes is not None:
@@ -455,12 +455,13 @@
 
   if guivisible('frmBackup', 'btnJustshowmybackupsettings'):
     ldtp.click('frmBackup', 'btnJustshowmybackupsettings')
+    remap('frmBackup')
 
   if backend is not None or includes is not None or excludes is not None:
     walk_prefs(backend=backend, dest=dest, includes=includes,
                excludes=excludes)
 
-  ldtp.selectrow('frmBackup', 'tblCategories', 'Overview')
+  ldtp.selecttab('frmBackup', 'ptlCategories', 'Overview')
   ldtp.click('frmBackup', 'btnBackUpNow')
   waitforgui('frmBackUp')
 
@@ -483,7 +484,7 @@
   if guivisible('frmBackup', 'btnIwanttorestorefilesfromapreviousbackup…'):
     ldtp.click('frmBackup', 'btnIwanttorestorefilesfromapreviousbackup…')
   else:
-    ldtp.selectrow('frmBackup', 'tblCategories', 'Overview')
+    ldtp.selecttab('frmBackup', 'ptlCategories', 'Overview')
     ldtp.click('frmBackup', 'btnRestore…')
 
   waitforgui('frmRestore')
@@ -492,7 +493,7 @@
     walk_restore_prefs('frmRestore', backend, dest)  
   ldtp.click('frmRestore', 'btnForward')
 
-  wait_for_finish('frmRestore', 'lblRestorefromWhen?', 200)
+  wait_for_finish('frmRestore', 'lblRestoreFromWhen?', 200)
   if date:
     ldtp.comboselect('frmRestore', 'cboDate', date)
   ldtp.click('frmRestore', 'btnForward')
@@ -528,7 +529,7 @@
     walk_restore_prefs('frmRestore', backend=backend, dest=dest)
   ldtp.click('frmRestore', 'btnForward')
 
-  wait_for_finish('frmRestore', 'lblRestorefromWhen?', 200)
+  wait_for_finish('frmRestore', 'lblRestoreFromWhen?', 200)
   if date:
     ldtp.comboselect('frmRestore', 'cboDate', date)
   ldtp.click('frmRestore', 'btnForward')

