Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/__init__.py
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/__init__.py	(revision 872)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/__init__.py	(revision 873)
@@ -1,2 +1,6 @@
+from zope.i18nmessageid import MessageFactory
+
+messageFactory = MessageFactory('quintagroup.plonetabs')
+
 def initialize(context):
     pass
Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/plonetabs.py
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/plonetabs.py	(revision 872)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/plonetabs.py	(revision 873)
@@ -18,5 +18,4 @@
 from Products.CMFCore.ActionInformation import Action, ActionCategory
 from Products.CMFCore.Expression import Expression
-from Products.CMFPlone import PloneMessageFactory as _
 from Products.CMFPlone import utils
 from Products.CMFPlone.browser.navigation import get_view_url
@@ -26,4 +25,5 @@
 
 from quintagroup.plonetabs.config import *
+from quintagroup.plonetabs import messageFactory as _
 from interfaces import IPloneTabsControlPanel
 
@@ -147,5 +147,6 @@
             action = self.addAction(cat_name, data)
             IStatusMessage(self.request).addStatusMessage(
-                _(u"'%s' action successfully added." % action.id), type="info")
+                _(u"'${id}' action successfully added.",
+                  mapping={'id':action.id}), type="info")
             self.redirect(search="category=%s" % cat_name)
             return False
@@ -172,5 +173,6 @@
             action = self.updateAction(id, cat_name, data)
             IStatusMessage(self.request).addStatusMessage(
-                _(u"'%s' action saved." % action.id), type="info")
+                _(u"'${id}' action saved.", mapping={'id': action.id}),
+                type="info")
             self.redirect(search="category=%s" % cat_name)
             return False
@@ -192,10 +194,11 @@
             self.deleteAction(id, cat_name)
             IStatusMessage(self.request).addStatusMessage(
-                _(u"'%s' action deleted." % id), type="info")
+                _(u"'${id}' action deleted.", mapping={'id': id}), type="info")
             self.redirect(search="category=%s" % cat_name)
             return False
         else:
             IStatusMessage(self.request).addStatusMessage(
-                _(u"No '%s' action in '%s' category." % (id, cat_name)),
+                _(u"No '${id}' action in '${cat_name}' category.",
+                  mapping={'id': id, 'cat_name': cat_name}),
                 type="error")
             return True
@@ -211,11 +214,11 @@
             self.moveAction(id, cat_name, steps=1)
             IStatusMessage(self.request).addStatusMessage(
-                _(u"'%s' action moved up." % id), type="info")
+                _(u"'${id}' action moved up.", mapping={'id': id}), type="info")
             self.redirect(search="category=%s" % cat_name)
             return False
         else:
             IStatusMessage(self.request).addStatusMessage(
-                _(u"No '%s' action in '%s' category." % (id, cat_name)),
-                type="error")
+                _(u"No '${id}' action in '${cat_name}' category.",
+                  mapping={'id': id, 'cat_name': cat_name}), type="error")
             return True
     
@@ -230,10 +233,12 @@
             self.moveAction(id, cat_name, steps=-1)
             IStatusMessage(self.request).addStatusMessage(
-                _(u"'%s' action moved down." % id), type="info")
+                _(u"'${id}' action moved down.", mapping={'id': id}),
+                type="info")
             self.redirect(search="category=%s" % cat_name)
             return False
         else:
             IStatusMessage(self.request).addStatusMessage(
-                _(u"No '%s' action in '%s' category." % (id, cat_name)),
+                _(u"No '${id}' action in '${cat_name}' category.",
+                  mapping={'id': id, 'cat_name': cat_name}),
                 type="error")
             return True
@@ -257,8 +262,17 @@
     ###################################
     
+    def _charset(self):
+        pp = getToolByName(self.context, 'portal_properties', None)
+        if pp is not None:
+            site_properties = getattr(pp, 'site_properties', None)
+            if site_properties is not None:
+                return site_properties.getProperty('default_charset', 'utf-8')
+        return 'utf-8'
+    
     def getPageTitle(self, category="portal_tabs"):
         """See interface"""
         portal_props = getToolByName(self.context, "portal_properties")
-        default_title = "Plone '%s' Configuration" % category
+        default_title = _(u"Plone '${cat_name}' Configuration",
+                          mapping={'cat_name': category})
         
         if not hasattr(portal_props, PROPERTY_SHEET):
@@ -275,5 +289,13 @@
             dict[cat] = title
         
-        return dict.get(category, None) or default_title
+        title = dict.get(category, None)
+        if title is None:
+            return default_title
+        
+        charset = self._charset()
+        if not isinstance(title, unicode):
+            title = title.decode(charset)
+        
+        return _(title)
     
     def hasActions(self, category="portal_tabs"):
@@ -473,14 +495,14 @@
         if checked == '1':
             self.setSiteProperties(**{field: False})
-            prefix = 'Generated'
             if field == 'disable_nonfolderish_sections':
-                prefix += ' not folderish'
-            message = _(u"%s tabs switched on." % prefix)
+                message = _(u"Generated not folderish tabs switched on.")
+            else:
+                message = _(u"Generated tabs switched on.")
         else:
             self.setSiteProperties(**{field: True})
-            prefix = 'Generated'
             if field == 'disable_nonfolderish_sections':
-                prefix += ' not folderish'
-            message = _(u"%s tabs switched off." % prefix)
+                message = _(u"Generated not folderish tabs switched off.")
+            else:
+                message = _(u"Generated tabs switched off.")
         
         # update client
@@ -506,5 +528,6 @@
         if obj_id not in portal.objectIds():
             raise KSSExplicitError, \
-                  "Object with %s id doesn't exist in portal root" % obj_id
+                  _(u"Object with '${id}' id doesn't exist in portal root.",
+                    mapping={'id': obj_id})
         
         if checked == '1':
@@ -815,9 +838,9 @@
             chooser.checkName(data['id'], self.context)
         except Exception, e:
-            errors['id'] = "%s" % str(e)
+            errors['id'] = self._formatError(e, **{'id':data['id']})
         
         # validate action name
         if not data['title'].strip():
-            errors['title'] = 'Empty or invalid title specified'
+            errors['title'] = _(u"Empty or invalid title specified")
         
         # validate condition expression
@@ -826,5 +849,9 @@
                 Expression(data['available_expr'])
             except Exception, e:
-                errors["available_expr"] = "%s" % str(e)
+                mapping = {'expr': data['available_expr']}
+                idx = data['available_expr'].find(':')
+                if idx != -1:
+                    mapping['expr_type'] = data['available_expr'][:idx]
+                errors["available_expr"] = self._formatError(e, **mapping)
         
         # validate action expression
@@ -833,7 +860,24 @@
                 Expression(data['url_expr'])
             except Exception, e:
-                errors["url_expr"] = "%s" % str(e)
+                mapping = {'expr': data['url_expr']}
+                idx = data['url_expr'].find(':')
+                if idx != -1:
+                    mapping['expr_type'] = data['url_expr'][:idx]
+                errors["url_expr"] = self._formatError(e, **mapping)
         
         return errors
+    
+    def _formatError(self, message, **kw):
+        """Make error message a little bit prettier to ease translation"""
+        charset = self._charset()
+        message = str(message)
+        message = message.replace('"', "'")
+        mapping = {}
+        for key, value in kw.items():
+            message = message.replace("'%s'" % value, "'${%s}'" % key)
+            # trying to work around zope.i18n issue
+            mapping[key] = unicode(value, charset)
+        message = message.strip()
+        return _(unicode(message, charset), mapping=mapping)
     
     def processErrors(self, errors, prefix='', sufix=''):
@@ -921,5 +965,6 @@
         except Exception:
             raise KSSExplicitError, \
-                  "'%s' action category does not exist" % cat_name
+                  _(u"'${cat_name}' action category does not exist.",
+                    mapping={'cat_name': cat_name})
         
         # extract action id from given list item id on client
@@ -930,5 +975,6 @@
         except Exception:
             raise KSSExplicitError, \
-                  "No '%s' action in '%s' category." % (action_id, cat_name)
+                  _(u"No '${id}' action in '${cat_name}' category.",
+                    mapping={'id': action_id, 'cat_name': cat_name})
         
         return (action_id, category, action)
@@ -937,9 +983,10 @@
         """Display error messages on the client"""
         ksscore = self.getCommandSet('core')
+        ts = getToolByName(self.context, 'translation_service')
         for field in fields:
             self.kss_issueFieldError(ksscore, field,
-                                     errors.get(field, False), editform)
-    
-    def kss_issueFieldError(self, ksscore, name, error, editform):
+                                     errors.get(field, False), editform, ts)
+    
+    def kss_issueFieldError(self, ksscore, name, error, editform, ts):
         """Issue this error message for the field"""
         if editform:
@@ -957,5 +1004,6 @@
 
         if error:
-            ksscore.replaceInnerHTML(field_error_selector, _(error))
+            error = ts.translate(error, context=self.context)
+            ksscore.replaceInnerHTML(field_error_selector, error)
             ksscore.addClass(field_selector, 'error')
         else:
Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.css
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.css	(revision 872)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.css	(revision 873)
@@ -49,5 +49,7 @@
 .kssTabsActive .add-controls,
 .kssTabsActive .kssHidden,
-.kssTabsActive #autogeneration_controls {
+.kssTabsActive #autogeneration_controls,
+.editcancel,
+#buttoncancel {
   display:none;
   }
@@ -67,5 +69,7 @@
 .kssTabsActive li:hover .delete,
 .kssTabsActive li:hover .drag-handle,
-.kssTabsActive #app #addaction.adding      .error-container {
+.kssTabsActive #app #addaction.adding      .error-container,
+.kssTabsActive .editcancel,
+.kssTabsActive #buttoncancel {
   display:inline;
   }
Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/actionslist.pt
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/actionslist.pt	(revision 872)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/actionslist.pt	(revision 873)
@@ -1,3 +1,4 @@
-<tal:tabs tal:define="test nocall:view/test;
+<tal:tabs i18n:domain="quintagroup.plonetabs"
+          tal:define="test nocall:view/test;
                       dummy python:request.RESPONSE.setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT');
                       category python:options.get('category', None) or 'portal_tabs';
@@ -13,5 +14,5 @@
                     class python:' '.join(klass)">
 
-  <a class="delete" href="#">Delete</a>
+  <a class="delete" href="#" i18n:translate="">Delete</a>
   <div class="titleWrapper kssHidden">
     <span class="tab-title" tal:content="tab/title">Tab Name</span>
@@ -45,7 +46,9 @@
                       tab_title tab/title"
           tal:attributes="class python:test(error, '%s error' % attrs['class'], attrs['class'])">
-        <dt><label tal:attributes="for name">Name</label></dt>
+        <dt><label tal:attributes="for name"
+                   i18n:translate="">Name</label></dt>
         <dd>
-          <span class="error-container" tal:content="error">Validation error output</span>
+          <span class="error-container" tal:content="error"
+                i18n:translate="">Validation error output</span>
           <input type="text" value="" name="title"
                  tal:attributes="value python:test(request.get(name, []) != [], request.get(name), tab_title);
@@ -55,5 +58,5 @@
 
       <dl class="collapseAdvanced collapsedBlock">
-        <dt class="headerAdvanced">Advanced</dt>
+        <dt class="headerAdvanced" i18n:translate="">Advanced</dt>
         <dd class="contentAdvanced">
           <dl class="edit-field-action"
@@ -62,7 +65,9 @@
                           tab_url tab/url_expr"
               tal:attributes="class python:test(error, '%s error' % attrs['class'], attrs['class'])">
-            <dt><label tal:attributes="for name">URL (Expression)</label></dt>
+            <dt><label tal:attributes="for name"
+                       i18n:translate="">URL (Expression)</label></dt>
             <dd>
-              <span class="error-container" tal:content="error">Validation error output</span>
+              <span class="error-container" tal:content="error"
+                    i18n:translate="">Validation error output</span>
               <input type="text" value="" name="url_expr"     size="30"
                      tal:attributes="value python:test(request.get(name, []) != [], request.get(name), tab_url);
@@ -75,7 +80,9 @@
                           tab_id tab/id"
               tal:attributes="class python:test(error, '%s error' % attrs['class'], attrs['class'])">
-            <dt><label tal:attributes="for name">Id</label></dt>
+            <dt><label tal:attributes="for name"
+                       i18n:translate="">Id</label></dt>
             <dd>
-              <span class="error-container" tal:content="error">Validation error output</span>
+              <span class="error-container" tal:content="error"
+                    i18n:translate="">Validation error output</span>
               <input type="text" value="" name="id"
                      tal:attributes="value python:test(request.get(name, []) != [], request.get(name), tab_id);
@@ -88,7 +95,9 @@
                           tab_cond tab/available_expr"
               tal:attributes="class python:test(error, '%s error' % attrs['class'], attrs['class'])">
-            <dt><label tal:attributes="for name">Condition (Expression)</label></dt>
+            <dt><label tal:attributes="for name"
+                       i18n:translate="">Condition (Expression)</label></dt>
             <dd>
-              <span class="error-container" tal:content="error">Validation error output</span>
+              <span class="error-container" tal:content="error"
+                    i18n:translate="">Validation error output</span>
               <input type="text" value="" name="available_expr"  size="30"
                      tal:attributes="value python:test(request.get(name, []) != [], request.get(name), tab_cond);
Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/autogenerated.pt
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/autogenerated.pt	(revision 872)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/autogenerated.pt	(revision 873)
@@ -2,4 +2,5 @@
 
   <div id="autogeneration_section"
+       i18n:domain="quintagroup.plonetabs"
        tal:define="category options/category;
                    errors options/errors|nothing;
@@ -23,6 +24,9 @@
                value="1"
                tal:attributes="checked python:test(generated_tabs, 'checked', None)" />
-        <label for="generated_tabs" i18n:translate="label_generated_tabs_enable">Automatically generate tabs</label>
-        <div class="formHelp" i18n:translate="help_generated_tabs">
+        <label for="generated_tabs"
+               i18n:translate="label_generated_tabs_enable"
+               i18n:domain="plone">Automatically generate tabs</label>
+        <div class="formHelp" i18n:translate="help_generated_tabs"
+             i18n:domain="plone">
           By default, all folders created at the root level will have global section
           navigation generated. You can turn this off if you prefer manually constructing
@@ -40,6 +44,9 @@
                value="1"
                tal:attributes="checked python:test(nonfolderish_tabs, 'checked', None)" />
-        <label for="nonfolderish_tabs" i18n:translate="label_nonfolderish_tabs_enable">Generate tabs for items other than folders</label>
-        <div class="formHelp" i18n:translate="help_nonfolderish_tabs">
+        <label for="nonfolderish_tabs"
+               i18n:translate="label_nonfolderish_tabs_enable">Generate tabs for items other than folders</label>
+        <div class="formHelp"
+             i18n:domain="plone"
+             i18n:translate="help_nonfolderish_tabs">
           By default, any content item in the root of the portal will be shown as
           a global section. If you turn this option off, only folders will be shown.
@@ -52,5 +59,5 @@
 
       <div id="autogeneration_controls">
-          <input class="submit-button context" type="submit" name="autogenerated.save" value="Save" />
+          <input class="submit-button context" type="submit" name="autogenerated.save" i18n:attributes="value" value="Save" />
       </div>
 
Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/plonetabs.pt
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/plonetabs.pt	(revision 872)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/plonetabs.pt	(revision 873)
@@ -36,5 +36,5 @@
   </a>
 
-  <div i18n:translate="description_plonetabs">
+  <div>
     <form id="selectcategory_form"
           name="selectcategory_form"
@@ -52,12 +52,14 @@
           <option value="current_category" selected="selected"
                   tal:attributes="value category"
+                  i18n:translate=""
                   tal:content="category" />
           <tal:options repeat="cat categories">
             <option tal:attributes="value cat"
                     tal:content="cat"
+                    i18n:translate=""
                     tal:condition="python: cat != category" />
           </tal:options>
         </select>
-        <input class="change-button kssHidden" type="submit" name="category.change" value="Change" />
+        <input class="change-button kssHidden" type="submit" i18n:attributes="value" name="category.change" value="Change" />
       </div>
     </form>
@@ -77,5 +79,5 @@
     <dl class="field-visible bridge">
       <dt>
-        <label for="actvisible">Visible</label>
+        <label for="actvisible" i18n:translate="">Visible</label>
       </dt>
       <dd>
@@ -88,8 +90,9 @@
         tal:attributes="class python:test(error, '%s error' % attrs['class'], attrs['class'])">
       <dt>
-        <label for="actname">Name</label>
+        <label for="actname" i18n:translate="">Name</label>
       </dt>
       <dd>
-        <span class="error-container" tal:content="error">Validation error output</span>
+        <span class="error-container" tal:content="error"
+              i18n:translate="">Validation error output</span>
         <input id="actname" type="text" value="" name="title" autocomplete="off"
                tal:attributes="value request/title|nothing"/>
@@ -100,8 +103,9 @@
         tal:attributes="class python:test(error, '%s error' % attrs['class'], attrs['class'])">
       <dt>
-        <label for="actaction">URL (Expression)</label>
+        <label for="actaction" i18n:translate="">URL (Expression)</label>
       </dt>
       <dd>
-        <span class="error-container" tal:content="error">Validation error output</span>
+        <span class="error-container" tal:content="error"
+              i18n:translate="">Validation error output</span>
         <input id="actaction" type="text" value="" size="30" name="url_expr"
                tal:attributes="value request/url_expr|nothing"/>
@@ -109,5 +113,5 @@
     </dl>
     <dl class="collapseAdvanced expandedBlock">
-      <dt class="headerAdvanced">Advanced</dt>
+      <dt class="headerAdvanced" i18n:translate="">Advanced</dt>
       <dd class="contentAdvanced">
         <dl class="field-id"
@@ -115,8 +119,9 @@
             tal:attributes="class python:test(error, '%s error' % attrs['class'], attrs['class'])">
           <dt>
-            <label for="actid">Id</label>
+            <label for="actid" i18n:translate="">Id</label>
           </dt>
           <dd>
-            <span class="error-container" tal:content="error">Validation error output</span>
+            <span class="error-container" tal:content="error"
+                  i18n:translate="">Validation error output</span>
             <input id="actid" type="text" value="" name="id"
                    tal:attributes="value request/id|nothing" />
@@ -127,8 +132,9 @@
             tal:attributes="class python:test(error, '%s error' % attrs['class'], attrs['class'])">
           <dt>
-            <label for="actcondition">Condition (Expression)</label>
+            <label for="actcondition" i18n:translate="">Condition (Expression)</label>
           </dt>
           <dd>
-            <span class="error-container" tal:content="error">Validation error output</span>
+            <span class="error-container" tal:content="error"
+                  i18n:translate="">Validation error output</span>
             <input id="actcondition" type="text" value="" size="30" name="available_expr"
                    tal:attributes="value request/available_expr|nothing" />
@@ -141,4 +147,5 @@
       <input type="submit" id="buttonadd" class="context" i18n:attributes="value" name="add.add" value="Add" />
       <input type="submit" id="buttoncancel" class="standalone" i18n:attributes="value" name="add.cancel" value="Cancel" />
+      <input type="reset"  id="buttonreset" class="editreset kssHidden context" i18n:attributes="value" name="add.reset" value="Reset"  />
     </div>
   </form>
Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/configure.zcml
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/configure.zcml	(revision 872)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/configure.zcml	(revision 873)
@@ -3,7 +3,10 @@
     xmlns:five="http://namespaces.zope.org/five"
     xmlns:zcml="http://namespaces.zope.org/zcml"
+    xmlns:i18n="http://namespaces.zope.org/i18n"
     i18n_domain="quintagroup.plonetabs">
 
     <include package="plone.browserlayer" />
+
+    <i18n:registerTranslations directory="locales" />
 
     <!-- Set up as a Zope2 product -->
Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/locales/quintagroup.plonetabs.pot
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/locales/quintagroup.plonetabs.pot	(revision 873)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/locales/quintagroup.plonetabs.pot	(revision 873)
@@ -0,0 +1,228 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: quintagroup.plonetabs 0.5\n"
+"POT-Creation-Date: 2009-03-28 12:59+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
+"Last-Translator: Vitaliy Podoba <piv@quintagroup.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: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+"Language-Code: en\n"
+"Language-Name: English\n"
+"Preferred-Encodings: utf-8 latin1\n"
+"Domain: quintagroup.plonetabs\n"
+
+#: ./browser/plonetabs.py:196
+msgid "'${id}' action deleted."
+msgstr ""
+
+#: ./browser/plonetabs.py:557
+msgid "'${id}' action is now invisible."
+msgstr ""
+
+#: ./browser/plonetabs.py:553
+msgid "'${id}' action is now visible."
+msgstr ""
+
+#: ./browser/plonetabs.py:235
+msgid "'${id}' action moved down."
+msgstr ""
+
+#: ./browser/plonetabs.py:216
+msgid "'${id}' action moved up."
+msgstr ""
+
+#: ./browser/plonetabs.py:175
+msgid "'${id}' action saved."
+msgstr ""
+
+#: ./browser/plonetabs.py:149
+msgid "'${id}' action successfully added."
+msgstr ""
+
+#: ./browser/plonetabs.py:581
+msgid "'${id}' action successfully removed."
+msgstr ""
+
+#: ./browser/plonetabs.py:732
+msgid "'${id}' action successfully updated."
+msgstr ""
+
+#: ./browser/plonetabs.py:531
+msgid "'${id}' object was excluded from navigation."
+msgstr ""
+
+#: ./browser/plonetabs.py:527
+msgid "'${id}' object was included into navigation."
+msgstr ""
+
+#: ./browser/plonetabs.py:778
+msgid "Actions successfully sorted."
+msgstr ""
+
+#. Default: "Add"
+#: ./browser/templates/plonetabs.pt:141
+msgid "Add"
+msgstr ""
+
+#: ./browser/plonetabs.py:672
+msgid "Adding canceled."
+msgstr ""
+
+#. Default: "Cancel"
+#: ./browser/templates/plonetabs.pt:142
+msgid "Cancel"
+msgstr ""
+
+#: ./browser/plonetabs.py:473
+msgid "Category changed successfully."
+msgstr ""
+
+#: ./browser/plonetabs.py:706
+msgid "Changes discarded."
+msgstr ""
+
+#: ./browser/plonetabs.py:130
+msgid "Changes saved!"
+msgstr ""
+
+#: ./browser/plonetabs.py:693
+msgid "Fill in required fields and click on Add."
+msgstr ""
+
+#: ./browser/plonetabs.py:487
+msgid "Generated not folderish tabs switched off."
+msgstr ""
+
+#: ./browser/plonetabs.py:481
+msgid "Generated not folderish tabs switched on."
+msgstr ""
+
+#: ./browser/plonetabs.py:489
+msgid "Generated tabs switched off."
+msgstr ""
+
+#: ./browser/plonetabs.py:483
+msgid "Generated tabs switched on."
+msgstr ""
+
+#: ./browser/plonetabs.py:201
+msgid "No '${id}' action in '${cat_name}' category."
+msgstr ""
+
+#: ./browser/plonetabs.py:966
+msgid "'${cat_name}' action category does not exist."
+msgstr ""
+
+#: ./browser/plonetabs.py:530
+msgid "Object with '${id}' id doesn't exist in portal root."
+msgstr ""
+
+#: ./browser/plonetabs.py:156
+msgid "Please correct the indicated errors."
+msgstr ""
+
+#. Default: "Reset"
+#: ./browser/templates/plonetabs.pt:143
+msgid "Reset"
+msgstr ""
+
+#. Default: "Select category to manage"
+#: ./browser/templates/plonetabs.pt:48
+msgid "label_select_category"
+msgstr ""
+
+#: ./browser/templates/changemodelink.pt:8
+msgid "Rich Mode"
+msgstr ""
+
+#: ./browser/templates/changemodelink.pt:8
+msgid "Plain Mode"
+msgstr ""
+
+#: ./browser/plonetabs.py:275
+msgid "Plone '${cat_name}' Configuration"
+msgstr ""
+
+#: ./profiles/default/propertiestool.xml:5
+msgid "Portal Tabs Configuration"
+msgstr ""
+
+#: ./profiles/default/propertiestool.xml:6
+msgid "Portal Footer Configuration"
+msgstr ""
+
+#: ./browser/templates/plonetabs.pt:61
+msgid "Change"
+msgstr ""
+
+#: ./browser/templates/actionslist.pt:15
+msgid "Delete"
+msgstr ""
+
+#: ./browser/templates/actionslist.pt:48
+msgid "Name"
+msgstr ""
+
+#: ./browser/templates/actionslist.pt:67
+msgid "URL (Expression)"
+msgstr ""
+
+#: ./browser/templates/actionslist.pt:82
+msgid "Id"
+msgstr ""
+
+#: ./browser/templates/actionslist.pt:97
+msgid "Condition (Expression)"
+msgstr ""
+
+#: ./browser/templates/actionslist.pt:111
+msgid "Save"
+msgstr ""
+
+#: ./browser/templates/actionslist.pt:115
+msgid "Move Up"
+msgstr ""
+
+#: ./browser/templates/actionslist.pt:117
+msgid "Move Down"
+msgstr ""
+
+#. Default: "Generate tabs for items other than folders"
+#: ./browser/templates/autogenerated.pt:46
+msgid "label_nonfolderish_tabs_enable"
+msgstr ""
+
+#: ./browser/plonetabs.py:843
+msgid "Empty or invalid title specified"
+msgstr ""
+
+#: ./browser/plonetabs.py
+msgid "Empty or invalid id specified"
+msgstr ""
+
+#: ./browser/plonetabs.py
+msgid "The id '${id}' is invalid - it is already in use."
+msgstr ""
+
+#: ./browser/plonetabs.py
+msgid "Id must contain only ASCII characters."
+msgstr ""
+
+#: ./browser/plonetabs.py
+msgid "Unrecognized expression type '${expr_type}'."
+msgstr ""
+
+#: ./browser/plonetabs.py
+msgid "Invalid variable name '${expr}'"
+msgstr ""
+
+#: ./browser/templates/plonetabs.pt:81
+msgid "Visible"
+msgstr ""
+
+#: ./browser/templates/plonetabs.pt:115
+msgid "Advanced"
+msgstr ""
Index: quintagroup.plonetabs/trunk/quintagroup/plonetabs/locales/uk/LC_MESSAGES/quintagroup.plonetabs.po
===================================================================
--- quintagroup.plonetabs/trunk/quintagroup/plonetabs/locales/uk/LC_MESSAGES/quintagroup.plonetabs.po	(revision 873)
+++ quintagroup.plonetabs/trunk/quintagroup/plonetabs/locales/uk/LC_MESSAGES/quintagroup.plonetabs.po	(revision 873)
@@ -0,0 +1,228 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: quintagroup.plonetabs 0.5\n"
+"POT-Creation-Date: 2009-03-28 12:59+0000\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n"
+"Last-Translator: Vitaliy Podoba <piv@quintagroup.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: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+"Language-Code: uk\n"
+"Language-Name: Ukrainian\n"
+"Preferred-Encodings: utf-8 latin1\n"
+"Domain: quintagroup.plonetabs\n"
+
+#: ./browser/plonetabs.py:196
+msgid "'${id}' action deleted."
+msgstr "'${id}' елемент видалений."
+
+#: ./browser/plonetabs.py:557
+msgid "'${id}' action is now invisible."
+msgstr "'${id}' елемент тепер невидимий."
+
+#: ./browser/plonetabs.py:553
+msgid "'${id}' action is now visible."
+msgstr "'${id}' елемент тепер видимий."
+
+#: ./browser/plonetabs.py:235
+msgid "'${id}' action moved down."
+msgstr "'${id}' елемент переміщений до низу."
+
+#: ./browser/plonetabs.py:216
+msgid "'${id}' action moved up."
+msgstr "'${id}' елемент переміщений до верху."
+
+#: ./browser/plonetabs.py:175
+msgid "'${id}' action saved."
+msgstr "'${id}' елемент збережений."
+
+#: ./browser/plonetabs.py:149
+msgid "'${id}' action successfully added."
+msgstr "'${id}' елемент успішно доданий."
+
+#: ./browser/plonetabs.py:581
+msgid "'${id}' action successfully removed."
+msgstr "'${id}' елемент успішно видалений."
+
+#: ./browser/plonetabs.py:732
+msgid "'${id}' action successfully updated."
+msgstr "'${id}' елемент успішно оновлений."
+
+#: ./browser/plonetabs.py:531
+msgid "'${id}' object was excluded from navigation."
+msgstr "'${id}' об'єкт вилучений з навігації."
+
+#: ./browser/plonetabs.py:527
+msgid "'${id}' object was included into navigation."
+msgstr "'${id}' об'єкт тепер видимий для навігації."
+
+#: ./browser/plonetabs.py:778
+msgid "Actions successfully sorted."
+msgstr "Елементи успішно посортовані."
+
+#. Default: "Add"
+#: ./browser/templates/plonetabs.pt:141
+msgid "Add"
+msgstr "Додати"
+
+#: ./browser/plonetabs.py:672
+msgid "Adding canceled."
+msgstr "Додавання відмінено."
+
+#. Default: "Cancel"
+#: ./browser/templates/plonetabs.pt:142
+msgid "Cancel"
+msgstr "Відмінити"
+
+#: ./browser/plonetabs.py:473
+msgid "Category changed successfully."
+msgstr "Категорія успішно змінена."
+
+#: ./browser/plonetabs.py:706
+msgid "Changes discarded."
+msgstr "Зміни скасовані."
+
+#: ./browser/plonetabs.py:130
+msgid "Changes saved!"
+msgstr "Зміни збережені!"
+
+#: ./browser/plonetabs.py:693
+msgid "Fill in required fields and click on Add."
+msgstr "Заповніть обов'язкові поля і натисніть на кнопку Додати."
+
+#: ./browser/plonetabs.py:487
+msgid "Generated not folderish tabs switched off."
+msgstr "Генеровані не папкоподібні таби вимкнені."
+
+#: ./browser/plonetabs.py:481
+msgid "Generated not folderish tabs switched on."
+msgstr "Генеровані не папкоподібні таби увімкнені."
+
+#: ./browser/plonetabs.py:489
+msgid "Generated tabs switched off."
+msgstr "Генеровані таби вимкнені."
+
+#: ./browser/plonetabs.py:483
+msgid "Generated tabs switched on."
+msgstr "Генеровані таби увімкнені."
+
+#: ./browser/plonetabs.py:201
+msgid "No '${id}' action in '${cat_name}' category."
+msgstr "Не знайдено '${id}' елемента у '${cat_name}' категорії."
+
+#: ./browser/plonetabs.py:966
+msgid "'${cat_name}' action category does not exist."
+msgstr "'${cat_name}' категорія не існує."
+
+#: ./browser/plonetabs.py:530
+msgid "Object with '${id}' id doesn't exist in portal root."
+msgstr "Об'єкта з '${id}' id немає в корені сайту."
+
+#: ./browser/plonetabs.py:156
+msgid "Please correct the indicated errors."
+msgstr "Будь-ласка, виправте знайдені помилки."
+
+#. Default: "Reset"
+#: ./browser/templates/plonetabs.pt:143
+msgid "Reset"
+msgstr "Скинути"
+
+#. Default: "Select category to manage"
+#: ./browser/templates/plonetabs.pt:48
+msgid "label_select_category"
+msgstr "Оберіть категорію для редагування"
+
+#: ./browser/templates/changemodelink.pt:8
+msgid "Rich Mode"
+msgstr "Стандартний режим"
+
+#: ./browser/templates/changemodelink.pt:8
+msgid "Plain Mode"
+msgstr "Базовий HTML"
+
+#: ./browser/plonetabs.py:275
+msgid "Plone '${cat_name}' Configuration"
+msgstr "Конфігурація категорії: '${cat_name}'"
+
+#: ./profiles/default/propertiestool.xml:5
+msgid "Portal Tabs Configuration"
+msgstr "Конфігурація Табів"
+
+#: ./profiles/default/propertiestool.xml:6
+msgid "Portal Footer Configuration"
+msgstr "Конфігурація Колонтитула"
+
+#: ./browser/templates/plonetabs.pt:61
+msgid "Change"
+msgstr "Змінити"
+
+#: ./browser/templates/actionslist.pt:15
+msgid "Delete"
+msgstr "Знищити"
+
+#: ./browser/templates/actionslist.pt:48
+msgid "Name"
+msgstr "Ім'я"
+
+#: ./browser/templates/actionslist.pt:67
+msgid "URL (Expression)"
+msgstr "URL (TAL вираз)"
+
+#: ./browser/templates/actionslist.pt:82
+msgid "Id"
+msgstr "Id"
+
+#: ./browser/templates/actionslist.pt:97
+msgid "Condition (Expression)"
+msgstr "Умова (TAL вираз)"
+
+#: ./browser/templates/actionslist.pt:111
+msgid "Save"
+msgstr "Зберегти"
+
+#: ./browser/templates/actionslist.pt:115
+msgid "Move Up"
+msgstr "Вгору"
+
+#: ./browser/templates/actionslist.pt:117
+msgid "Move Down"
+msgstr "Вниз"
+
+#. Default: "Generate tabs for items other than folders"
+#: ./browser/templates/autogenerated.pt:46
+msgid "label_nonfolderish_tabs_enable"
+msgstr "Також автоматично створювати закладки для елементів що не є папками"
+
+#: ./browser/plonetabs.py:843
+msgid "Empty or invalid title specified"
+msgstr "Вказано порожнє або не дійсне ім'я"
+
+#: ./browser/plonetabs.py
+msgid "Empty or invalid id specified"
+msgstr "Вказано порожнє або не дійсне id"
+
+#: ./browser/plonetabs.py
+msgid "The id '${id}' is invalid - it is already in use."
+msgstr "Id '${id}' не є дійсним - воно уже використовується."
+
+#: ./browser/plonetabs.py
+msgid "Unrecognized expression type '${expr_type}'."
+msgstr "Недійсний тип виразу '${expr_type}'."
+
+#: ./browser/plonetabs.py
+msgid "Invalid variable name '${expr}'"
+msgstr "Недійсна назва змінної '${expr}'"
+
+#: ./browser/plonetabs.py
+msgid "Id must contain only ASCII characters."
+msgstr "Id повинно містити лише ASCII символи."
+
+#: ./browser/templates/plonetabs.pt:81
+msgid "Visible"
+msgstr "Видимість"
+
+#: ./browser/templates/plonetabs.pt:115
+msgid "Advanced"
+msgstr "Більше"
