Index: turbogears/i18n/tg_gettext.py
===================================================================
--- turbogears/i18n/tg_gettext.py	(Revision 1936)
+++ turbogears/i18n/tg_gettext.py	(Arbeitskopie)
@@ -52,7 +52,6 @@
     @param locale: locale code to be used.If locale is None, gets the value provided by 
     get_locale.
     """
-
     if locale is None:locale = get_locale()
     if not is_locale_supported(locale):locale = locale[:2]
     if key == '': return '' # special case
Index: turbogears/i18n/data/de/LC_MESSAGES/TurboGears.mo
===================================================================
Kann nicht anzeigen: Dateityp ist als binÃ¤r angegeben.
svn:mime-type = application/octet-stream

Eigenschaftsänderungen: turbogears/i18n/data/de/LC_MESSAGES/TurboGears.mo
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: turbogears/i18n/data/de/LC_MESSAGES/TurboGears.po
===================================================================
--- turbogears/i18n/data/de/LC_MESSAGES/TurboGears.po	(Revision 0)
+++ turbogears/i18n/data/de/LC_MESSAGES/TurboGears.po	(Revision 0)
@@ -0,0 +1,37 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR ORGANIZATION
+# FIRST AUTHOR <gh@gregor-horvath.com>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2006-10-03 10:24+CEST\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Gregor Horvath <gh@gregor-horvath.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: utf-8\n"
+"Generated-By: pygettext.py 1.5\n"
+
+
+#: validators.py:29
+msgid "Invalid number format"
+msgstr "UngÃ¼ltiges Nummernformat"
+
+#: validators.py:30 validators.py:80
+msgid "Empty values not allowed"
+msgstr "Leere Werte sind nicht erlaubt"
+
+#: validators.py:79
+msgid "Invalid datetime format"
+msgstr "UngÃ¼ltiges Datumsformat"
+
+#: validators.py:125
+msgid "Invalid data or incorrect encoding"
+msgstr "UngÃ¼ltige Daten oder falsche Zeichenkodierung"
+
+#: validators.py:169
+msgid "Please select at least a value"
+msgstr "Bitte mindestens einen Wert auswÃ¤hlen"
+
Index: turbogears/i18n/data/TurboGears.pot
===================================================================
--- turbogears/i18n/data/TurboGears.pot	(Revision 0)
+++ turbogears/i18n/data/TurboGears.pot	(Revision 0)
@@ -0,0 +1,37 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR ORGANIZATION
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2006-10-03 10:24+CEST\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"
+
+
+#: validators.py:29
+msgid "Invalid number format"
+msgstr ""
+
+#: validators.py:30 validators.py:80
+msgid "Empty values not allowed"
+msgstr ""
+
+#: validators.py:79
+msgid "Invalid datetime format"
+msgstr ""
+
+#: validators.py:125
+msgid "Invalid data or incorrect encoding"
+msgstr ""
+
+#: validators.py:169
+msgid "Please select at least a value"
+msgstr ""
+
Index: turbogears/validators.py
===================================================================
--- turbogears/validators.py	(Revision 1936)
+++ turbogears/validators.py	(Arbeitskopie)
@@ -22,10 +22,21 @@
 
 from formencode import validators # Needed to disambiguate the Number validator... 
 
-class Money(FancyValidator):
+import __builtin__
+
+def _(s): return s # dummy
+
+Validator.gettextargs['domain'] = 'FormEncode' # FormEncode should call Tg's gettext \
+                                               # function with domain = "FormEncode"
+
+class TgFancyValidator(FancyValidator):
+    gettextargs = {'domain':'TurboGears'}
+    
+class Money(TgFancyValidator):
+    
     messages = {
-        'badFormat': 'Invalid number format',
-        'empty': 'Empty values not allowed',
+        'badFormat': _('Invalid number format'),
+        'empty': _('Empty values not allowed'),
     }
     
     def __init__(self, allow_empty=None, *args, **kw):
@@ -48,7 +59,7 @@
         return format.format_currency(value)
 
 
-class Number(FancyValidator):
+class Number(TgFancyValidator):
 
     def _to_python(self, value, state):
         """ parse a string and returns a float or integer """
@@ -68,14 +79,14 @@
             return format.format_number(value)
 
 
-class DateTimeConverter(FancyValidator):
+class DateTimeConverter(TgFancyValidator):
 
     """
     Converts Python date and datetime objects into string representation and back.
     """
     messages = {
-        'badFormat': 'Invalid datetime format',
-        'empty': 'Empty values not allowed',
+        'badFormat': _('Invalid datetime format'),
+        'empty': _('Empty values not allowed'),
     }
 
     def __init__(self, format = "%Y/%m/%d %H:%M", allow_empty = None,
@@ -85,7 +96,7 @@
                           DeprecationWarning, 2)
             not_empty = not allow_empty
             kw["not_empty"] = not_empty
-        super(FancyValidator, self).__init__(*args, **kwargs)
+        super(TgFancyValidator, self).__init__(*args, **kwargs)
         self.format = format
 
     def _to_python(self, value, state):
@@ -120,7 +131,7 @@
 class UnicodeString(String):
     encoding = 'utf-8'
     messages = {
-        'badEncoding' : "Invalid data or incorrect encoding",
+        'badEncoding' : _("Invalid data or incorrect encoding"),
     }
     def __init__(self, inputEncoding=None, outputEncoding=None, **kw):
         String.__init__(self, **kw)
@@ -147,7 +158,7 @@
 # another formencode workaround,
 # see #1464357 on FE bugtracker (http://tinyurl.com/lm9ae).
 # Custom version of FieldStorage validator that does not break FE schema validator.
-class FieldStorageUploadConverter(FancyValidator):
+class FieldStorageUploadConverter(TgFancyValidator):
     def to_python(self, value, state=None):
         if isinstance(value, cgi.FieldStorage):
             if value.filename:
@@ -164,7 +175,7 @@
         try:
             return super(MultipleSelection, self).to_python(value, state)
         except Invalid:
-            raise Invalid("Please select at least a value", value, state)
+            raise Invalid(_("Please select at least a value"), value, state)
 
 class Schema(Schema):
     """ A Schema validator """
@@ -177,7 +188,7 @@
         # adjust_value already takes care of that for all childs.
         return value
 
-class JSONValidator(FancyValidator):
+class JSONValidator(TgFancyValidator):
 
     def _from_python(self, value, state):
         return jsonify.encode(value)
Index: turbogears/tests/test_controllers.py
===================================================================
--- turbogears/tests/test_controllers.py	(Revision 1936)
+++ turbogears/tests/test_controllers.py	(Arbeitskopie)
@@ -191,7 +191,6 @@
     
     def test_impliedJson(self):
         testutil.createRequest("/impliedjson?tg_format=json")
-        print cherrypy.response.body[0]
         assert '"title": "Blah"' in cherrypy.response.body[0]
     
     def test_allowJson(self):
Index: turbogears/command/i18n.py
===================================================================
--- turbogears/command/i18n.py	(Revision 1936)
+++ turbogears/command/i18n.py	(Arbeitskopie)
@@ -12,12 +12,14 @@
 
 from elementtree.ElementTree import ElementTree
 
+import formencode
 import turbogears
 import turbogears.i18n
 from turbogears.toolbox.admi18n import pygettext, msgfmt, catalog
 from turbogears.toolbox.admi18n.catalog import quote, normalize
 from turbogears.command.base import silent_os_remove
 from turbogears.util import get_model, load_project_config, get_package_name
+from pkg_resources import resource_filename
 
 class ProgramError(StandardError):
     """Signals about a general application error."""
@@ -145,6 +147,24 @@
                 print 'Compiled %s OK' % fname
             else:
                 print 'Compilation of %s failed!' % fname
+
+    def _copy_file_withcheck(self, sourcefile, targetfile):
+        if not (os.path.exists(targetfile) and not self.options.force_ops):
+            copy_file(sourcefile, targetfile)
+            print 'Copy', sourcefile, 'to', targetfile
+        else:
+            print "File %s exists, use --force to override" % targetfile
+            
+
+    def _copy_moduletranslation(self, sourcefile, targetdir, language):
+        modulefilename = os.path.basename(sourcefile)
+        if os.path.exists(sourcefile):
+            targetfile = os.path.join(targetdir, modulefilename)
+            self._copy_file_withcheck(sourcefile, targetfile)
+        else:
+            print "%s translation for language '%s' does not exist (file searched '%s').\nPlease consider to contribute a translation." % (modulefilename, language, sourcefile)
+
+
     def add_languages(self, codes):
         potfile = self.get_potfile_path()
         if not os.path.isfile(potfile):
@@ -155,11 +175,21 @@
             langdir = os.path.dirname(catalog_file)
             if not os.path.exists(langdir):
                 os.makedirs(langdir)
-            if os.path.exists(catalog_file) and not self.options.force_ops:
-                print "File %s exists, use --force to override" % catalog_file
-                continue
-            copy_file(potfile, catalog_file)
-            print 'Copy', potfile, 'to', catalog_file
+
+            sourcefile_fe = os.path.join(formencode.api.get_localedir(), code, \
+                "LC_MESSAGES","FormEncode.mo")
+            self._copy_moduletranslation(sourcefile_fe, langdir, code)
+
+            basedir_i18n_tg = resource_filename(__name__, "/18n/data")
+            sourcefile_tg  = os.path.join(basedir_i18n_tg, code, \
+                                          "LC_MESSAGES", "TurboGears.mo")
+            self._copy_moduletranslation(sourcefile_tg, langdir, code)
+
+            self._copy_file_withcheck(potfile, catalog_file)
+                
+
+        
+        
     def scan_source_files(self):
         source_files = []
         kid_files = []
